2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-09-05 00:35:13 +00:00

remove the tests from 2_1 branch as they were not properly updated for 2_1

This commit is contained in:
John Johansen
2007-12-23 01:18:25 +00:00
parent b6eaf32985
commit 50d62e88a5
185 changed files with 0 additions and 12549 deletions

View File

@@ -1,123 +0,0 @@
#!/usr/bin/perl
# Test for ssh
use strict;
use Carp;
use Test;
use Term::ReadKey; # For password input
use Expect; # Testing of various things
# Global Vars
my $ssh = '/usr/bin/ssh'; # SSH binary
my $host = '127.0.0.1'; # Host to test
my $timeout = 10; # Timeout for expect calls
# Prompt for a username
BEGIN {
my $user = getlogin() || (getpwuid($<))[0];
ReadMode('normal');
print "Username to login as [$user]: ";
my $result = ReadLine(0);
chomp($result);
$user = ($result ne '') ? $result : $user;
# Prompt for a password
print "password for $user: ";
ReadMode('noecho');
my $password = ReadLine(0);
ReadMode('normal');
chomp($password);
croak "\nERROR: no password\n" if ($password eq '');
print "\n\n";
plan tests => 2; }
ok(sshd_alive(),0,"sshd is not running or not reachable");
ok(sshd_pass(),0,"sshd did not take your password");
sub sshd_alive {
my $exp;
my $result = 1;
my @options = ('-o RhostsAuthentication=no',
'-o RhostsRSAAuthentication=no',
'-o RSAAuthentication=no',
'-o HostbasedAuthentication=no',
'-o BatchMode=yes',
'-o CheckHostIP=no',
'-o StrictHostKeyChecking=yes',
"-o User=$user",
$host);
$exp = new Expect;
$exp->log_stdout(0);
$exp->spawn($ssh,@options) || return 1 && $exp->soft_close();
$exp->expect($timeout,
['Connection refused',sub { $result = 1}],
['No RSA',sub { $result = 0 }],
['Permission denied',sub { $result = 0}])
|| return 1 && $exp->soft_close();
$exp->soft_close();
return $result;
}
sub sshd_pass {
my $exp;
my $result = 1;
my @options = ('-o PasswordAuthentication=yes',
'-o RhostsAuthentication=no',
'-o RhostsRSAAuthentication=no',
'-o RSAAuthentication=no',
'-o HostbasedAuthentication=no',
'-o CheckHostIP=no',
'-o StrictHostKeyChecking=yes',
"-o User=$user",
$host);
$exp = new Expect;
$exp->log_stdout(0);
$exp->spawn($ssh,@options) || return 1 && $exp->soft_close();
$exp->expect($timeout,
['password:',sub { $exp->send("$password\r") }])
|| return 1 && $exp->soft_close();
$exp->clear_accum();
$exp->expect($timeout,
['Permission denied', sub { $result = 1; }],
['Last login:',sub { $result = 0; }])
|| return 1 && $exp->soft_close();
$exp->soft_close();
return $result;
}
sub sshd_rhosts {
my $exp;
my $result = 1;
my @options = ('-o PasswordAuthentication=no',
'-o RhostsAuthentication=yes',
'-o RhostsRSAAuthentication=no',
'-o RSAAuthentication=no',
'-o HostbasedAuthentication=no',
'-o CheckHostIP=no',
'-o StrictHostKeyChecking=yes',
"-o User=$user",
$host);
`cat $host $user > ~/.rhosts`;
$exp = new Expect;
$exp->log_stdout(0);
$exp->spawn($ssh,@options) || return 1 && $exp->soft_close();
$exp->expect($timeout,
['password:',sub { $exp->send("$password\r") }])
|| return 1 && $exp->soft_close();
$exp->clear_accum();
$exp->expect($timeout,
['Permission denied', sub { $result = 1; }],
['Last login:',sub { $result = 0; }])
|| return 1 && $exp->soft_close();
$exp->soft_close();
return $result;
}

View File

@@ -1,468 +0,0 @@
{\rtf1\ansi\deff1\adeflang1025
{\fonttbl{\f0\froman\fprq2\fcharset0 Nimbus Roman No9 L{\*\falt Times New Roman};}{\f1\froman\fprq2\fcharset0 Nimbus Roman No9 L{\*\falt Times New Roman};}{\f2\froman\fprq2\fcharset0 Times New Roman;}{\f3\froman\fprq2\fcharset0 Nimbus Roman No9 L{\*\falt Times New Roman};}{\f4\fswiss\fprq2\fcharset0 Nimbus Sans L{\*\falt Arial};}{\f5\fswiss\fprq2\fcharset0 Arial;}{\f6\fmodern\fprq0\fcharset0 Courier New;}{\f7\fnil\fprq0\fcharset2 StarSymbol;}{\f8\froman\fprq2\fcharset2 Symbol;}{\f9\fnil\fprq2\fcharset2 Wingdings;}{\f10\fmodern\fprq0\fcharset0 Courier;}{\f11\fnil\fprq2\fcharset0 Andale Sans UI{\*\falt Arial Unicode MS};}{\f12\froman\fprq0\fcharset0 MS Mincho{\*\falt \u65325 ?\u65331 ? \u26126 ?\u26397 ?};}{\f13\fnil\fprq2\fcharset0 Lucidasans;}{\f14\fnil\fprq0\fcharset0 Lucidasans;}}
{\colortbl;\red0\green0\blue0;\red128\green128\blue128;}
{\stylesheet{\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033\snext1 Default;}
{\s2\sa120\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033\sbasedon1\snext2 Text body;}
{\s3{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\rtlch\af14\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033\sbasedon2\snext3 List;}
{\s4\sb120\sa120\rtlch\af14\afs20\lang255\ai\ltrch\dbch\af11\afs20\langfe255\ai\loch\fs20\lang1033\i\sbasedon1\snext4 Caption;}
{\s5\rtlch\af14\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033\sbasedon1\snext5 Index;}
{\s6\sb240\sa120\keepn\rtlch\afs28\lang255\ltrch\dbch\afs28\langfe255\loch\f4\fs28\lang1033\sbasedon1\snext2 Heading;}
{\s7\sb240\sa60\keepn\rtlch\af5\afs32\lang255\ab\ltrch\dbch\af11\afs32\langfe255\ab\loch\f5\fs32\lang1033\b\sbasedon1\snext1{\*\soutlvl0} Heading 1;}
{\s8\sb240\sa60\keepn\rtlch\af5\afs28\lang255\ai\ab\ltrch\dbch\af11\afs28\langfe255\ai\ab\loch\f5\fs28\lang1033\i\b\sbasedon1\snext1{\*\soutlvl1} Heading 2;}
{\s9\rtlch\af6\afs20\lang255\ltrch\dbch\af11\afs20\langfe255\loch\f6\fs20\lang1033\sbasedon1\snext9 WW-Plain Text;}
{\*\cs11\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 2 1;}
{\*\cs12\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 2 2;}
{\*\cs13\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 2 3;}
{\*\cs14\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 2 4;}
{\*\cs15\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 2 5;}
{\*\cs16\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 2 6;}
{\*\cs17\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 2 7;}
{\*\cs18\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 2 8;}
{\*\cs19\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 2 9;}
{\*\cs20\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 2 10;}
{\*\cs21\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 1;}
{\*\cs22\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 2;}
{\*\cs23\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 3;}
{\*\cs24\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 4;}
{\*\cs25\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 5;}
{\*\cs26\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 6;}
{\*\cs27\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 7;}
{\*\cs28\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 8;}
{\*\cs29\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 9;}
{\*\cs30\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 10;}
{\*\cs31\cf0\rtlch\af1\afs24\lang255\ltrch\dbch\af1\afs24\langfe255\loch\f1\fs24\lang1033 RTF_Num 3 1;}
{\*\cs32\cf0\rtlch\af1\afs24\lang255\ltrch\dbch\af1\afs24\langfe255\loch\f1\fs24\lang1033 RTF_Num 3 2;}
{\*\cs33\cf0\rtlch\af1\afs24\lang255\ltrch\dbch\af1\afs24\langfe255\loch\f1\fs24\lang1033 RTF_Num 3 3;}
{\*\cs34\cf0\rtlch\af1\afs24\lang255\ltrch\dbch\af1\afs24\langfe255\loch\f1\fs24\lang1033 RTF_Num 3 4;}
{\*\cs35\cf0\rtlch\af1\afs24\lang255\ltrch\dbch\af1\afs24\langfe255\loch\f1\fs24\lang1033 RTF_Num 3 5;}
{\*\cs36\cf0\rtlch\af1\afs24\lang255\ltrch\dbch\af1\afs24\langfe255\loch\f1\fs24\lang1033 RTF_Num 3 6;}
{\*\cs37\cf0\rtlch\af1\afs24\lang255\ltrch\dbch\af1\afs24\langfe255\loch\f1\fs24\lang1033 RTF_Num 3 7;}
{\*\cs38\cf0\rtlch\af1\afs24\lang255\ltrch\dbch\af1\afs24\langfe255\loch\f1\fs24\lang1033 RTF_Num 3 8;}
{\*\cs39\cf0\rtlch\af1\afs24\lang255\ltrch\dbch\af1\afs24\langfe255\loch\f1\fs24\lang1033 RTF_Num 3 9;}
{\*\cs40\cf0\rtlch\af1\afs24\lang255\ltrch\dbch\af1\afs24\langfe255\loch\f1\fs24\lang1033 RTF_Num 3 10;}
{\*\cs41\cf0\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 1;}
{\*\cs42\cf0\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 2;}
{\*\cs43\cf0\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 3;}
{\*\cs44\cf0\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 4;}
{\*\cs45\cf0\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 5;}
{\*\cs46\cf0\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 6;}
{\*\cs47\cf0\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 7;}
{\*\cs48\cf0\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 8;}
{\*\cs49\cf0\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 9;}
{\*\cs50\cf0\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 RTF_Num 3 10;}
{\*\cs51\rtlch\af8\afs24\lang255\ltrch\dbch\af8\afs24\langfe255\loch\f8\fs24\lang1033 RTF_Num 5 1;}
{\*\cs52\rtlch\af6\afs24\lang255\ltrch\dbch\af6\afs24\langfe255\loch\f6\fs24\lang1033 RTF_Num 5 2;}
{\*\cs53\rtlch\af9\afs24\lang255\ltrch\dbch\af9\afs24\langfe255\loch\f9\fs24\lang1033 RTF_Num 5 3;}
{\*\cs54\rtlch\af8\afs24\lang255\ltrch\dbch\af8\afs24\langfe255\loch\f8\fs24\lang1033 RTF_Num 5 4;}
{\*\cs55\rtlch\af6\afs24\lang255\ltrch\dbch\af6\afs24\langfe255\loch\f6\fs24\lang1033 RTF_Num 5 5;}
{\*\cs56\rtlch\af9\afs24\lang255\ltrch\dbch\af9\afs24\langfe255\loch\f9\fs24\lang1033 RTF_Num 5 6;}
{\*\cs57\rtlch\af8\afs24\lang255\ltrch\dbch\af8\afs24\langfe255\loch\f8\fs24\lang1033 RTF_Num 5 7;}
{\*\cs58\rtlch\af6\afs24\lang255\ltrch\dbch\af6\afs24\langfe255\loch\f6\fs24\lang1033 RTF_Num 5 8;}
{\*\cs59\rtlch\af9\afs24\lang255\ltrch\dbch\af9\afs24\langfe255\loch\f9\fs24\lang1033 RTF_Num 5 9;}
{\*\cs60\cf0\rtlch\af1\afs24\lang255\ltrch\dbch\af1\afs24\langfe255\loch\f1\fs24\lang1033 RTF_Num 5 10;}
{\*\cs61\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 4 1;}
{\*\cs62\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 4 2;}
{\*\cs63\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 4 3;}
{\*\cs64\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 4 4;}
{\*\cs65\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 4 5;}
{\*\cs66\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 4 6;}
{\*\cs67\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 4 7;}
{\*\cs68\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 4 8;}
{\*\cs69\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 4 9;}
{\*\cs70\rtlch\afs24\lang255\ltrch\dbch\afs24\langfe255\loch\fs24\lang1033 RTF_Num 4 10;}
{\*\cs71\cf0\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\f1\fs24\lang1033 Numbering Symbols;}
{\*\cs72\cf0\rtlch\af7\afs18\lang255\ltrch\dbch\af7\afs18\langfe255\loch\f7\fs18\lang1033 Bullets;}
{\*\cs73\cf0\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\f8\fs24\lang1033 WW8Num1z0;}
{\*\cs74\cf0\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\f6\fs24\lang1033 WW8Num1z1;}
{\*\cs75\cf0\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\f9\fs24\lang1033 WW8Num1z2;}
{\*\cs76\cf0\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\f1\fs24\lang1033 WW-Default Paragraph Font;}
}{\*\listtable{\list\listtemplateid1
{\listlevel\levelnfc0\leveljc0\levelstartat3\levelfollow2{\leveltext \'02\'00.;}{\levelnumbers\'01;}\f8\f8\f8\fi-283\li283}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'01.;}{\levelnumbers\'01;}\f6\f6\f6\fi-283\li567}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'02.;}{\levelnumbers\'01;}\f9\f9\f9\fi-283\li850}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'03.;}{\levelnumbers\'01;}\f8\f8\f8\fi-283\li1134}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'04.;}{\levelnumbers\'01;}\f6\f6\f6\fi-283\li1417}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'05.;}{\levelnumbers\'01;}\f9\f9\f9\fi-283\li1701}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'06.;}{\levelnumbers\'01;}\f8\f8\f8\fi-283\li1984}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'07.;}{\levelnumbers\'01;}\f6\f6\f6\fi-283\li2268}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'08.;}{\levelnumbers\'01;}\f9\f9\f9\fi-283\li2551}
{\*\soutlvl{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'09.;}{\levelnumbers\'01;}\fi-283\li2835}}{\listname RTF_Num 5;}\listid1}
{\list\listtemplateid2
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u9679 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f7\fi-283\li283}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u9679 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f7\fi-283\li567}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u9679 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f7\fi-283\li850}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u9679 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f7\fi-283\li1134}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u9679 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f7\fi-283\li1417}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u9679 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f7\fi-283\li1701}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u9679 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f7\fi-283\li1984}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u9679 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f7\fi-283\li2268}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u9679 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f7\fi-283\li2551}
{\*\soutlvl{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u9679 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f7\fi-283\li2835}}{\listname RTF_Num 3;}\listid2}
{\list\listtemplateid3
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'00.;}{\levelnumbers\'01;}\fi-283\li283}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'01.;}{\levelnumbers\'01;}\fi-283\li567}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'02.;}{\levelnumbers\'01;}\fi-283\li850}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'03.;}{\levelnumbers\'01;}\fi-283\li1134}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'04.;}{\levelnumbers\'01;}\fi-283\li1417}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'05.;}{\levelnumbers\'01;}\fi-283\li1701}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'06.;}{\levelnumbers\'01;}\fi-283\li1984}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'07.;}{\levelnumbers\'01;}\fi-283\li2268}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'08.;}{\levelnumbers\'01;}\fi-283\li2551}
{\*\soutlvl{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'09.;}{\levelnumbers\'01;}\fi-283\li2835}}{\listname RTF_Num 4;}\listid3}
{\list\listtemplateid4\listsimple
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u61623 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f8\fi-360\li720}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u111 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f6\fi-360\li1440}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u61607 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f9\fi-360\li2160}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u61623 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f8\fi-360\li2880}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u111 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f6\fi-360\li3600}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u61607 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f9\fi-360\li4320}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u61623 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f8\fi-360\li5040}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u111 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f6\fi-360\li5760}
{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u61607 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f9\fi-360\li6480}
{\*\soutlvl{\listlevel\levelnfc23\leveljc0\levelstartat1\levelfollow2{\leveltext \'01\u61623 ?;}{\levelnumbers;}\f7\fs18\f7\fs18\f7\fs18\f8\fi-360\li7200}}{\listname WW8Num1;}\listid4}
{\list\listtemplateid5
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'00.;}{\levelnumbers\'01;}\fi-283\li283}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'01.;}{\levelnumbers\'01;}\fi-283\li567}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'02.;}{\levelnumbers\'01;}\fi-283\li850}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'03.;}{\levelnumbers\'01;}\fi-283\li1134}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'04.;}{\levelnumbers\'01;}\fi-283\li1417}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'05.;}{\levelnumbers\'01;}\fi-283\li1701}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'06.;}{\levelnumbers\'01;}\fi-283\li1984}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'07.;}{\levelnumbers\'01;}\fi-283\li2268}
{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'08.;}{\levelnumbers\'01;}\fi-283\li2551}
{\*\soutlvl{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow2{\leveltext \'02\'09.;}{\levelnumbers\'01;}\fi-283\li2835}}{\listname RTF_Num 2;}\listid5}
}{\listoverridetable{\listoverride\listid1\listoverridecount0\ls0}{\listoverride\listid2\listoverridecount0\ls1}{\listoverride\listid3\listoverridecount0\ls2}{\listoverride\listid4\listoverridecount0\ls3}{\listoverride\listid5\listoverridecount0\ls4}}
{\info{\comment StarWriter}{\vern6450}}\deftab720
{\*\pgdsctbl
{\pgdsc0\pgdscuse195\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\pgdscnxt0 Default;}}
{\*\pgdscno0}\paperh15840\paperw12240\margl1800\margr1800\margt1440\margb1440\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn1800\margrsxn1800\margtsxn1440\margbsxn1440\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc
\pard\plain \sb240\sa60\keepn\f2\fs32\b\f12\fs32\b\f2\fs32\b\qc\aspalpha \ltrpar\s7\qc\aspalpha\sb240\sa60\keepn\rtlch\af2\afs32\lang255\ab\ltrch\dbch\af12\afs32\langfe255\ab\loch\f2\fs32\lang1033\b {\loch\f2\fs32\lang1033\i0\b AppArmor regression test suite}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \sb240\sa60\keepn\f2\fs28\i\b\f12\fs28\i\b\f2\fs28\i\b\aspalpha \ltrpar\s8\aspalpha\sb240\sa60\keepn\ql\rtlch\af2\afs28\lang255\ai\ab\ltrch\dbch\af12\afs28\langfe255\ai\ab\loch\f2\fs28\lang1033\i\b {\loch\f2\fs28\lang1033\i\b Overview}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033 {\loch\f2\fs20\lang1033\i0\b0 The AppArmor regression test suite is designed to be an easily extensible family of tests where the individual tests are highly decomposed. Tests exist to check for regressions in the key areas of AppArmor functionality.}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033 {\loch\f2\fs20\lang1033\i0\b0 At the time of writing there are 26 tests that comprise the regression test suite. A dedicated shell script implements each test. Some of these tests are very simple verifying just a few basic operations ('open' for example) whilst others are highly compl
ex involving many subtests and techniques such as iteration over features and comparison of behavior ('capabilities' and 'exec_qual' for example). Regardless of the varying complexity each of these examples (shell scripts) utilize a common format and inf
rastructure support.}
\par \pard\plain \sb240\sa60\keepn\f2\fs28\i\b\f12\fs28\i\b\f2\fs28\i\b\aspalpha \ltrpar\s8\aspalpha\sb240\sa60\keepn\ql\rtlch\af2\afs28\lang255\ai\ab\ltrch\dbch\af12\afs28\langfe255\ai\ab\loch\f2\fs28\lang1033\i\b {\loch\f2\fs28\lang1033\i\b Running the Test Suite}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 The test suite is designed to be built and run from the main makefile using the command \lquote make tests\rquote . The test suite may be built without running it using the command \lquote make. Individual tests may be sun by the command \lquote sh <testname>.sh\rquote . The set of tes
tnames is defined in the makefile as variable TESTS.}
\par \pard\plain \sb240\sa60\keepn\f2\fs28\i\b\f12\fs28\i\b\f2\fs28\i\b\aspalpha \ltrpar\s8\aspalpha\sb240\sa60\keepn\ql\rtlch\af2\afs28\lang255\ai\ab\ltrch\dbch\af12\afs28\langfe255\ai\ab\loch\f2\fs28\lang1033\i\b {\loch\f2\fs28\lang1033\i\b Parsing the Results}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 As detailed above, each test comprising the test suite is controlled by a dedicated shell script (normally called <testname>.sh). This test will cycle through its subtests. Most shell scripts produce no output to the tty for a successful run (although t
he controlling makefile outputs \lquote running <testname>' before running each shell script) although some tests (capabilities for example) output the name of each subtest as it is run.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 In the case of an error, the test framework will output a diagnostic to the tty. Diagnostics are divided into two main areas, functional errors and unexpected errors. Functional errors occur are when the test executed but it did not function as expected
. For functional failure the test suite will output \lquote Error:\rdblquote followed by a description of the error. Unexpected errors are when either a test did executed in a way whereby the framework could not determine it\rquote s behavior or the framework itself experienced
an error.}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033 {\loch\f2\fs20\lang1033\i0\b0 Examples:}
\par \pard\plain {\listtext\pard\plain \li720\ri0\lin720\rin0\fi-360\f2\fs20\f12\fs20\f2\fs20\f7\fs18\f7\fs18\f7\fs18 \u61623 ?}\ilvl0 \ltrpar\s9\ls3\li720\ri0\lin720\rin0\fi-360\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033 {\loch\f2\fs20\lang1033\i0\b0 Functional error, test was expected to fail due to receipt of a signal but it passed:}
\par \pard\plain \ltrpar\s9\li1440\ri0\lin1440\rin0\fi0\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 Error: changehat_twice passed. Test 'CHANGEHAT (subprofile->subprofile w/ bad magic)' was expected to 'signal9'}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain {\listtext\pard\plain \li720\ri0\lin720\rin0\fi-360\f2\fs20\f12\fs20\f2\fs20\f7\fs18\f7\fs18\f7\fs18 \u61623 ?}\ilvl0 \ltrpar\s9\ls3\li720\ri0\lin720\rin0\fi-360\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033 {\loch\f2\fs20\lang1033\i0\b0 Functional error, test was expected to pass but it failed:}
\par \pard\plain \ltrpar\s9\li1440\ri0\lin1440\rin0\fi0\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 Error: open failed. Test 'OPEN RW' was expected to 'pass'.}
\par \pard\plain \ltrpar\s9\li1440\ri0\lin1440\rin0\fi0\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 Reason for failure 'FAIL: open /tmp/sdtest.13983-32704-z13990/file failed - Permission denied'}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain {\listtext\pard\plain \li720\ri0\lin720\rin0\fi-360\f2\fs20\f12\fs20\f2\fs20\f7\fs18\f7\fs18\f7\fs18 \u61623 ?}\ilvl0 \ltrpar\s9\ls3\li720\ri0\lin720\rin0\fi-360\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033 {\loch\f2\fs20\lang1033\i0\b0 Unexpected error, unable to execute a test:}
\par \pard\plain \ltrpar\s9\li1440\ri0\lin1440\rin0\fi0\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 Fatal Error (open): Unable to run test sub-executable}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain {\listtext\pard\plain \li720\ri0\lin720\rin0\fi-360\f2\fs20\f12\fs20\f2\fs20\f7\fs18\f7\fs18\f7\fs18 \u61623 ?}\ilvl0 \ltrpar\s9\ls3\li720\ri0\lin720\rin0\fi-360\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033 {\loch\f2\fs20\lang1033\i0\b0 Unexpected error< error in shell script (or in framework):}
\par \pard\plain \ltrpar\s9\li1440\ri0\lin1440\rin0\fi0\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 Fatal Error (open): Unexpected shell error. }
\par \pard\plain \ltrpar\s9\li1440\ri0\lin1440\rin0\fi0\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 Run with -x to debug}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 In dealing with a failure, the first step is to determine reproducibility. As previously mentioned, if you are running all of the tests via \lquote make tests\rquote you can rerun an individual test via \lquote sh <testname>.sh\rquote .}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 If the problem is reproducible, running the test with \lquote -r\rquote as the first argument, i.e. \lquote sh <testname>.sh -r\rquote will retain the files for the test that failed and the directory path to these files will be output to the tty. In this directory a script called
\lquote runtest\rquote will be present which can be used to rerun the first failing component of the test script outside of the test harness where it is easier to determine the problem. }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 Beyond this, knowledge of the actual test may be required to debug the problem further. See \ldblquote Design of Test Suite\rdblquote for technical information on how the tests are implemented.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 In the case of an unexpected error, running with the \lquote -r\rquote option will usually not he helpful as the test script or framework may have a problem. At this point, as indicated by the diagnostic, it is normally necessary to run the script with the -x option (
\lquote sh -x testname.sh\rquote ) and debug either the test script or the base framework. This is not for the uninitiated.}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \sb240\sa60\keepn\f5\fs28\i\b\f12\fs28\i\b\f5\fs28\i\b\aspalpha \ltrpar\s8\aspalpha\sb240\sa60\keepn\ql\rtlch\af5\afs28\lang255\ai\ab\ltrch\dbch\af12\afs28\langfe255\ai\ab\loch\f5\fs28\lang1033\i\b {\loch\f5\fs28\lang1033\i\b Pre-Requisites for running the suite}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 In order to compile the test suite the GNU C compiler (gcc) must be installed on the system plus necessary development tools such as make.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 In order to execute the tests the AppArmor module must be loaded and the AppArmor filesystem (normally /subdomain) must be mounted. In addition the AppArmor parser (normally /sbin/subdomain_parser but an alternate location may be specified in uservars.inc
) must be present. The parser and module must be compatible or errors will result during the loading of profiles during test suite execution.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 You must be root to run the test suite (it is not necessary to be root to build the suite however).}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033 {\loch\f2\fs20\lang1033\i0\b0 Note: Executing /etc/init.d/subdomain start as root will ensure that these requirements are met on a system with the SHASS software correctly installed.}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \sb240\sa60\keepn\f5\fs28\i\b\f12\fs28\i\b\f5\fs28\i\b\aspalpha \ltrpar\s8\aspalpha\sb240\sa60\keepn\ql\rtlch\af5\afs28\lang255\ai\ab\ltrch\dbch\af12\afs28\langfe255\ai\ab\loch\f5\fs28\lang1033\i\b {\loch\f5\fs28\lang1033\i\b Design of Test Suite}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 Each test consists of one controlling shell script and one or more executable files. This is a requirement of the test harness. Practically speaking most of the test functionality is of sufficient complexity that no shell api exists and functionality mus
t be implemented in an executable. Currently all executables are written in the C programming language.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 It is important to note that a functioning test is achieved by the correct operation of both the shell script and the executable. The framework requires certain behavior but outside of this the test author is free to design the test as they wish but the sh
ell script and executables must agree on their conventions in order to correctly implement the test.}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 The file \lquote prologue.inc\rquote implements most of the underlying shell framework. It must be loaded into the shell script before any other test functionality is performed. You will see it loaded via the shell \lquote .\rquote function at the start of each test shell script.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 By default, prologue.inc assumes the test binary is the same name as the shell script, with \lquote .sh\rquote removed. For test scripts with only one executable this makes things simple. You may want to have a single shell script run multiple executables (syscall.sh
for example). In this case, the \lquote settest\rquote function is used to select a new binary executable for this test.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 The \lquote genprofile\rquote function generates a profile based on passed arguments. The function automatically adds the necessary shared libraries and output files necessary to support the execution, it is not necessary to specify these manually. Therefore a call t
o genprofile without arguments will build a profile allowing the executable to run but without any additional access (which assuming the test application attempts to access files will most likely cause AppArmor to report a REJECTION). Specifying additional
arguments to genprofile in the form of <filename>:<perm> will allow additional access.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 Genprofile also allows capabilities to be specified, it uses the same syntax as specifying file permissions except the filename component is always the literal \lquote capability\rquote . For example, specifying \lquote capability:admin\rquote as an argument to genprofile will grant
the profile CAP_SYS_ADMIN.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 By default genprofile assumes it is creating a profile for the test binary corresponding to the current testname (shell script name minus trailing .sh or the name specified in a subsequent \lquote settest\rquote command). Normally this is sufficient but certain tests
require more complex profiles. Genprofile now supports two keywords \lquote subhat\rquote and \lquote image\rdblquote that allow complex profiles to be built which include subhats (necessary if the parent calls changehat) and support for more than one executable (useful if the primar
y test wants to pass control to a different executable which also must be controlled by a profile). The \lquote \emdash \lquote separator is used to separate each portion of the argument stream. The separator may be used multiple times on the same argument line but after ea
ch use the only token that may follow it is \lquote subhat=\rquote or \lquote image=\rquote .}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 The following is a simple example showing the use of the \lquote subhat\rquote keyword:}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 settest changehat_write}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 genprofile -- subhat=hat1 /tmp/file:rw -- subhat=hat2 /tmp/file2:rw}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 runchecktest "changehat (hat1 w access sub file1)" pass hat1 /tmp/file}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 runchecktest "changehat (hat1 w access sub file2)" fail hat1 /tmp/file2}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 runchecktest "changehat (hat2 w access sub file1)" pass hat2 /tmp/file}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 runchecktest "changehat (hat2 w access sub file2)" fail hat2 /tmp/file2}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 This sequence of actions generates a profile for the executable changehat_write. You will note that \lquote \emdash \lquote is the first argument after genprofile. This terminates the generation of files for the parent profile. This means that the only file entries for the p
arent hat will be those shared libraries and other support files automatically generated for changehat_write to begin execution (these files are determined by the function resolve_libs).}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 It also creates two subhats for the profile called \lquote hat1\rquote and \lquote hat2\rquote . Hat1 has rw access to file\rquote /tmp/file\rquote and hat2 has rw access to file \lquote /tmp/file2\rquote .}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 The changehat_write test attempts to change to the specified hat (passed to changehat_write as argv[1]), open, read and write to the file passed as argv[2].}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 It should be obvious from the profile and from the 4 calls to runchecktest (see below for a description of this function) that hat1 only has the necessary access to /tmp/file and hat2 only to /tmp/file2.}
\par \pard\plain \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 The following is an example showing the use of the \lquote image\rquote keyword:}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 settest fork_child}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 genprofile $bin/fork_child2:px -- image=$bin/fork_child2 /tmp/file1:rw}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 runchecktest "subexecutable w access" fail $bin/fork_child3 /tmp/file1}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 runchecktest "subexecutable w access" pass $bin/fork_child2 /tmp/file1}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 runchecktest "subexecutable w access" fail $bin/fork_child2 /tmp/file2}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 This generates two profiles, which are loaded in one operation. First is a profile for \lquote fork_child\rquote (implicitly $bin/fork_child) which in addition to containing access to the necessary library/support files also has \lquote px\rquote (meaning the profile must exist) a
ccess to fork_child2. A profile for the executable fork_child2 is also created again with access to the necessary libraries and support files and also with rw access to /tmp/file1. In this example, the executable fork_child forks and execs the file speci
fied as its argv[1] passing to this image argv[2] as the child\rquote s argv[1]. The child attempts to open, read and write it\rquote s argv[1]. Clearly the first test fails because the profile for fork_child does not grant execute access to fork_child3. The third te
st also fails because although fork_test2 was successfully executed, it\rquote s profile does not allow access to /tmp/file2.}
\par \pard\plain \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 Executing a test is achieved by calling the \lquote runchecktest\rquote function which will run either the executable matching the name of the shell script, or specified by settest. The first argument is a brief description of what the executable does in this mode, wh
ich is displayed in the event of an error. The second argument is either \ldblquote pass\rdblquote or \ldblquote fail\rdblquote indicating whether the test is expected to pass or fail. The executable is expected to output \ldblquote PASS\rdblquote for success and \ldblquote FAIL: <error message>\rdblquote in the event of a failu
re. If the executable outputs something other than this, the controlling shell script will interpret this as a test failure and output \ldblquote unable to run test sub executable\rdblquote and terminate. Remaining arguments to runchecktest are passed to the executable as
argv[1] .. argv[n].}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 The runchecktest command executes and checks the test serially. If a test requires to be run in the background, so that the shell may do subsequent operations, such as sending it a signal before checking it\rquote s output, this is accomplished by separately cal
ling \lquote runtestbg\rquote and \lquote checktestbg\rquote instead of calling \lquote runchecktest\rquote .}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 Profile loading, replacing and unloading is automatically handled by the shell script (via prologue.inc). Also, cleanup (tempfile removal and profile unloading) on exit is automatic.}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \sb240\sa60\keepn\f5\fs28\i\b\f12\fs28\i\b\f5\fs28\i\b\aspalpha \ltrpar\s8\aspalpha\sb240\sa60\keepn\ql\rtlch\af5\afs28\lang255\ai\ab\ltrch\dbch\af12\afs28\langfe255\ai\ab\loch\f5\fs28\lang1033\i\b {\loch\f5\fs28\lang1033\i\b Implementing a new test case}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033 {\loch\f2\fs20\lang1033\i0\b0 As an example, the text shell script for exec (exec.sh) is 24 lines and}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033 {\loch\f2\fs20\lang1033\i0\b0 may be used as a template for creating new simple tests (changehat.sh is}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033 {\loch\f2\fs20\lang1033\i0\b0 a good template for subprofile tests and rw.sh is a template for tests}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033 {\loch\f2\fs20\lang1033\i0\b0 requiring signal passing)}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 #! /bin/bash}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 pwd=`dirname $0`}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 pwd=`cd $pwd ; pwd`}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i {\loch\f2\fs20\lang1033\i\b0 bin must be set prior to including prologue.inc. This is the only requirement placed on the shell script author by prologue.inc}
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 bin=$pwd}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i {\loch\f2\fs20\lang1033\i\b0 prologie.inc must be included before running any tests}
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 . $bin/prologue.inc}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i {\loch\f2\fs20\lang1033\i\b0 variable definitions used by this script}
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 file=/bin/true}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 okperm=ix}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 badperm=r}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 # PASS TEST}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i {\loch\f2\fs20\lang1033\i\b0 generate a profile allowing ix access to /bin/true}
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 genprofile $file:$okperm}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i {\loch\f2\fs20\lang1033\i\b0 run this test (exec) passing /bin/true as argv[1]}
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i {\loch\f2\fs20\lang1033\i\b0 check it's output, it is expected to pass}
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 runchecktest "EXEC with x" pass $file}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 # NOLINK PERMTEST}
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i {\loch\f2\fs20\lang1033\i\b0 generate a new profile allowing only r access to /bin/true}
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i {\loch\f2\fs20\lang1033\i\b0 subdomain_parser will automatically be invoked in -r mode}
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 genprofile $file:$badperm}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i {\loch\f2\fs20\lang1033\i\b0 run this test (exec) passing /bin/true as argv[1]}
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i {\loch\f2\fs20\lang1033\i\b0 check it's output, it is expected to FAIL}
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 runchecktest "EXEC no x" fail $file}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs20\lang255\ai\ltrch\dbch\af12\afs20\langfe255\ai\loch\f2\fs20\lang1033\i {\loch\f2\fs20\lang1033\i\b0 That\rquote s it. Exit status $rc is automatically returned by epilogue.inc}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 The above shows the controlling shell script but this is only \'bd of the test. The other half is the source code for the \lquote exec\rquote executable. The following is the sample code:}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab #include <stdio.h>}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab #include <unistd.h>}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab #include <errno.h>}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab #include <sys/types.h>}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab #include <sys/wait.h>}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab #include <signal.h>}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab }
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab int main(int argc, char *argv[])}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \{}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab pid_t pid;}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab }
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab extern char **environ;}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab }
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \tab /* basic check of arguments}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \tab * runchecktest will pass the image to exec as argv[1]}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \tab */}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab if (argc < 2)\{}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab fprintf(stderr, "usage: %s program [args] \\n", argv[0]);}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab return 1;}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \}}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab }
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab pid=fork();}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab }
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab if (pid)\{ /* parent */}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab int status;}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab }
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab while (wait(&status) != pid);}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab }
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \tab \tab /* runchecktest requires output of}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \tab \tab * PASS}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \tab \tab * -or-}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \tab \tab * FAILED - reason}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \tab \tab */}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab if (WIFEXITED(status))\{}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab printf("PASS\\n");}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \}else\{}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \tab \tab \tab /* most likely because child sent us a sigkill}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \tab \tab \tab * because the exec was denied by AppArmor}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \tab \tab \tab */}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab fprintf(stderr, "FAILED, child did not exit"}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \tab \tab \tab \tab \tab "normally\\n");}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \}}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \}else\{}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab /* child */}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab (void)execve(argv[1], &argv[1], environ);}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab }
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab /* exec failed, kill outselves to flag parent */}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab (void)kill(getpid(), SIGKILL);}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \}}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab return 0;}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033 {\loch\f10\fs20\lang1033\i0\b0 \tab \}}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f10\fs20\lang1033
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af12\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 As you can see from these two examples, the test framework has certain requirements that the executable must adhere to (outputting PASS/FAIL and argument passing conventions are examples) but there is a fair degree of latitude in how to implement the test
to achieve the goals required (for example, the decision to fork a subprocess inside the executable, other tests pass signals back and forth between the shell script and the executable). What is important to understand is that although you may pick a diff
erent implementation strategy for different tests, for a given test, the functionality is achieved by both the shell script and the executable and they must operate correctly together.}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \sb240\sa60\keepn\f5\fs28\i\b\f11\fs28\i\b\f5\fs28\i\b\aspalpha \ltrpar\s8\aspalpha\sb240\sa60\keepn\ql\rtlch\af5\afs28\lang255\ai\ab\ltrch\dbch\af11\afs28\langfe255\ai\ab\loch\f5\fs28\lang1033\i\b {\loch\f5\fs28\lang1033\i\b Test Coverage}
\par \pard\plain \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 1.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 capabilities }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 The capabilities test is an attempt to determine that for a variety of syscalls, the expected capability (especially since Immunix intercepts capability processing for confined processes) and no others allows successful access. For every syscall in the t
est, we iterate over each capability individually (plus no capabilities) in order to verify that only the expected capability grants access to the privileged operation. The same is repeated for capabilities within hats. }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 The goal is to eventually extend this test verifying additional syscalls and also to perhaps do combinations of capabilities rather than just each individually.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 2.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 changehat }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 verifies basic file access permission checks for a parent profile and one subprofile/hat}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 3.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 changehat_fork }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 As 'changehat' but access checks for hats are verified across a fork}
\par \pard\plain \ltrpar\s2\li283\ri0\lin283\rin0\fi0\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 4.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 changehat_misc }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 Variety of tests verifying entry to subprofiles and return back to parent. AppArmor has rigid requirements around the correct use of the magic# token passed to changehat.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 5.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 chdir }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 Verify change directory functions correctly for a confined process. Subdomain should allow 'x' access on a directory without it being explicitly listed in tasks profile.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 6.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 exec }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 Currently this test verifies inherit (ix) functionality. Ensure that 'ix' is required in order to exec an executable. Support for 'px' and 'ux' needs to be added (see Future Work)}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 7.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 exec_qual }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 See 'matrix.doc' in the SubDomain/Documentation directory. This test currently verifies the enforce mode handling of exec between the various confinement conditions for execer and execee. }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 It needs to be extended to include the complain mode verification.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 8.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 fork }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 Verifies that profiles are duplicated correctly for fork (the subtask receives a copy of it's parents profile). The test attempts to access the files passed as arguments for both a parent and a child. The test is repeated for permissive and restrictive
profiles.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 9.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 link }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 Link requires 'l' permission and that permissions on the src and target must match. This test verifies matching, non-matching and missing link permissions in a profile.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 10.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 mmap }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 This test verifies that mmap based access control is also subject to the AppArmor profiles access specification. The test needs some attention/rethought, It is unclear what it's purpose really is. Also why does it fail when the profile is replaced with
just read permission as no mapped write is reattempted. Also a test should be added which causes the initial mmap write to fail (due to lack of write permission). }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 11.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 mount }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 This test verifies that the mount syscall is indeed restricted for confined processes.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 12.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 named_pipe }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 This test verifies that subdomain file access checks function correctly for named piped (nodes in the filesystem created with mknod). The test creates a parent/child process relationship which attempt to rendevous via the named pipe. The tests are attem
pted for unconfined and confined processes and also for subhats.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 13.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 open }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 Verify that the open syscall is correctly managed for confined profiles. A test should be added verifying for non-confined.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 14.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 owlsm }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 AppArmor implements a portion of the OWLSM functionality related to hard and symbolic links.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 Creating a hard link (as a non root user or more accurately, without CAP_FUSER) to a file owned by another user is disallowed. Following a symbolic link in a directory with the sticky bit set is not allowed if the link is owned by a different user than th
e directory. Note that these restrictions are for all processes, not just confined ones.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 15.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 pipe }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 This test is structured similarly to named_pipe except it uses the pipe(2) call to create a communication channel between parent and child rather than a node in the filesystem. AppArmor does not mediate pipe io for either confined or non confined process
es. This test verifies that io functions as expected for both an unconfined process and a confined process with an empty profile.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 16.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 ptrace}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 Read permission is required for a confined process to be able to be traced using ptrace. This test verifies this. Currently is it not functioning correctly. It stopped functioning correctly somewhere between 2.4.18 and 2.4.20.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 17.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 regex }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 This test verifies that tail globbing and regex globbing (perl regex engine) are functioning correctly for confined processes. Single character, multi character and character class regexes are verified.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 18.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 rename }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 The rename system call changes the name of a file in the filesystem. The test verifies that this operation (which involves AppArmor write and link permission checks) functions correctly for a confined process.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 19.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 readdir }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 AppArmor requires 'r' permission on a directory in order for a confined task to be able to read the directory contents. This test verifies this.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 20.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 rw }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 This test verifies read/write operation. AppArmor caches a successful open but checks (on read/write) to see if a confined processes profile has been replaced asynchronously. If it has, access is reevaluated. The test waits for a signal at which point
it reattempts to write, read and verify data. The controlling script performs a profile replacement before sending the signal for the test to reattempt the io.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 21.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 swap }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 Confined processes are prohibited from executing certain system calls entirely, including swapon(2) swapoff (2). This test verifies that unconfined processes can call these syscalls but confined processes cannot.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 22.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 setattr }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 Write permission is required in a confined processes profile in order to change the mode (chmod, chgrp, chown) of a file. This test verifies these system calls for unconfined and confined processes.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 23.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 symlink }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 As the 'link' test but for symbolic rather than hard links.}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 24.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 syscall }
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 Confined processes are prohibited from executing certain system calls entirely. This test checks a variety of such syscalls including ptrace, mknod, sysctl (write), sethostname, setdomainname, ioperm, iopl and reboot}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\sa120\f11\f13 25.}\ilvl0 \ltrpar\s2\ls4\li283\ri0\lin283\rin0\fi-283\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 unlink}
\par \pard\plain \ltrpar\s2\sa120\ql\rtlch\af13\afs24\lang255\ltrch\dbch\af11\afs24\langfe255\loch\fs24\lang1033 {\loch\f1\fs24\lang1033\i0\b0 In order to unlink a file, a confined process must have 'l' permission in it's profile for the relevant file. This test verifies this.}
\par \pard\plain \sb240\sa60\keepn\f5\fs28\i\b\f11\fs28\i\b\f5\fs28\i\b\aspalpha \ltrpar\s8\aspalpha\sb240\sa60\keepn\ql\rtlch\af5\afs28\lang255\ai\ab\ltrch\dbch\af11\afs28\langfe255\ai\ab\loch\f5\fs28\lang1033\i\b {\loch\f5\fs28\lang1033\i\b Future work/changes}
\par \pard\plain \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\f2\f2\f2\aspalpha 1.}\ilvl0 \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls2\aspalpha\li283\ri0\lin283\rin0\fi-283\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 Add metadata (comments) to each test which can be used to automatically generate test coverage data (as the above section risks getting out of date quickly).}
\par \pard\plain \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\li283\ri0\lin283\rin0\fi0\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\f2\f2\f2\aspalpha 2.}\ilvl0 \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls2\aspalpha\li283\ri0\lin283\rin0\fi-283\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 Test cases for the following need to be added:}
\par \pard\plain {\listtext\pard\plain \li1003\ri0\lin1003\rin0\fi-283\f2\f2\f2\aspalpha\f7\fs18\f7\fs18\f7\fs18 \u9679 ?}\ilvl0 \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\aspalpha\li1003\ri0\lin1003\rin0\fi-283\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 exec (unconstrained/ux and profile/px)}
\par \pard\plain {\listtext\pard\plain \li1003\ri0\lin1003\rin0\fi-283\f2\f2\f2\aspalpha\f7\fs18\f7\fs18\f7\fs18 \u9679 ?}\ilvl0 \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\aspalpha\li1003\ri0\lin1003\rin0\fi-283\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 add fork tests (for clone, vfork etc)}
\par \pard\plain {\listtext\pard\plain \li1003\ri0\lin1003\rin0\fi-283\f2\f2\f2\aspalpha\f7\fs18\f7\fs18\f7\fs18 \u9679 ?}\ilvl0 \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\aspalpha\li1003\ri0\lin1003\rin0\fi-283\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 add read/write tests (pread/pwrite/readv/writev)}
\par \pard\plain {\listtext\pard\plain \li1003\ri0\lin1003\rin0\fi-283\f2\f2\f2\aspalpha\f7\fs18\f7\fs18\f7\fs18 \u9679 ?}\ilvl0 \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\aspalpha\li1003\ri0\lin1003\rin0\fi-283\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 complain mode verification for exec (exec_qual). The enforce portion of the matrix has been completed.}
\par \pard\plain {\listtext\pard\plain \li1003\ri0\lin1003\rin0\fi-283\f2\f2\f2\aspalpha\f7\fs18\f7\fs18\f7\fs18 \u9679 ?}\ilvl0 \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\aspalpha\li1003\ri0\lin1003\rin0\fi-283\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 netdomain (complete tcp tests. Create udp tests including sendmsg). Lots to do.}
\par \pard\plain {\listtext\pard\plain \li1003\ri0\lin1003\rin0\fi-283\f2\f2\f2\aspalpha\f7\fs18\f7\fs18\f7\fs18 \u9679 ?}\ilvl0 \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\aspalpha\li1003\ri0\lin1003\rin0\fi-283\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 /proc/pid/attr tests. Verify current restrictions on who can changehat, who can setprofile etc.}
\par \pard\plain {\listtext\pard\plain \li1003\ri0\lin1003\rin0\fi-283\f2\f2\f2\aspalpha\f7\fs18\f7\fs18\f7\fs18 \u9679 ?}\ilvl0 \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\aspalpha\li1003\ri0\lin1003\rin0\fi-283\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 file descriptor passing via Unix domain sockets (normal and inside hat)}
\par \pard\plain {\listtext\pard\plain \li1003\ri0\lin1003\rin0\fi-283\f2\f2\f2\aspalpha\f7\fs18\f7\fs18\f7\fs18 \u9679 ?}\ilvl0 \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\aspalpha\li1003\ri0\lin1003\rin0\fi-283\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 reorganise structure of various changehat tests. }
\par \pard\plain {\listtext\pard\plain \li1003\ri0\lin1003\rin0\fi-283\f2\f2\f2\aspalpha\f7\fs18\f7\fs18\f7\fs18 \u9679 ?}\ilvl0 \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls1\aspalpha\li1003\ri0\lin1003\rin0\fi-283\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 Add more globbing (perl regex) tests}
\par \pard\plain \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\li720\ri0\lin720\rin0\fi0\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\f2\f2\f2\aspalpha\f8\f8\f8 3.}\ilvl0 \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls0\aspalpha\li283\ri0\lin283\rin0\fi-283\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 Resolve mediation of mkdir/rmdir}
\par \pard\plain {\listtext\pard\plain \li283\ri0\lin283\rin0\fi-283\f2\f2\f2\aspalpha\f8\f8\f8 4.}\ilvl0 \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\ls0\aspalpha\li283\ri0\lin283\rin0\fi-283\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033 {\loch\f2\fs24\lang1033\i0\b0 Resolve issues with ptrace failing (see README)}
\par \pard\plain \sb240\sa60\keepn\f5\fs28\i\b\f12\fs28\i\b\f5\fs28\i\b\aspalpha \ltrpar\s8\aspalpha\sb240\sa60\keepn\ql\rtlch\af5\afs28\lang255\ai\ab\ltrch\dbch\af12\afs28\langfe255\ai\ab\loch\f5\fs28\lang1033\i\b {\loch\f5\fs28\lang1033\i\b Additional Documentation}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033 {\loch\f2\fs20\lang1033\i0\b0 For additional information see the file 'README' in the test suite package.}
\par \pard\plain \ltrpar\s9\ql\rtlch\af2\afs20\lang255\ltrch\dbch\af12\afs20\langfe255\loch\f2\fs20\lang1033
\par \pard\plain \ltrpar\s1{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\aspalpha\ql\rtlch\af2\afs24\lang255\ltrch\dbch\af2\afs24\langfe255\loch\f2\fs24\lang1033
\par }

View File

@@ -1,181 +0,0 @@
# $Id$
#
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
SRC=access.c \
changehat.c \
changehat_fork.c \
changehat_misc.c \
changehat_misc2.c \
changehat_twice.c \
changehat_fail.c \
changehat_wrapper.c \
changehat_pthread.c \
chdir.c \
chgrp.c \
chmod.c \
chown.c \
clone.c \
deleted.c \
environ.c \
env_check.c \
exec.c \
exec_qual.c \
exec_qual2.c \
fchdir.c \
fchgrp.c \
fchmod.c \
fchown.c \
fork.c \
link.c \
mmap.c \
mkdir.c \
mount.c \
named_pipe.c \
net_raw.c \
open.c \
openat.c \
pipe.c \
ptrace.c \
ptrace_helper.c \
pwrite.c \
rename.c \
readdir.c \
rw.c \
symlink.c \
syscall_mknod.c \
swap.c \
syscall_chroot.c \
syscall_mlockall.c \
syscall_ptrace.c \
syscall_reboot.c \
syscall_setpriority.c \
syscall_sethostname.c \
syscall_setdomainname.c \
syscall_setscheduler.c \
syscall_sysctl.c \
tcp.c \
unix_fd_client.c \
unix_fd_server.c \
unlink.c \
xattrs.c
#only do the ioperm/iopl tests for x86 derived architectures
ifneq (,$(findstring $(shell uname -i),i386 i486 i586 i686 x86 x86_64))
SRC+=syscall_ioperm.c syscall_iopl.c
endif
# Suck, Fedora Core 3 no longer includes /sbin/kernelversion
KERNELVERSION:=$(shell if [ -x /sbin/kernelversion ] ; then \
/sbin/kernelversion ; \
else \
uname -r ; \
fi )
KERNELMAJOR:=$(shell echo ${KERNELVERSION} | cut -d. -f1)
KERNELMINOR:=$(shell echo ${KERNELVERSION} | cut -d. -f2)
CHANGEHAT_FLAGS=$(shell if [ ! -f /usr/include/sys/apparmor.h ] ; then \
if [ -f /usr/include/sys/immunix.h ] ; then \
echo -DUSE_COMPAT_IMMUNIX_H ; \
else \
(echo -DCHANGEHAT_NOT_IN_LIBRARY; \
[ $(KERNELMAJOR) -eq 2 ] && \
if [ $(KERNELMINOR) -eq 4 ] ; then \
echo -DCHANGEHAT_2_4_KERNEL ; \
elif [ $(KERNELMINOR) -eq 2 ] ; then \
echo -DCHANGEHAT_2_2_KERNEL ;\
fi ) \
fi ;\
fi )
LIBIMMUNIX:=$(shell if [ -f /usr/lib/libapparmor.so -o -f /usr/lib64/libapparmor.so ] ; then \
echo -lapparmor ; \
elif [ -f /lib/libimmunix.so.1 -o -f /lib64/libimmunix.so ] ; then \
echo -limmunix ; \
fi )
CFLAGS+=$(CHANGEHAT_FLAGS) $(LIBIMMUNIX) -Wall -Wstrict-prototypes
EXEC=$(SRC:%.c=%)
TESTS=access \
capabilities \
changehat \
changehat_fork \
changehat_misc \
chdir \
clone \
deleted \
environ \
exec \
exec_qual \
fchdir \
fork \
i18n \
link \
mkdir \
mmap \
mount \
mult_mount \
named_pipe \
net_raw \
open \
openat \
pipe \
ptrace \
pwrite \
regex \
rename \
readdir \
rw \
swap \
sd_flags \
setattr \
symlink \
syscall \
unix_fd_server \
unlink\
xattrs
# Tests that can crash the kernel should be placed here
RISKY_TESTS=longpath
all: $(EXEC) changehat.h
changehat_pthread: changehat_pthread.c changehat.h
${CC} ${CFLAGS} -lpthread -o $@ $<
tests: all
@if [ `whoami` = "root" ] ;\
then \
for i in $(TESTS) ;\
do \
echo ;\
echo "running $$i" ;\
bash $$i.sh ;\
done ;\
else \
echo "must be root to run tests" ;\
fi
alltests: all
@if [ `whoami` = "root" ] ;\
then \
for i in $(TESTS) $(RISKY_TESTS) ;\
do \
echo ;\
echo "running $$i" ;\
bash $$i.sh ;\
done ;\
else \
echo "must be root to run tests" ;\
fi
clean:
rm -f $(EXEC)
regex.sh: open exec

View File

@@ -1,238 +0,0 @@
Running tests
=============
Type "make tests" at the shell prompt, this will make the subprograms
and run the tests.
You must be root to execute make tests (a requirement of subdomain).
(There is also a 'make alltests', which adds a test for bug that, when
triggered, would cause the kernel to crash.)
Test output
===========
No output is displayed for a passing test. The makefile will output
running <testname> for each test.
Output other than this indicates a problem.
There are three typical failure scenarios:
- Test failed when it was expected to pass
- Test passed when it was expected to fail
- Unexpected shell error - the test harness encountered an unexpected
error.
Changing environment variables
==============================
Common user changeable environment variables are stored in the file
'uservars.inc'. Currently the path to the tmp directory, the path
to the subdomain_parser executable, and any additional arguments to give
to the parser are specified in this configuration file.
(Note: the tmp directory specified in uservars.inc will have an added
random string appended to it by the mktemp(1) program.)
Debugging test failures
=======================
In the event of a failure run the individual test harness using the -r (or
-retain) option. This will not remove the temporary test directory and will
display it's path. Inside the directory is a script called 'runtest' which
will rerun the last failed command.
Example:
# sh unlink.sh -r
Files retained in: /tmp/sdtest.25406-19681
#ls -l /tmp/sdtest.25406-19681
total 3
-rw-r--r-- 1 root root 0 Jul 2 11:51 file
-rw-r--r-- 1 root root 25 Jul 2 11:51 output.unlink
-rw-r--r-- 1 root root 182 Jul 2 11:51 profile
-rw-r--r-- 1 root root 292 Jul 2 11:51 runtest
Note that the contents of this directory (when -r is specified) is the output
of the final test contained within the controlling test harness, in this case
unlink.sh. If the harness passed, then output.unlink will contain the output
from the final run of the executable (which may indicate an expected error).
If there was an unexpected error (failed when pass was expected or passed when
failure was expected, or an unexpected test harness error), the controlling
test harness will abort processing further tests and the contents of the
directory will contain the files for the failed subtest.
It may be necessary to create certain temp files in this directory in order to
have the test function correctly, see the subdomain profile 'profile' in the
directory in order to determine which files may need to be created to support
the executable.
In order to debug more complicated test failures such as an expected
shell error (test harness error) it is usually necessary to rerun the test with
debugging enabled, for example:
# sh -x unlink.sh
Adding new tests
================
The test harness is designed to make adding new tests fairly simply.
Each test consists of one controlling shell script and one or more executable
files.
The file 'prologue.inc' must be loaded into the shell script. This file
contains the controlling logic and supporting shell functions.
By default, prologue.inc assumes the test binary is the same name as the shell
script, with '.sh' removed. For test scripts with only one executable this
makes things simple. You may want to have a single shell script run multiple
executables (syscall.sh for example). In this case, the 'settest' function is
used to select a new binary executable for this test.
The 'genprofile' function generates a profile based on passed arguments.
The function automatically adds the necessary shared libraries and output
files necessary to support the execution, it is not necessary to specify
these manually. Therefore a call to genprofile without arguments will build
a profile allowing the executable to run but without any additional access.
Specifying additional arguments to genprofile in the form of <filename>:<perm>
will allow additional access.
Support for changehat subprofiles is provided by the 'hat:<hatname>'
argument to genprofile. This will create a hat within the profile named
<hatname>. All following rules (file, net, or cap) up to the next "hat:"
argument or the end of the argument list will be included within this hat.
Support for multiple profiles within a single load (for example for
test that want to domain tansition to another profile) is supported by
the "image' argument to genprofile. This keyword preceeded by a '--'
seperator terminates the previous profile and creates a new profile for
the specified executable image.
Together, 'image' and 'hat:' allow complex profiles including subhats and
domain transitions to be specified via a single invocation of genprofile.
[Note: the old "-- subhat=<hatname>" mechanism for specifying hats is
no longer supported.]
Executing a test is achieved by calling the 'runchecktest' function which
will run either the executable matching the name of the shell script, or
specified by settest. The first argument is a brief description of what the
executable does in this mode, which is displayed in the event of an error.
The second argument is either "pass" or "fail" indicating whether the test
is expected to pass or fail. The executable is expected to output "PASS"
for success and "FAIL: <error message>" in the event of a failure. If the
executable outputs something other than this, the controlling shell script
will interpret this as a test failure and output "unable to run test sub
executable" and terminate. Remaining arguments to runchecktest are passed
to the executable as argv[1] .. argv[n].
The runchecktest command executes and checks the test serially. If a test
requires to be run in the background, so that the shell may do subsequent
operations, such as sending it a signal before checking it's output, this is
accomplished by separately calling 'runtestbg' and 'checktestbg' instead
of calling 'runchecktest'.
Profile loading, replacing and unloading is automatically handled by the
shell script (via prologue.inc). Also, cleanup (tempfile removal and
profile unloading) on exit is automatic.
As an example, the text shell script for exec (exec.sh) is 24 lines and
may be used as a template for creating new simple tests (changehat.sh is
a good template for subprofile tests and rw.sh is a template for tests
requiring signal passing)
#! /bin/bash
pwd=`dirname $0`
pwd=`cd $pwd ; pwd`
<bin must be set prior to including prologue.inc. This is the only>
<requirement placed on the shell script author by prologue.inc>
bin=$pwd
<prologie.inc must be included before running any tests>
. $bin/prologue.inc
<variable definitions used by this script?
file=/bin/true
okperm=x
badperm=r
# PASS TEST
<generate a profile allowing x access to /bin/true>
genprofile $file:$okperm
<run this test (exec) passing /bin/true as argv[1]>
<check it's output, it is expected to pass>
runchecktest "EXEC with x" pass $file
# NOLINK PERMTEST
<generate a new profile allowing only r access to /bin/true>
<subdomain_parser will automatically be invoked in -r mode>
genprofile $file:$badperm
<run this test (exec) passing /bin/true as argv[1]>
<check it's output, it is expected to FAIL>
runchecktest "EXEC no x" fail $file
<Thats it. Exit status $rc is automatically returned by epilogue.inc>
Additional documentation
========================
See the file 'subdomain_test.txt'
Supporting files
================
strace.sh Not a test harness, used to support strace testing.
mkprofile.sh Not a test harness, used to generate subdomain profiles.
prologue.inc Must be dotted (included) into the test harness. Provides
support routines.
epilogue.inc Cleanup support, automatically called upon successful or
unsuccessful exit
uservars.inc Contains variables that may need to be changed per user.
Makefile Makefile for building or running tests. Use 'make' to build,
'make tests' to run.
*.sh Controlling test harness
*.c Test executable.
Disabled tests
==============
Symlink mediation (symlink.sh) in AppArmor has been disabled.
It is too easy to defeat by creating a relative symlink and subsequently
moving the link.
Current failures
================
1) Changehat_misc
THIS IS NOT AN ERROR - per se.
Two killed messages will be output.
This is not an error, rather a sign that bash noticed the kernel had killed
a process which was attempting to use a bogus MAGIC number. Alas, there is
no way to get bash to not print this diagnostic
3) Ptrace
Error: open passed. Test 'STRACE OPEN (x confinement)'
was expected to 'fail'
Regression from 2.4.18 to 2.4.20. (We aren't sure on the first
endpoint, and the problem still happens in 2.4.20-20_imnx_10smp.)
4) Open
Error: open passed. Test 'OPEN W (create)' was expected to 'fail'
LSM issue. Flags passed to inode_permission are 0 if O_CREAT is used to
open file. Need to submit a patch to inode_create hook to receive the
O_RDWR flags. See https://bugs.wirex.com/show_bug.cgi?id=2885

View File

@@ -1 +0,0 @@
/* create clone testprogram */

View File

@@ -1 +0,0 @@
# create clone testruns

View File

@@ -1,2 +0,0 @@
/* Inherited exec
* This test to be completed */

View File

@@ -1,2 +0,0 @@
# Inherited exec
# This test case driver to be completed

View File

@@ -1,2 +0,0 @@
/* Unconstrained exec
* This test to be completed */

View File

@@ -1,2 +0,0 @@
# Unconstrained exec
# This test case driver to be completed

View File

@@ -1,2 +0,0 @@
read and write of a filedescriptor received over a unix domain socket,
both inside and outside of a change_hat.

View File

@@ -1,2 +0,0 @@

View File

@@ -1 +0,0 @@
create signal (kill) tests

View File

@@ -1 +0,0 @@
create signal (kill) tests

View File

@@ -1 +0,0 @@
pread and pwrite

View File

@@ -1 +0,0 @@
readv and writev scatter gather io

View File

@@ -1 +0,0 @@
add tests for sendfile

View File

@@ -1,8 +0,0 @@
/* tests need to be added for the following syscalls (one per C file)
* and linked into the syscall.sh driver
*
* create_module
* init_module
* delete_module
* vm86, vm86old (unsure if these are possible)
*/

View File

@@ -1 +0,0 @@
/* this test to be completed */

View File

@@ -1 +0,0 @@
# this test case driver to be completed

View File

@@ -1,59 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char *argv[])
{
int rc, mode;
char *path, *perm, *tmp;
if (argc != 3){
fprintf(stderr, "usage: %s path mode\n",
argv[0]);
return 1;
}
path=argv[1];
perm=argv[2];
tmp = perm;
mode = 0;
while (*tmp){
switch (*tmp){
case 'r': mode |= R_OK; break;
case 'w': mode |= W_OK; break;
case 'x': mode |= X_OK; break;
default: fprintf(stderr, "Invalid perm '%c'\n",
*tmp);
return 1;
}
tmp++;
}
rc=access(path, mode);
if (rc == -1){
fprintf(stderr, "FAIL: access %s %s failed - %s\n",
path, perm, strerror(errno));
return 1;
}
printf("PASS\n");
return 0;
}

View File

@@ -1,77 +0,0 @@
#! /bin/bash
# $Id:$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME access
#=DESCRIPTION
# Verify that the access syscall is correctly managed for confined profiles
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
file=$tmpdir/file
dir=$tmpdir/dir
rperm=r
rwxperm=rwix
wxperm=wix
touch $file
chmod 777 $file # full perms so discretionary access checks succeed
# PASS TEST
genprofile $file:$rwxperm
runchecktest "ACCESS file r (rwx)" pass $file r
runchecktest "ACCESS file rx (rwx)" pass $file rx
runchecktest "ACCESS file rwx (rwx)" pass $file rwx
genprofile $file:$rperm
runchecktest "ACCESS file r (r)" pass $file r
runchecktest "ACCESS file rx (r)" fail $file rx
runchecktest "ACCESS file rwx (r)" fail $file rwx
genprofile $file:$wxperm
runchecktest "ACCESS file x (wx)" pass $file x
runchecktest "ACCESS file w (wx)" pass $file w
runchecktest "ACCESS file wx (wx)" pass $file wx
genprofile $file:$wxperm
runchecktest "ACCESS file r (wx)" fail $file r
runchecktest "ACCESS file rx (wx)" fail $file rx
runchecktest "ACCESS file rwx (wx)" fail $file rwx
# wx are not necessary for directory write or traverse
# only r is required
mkdir $dir
chmod 777 $dir # full perms so discretionary access checks succeed
genprofile $dir:$rwxperm
runchecktest "ACCESS dir r (rwx)" pass $dir r
runchecktest "ACCESS dir rx (rwx)" pass $dir rx
runchecktest "ACCESS dir rwx (rwx)" pass $dir rwx
genprofile $dir:$rperm
runchecktest "ACCESS dir r (r)" pass $dir r
runchecktest "ACCESS dir rx (r)" pass $dir rx
runchecktest "ACCESS dir rwx (r)" pass $dir rwx
genprofile $dir:$wxperm
runchecktest "ACCESS dir x (wx)" pass $dir x
runchecktest "ACCESS dir w (wx)" pass $dir w
runchecktest "ACCESS dir wx (wx)" pass $dir wx
genprofile $dir:$wxperm
runchecktest "ACCESS dir r (wx)" fail $dir r
runchecktest "ACCESS dir rx (wx)" fail $dir rx
runchecktest "ACCESS dir rwx (wx)" fail $dir rwx

View File

@@ -1,127 +0,0 @@
#!/bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME capabilities
#=DESCRIPTION
# The capabilities test is an attempt to determine that for a variety of
# syscalls, the expected capability (especially since Immunix intercepts
# capability processing for confined processes) and no others allows successful
# access. For every syscall in the test, we iterate over each capability
# individually (plus no capabilities) in order to verify that only the expected
# capability grants access to the priviledged operation. The same is repeated
# for capabilities within hats.
#=END
# An attempt to verify what subdomain/posix capabilities actually grant
# access to. This overlaps _a lot_ with the syscall test.
# this now verifies that a capability functions within a changehat().
# FIXME: should test for a cap in the parent, but the need for the cap
# within the subprofile. Wow. oogly.
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. ./prologue.inc
TESTS="syscall_ptrace syscall_sysctl syscall_sethostname \
syscall_setdomainname syscall_setpriority syscall_setscheduler \
syscall_reboot syscall_chroot \
syscall_mlockall net_raw"
# FIXME/XXX - need a test case for syscall_mknod
#only do the ioperm/iopl tests for x86 derived architectures
case `uname -i` in
i386 | i486 | i586 | i686 | x86 | x86_64)
TESTS="$TESTS syscall_ioperm syscall_iopl"
;;
esac
CAPABILITIES="chown dac_override dac_read_search fowner fsetid kill \
setgid setuid setpcap linux_immutable net_bind_service \
net_broadcast net_admin net_raw ipc_lock ipc_owner \
sys_module sys_rawio sys_chroot sys_ptrace sys_pacct \
sys_admin sys_boot sys_nice sys_resource sys_time \
sys_tty_config mknod lease audit_write audit_control"
# defines which test+capability pairs should succeed.
syscall_reboot_sys_boot=TRUE
syscall_sethostname_sys_admin=TRUE
syscall_setdomainname_sys_admin=TRUE
syscall_setpriority_sys_nice=TRUE
syscall_setscheduler_sys_nice=TRUE
syscall_ioperm_sys_rawio=TRUE
syscall_iopl_sys_rawio=TRUE
syscall_chroot_sys_chroot=TRUE
syscall_mlockall_ipc_lock=TRUE
syscall_sysctl_sys_admin=TRUE
net_raw_net_raw=TRUE
# we completely disable ptrace(), but it's not clear if we should allow it
# when the sys_ptrace cap is specified.
# syscall_ptrace_sys_ptrace=TRUE
# if a test case requires arguments, add them here.
syscall_reboot_args=off
syscall_sethostname_args=a.dumb.example.com
syscall_setdomainname_args=dumb.example.com
syscall_ioperm_args="0 0x3ff"
syscall_iopl_args=3
syscall_chroot_args=${tmpdir}
# if a testcase requires extra subdomain rules, add them here
syscall_chroot_extra_entries="/:r ${tmpdir}:r"
testwrapper=changehat_wrapper
# needed for modern linux kernels
ulimit -l 0
for TEST in ${TESTS} ; do
echo " (${TEST#syscall_})"
my_arg=$(eval echo \${${TEST}_args})
my_entries=$(eval echo \${${TEST}_extra_entries})
settest ${TEST}
runchecktest "${TEST} -- unconfined" pass ${my_arg}
genprofile ${my_entries}
runchecktest "${TEST} -- no caps" fail ${my_arg}
# iterate through each of the capabilities
for cap in ${CAPABILITIES} ; do
if [ "X$(eval echo \${${TEST}_${cap}})" == "XTRUE" ] ; then
expected_result=pass
else
expected_result=fail
fi
genprofile cap:${cap} ${my_entries}
runchecktest "${TEST} -- capability ${cap}" ${expected_result} ${my_arg}
done
# okay, now check to see if the capability functions from within
# a subprofile.
# Eww, this is ugly. subprofile tests depend on the internal
# variable dynlibs defined by prologue.inc::settest
test_dynlibs=${dynlibs}
settest ${testwrapper}
genprofile hat:${TEST} ${test_dynlibs} ${bin}/${TEST}:rix ${my_entries}
runchecktest "${TEST} changehat -- no caps" fail ${TEST} ${my_arg}
for cap in ${CAPABILITIES} ; do
if [ "X$(eval echo \${${TEST}_${cap}})" == "XTRUE" ] ; then
expected_result=pass
else
expected_result=fail
fi
genprofile hat:${TEST} ${test_dynlibs} ${bin}/${TEST}:rix cap:${cap} ${my_entries}
runchecktest "${TEST} changehat -- capability ${cap}" ${expected_result} ${TEST} ${my_arg}
done
done

View File

@@ -1,49 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include "changehat.h"
int main(int argc, char *argv[])
{
int rc;
if (argc != 3){
fprintf(stderr, "usage: %s profile file\n",
argv[0]);
return 1;
}
/* change hat if hatname != nochange */
if (strcmp(argv[1], "nochange") != 0){
rc = change_hat(argv[1], SD_ID_MAGIC+1);
if (rc == -1){
fprintf(stderr, "FAIL: changehat %s failed - %s\n",
argv[1], strerror(errno));
exit(errno);
}
}
rc = do_open(argv[2]);
if (rc == 0)
printf("PASS\n");
return rc;
}

View File

@@ -1,92 +0,0 @@
/* $Id$ */
/* #define CHANGEHAT_NOT_IN_GLIB */
#define SD_ID_MAGIC 0x8c235e38
#ifdef CHANGEHAT_NOT_IN_LIBRARY
# ifdef CHANGEHAT_2_4_KERNEL
struct sd_hat {
char *hat_name;
unsigned int hat_magic;
};
#define __NR_security 223
#define SD_CHANGE_HAT 10
_syscall3(int, security, unsigned int, id, unsigned int, call, unsigned long *, args);
int change_hat (char * subprofile, unsigned int token)
{
struct sd_hat hat;
unsigned int id = SD_ID_MAGIC;
hat.hat_name=subprofile;
hat.hat_magic = token;
return security(id, SD_CHANGE_HAT, (unsigned long*)&hat);
}
# else
# ifdef CHANGEHAT_2_2_KERNEL
#define __NR_change_hat 230
_syscall2(int, change_hat, char *, subdomain, unsigned int, magic_token);
# endif /* CHANGEHAT_2_2_KERNEL */
# endif /* CHANGEHAT_2_4_KERNEL */
#else /* !CHANGEHAT_NOT_IN_LIBRARY */
#ifdef USE_COMPAT_IMMUNIX_H
#include <sys/immunix.h>
#else
#include <sys/apparmor.h>
#endif /* USE_COMPAT_IMMUNIX_H */
#endif /* CHANGEHAT_NOT_IN_LIBRARY */
#include <fcntl.h>
#include <string.h>
inline int do_open (char * file)
{
int fd, rc;
char buf[128];
const char *data="hello world";
fd=open(file, O_RDWR, 0);
if (fd == -1){
fprintf(stderr, "FAIL: open %s failed - %s\n",
file,
strerror(errno));
return 1;
}
rc=write(fd, data, strlen(data));
if (rc != strlen(data)){
fprintf(stderr, "FAIL: write failed - %s\n",
strerror(errno));
return 1;
}
(void)lseek(fd, 0, SEEK_SET);
rc=read(fd, buf, sizeof(buf));
if (rc != strlen(data)){
fprintf(stderr, "FAIL: read failed - %s\n",
strerror(errno));
return 1;
}
if (memcmp(buf, data, strlen(data)) != 0){
fprintf(stderr, "FAIL: comparison failed - %s\n",
strerror(errno));
return 1;
}
close(fd);
return 0;
}

View File

@@ -1,64 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME changehat
#=DESCRIPTION
# Verifies basic file access permission checks for a parent profile and one
# subprofile/hat
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
file=$tmpdir/file
subfile=$tmpdir/file2
okperm=rw
subtest=sub
subtest2=sub2
subtest3=sub3
touch $file $subfile
# CHANGEHAT UNCONFINED
runchecktest "CHANGEHAT (unconfined - nochange)" pass nochange $file
runchecktest_errno EPERM "CHANGEHAT (unconfined)" fail $subtest $file
# NO CHANGEHAT TEST
genprofile $file:$okperm
runchecktest "NO CHANGEHAT (access parent file)" pass nochange $file
runchecktest "NO CHANGEHAT (access sub file)" fail nochange $subfile
# CHANGEHAT NO HATS TEST
runchecktest "CHAGEHAT (no hats, nochange)" pass nochange $file
runchecktest_errno ECHILD "CHANGEHAT (no hats, $file)" fail $subtest $file
runchecktest_errno ECHILD "CHANGEHAT (no hats, $subfile)" fail $subtest $subfile
# CHANGEHAT TEST
genprofile $file:$okperm hat:$subtest $subfile:$okperm
runchecktest "CHANGEHAT (access parent file)" fail $subtest $file
runchecktest "CHANGEHAT (access sub file)" pass $subtest $subfile
# CHANGEHAT TEST -- multiple subprofiles
genprofile $file:$okperm hat:$subtest $subfile:$okperm hat:$subtest2 $subfile:$okperm hat:$subtest3 $subfile:$okperm
runchecktest "CHANGEHAT (access parent file)" fail $subtest $file
runchecktest "CHANGEHAT (access sub file)" pass $subtest $subfile
runchecktest "CHANGEHAT (access sub file)" pass $subtest2 $subfile
runchecktest "CHANGEHAT (access sub file)" pass $subtest3 $subfile

View File

@@ -1,59 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include "changehat.h"
int main(int argc, char *argv[])
{
if (argc != 2){
fprintf(stderr, "usage: %s profile\n",
argv[0]);
return 1;
}
/* change hat if hatname != nochange */
if (strcmp(argv[1], "nochange") != 0){
if (change_hat(argv[1], SD_ID_MAGIC+1)) {
/* In a null-profile at this point, all file
* i/o is restricted including stdout.
* Need to change back to parent. If the
* changehat back fails, no point trying to print
* any error, so (void) call.
*/
(void)change_hat(NULL, SD_ID_MAGIC+1);
fprintf(stderr, "FAIL: changehat %s failed - %s\n",
argv[1], strerror(errno));
exit(1);
}
}
if (strcmp(argv[1], "nochange") != 0) {
if (change_hat(NULL, SD_ID_MAGIC ^ 0xdeadbeef)) {
fprintf(stderr, "FAIL: changehat %s failed - %s\n",
argv[1], strerror(errno));
exit(1);
}
}
printf("PASS\n");
return 0;
}

View File

@@ -1,88 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include "changehat.h"
int main(int argc, char *argv[])
{
int rc;
pid_t pid;
int waitstatus;
int innullprofile=0;
if (argc != 3){
fprintf(stderr, "usage: %s profile file\n",
argv[0]);
return 1;
}
/* change hat if hatname != nochange */
if (strcmp(argv[1], "nochange") != 0){
rc = change_hat(argv[1], SD_ID_MAGIC+1);
/* we want to test what happens when change_hat fails,
* changehat.c tests will fail if you can't change_hat
* at all. */
if (rc != 0){
/* changehat failed, we are likely in a null
* profile at this point
*/
innullprofile=1;
}
}
pid = fork();
if (pid == -1) {
fprintf(stderr, "FAIL: fork failed - %s\n",
strerror(errno));
exit(1);
} else if (pid != 0) {
/* parent */
rc = wait(&waitstatus);
if (rc == -1){
fprintf(stderr, "FAIL: wait failed - %s\n",
strerror(errno));
exit(1);
}
} else {
/* child */
exit(do_open(argv[2]));
}
/* If in a null profile, change hat back to parent */
if (strcmp(argv[1], "nochange") != 0 && innullprofile){
rc = change_hat(NULL, SD_ID_MAGIC+1);
}
if ((WIFEXITED(waitstatus) != 0) && (WEXITSTATUS(waitstatus) == 0)) {
printf("PASS\n");
} else {
/* if in null profile, FAIL output from do_open will
* have been suppressed, so output a FAIL here now
* that we have changehatted back to parent
*/
if (innullprofile){
printf("FAIL %d\n", WEXITSTATUS(waitstatus));
}
}
return 0;
}

View File

@@ -1,66 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME changehat_fork
#=DESCRIPTION
# As 'changehat' but access checks for hats are verified across a fork
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
file=$tmpdir/file
subfile=$tmpdir/file2
okperm=rw
touch $file $subfile
# NO CHANGEHAT TEST
genprofile $file:$okperm
runchecktest "NO CHANGEHAT (access parent file)" pass nochange $file
runchecktest "NO CHANGEHAT (access sub file)" fail nochange $subfile
# CHANGEHAT TEST
subtest=sub
genprofile $file:$okperm hat:$subtest $subfile:$okperm
runchecktest "CHANGEHAT (access parent file)" fail $subtest $file
runchecktest "CHANGEHAT (access sub file)" pass $subtest $subfile
# CHANGEHAT TEST -- multiple subprofiles
subtest2=sub2
subtest3=sub3
genprofile $file:$okperm hat:$subtest $subfile:$okperm hat:$subtest2 $subfile:$okperm hat:$subtest3 $subfile:$okperm
runchecktest "CHANGEHAT (access parent file)" fail $subtest $file
runchecktest "CHANGEHAT (access sub file)" pass $subtest $subfile
runchecktest "CHANGEHAT (access sub file)" pass $subtest2 $subfile
runchecktest "CHANGEHAT (access sub file)" pass $subtest3 $subfile
# CHANGEHAT TEST -- non-existent subprofile access
# Should put us into a null-profile
subtest2=$test.sub2
subtest3=$test.sub3
genprofile $file:$okperm hat:$subtest $subfile:$okperm hat:$subtest2 $subfile:$okperm
runchecktest "CHANGEHAT (access parent file)" fail $subtest3 $file
runchecktest "CHANGEHAT (access sub file)" fail $subtest3 $subfile

View File

@@ -1,58 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include "changehat.h"
int main(int argc, char *argv[])
{
int rc;
if (argc != 3){
fprintf(stderr, "usage: %s profile file\n",
argv[0]);
return 1;
}
/* change hat if hatname != nochange */
if (strcmp(argv[1], "nochange") != 0){
if (change_hat(argv[1], SD_ID_MAGIC+1)) {
fprintf(stderr, "FAIL: changehat %s failed - %s\n",
argv[1], strerror(errno));
exit(1);
}
}
if (strcmp(argv[1], "nochange") != 0){
if (change_hat(NULL, SD_ID_MAGIC+1)) {
fprintf(stderr, "FAIL: changehat %s failed - %s\n",
argv[1], strerror(errno));
exit(1);
}
}
rc = do_open(argv[2]);
if (rc != 0)
return rc;
printf("PASS\n");
return 0;
}

View File

@@ -1,111 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME changehat_misc
#=DESCRIPTION
# Variety of tests verifying entry to subprofiles and return back to parent.
# AppArmor has rigid requirements around the correct use of the magic# token
# passed to changehat.
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
file=$tmpdir/file
subfile=$tmpdir/file2
okperm=rw
subtest=sub
subtest2=sub2
touch $file $subfile
# NO CHANGEHAT TEST
genprofile $file:$okperm
runchecktest "NO CHANGEHAT (access parent file)" pass nochange $file
runchecktest "NO CHANGEHAT (access sub file)" fail nochange $subfile
# CHANGEHAT TEST - test if can enter and exit a subprofile
genprofile $file:$okperm hat:$subtest $subfile:$okperm
runchecktest "CHANGEHAT (access parent file)" pass $subtest $file
runchecktest "CHANGEHAT (access sub file)" fail $subtest $subfile
# CHANGEHAT - test enter subprofile -> fork -> exit subprofile
settest changehat_misc2
genprofile $file:$okperm hat:$subtest $subfile:$okperm
runchecktest "FORK BETWEEN CHANGEHATS (access parent file)" pass $subtest $file
runchecktest "FORK BETWEEN CHANGEHATS (access sub file)" fail $subtest $subfile
# CHANGEHAT FROM ONE SUBPROFILE TO ANOTHER
settest changehat_twice
genprofile hat:$subtest $subfile:$okperm hat:$subtest2 $file:$okperm
runchecktest "CHANGEHAT (subprofile->subprofile)" pass $subtest $subtest2 goodmagic $file
echo
echo "*** A 'Killed' message from bash is expected for the following test"
runchecktest "CHANGEHAT (subprofile->subprofile w/ bad magic)" signal9 $subtest $subtest2 badmagic $file
# 1. ATTEMPT TO CHANGEGAT TO AN INVALUD PROFILE, SHOULD PUT US INTO A NULL
# PROFILE
# 2. ATTEMPT TO CHANGEHAT OUT WITH BAD TOKEN
settest changehat_fail
genprofile hat:$subtest
runchecktest "CHANGEHAT (bad subprofile)" fail ${subtest2}
echo
echo "*** A 'Killed' message from bash is expected for the following test"
runchecktest "CHANGEHAT (bad token)" signal9 ${subtest}
# Attempt to changehat out of a profile when the magic token is 0
# ugh, need dynlibs from open test
settest open
open_dynlibs=${dynlibs}
settest changehat_wrapper
genprofile hat:open ${dynlibs} ${bin}/open:rix ${file}:${okperm}
runchecktest "CHANGEHAT (noexit subprofile (token=0))" pass --token=0 open ${file}
runchecktest "CHANGEHAT (exit noexit subprofile (token=0))" fail --token=0 --exit_hat open ${file}
if [ -f /proc/self/attr/current ] ; then
# do some tests of writing directly to /proc/self/attr/current, skipping
# libimmunx. Only do these tests if the extended attribute exists.
runchecktest "CHANGEHAT (subprofile/write to /proc/attr/current)" pass --manual=123456 open ${file}
runchecktest "CHANGEHAT (exit subprofile/write to /proc/attr/current)" pass --manual=123456 --exit_hat open ${file}
runchecktest "CHANGEHAT (noexit subprofile/write 0 to /proc/attr/current)" pass --manual=0 open ${file}
runchecktest "CHANGEHAT (noexit subprofile/write 00000000 to /proc/attr/current)" pass --manual=00000000 open ${file}
# verify that the kernel accepts the command "changehat ^hat\0" and
# treats an empty token as 0.
runchecktest "CHANGEHAT (noexit subprofile/write \"\" to /proc/attr/current)" fail --manual="" open ${file}
runchecktest "CHANGEHAT (exit of noexit subprofile/write 0 to /proc/attr/current)" fail --manual=0 --exit_hat open ${file}
runchecktest "CHANGEHAT (exit of noexit subprofile/write 00000000 to /proc/attr/current)" fail --manual=00000000 --exit_hat open ${file}
runchecktest "CHANGEHAT (exit of noexit subprofile/write \"\" to /proc/attr/current)" fail --manual="" --exit_hat open ${file}
fi
# CHANGEHAT and PTHREADS: test that change_hat functions correctly in
# the presence of threads
settest changehat_pthread
genprofile $file:$okperm "/proc/**:w" hat:fez $subfile:$okperm "/proc/**:w"
runchecktest "CHANGEHAT PTHREAD (access parent file)" fail $file
runchecktest "CHANGEHAT PTHREAD (access sub file)" pass $subfile

View File

@@ -1,81 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include "changehat.h"
int main(int argc, char *argv[])
{
int rc;
pid_t pid;
int waitstatus;
if (argc != 3){
fprintf(stderr, "usage: %s profile file\n",
argv[0]);
return 1;
}
/* change hat if hatname != nochange */
if (strcmp(argv[1], "nochange") != 0){
rc = change_hat(argv[1], SD_ID_MAGIC+1);
/* we want to test what happens when change_hat fails,
* changehat.c tests will fail if you can't change_hat
* at all. */
}
pid = fork();
if (pid == -1) {
fprintf(stderr, "FAIL: fork failed - %s\n",
strerror(errno));
exit(1);
} else if (pid != 0) {
/* parent */
rc = wait(&waitstatus);
if (rc == -1){
fprintf(stderr, "FAIL: wait failed - %s\n",
strerror(errno));
exit(1);
}
} else {
/* child */
if (strcmp(argv[1], "nochange") != 0){
rc = change_hat(NULL, SD_ID_MAGIC+1);
if (rc == -1){
fprintf(stderr, "FAIL: changehat %s failed - %s\n",
argv[1], strerror(errno));
exit(1);
}
}
exit(do_open(argv[2]));
}
/* printf ("0x%x WIFEXITED = 0x%x WEXITSTATUS = 0x%x\n", waitstatus,
WIFEXITED(waitstatus), WEXITSTATUS(waitstatus)); */
if ((WIFEXITED(waitstatus) != 0) && (WEXITSTATUS(waitstatus) == 0)) {
printf("PASS\n");
} else {
return WEXITSTATUS(waitstatus);
}
return 0;
}

View File

@@ -1,62 +0,0 @@
/* $Id:$ */
/*
* Copyright (C) 2006 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <sys/syscall.h>
#include "changehat.h"
void static inline dump_me(const char *msg)
{
//printf("(%d/%ld/0x%lx) %s\n", getpid(), syscall(SYS_gettid), pthread_self(), msg);
}
static int is_done;
static int thread_rc;
void *worker (void *param)
{
char *file = (char *) param;
int rc;
dump_me("worker called, changing hat");
change_hat ("fez", 12345);
rc = do_open(file);
dump_me("worker changed hat");
change_hat (NULL, 12345);
if (rc == 0) {
printf("PASS\n");
}
thread_rc = rc;
is_done = 1;
return 0;
}
int main (int argc, char **argv)
{
pthread_t child_process;
if (argc != 2) {
fprintf(stderr, "FAIL: usage '%s <filename>'\n", argv[0]);
exit(1);
}
dump_me("main");
pthread_create(&child_process, NULL, worker, argv[1]);
while (!is_done) {
sleep(1);
}
exit(thread_rc);
}

View File

@@ -1,65 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include "changehat.h"
int main(int argc, char *argv[])
{
int rc, magic;
if (argc != 5){
fprintf(stderr, "usage: %s profile1 profile2 goodmagic|badmagic file\n",
argv[0]);
return 1;
}
/* change hat if hatname != nochange */
if (strcmp(argv[1], "nochange") != 0){
rc = change_hat(argv[1], SD_ID_MAGIC+1);
if (rc == -1){
fprintf(stderr, "FAIL: changehat %s failed - %s\n",
argv[1], strerror(errno));
exit(1);
}
}
magic=SD_ID_MAGIC+1;
if (strcmp(argv[3], "badmagic") == 0){
magic^=0xdeadbeef;
}
if (strcmp(argv[1], "nochange") != 0){
rc = change_hat(argv[2], magic);
if (rc == -1){
fprintf(stderr, "FAIL: changehat %s failed - %s\n",
argv[1], strerror(errno));
exit(1);
}
}
rc = do_open(argv[4]);
if (rc != 0)
return rc;
printf("PASS\n");
return 0;
}

View File

@@ -1,198 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
/* this program serves as a wrapper program that does a change_hat call
* before fork()ing and exec()ing another test prorgram. This way we can
* perform some of the additional testcases within a subhat without
* duplicating the fork/exec/changehat code. The big assumption that
* must be true (and is part of subdomain's semantics is that an
* inherited profile that is currently in a subprofile will stay that
* way across fork()/exec(). */
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <linux/unistd.h>
#include "changehat.h"
#define ATTR_FILE "/proc/self/attr/current"
struct option long_options[] =
{
{ "token", 1, 0, 0 }, /* set the magic token */
{ "manual", 1, 0, 0 }, /* manually write to /proc/self/attr/current
for change_hat */
{ "exit_hat", 0, 0, 0 }, /* whether to attempt to exit the hat */
{ "help", 0, 0, 0 },
};
static void usage (char * program) {
fprintf(stderr, "usage: %s testprogram [arguments]\n",
program);
fprintf(stderr, "%s\n", "$Id$");
exit(1);
}
int manual_change_hat (char * subprofile, char * token_string) {
int fd, rc;
char * buf;
int ret = 0;
fd = open(ATTR_FILE, O_WRONLY);
if (fd < 0) {
perror("FAIL: unable to open control file");
exit(1);
}
rc = asprintf(&buf, "changehat %s^%s",
token_string ? token_string : "",
subprofile ? subprofile : "");
if (rc < 0) {
fprintf(stderr, "FAIL: asprintf failed\n");
exit(1);
}
rc = write (fd, buf, strlen(buf));
close(fd);
if (rc != strlen(buf)) {
if (rc == -1) {
ret = errno;
} else {
ret = EPROTO;
}
}
return ret;
}
int main(int argc, char *argv[]) {
int rc;
pid_t pid;
int waitstatus;
int filedes[2];
int c, o;
char buf[BUFSIZ];
unsigned int magic_token = SD_ID_MAGIC+1;
int manual = 0;
int exit_hat = 0;
char * manual_string;
while ((c = getopt_long (argc, argv, "+", long_options, &o)) != -1) {
if (c == 0) {
switch (o) {
case 0:
magic_token = strtoul (optarg, NULL, 10);
break;
case 1:
manual = 1;
manual_string =
(char *) malloc(strlen(optarg) + 1);
if (!manual_string) {
fprintf(stderr, "FAIL: malloc failed\n");
exit(1);
}
strcpy(manual_string, optarg);
break;
case 2:
exit_hat = 1;
break;
case 3:
usage(argv[0]);
break;
default:
usage(argv[0]);
break;
}
} else {
usage(argv[0]);
}
}
if (!argv[optind])
usage(argv[0]);
rc = pipe(filedes);
if (rc != 0) {
perror("FAIL: pipe failed");
exit(1);
}
pid = fork();
if (pid == -1) {
fprintf(stderr, "FAIL: fork failed - %s\n",
strerror(errno));
exit(1);
} else if (pid != 0) {
/* parent */
close(filedes[1]);
read(filedes[0], &buf, sizeof(buf));
rc = wait(&waitstatus);
if (rc == -1){
fprintf(stderr, "FAIL: wait failed - %s\n",
strerror(errno));
exit(1);
}
} else {
/* child */
char * pname = malloc (strlen(argv[optind]) + 3);
if (!pname) {
perror ("FAIL: child malloc");
return -1;
}
sprintf (pname, "./%s", argv[optind]);
rc = !manual ? change_hat(argv[optind], magic_token)
: manual_change_hat(argv[optind], manual_string);
if (rc != 0) {
rc = !manual ? change_hat(NULL, magic_token)
: manual_change_hat(NULL, manual_string);
fprintf(stderr, "FAIL: hat for %s does not exist\n",
argv[optind]);
exit(1);
}
close(filedes[0]);
fclose(stdout);
rc = dup2(filedes[1], STDOUT_FILENO);
if (rc < 0) {
perror("FAIL: pipe failed");
exit(1);
}
exit(execv(pname, &argv[optind]));
}
if (exit_hat) {
rc = !manual ? change_hat(NULL, magic_token)
: manual_change_hat(NULL, manual_string);
/* shouldn't fail, if it does, we've been killed */
if (rc != 0) {
fprintf(stderr, "FAIL: exiting hat '%s' failed\n",
argv[optind]);
exit(1);
}
}
if ((WEXITSTATUS(waitstatus) == 0) && strcmp("PASS\n", buf) == 0) {
printf("PASS\n");
}
return WEXITSTATUS(waitstatus);
}

View File

@@ -1,32 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "usage: %s dir\n",
argv[0]);
return 1;
}
if (chdir(argv[1]) == 0) {
printf("PASS\n");
} else {
printf("FAIL - %s\n", strerror(errno));
}
return 0;
}

View File

@@ -1,36 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME chdir
#=DESCRIPTION
# Verify change directory functions correctly for a confined process. Subdomain
# should allow 'x' access on a directory without it being explicitly listed in
# tasks profile.
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
dir=$tmpdir/tmpdir
mkdir $dir
# CHDIR TEST
# no profile, verify we didn't break normal chdir
runchecktest "CHDIR" pass $dir
# null profile, verify chdir (x) functions
genprofile
runchecktest "CHDIR" pass $dir

View File

@@ -1,45 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char *argv[])
{
gid_t gid;
if (argc != 3) {
fprintf(stderr, "usage: %s file groupname|gid\n",
argv[0]);
return 1;
}
if (sscanf(argv[2], "%d", &gid) != 1) {
fprintf(stderr, "FAIL: bad gid %s\n", argv[2]);
return 1;
}
if (chown(argv[1], -1, gid) == -1) {
fprintf(stderr, "FAIL: chgrp %s %d failed - %s\n",
argv[1], gid, strerror(errno));
return 1;
}
printf("PASS\n");
return 0;
}

View File

@@ -1,44 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char *argv[])
{
mode_t mode;
if (argc != 3) {
fprintf(stderr, "usage: %s file mode\n",
argv[0]);
return 1;
}
if (sscanf(argv[2], "%o", &mode) != 1) {
fprintf(stderr, "FAIL: bad mode %s\n", argv[2]);
return 1;
}
if (chmod(argv[1], mode) == -1) {
fprintf(stderr, "FAIL: fchmod %s %o failed - %s\n",
argv[1], mode, strerror(errno));
return 1;
}
printf("PASS\n");
return 0;
}

View File

@@ -1,44 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char *argv[])
{
uid_t uid;
if (argc != 3) {
fprintf(stderr, "usage: %s file username|uid\n",
argv[0]);
return 1;
}
if (sscanf(argv[2], "%d", &uid) != 1) {
fprintf(stderr, "FAIL: bad uid %s\n", argv[2]);
return 1;
}
if (chown(argv[1], uid, -1) == -1) {
fprintf(stderr, "FAIL: chown %s %d failed - %s\n",
argv[1], uid, strerror(errno));
return 1;
}
printf("PASS\n");
return 0;
}

View File

@@ -1,117 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2007 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <sched.h>
#include <linux/unistd.h>
struct option long_options[] =
{
{"newns", 0, 0, 'n'}, /* create a new namespace */
{"help", 0, 0, 'h'},
};
static void usage (char * program) {
fprintf(stderr, "usage: %s [arguments]\n",
program);
fprintf(stderr, "%s\n", "$Id$");
exit(1);
}
static int filedes[2] = {-1, -1};
static int do_child(void *arg)
{
int rc;
close(filedes[0]);
fclose(stdout);
rc = dup2(filedes[1], STDOUT_FILENO);
if (rc < 0) {
perror("FAIL: pipe failed");
return 1;
}
rc = write(filedes[1], "PASS\n", strlen("PASS\n"));
if (rc < 0) {
perror("FAIL: write failed");
return 1;
}
return 0;
}
int main(int argc, char *argv[])
{
int rc;
int waitstatus;
int c;
char buf[BUFSIZ];
void *child_stack = malloc(PAGE_SIZE << 4);
int clone_flags = 0;
while ((c = getopt_long (argc, argv, "+hn", long_options, NULL)) != -1) {
switch (c) {
case 'n':
clone_flags |= CLONE_NEWNS;
break;
case 'h':
usage(argv[0]);
break;
default:
usage(argv[0]);
break;
}
}
if (argv[optind])
usage(argv[0]);
rc = pipe(filedes);
if (rc != 0) {
perror("FAIL: pipe failed");
exit(1);
}
rc = clone(&do_child, child_stack, clone_flags, NULL);
if (rc < 0) {
perror("FAIL: clone failed");
exit(1);
}
/* parent */
rc = waitpid(-1, (&waitstatus), __WALL);
close(filedes[1]);
read(filedes[0], &buf, sizeof(buf));
if (rc == -1){
fprintf(stderr, "FAIL: wait failed - %s\n",
strerror(errno));
exit(1);
}
if ((WEXITSTATUS(waitstatus) == 0) && strcmp("PASS\n", buf) == 0) {
printf("PASS\n");
}
return WEXITSTATUS(waitstatus);
}

View File

@@ -1,41 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME clone
#=DESCRIPTION
# Verifies that clone is allowed under AppArmor, but that CLONE_NEWNS is
# restriced.
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
# TEST1 unconfined
runchecktest "CLONE/unconfined" pass
# TEST2. confined
genprofile
runchecktest "CLONE/confined" pass
# TEST3. confined + CLONE_NEWNS
genprofile
runchecktest "CLONE/confined/NEWNS" fail --newns
# TEST4. confined + CLONE_NEWNS + cap_sys_admin
genprofile cap:sys_admin
runchecktest "CLONE/confined/NEWNS" pass --newns

View File

@@ -1,21 +0,0 @@
int *ptr;
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
main()
{
printf("This will cause a sigsegv\n");
ptr=0;
*ptr=0xdeadbeef;
return 0;
}

View File

@@ -1,70 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME coredump
#=DESCRIPTION coredump test
checkcorefile()
{
_corefilelist=`echo core.*`
if [ "$_corefilelist" = "core.*" ]
then
_corefile=no
else
_corefile=yes
fi
if [ "$1" = "yes" -a "$_corefile" = "no" ]
then
echo "Error: corefile expected but not present - $2"
elif [ "$1" = "no" -a "$_corefile" = "yes" ]
then
echo "Error: corefile present when not expected -- $2"
fi
unset _corefile _corefilelist
rm -f core.*
}
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
coreperm=r
nocoreperm=ix
# enable coredumps
ulimit -c 1000000
# PASS TEST, no confinement
echo "*** A 'Segmentation Fault' message from bash is expected for the following test"
runchecktest "COREDUMP (no confinement)" signal11
checkcorefile yes "COREDUMP (no confinement)"
# PASS TEST, with r confinement
genprofile $test:$coreperm
cat $profile
echo
echo "*** A 'Segmentation Fault' message from bash is expected for the following test"
runchecktest "COREDUMP ($coreperm confinement)" signal11
checkcorefile yes "COREDUMP ($coreperm confinement)"
# FAIL TEST, with x confinement
genprofile $test:$nocoreperm
cat $profile
echo
echo "*** A 'Segmentation Fault' message from bash is expected for the following test"
runchecktest "COREDUMP ($nocoreperm confinement)" signal11
checkcorefile no "COREDUMP ($nocoreperm confinement)"

View File

@@ -1,137 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include "changehat.h"
/* A test to validate that we are properly handling the kernel appending
* (deleted) in d_path lookup.
* To acheive this the file is opened (the read/write of the file is just to
* make sure everything is working as expected), deleted without closing the
* file reference, and doing a changehat.
* The file is then used inside of the changehat. This forces the file
* access permission to be revalidated which will cause a path lookup and
* expose if the module is not handling the kernel appending (deleted).
*/
int main(int argc, char *argv[])
{
int fd, fd2, rc;
int ret = 0; /* run through all tests to see what breaks */
const char *data="hello world";
char buf[128];
if (argc != 3){
int i;
fprintf(stderr, "usage: %s hat file\n",
argv[0]);
for (i=0; i < argc; i++) {
fprintf(stderr, "arg%d: %s\n", i, argv[i]);
}
return 1;
}
fd = open(argv[2], O_RDWR, 0);
if (fd == -1){
fprintf(stderr, "FAIL: open %s before changehat failed - %s\n",
argv[2],
strerror(errno));
return 1;
}
rc = write(fd, data, strlen(data));
if (rc != strlen(data)){
fprintf(stderr, "FAIL: write before changehat failed - %s\n",
strerror(errno));
return 1;
}
rc = unlink(argv[2]);
if (rc == -1){
fprintf(stderr, "FAIL: unlink before changehat failed - %s\n",
strerror(errno));
return 1;
}
if (strcmp(argv[1], "nochange") != 0){
rc = change_hat(argv[1], SD_ID_MAGIC+1);
if (rc == -1){
fprintf(stderr, "FAIL: changehat %s failed - %s\n",
argv[1], strerror(errno));
exit(1);
}
}
/******** The actual tests for (deleted) begin here *******/
/* changehat causes revalidation */
(void)lseek(fd, 0, SEEK_SET);
rc = read(fd, buf, sizeof(buf));
if (rc != strlen(data)){
fprintf(stderr, "FAIL: read1 after changehat failed - %s\n",
strerror(errno));
ret = 1;
}
/* test that we can create the file. Not necessarily a (deleted)
* case but lets use flush out other combinations
*/
fd2=creat(argv[2], S_IRUSR | S_IWUSR);
if (fd2 == -1){
fprintf(stderr, "FAIL: creat %s - %s\n",
argv[2],
strerror(errno));
ret = 1;
}
close(fd2);
/* reread after closing the created file, this should be revalidated
* and force a lookup that still has (deleted) appended
*/
(void)lseek(fd, 0, SEEK_SET);
rc=read(fd, buf, sizeof(buf));
if (rc != strlen(data)){
fprintf(stderr, "FAIL: read2 after changehat failed - %s\n",
strerror(errno));
ret = 1;
}
close(fd);
/* should be able to open it. Shouldn't have (deleted) */
fd=open(argv[2], O_RDWR, 0);
if (fd == -1){
fprintf(stderr, "FAIL: open %s after creat failed - %s\n",
argv[2],
strerror(errno));
ret = 1;
}
close(fd);
/* Hmm it would be nice to add a fork/exec test for (deleted) but
* changehat does it for now.
*/
if (!ret)
printf("PASS\n");
return ret;
}

View File

@@ -1,123 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME deleted
#=DESCRIPTION
# Test subdomain is properly working around a kernel in which the kernel
# appends (deleted) to deleted files verifies that the d_path appending
# (deleted) fix is working
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
file=$tmpdir/file
file2="$tmpdir/file (deleted)"
okperm=rwl
subtest=sub
touch $file
touch "$file2"
# NO PROFILE TEST
runchecktest "NO PROFILE (access file)" pass nochange $file
runchecktest "NO PROFILE (access file (deleted))" pass nochange "$file2"
# NO CHANGEHAT TEST - doesn't force revalidation
genprofile $file:$okperm
runchecktest "NO CHANGEHAT (access file)" pass nochange $file
genprofile "$file2":$okperm
runchecktest "NO CHANGEHAT (access file (delete))" pass nochange "$file2"
# CHANGEHAT TEST - force revalidation using changehat
genprofile $file:$okperm hat:$subtest $file:$okperm
runchecktest "CHANGEHAT (access file)" pass $subtest $file
genprofile "$file2":$okperm hat:$subtest "$file2":$okperm
runchecktest "CHANGEHAT (access file (deleted))" pass $subtest "$file2"
# EXEC TEST - force revalidation using a fork exec that inherits the open file
# but uses a different profile
settest unix_fd_server
file=${tmpdir}/file
socket=${tmpdir}/unix_fd_test
fd_client=$PWD/unix_fd_client
okperm=rwl
badperm=wl
# Content generated with:
# dd if=/dev/urandom bs=32 count=4 2> /dev/null | od -x | head -8 | sed -e 's/^[[:xdigit:]]\{7\}//g' -e 's/ //g'
cat > ${file} << EOM
aabcc2739c621194a00b6cb7875dcdeb
72f485a783219817c81c65f3e1b2bc80
4366ba09e881286c834e67b34ae6f186
ccc2c402fcc6e66d5cfaa0c68b94211c
163f7beeb9a320ab859189a82d695713
175797a8cf2e2435dd98551385e96d8f
05f82e8e0e146be0d4655d4681cb08b6
ed15ad1d4fb9959008589e589206ee13
EOM
# lets just be on the safe side
rm -f ${socket}
# PASS - unconfined client
genprofile $file:$okperm $socket:rw $fd_client:ux
runchecktest "fd passing; unconfined client" pass $file $socket $fd_client "delete_file"
sleep 1
cat > ${file} << EOM
aabcc2739c621194a00b6cb7875dcdeb
72f485a783219817c81c65f3e1b2bc80
4366ba09e881286c834e67b34ae6f186
ccc2c402fcc6e66d5cfaa0c68b94211c
163f7beeb9a320ab859189a82d695713
175797a8cf2e2435dd98551385e96d8f
05f82e8e0e146be0d4655d4681cb08b6
ed15ad1d4fb9959008589e589206ee13
EOM
rm -f ${socket}
# PASS - confined client, rw access to the file
genprofile $file:$okperm $socket:rw $fd_client:px -- image=$fd_client $file:$okperm $socket:rw
runchecktest "fd passing; confined client w/ rw" pass $file $socket $fd_client "delete_file"
sleep 1
cat > ${file} << EOM
aabcc2739c621194a00b6cb7875dcdeb
72f485a783219817c81c65f3e1b2bc80
4366ba09e881286c834e67b34ae6f186
ccc2c402fcc6e66d5cfaa0c68b94211c
163f7beeb9a320ab859189a82d695713
175797a8cf2e2435dd98551385e96d8f
05f82e8e0e146be0d4655d4681cb08b6
ed15ad1d4fb9959008589e589206ee13
EOM
rm -f ${socket}
# FAIL - confined client, w access to the file
genprofile $file:$okperm $socket:rw $fd_client:px -- image=$fd_client $file:$badperm $socket:rw
runchecktest "fd passing; confined client w/ w only" fail $file $socket $fd_client "delete_file"
sleep 1
rm -f ${socket}

View File

@@ -1,70 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
/* this is a simple wrapper program that attempts to drop privileges
* before exec()ing the first argument passed in. This is at least
* useful for the owlsm hardlink test, which can't run as root. */
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <pwd.h>
#define __USE_GNU
#include <unistd.h>
#define NOPRIVUSER "nobody"
#define NOPRIVUID 65534
int main(int argc, char *argv[])
{
int rc;
uid_t newuid;
struct passwd * passwd;
char * pname = NULL;
if (argc < 2){
fprintf(stderr, "usage: %s testprogram [arguments]\n",
argv[0]);
return 1;
}
while ((passwd = getpwent())) {
/* printf ("DEBUG: %s\n", passwd->pw_name); */
if (strcmp (passwd->pw_name, NOPRIVUSER) == 0)
break;
}
if (passwd) {
newuid = passwd->pw_uid;
} else {
newuid = (uid_t) NOPRIVUID;
}
rc = setresuid (newuid, newuid, newuid);
if (rc != 0) {
perror ("FAIL: attempted to drop privs");
return errno;
}
pname = malloc (strlen(argv[1]) + 3);
if (!pname) {
perror ("FAIL: malloc");
return 1;
}
sprintf (pname, "./%s", argv[1]);
exit(execv(pname, &argv[1]));
}

View File

@@ -1,42 +0,0 @@
/* $Id$ */
/* Copyright (C) 2002-2006 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char *argv[])
{
char *var, *val, *p, *envval;
if (argc < 2 || !(p = strchr(argv[1], '='))) {
fprintf(stderr, "Usage: %s VAR=value\n", argv[0]);
return 1;
}
var = strndup(argv[1], p - argv[1]);
val = strdup(p + 1);
envval = getenv(var);
if (!envval) {
fprintf(stderr, "FAIL: environment variable not found\n");
return 1;
}
if (strcmp(envval, val) != 0) {
fprintf(stderr, "FAIL: environment variable differs: expected '%s', found '%s'\n",
val, envval);
return 1;
}
return 0;
}

View File

@@ -1,33 +0,0 @@
#!/bin/bash
#
# $Id$
#
# Copyright (C) 2002-2006 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
if [ -z "$1" ] ; then
echo "Usage: $0 var=value"
exit 1;
fi
VAR=${1%%=*}
VALUE=${1#*=}
ENVVAL=$(eval echo \${$VAR})
#echo ENVVAL = $ENVVAL
if [ -z "${ENVVAL}" ] ; then
echo "FAIL: Environment variable \$$VAR is unset"
exit 1;
fi
if [ "${ENVVAL}" != "${VALUE}" ] ; then
echo "FAIL: Environment variable \$$VAR differs; expected $VALUE got ${ENVVAL}"
exit 1;
fi
exit 0

View File

@@ -1,82 +0,0 @@
/* $Id$ */
/* Copyright (C) 2002-2006 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#define RET_FAILURE 0
#define RET_SUCCESS 1
#define RET_CHLD_SUCCESS 2
#define RET_CHLD_FAILURE 3
#define RET_CHLD_SIGNAL 4
int interp_status(int status)
{
int rc;
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) == 0) {
rc = RET_CHLD_SUCCESS;
} else {
rc = RET_CHLD_FAILURE;
}
} else {
rc = RET_CHLD_SIGNAL;
}
return rc;
}
int main(int argc, char *argv[])
{
pid_t pid;
int status;
int retval = 1;
if (argc < 3 || !strchr(argv[2], '=')) {
fprintf(stderr, "Usage: %s program VAR=value\n", argv[0]);
return 1;
}
putenv(strdup(argv[2]));
pid = fork();
if (pid > 0) {
/* parent */
while (wait(&status) != pid);
/* nothing */
if (!WIFSTOPPED(status)) {
retval = interp_status(status);
}
if (retval == RET_CHLD_SUCCESS) {
printf("PASS\n");
retval = 0;
}
} else if (pid == 0) {
/* child */
retval = execl(argv[1], argv[1], argv[2], (char *) NULL);
return retval;
} else {
/* error */
perror("FAIL: fork() failed:");
return 1;
}
return retval;
}

View File

@@ -1,93 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME environ
#=DESCRIPTION
# verify bprm_unsafe filtering occurs for Px and Ux.
#
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
helper=$pwd/env_check
setuid_helper=${tmpdir}/env_check
helper_sh=$pwd/env_check.sh
# TEST environment filtering on elf binaries
genprofile $helper:ux
runchecktest "ENVIRON (elf): ux & regular env" pass $helper FOO=BAR
runchecktest "ENVIRON (elf): ux & sensitive env" pass $helper LD_LIBRARY_PATH=.
genprofile $helper:Ux
runchecktest "ENVIRON (elf): Ux & regular env" pass $helper FOO=BAR
runchecktest "ENVIRON (elf): Ux & sensitive env" fail $helper LD_LIBRARY_PATH=.
genprofile $helper:rix
runchecktest "ENVIRON (elf): ix & regular env" pass $helper FOO=BAR
runchecktest "ENVIRON (elf): ix & sensitive env" pass $helper LD_LIBRARY_PATH=.
genprofile $helper:px -- image=$helper
runchecktest "ENVIRON (elf): px & regular env" pass $helper FOO=BAR
runchecktest "ENVIRON (elf): px & sensitive env" pass $helper LD_LIBRARY_PATH=.
genprofile $helper:Px -- image=$helper
runchecktest "ENVIRON (elf): Px & regular env" pass $helper FOO=BAR
runchecktest "ENVIRON (elf): Px & sensitive env" fail $helper LD_LIBRARY_PATH=.
genprofile image=$helper
runchecktest "ENVIRON (elf): unconfined --> confined & regular env" pass $helper FOO=BAR
runchecktest "ENVIRON (elf): unconfined --> confined & sensitive env" pass $helper LD_LIBRARY_PATH=.
genprofile -C
runchecktest "ENVIRON (elf): confined/complain & regular env" pass $helper FOO=BAR
runchecktest "ENVIRON (elf): confined/complain & sensitive env" pass $helper LD_LIBRARY_PATH=.
# TEST environment filtering on shell scripts
genprofile ${helper_sh}:ux
runchecktest "ENVIRON (shell script): ux & regular env" pass ${helper_sh} FOO=BAR
runchecktest "ENVIRON (shell script): ux & sensitive env" pass ${helper_sh} LD_LIBRARY_PATH=.
genprofile ${helper_sh}:Ux
runchecktest "ENVIRON (shell script): Ux & regular env" pass ${helper_sh} FOO=BAR
runchecktest "ENVIRON (shell script): Ux & sensitive env" fail ${helper_sh} LD_LIBRARY_PATH=.
genprofile ${helper_sh}:px -- image=${helper_sh} /bin/bash:rix "/lib*/lib*:mr"
runchecktest "ENVIRON (shell script): px & regular env" pass ${helper_sh} FOO=BAR
runchecktest "ENVIRON (shell script): px & sensitive env" pass ${helper_sh} LD_LIBRARY_PATH=.
genprofile ${helper_sh}:Px -- image=${helper_sh} /bin/bash:rix "/lib*/lib*:mr"
runchecktest "ENVIRON (shell script): Px & regular env" pass ${helper_sh} FOO=BAR
runchecktest "ENVIRON (shell script): Px & sensitive env" fail ${helper_sh} LD_LIBRARY_PATH=.
genprofile ${helper_sh}:rix /bin/bash:rix "/lib*/lib*:mr"
runchecktest "ENVIRON (shell script): ix & regular env" pass ${helper_sh} FOO=BAR
runchecktest "ENVIRON (shell script): ix & sensitive env" pass ${helper_sh} LD_LIBRARY_PATH=.
genprofile image=${helper_sh} /bin/bash:rix "/lib*/lib*:mr"
runchecktest "ENVIRON (shell script): unconfined --> confined & regular env" pass ${helper_sh} FOO=BAR
runchecktest "ENVIRON (shell script): unconfined --> confined & sensitive env" pass ${helper_sh} LD_LIBRARY_PATH=.
genprofile -C
runchecktest "ENVIRON (shell script): confined/complain & regular env" pass ${helper_sh} FOO=BAR
runchecktest "ENVIRON (shell script): confined/complain & sensitive env" pass ${helper_sh} LD_LIBRARY_PATH=.
# TEST environment filtering still works on setuid apps
removeprofile
cp $helper ${setuid_helper}
chown nobody ${setuid_helper}
chmod u+s ${setuid_helper}
runchecktest "ENVIRON (elf): unconfined setuid helper" pass ${setuid_helper} FOO=BAR
runchecktest "ENVIRON (elf): unconfined setuid helper" fail ${setuid_helper} LD_LIBRARY_PATH=.

View File

@@ -1,18 +0,0 @@
if [ -n "$do_onexit" ]
then
$do_onexit
fi
if [ -n "$subdomain" -a -f "$profile" -a ${profileloaded:-0} -eq 1 ]
then
removeprofile
fi
if [ "$retaintmpdir" = "true" ]
then
echo "Files retained in: $tmpdir"
else
rm -rf $tmpdir
fi
exit $num_testfailures

View File

@@ -1,51 +0,0 @@
#include <stdio.h>
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
int main(int argc, char *argv[])
{
pid_t pid;
extern char **environ;
if (argc < 2){
fprintf(stderr, "usage: %s program [args] \n", argv[0]);
return 1;
}
pid=fork();
if (pid){ /* parent */
int status;
while (wait(&status) != pid);
if (WIFEXITED(status)){
printf("PASS\n");
}else{
fprintf(stderr, "FAILED, child did not exit normally\n");
}
}else{
/* child */
(void)execve(argv[1], &argv[1], environ);
/* exec failed, kill outselves to flag parent */
(void)kill(getpid(), SIGKILL);
}
return 0;
}

View File

@@ -1,72 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME exec
#=DESCRIPTION Runs exec() through ux, ix & px functionality
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
file=/bin/true
ok_ix_perm=rix
badperm=r
ok_ux_perm=ux
ok_px_perm=px
bad_mx_perm=rm
# PASS TEST - inherited
genprofile $file:$ok_ix_perm
runchecktest "EXEC with ix" pass $file
# PASS TEST - unconfined
genprofile $file:$ok_ux_perm
runchecktest "EXEC with ux" pass $file
# PASS TEST - profiled
genprofile $file:$ok_px_perm -- image=$file
runchecktest "EXEC with px" pass $file
# FAIL TEST - px/no profile
genprofile $file:$ok_px_perm
runchecktest "EXEC with px - no profile" fail $file
# NOLINK PERMTEST
genprofile $file:$badperm
runchecktest "EXEC no x" fail $file
# MMAP exec
genprofile $file:$bad_mx_perm
runchecktest "EXEC mmap x" fail $file
# UNCONFINED -> CONFINED
genprofile image=$file
runchecktest "EXEC unconfined -> confined" pass $file
# UNCONFINED -> CONFINED no access to self binary
genprofile -N image=$file "/lib/ld*.so*:rix" "/lib/lib*.so*:rm"
runchecktest "EXEC unconfined -> confined/no access to self" pass $file

View File

@@ -1,34 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <string.h>
int main(int argc, char *argv[])
{
extern char **environ;
if (argc < 2){
fprintf(stderr, "usage: %s program [args] \n", argv[0]);
return 1;
}
(void)execve(argv[1], &argv[1], environ);
fprintf(stderr, "FAILED: exec failed %s\n", strerror(errno));
return 1;
}

View File

@@ -1,198 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME exec_qual
#=DESCRIPTION
# See 'matrix.doc' in the SubDomain/Documentation directory. This test
# currently verifies the enforce mode handling of exec between the various
# confinement conditions for execer and execee. It needs to be extended to
# include the complain mode verification.
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
file=/etc/group
test1=$bin/exec_qual
test2=$bin/exec_qual2
test2_rex1=$bin/exec_\*
test2_rex2=$bin/exec_qual[1-9]
test2perm=rpx
fileperm=rw
local_runchecktest()
{
desc=$1
passfail=$2
expected_confinement=$3
actual_confinement=""
shift 3
runtestbg "$desc" $passfail $*
sleep 1
if [ -r /proc/$_pid/attr/current ]
then
actual_confinement=`cat /proc/$_pid/attr/current | cut -d ' ' -f1`
# signal pid to continue
kill -USR1 $_pid
elif [ -z $outfile ]
then
echo "FAIL: Unable to determine confinment for pid $pid" >> $outfile
fi
checktestbg
if [ "$teststatus" == "pass" -a -n "$actual_confinement" -a "$actual_confinement" != "$expected_confinement" ]
then
echo "Error: ${testname} failed. Test '${_testdesc}' actual confinement '$actual_confinement' differed from expected confinement '$expected_confinement'"
testfailed
fi
}
# ENFORCE mode
# confined parent, exec child with 'px'
# case 1: parent profile grants access (should be irrelevant)
# child profile grants access
# expected behaviour: child should be able to access resource
genprofile $test2:px $file:$fileperm -- image=$test2 $file:$fileperm
local_runchecktest "enforce px case1" pass $test2 $test2 $file
# case 2: parent profile grants access (should be irrelevant)
# child profile disallows access
# expected behaviour: child should be unable to access resource
genprofile $test2:px $file:$fileperm -- image=$test2
local_runchecktest "enforce px case2" fail $test2 $test2 $file
# case 3: parent profile disallows access (should be irrelevant)
# child profile allows access
# expected behaviour: child should be able to access resource
genprofile $test2:px -- image=$test2 $file:$fileperm
local_runchecktest "enforce px case3" pass $test2 $test2 $file
# case 4: parent profile grants access (should be irrelevant)
# missing child profile
# expected behaviour: exec of child fails
genprofile $test2:px $file:$fileperm
local_runchecktest "enforce px case4" fail "n/a" $test2 $file
# confined parent, exec child with 'ix'
# case 1: parent profile grants access
# child profile grants access (should be irrelevant)
# expected behaviour: child should be able to access resource
genprofile $test2:rix $file:$fileperm -- image=$test2 $file:$fileperm
local_runchecktest "enforce ix case1" pass $test1 $test2 $file
# case 2: parent profile grants access
# child profile disallows access (should be irrelevant)
# expected behaviour: child should be able to access resource
genprofile $test2:rix $file:$fileperm -- image=$test2
local_runchecktest "enforce ix case2" pass $test1 $test2 $file
# case 3: parent profile disallows access
# child profile allows access (should be irrelevant)
# expected behaviour: child should be unable to access resource
genprofile $test2:rix -- image=$test2 $file:$fileperm
local_runchecktest "enforce ix case3" fail $test1 $test2 $file
# case 4: parent profile grants access
# missing child profile (irrelvant)
# expected behaviour: child should be able to access resource
genprofile $test2:rix $file:$fileperm
local_runchecktest "enforce ix case4" pass $test1 $test2 $file
# confined parent, exec child with 'ux'
# case 1: parent profile grants access (should be irrelevant)
# expected behaviour, child should be able to access resource
genprofile $test2:ux $file:$fileperm
local_runchecktest "enforce ux case1" pass "unconstrained" $test2 $file
# case 2: parent profile denies access (should be irrelevant)
# expected behaviour, child should be able to access resource
genprofile $test2:ux
local_runchecktest "enforce ux case1" pass "unconstrained" $test2 $file
# confined parent, exec child with conflicting exec qualifiers
# case 1:
# expected behaviour: exec of child fails
genprofile $test2_rex1:px $test2_rex2:ix -- image=$test2 $file:$fileperm
local_runchecktest "enforce conflicting exec qual" fail "n/a" $test2 $file
# unconfined parent
# case 1: child profile exists, child profile grants access
# expected behaviour: child should be able to access resource
genprofile image=$test2 $file:$fileperm
local_runchecktest "enforce unconfined case1" pass $test2 $test2 $file
# case 2: child profile exists, child profile denies access
# expected behaviour: child should be unable to access resource
genprofile image=$test2
local_runchecktest "enforce unconfined case2" fail $test2 $test2 $file
# case 3: no child profile exists, unconfined
# expected behaviour: child should be able to access resource
removeprofile
local_runchecktest "enforce unconfined case3" pass "unconstrained" $test2 $file
# -----------------------------------------------------------------------
# COMPLAIN mode -- all the tests again but with profiles loaded in
# complain mode rather than enforce mode
# confined parent, exec child with 'px'
# case 1: expected behaviour: as enforce
# case 2: expected behaviour: child should be able to access resource
# case 3: expected behaviour: as enforce
# case 4: expected behaviour: child should be able to access resource
# verify child is in null-complain-profile
# confined parent, exec child with 'ix'
# case 1: expected behaviour: as enforce
# case 2: expected behaviour: as enforce
# case 3: expected behaviour: child should be able to access resource
# case 4: expected behaviour: as enforce
# constrined parent, exec child with 'ux'
# case 1: expected behaviour, child should be able to access resource
# case 2: expected behaviour, child should be able to access resource
# confined parent, exec child with conflicting exec qualifiers
# case 1: child should be able to access resource
# verify that child is in null-complain-profile
# unconfined parent
# case 1: expected behaviour: as enforce
# case 2: expected behaviour, child should be able to access resource
# case 3: expected behaviour: as enforce

View File

@@ -1,60 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
void handler(int sig)
{
}
int main(int argc, char *argv[])
{
int fd;
if (argc != 2){
fprintf(stderr, "usage: %s file\n",
argv[0]);
return 1;
}
if (signal(SIGUSR1, handler) == SIG_ERR){
fprintf(stderr, "FAIL: signal failed - %s:%s\n",
argv[1],
strerror(errno));
return 1;
}
/* wait for signal -- this allows parent to inspect what profile
* confinement we have via /proc/pid/attr/current
*/
(void)pause();
fd=open(argv[1], O_RDWR, 0);
if (fd == -1){
fprintf(stderr, "FAIL: open %s failed - %s\n",
argv[1],
strerror(errno));
return 1;
}
close(fd);
printf("PASS\n");
return 0;
}

View File

@@ -1,45 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2007 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int dirfd;
char *dir = argv[1];
if (argc != 2){
fprintf(stderr, "usage: %s dir\n",
argv[0]);
return 1;
}
dirfd = open(dir, O_RDONLY | O_DIRECTORY);
if (dirfd == -1) {
fprintf(stderr, "FAIL: open %s failed - %s\n",
dir, strerror(errno));
return 1;
}
if (fchdir(dirfd) == 0) {
printf("PASS\n");
} else {
printf("FAIL - %s\n", strerror(errno));
}
return 0;
}

View File

@@ -1,36 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME chdir
#=DESCRIPTION
# Verify change directory functions correctly for a confined process. Subdomain
# should allow 'x' access on a directory without it being explicitly listed in
# tasks profile.
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
dir=$tmpdir/tmpdir
mkdir $dir
# CHDIR TEST
# no profile, verify we didn't break normal fchdir
runchecktest "FCHDIR/no profile" pass $dir
# null profile, verify fchdir (x) functions
genprofile
runchecktest "FCHDIR/profile" pass $dir

View File

@@ -1,54 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2007 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char *argv[])
{
gid_t gid;
int fd;
if (argc != 3) {
fprintf(stderr, "usage: %s file groupname|gid\n",
argv[0]);
return 1;
}
if (sscanf(argv[2], "%d", &gid) != 1) {
fprintf(stderr, "FAIL: bad gid %s\n", argv[2]);
return 1;
}
fd = open(argv[1], O_RDONLY);
if (fd == -1) {
fprintf(stderr, "FAIL: open %s failed - %s\n",
argv[1], strerror(errno));
perror("FAIL: open");
return 1;
}
if (fchown(fd, -1, gid) == -1) {
fprintf(stderr, "FAIL: fchgrp %s %d failed - %s\n",
argv[1], gid, strerror(errno));
return 1;
}
printf("PASS\n");
return 0;
}

View File

@@ -1,50 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2007 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
int main(int argc, char *argv[])
{
mode_t mode;
int fd;
if (argc != 3) {
fprintf(stderr, "usage: %s file mode\n", argv[0]);
return 1;
}
if (sscanf(argv[2], "%o", &mode) != 1) {
fprintf(stderr, "FAIL: bad mode %s\n", argv[2]);
return 1;
}
fd = open(argv[1], O_RDONLY);
if (fd == -1) {
fprintf(stderr, "FAIL: open %s failed - %s\n",
argv[1], strerror(errno));
perror("FAIL: open");
return 1;
}
if (fchmod(fd, mode) == -1) {
fprintf(stderr, "FAIL: fchmod %s %o failed - %s\n",
argv[1], mode, strerror(errno));
return 1;
}
printf("PASS\n");
return 0;
}

View File

@@ -1,53 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char *argv[])
{
uid_t uid;
int fd;
if (argc != 3) {
fprintf(stderr, "usage: %s file username|uid\n",
argv[0]);
return 1;
}
if (sscanf(argv[2], "%d", &uid) != 1) {
fprintf(stderr, "FAIL: bad uid %s\n", argv[2]);
return 1;
}
fd = open(argv[1], O_RDONLY);
if (fd == -1) {
fprintf(stderr, "FAIL: open %s failed - %s\n",
argv[1], strerror(errno));
perror("FAIL: open");
return 1;
}
if (fchown(fd, uid, -1) == -1) {
fprintf(stderr, "FAIL: chown %s %d failed - %s\n",
argv[1], uid, strerror(errno));
return 1;
}
printf("PASS\n");
return 0;
}

View File

@@ -1,13 +0,0 @@
Index: subdomain/access.sh
===================================================================
--- subdomain.orig/access.sh
+++ subdomain/access.sh
@@ -64,7 +64,7 @@ runchecktest "ACCESS dir rwx (rwx)" pass
genprofile $dir:$rperm
runchecktest "ACCESS dir r (r)" pass $dir r
runchecktest "ACCESS dir rx (r)" pass $dir rx
-runchecktest "ACCESS dir rwx (r)" pass $dir rwx
+runchecktest "ACCESS dir rwx (r)" fail $dir rwx
genprofile $dir:$wxperm
runchecktest "ACCESS dir x (wx)" pass $dir x

View File

@@ -1,40 +0,0 @@
Index: subdomain/prologue.inc
===================================================================
--- subdomain.orig/prologue.inc
+++ subdomain/prologue.inc
@@ -335,6 +335,7 @@ fi
local num_emitted imagename hat args arg names1 names2
#global complainflag escapeflag nodefaults profile profilenames
+ local hat_string="hat:"
complainflag=""
escapeflag=""
@@ -392,7 +393,9 @@ fi
;;
esac
- num_args=0
+ #give every profile/hat access to change_hat
+ args[0]="/proc/*/attr/current:w"
+ num_args=1
while [ $# -gt 0 ]
do
arg="$1"
@@ -404,8 +407,15 @@ fi
eval emit_profile \"$imagename\" \"$imageperm\" \
$(for i in $(seq 0 $((${num_args} - 1))) ; do echo \"\${args[${i}]}\" ; done)
num_emitted=$((num_emitted + 1))
- num_args=0
+ #give every profile/hat access to change_hat
+ args[0]="/proc/*/attr/current:w"
+ num_args=1
continue 2
+ elif [ ${arg:0:4} == "hat:" ] ; then
+ args[${num_args}]=${arg}
+ num_args=$(($num_args + 1))
+ args[${num_args}]="/proc/*/attr/current:w"
+ num_args=$(($num_args + 1))
else
args[${num_args}]=${arg}
num_args=$(($num_args + 1))

View File

@@ -1,20 +0,0 @@
Index: subdomain/fchdir.sh
===================================================================
--- subdomain.orig/fchdir.sh
+++ subdomain/fchdir.sh
@@ -22,7 +22,7 @@ bin=$pwd
. $bin/prologue.inc
-dir=$tmpdir/tmpdir
+dir=$tmpdir/tmpdir/
mkdir $dir
@@ -32,5 +32,5 @@ mkdir $dir
runchecktest "FCHDIR/no profile" pass $dir
# null profile, verify fchdir (x) functions
-genprofile
+genprofile $dir:r
runchecktest "FCHDIR/profile" pass $dir

View File

@@ -1,13 +0,0 @@
Index: subdomain/capabilities.sh
===================================================================
--- subdomain.orig/capabilities.sh
+++ subdomain/capabilities.sh
@@ -77,7 +77,7 @@ syscall_iopl_args=3
syscall_chroot_args=${tmpdir}
# if a testcase requires extra subdomain rules, add them here
-syscall_chroot_extra_entries="/:r"
+syscall_chroot_extra_entries="/:r ${tmpdir}:r"
testwrapper=changehat_wrapper

View File

@@ -1,29 +0,0 @@
Index: subdomain/exec_qual.sh
===================================================================
--- subdomain.orig/exec_qual.sh
+++ subdomain/exec_qual.sh
@@ -131,13 +131,13 @@ local_runchecktest "enforce ix case4" pa
# expected behaviour, child should be able to access resource
genprofile $test2:ux $file:$fileperm
-local_runchecktest "enforce ux case1" pass "unconstrained" $test2 $file
+local_runchecktest "enforce ux case1" pass "unconfined" $test2 $file
# case 2: parent profile denies access (should be irrelevant)
# expected behaviour, child should be able to access resource
genprofile $test2:ux
-local_runchecktest "enforce ux case1" pass "unconstrained" $test2 $file
+local_runchecktest "enforce ux case1" pass "unconfined" $test2 $file
# confined parent, exec child with conflicting exec qualifiers
# that overlap in such away that px is prefered (ix is glob, px is exact
@@ -165,7 +165,7 @@ local_runchecktest "enforce unconfined c
# expected behaviour: child should be able to access resource
removeprofile
-local_runchecktest "enforce unconfined case3" pass "unconstrained" $test2 $file
+local_runchecktest "enforce unconfined case3" pass "unconfined" $test2 $file
# -----------------------------------------------------------------------

View File

@@ -1,21 +0,0 @@
Index: subdomain/deleted.sh
===================================================================
--- subdomain.orig/deleted.sh
+++ subdomain/deleted.sh
@@ -97,7 +97,6 @@ EOM
rm -f ${socket}
# PASS - confined client, rw access to the file
-
genprofile $file:$okperm $socket:rw $fd_client:px -- image=$fd_client $file:$okperm $socket:rw
runchecktest "fd passing; confined client w/ rw" pass $file $socket $fd_client "delete_file"
@@ -116,7 +115,7 @@ rm -f ${socket}
# FAIL - confined client, w access to the file
genprofile $file:$okperm $socket:rw $fd_client:px -- image=$fd_client $file:$badperm $socket:rw
-runchecktest "fd passing; confined client w/ w only" fail $file $socket $fd_client "delete_file"
+runchecktest "fd passing; confined client w/ w only" pass $file $socket $fd_client "delete_file"
sleep 1
rm -f ${socket}

View File

@@ -1,26 +0,0 @@
Index: subdomain/deleted.sh
===================================================================
--- subdomain.orig/deleted.sh
+++ subdomain/deleted.sh
@@ -48,10 +48,10 @@ runchecktest "NO CHANGEHAT (access file
# CHANGEHAT TEST - force revalidation using changehat
genprofile $file:$okperm hat:$subtest $file:$okperm
-runchecktest "CHANGEHAT (access file)" pass $subtest $file
+runchecktest "CHANGEHAT (access file)" fail $subtest $file
genprofile "$file2":$okperm hat:$subtest "$file2":$okperm
-runchecktest "CHANGEHAT (access file (deleted))" pass $subtest "$file2"
+runchecktest "CHANGEHAT (access file (deleted))" fail $subtest "$file2"
# EXEC TEST - force revalidation using a fork exec that inherits the open file
# but uses a different profile
@@ -99,7 +99,7 @@ rm -f ${socket}
# PASS - constrained client, rw access to the file
genprofile $file:$okperm $socket:rw $fd_client:px -- image=$fd_client $file:$okperm $socket:rw
-runchecktest "fd passing; constrained client w/ rw" pass $file $socket $fd_client "delete_file"
+runchecktest "fd passing; constrained client w/ rw" fail $file $socket $fd_client "delete_file"
sleep 1
cat > ${file} << EOM

View File

@@ -1,106 +0,0 @@
Index: subdomain/capabilities.sh
===================================================================
--- subdomain.orig/capabilities.sh
+++ subdomain/capabilities.sh
@@ -74,11 +74,11 @@ syscall_sethostname_args=a.dumb.example.
syscall_setdomainname_args=dumb.example.com
syscall_ioperm_args="0 0x3ff"
syscall_iopl_args=3
-syscall_chroot_args=${tmpdir}
+syscall_chroot_args=${tmpdir}/
syscall_ptrace_args=sub
# if a testcase requires extra subdomain rules, add them here
-syscall_chroot_extra_entries="/:r ${tmpdir}:r"
+syscall_chroot_extra_entries="/:r ${tmpdir}/:r"
syscall_ptrace_extra_entries="hat:sub"
testwrapper=changehat_wrapper
Index: subdomain/mult_mount.sh
===================================================================
--- subdomain.orig/mult_mount.sh
+++ subdomain/mult_mount.sh
@@ -48,8 +48,8 @@ file1b=$mp1/file2
file2a=$mp2/file
file2b=$mp2/file2
-dir1=$mp1/dir
-dir2=$mp2/dir
+dir1=$mp1/dir/
+dir2=$mp2/dir/
mkdirperm=w
mkdirperm_fail=r
Index: subdomain/readdir.sh
===================================================================
--- subdomain.orig/readdir.sh
+++ subdomain/readdir.sh
@@ -30,12 +30,12 @@ mkdir $dir
# CHDIR TEST
-genprofile $dir:$okperm
+genprofile $dir/:$okperm
runchecktest "READDIR" pass $dir
# CHDIR TEST (no perm)
-genprofile $dir:$badperm
+genprofile $dir/:$badperm
runchecktest "READDIR (no perm)" fail $dir
Index: subdomain/rename.sh
===================================================================
--- subdomain.orig/rename.sh
+++ subdomain/rename.sh
@@ -24,8 +24,8 @@ bin=$pwd
file1=$tmpdir/file1
file2=$tmpdir/file2
-dir1=$tmpdir/dir1
-dir2=$tmpdir/dir2
+dir1=$tmpdir/dir1/
+dir2=$tmpdir/dir2/
okfile1perm=rw
badfile1perm1=r
Index: subdomain/access.sh
===================================================================
--- subdomain.orig/access.sh
+++ subdomain/access.sh
@@ -22,7 +22,7 @@ bin=$pwd
file=$tmpdir/file
-dir=$tmpdir/dir
+dir=$tmpdir/dir/
rperm=r
rwxperm=rwix
wxperm=wix
Index: subdomain/mkdir.sh
===================================================================
--- subdomain.orig/mkdir.sh
+++ subdomain/mkdir.sh
@@ -18,7 +18,7 @@ bin=$pwd
. $bin/prologue.inc
-dir=$tmpdir/tmpdir
+dir=$tmpdir/tmpdir/
perms=w
excess_perms=wl
badperms=r
Index: subdomain/xattrs.sh
===================================================================
--- subdomain.orig/xattrs.sh
+++ subdomain/xattrs.sh
@@ -40,7 +40,7 @@ bin=$pwd
file=$tmpdir/testfile
link=$tmpdir/testlink
-dir=$tmpdir/testdir
+dir=$tmpdir/testdir/
okperm=rw
badperm=r

View File

@@ -1,21 +0,0 @@
Index: subdomain/exec_qual.sh
===================================================================
--- subdomain.orig/exec_qual.sh
+++ subdomain/exec_qual.sh
@@ -140,11 +140,13 @@ genprofile $test2:ux
local_runchecktest "enforce ux case1" pass "unconstrained" $test2 $file
# confined parent, exec child with conflicting exec qualifiers
+# that overlap in such away that px is prefered (ix is glob, px is exact
+# match). Other overlap tests should be in the parser.
# case 1:
-# expected behaviour: exec of child fails
+# expected behaviour: exec of child passes
-genprofile $test2_rex1:px $test2_rex2:ix -- image=$test2 $file:$fileperm
-local_runchecktest "enforce conflicting exec qual" fail "n/a" $test2 $file
+genprofile $test2:px $test2_rex1:ix -- image=$test2 $file:$fileperm
+local_runchecktest "enforce conflicting exec qual" pass $test2 $test2 $file
# unconfined parent
# case 1: child profile exists, child profile grants access

View File

@@ -1,114 +0,0 @@
---
tests/regression/subdomain/Makefile | 2 +
tests/regression/subdomain/symlink.c | 4 ---
tests/regression/subdomain/symlink.sh | 42 ++++++++--------------------------
3 files changed, 14 insertions(+), 34 deletions(-)
Index: subdomain/symlink.c
===================================================================
--- subdomain.orig/symlink.c
+++ subdomain/symlink.c
@@ -1,13 +1,11 @@
/*
-
-/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
- */
+ *
* $Id: symlink.c 61 2006-05-19 18:32:14Z steve-beattie $
*/
Index: subdomain/symlink.sh
===================================================================
--- subdomain.orig/symlink.sh
+++ subdomain/symlink.sh
@@ -9,9 +9,7 @@
# License.
#=NAME symlink
-#=DESCRIPTION As the 'link' test but for symbolic rather than hard links
-
-echo "symlink mediation in AppArmor has been removed"; exit 1
+#=DESCRIPTION creating a symlink should require write access to the new name
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
@@ -20,42 +18,24 @@ bin=$pwd
. $bin/prologue.inc
-src1=$tmpdir/src1
-src2=$tmpdir/src2
-src3=$tmpdir/src3
+src=$tmpdir/src1
target=$tmpdir/target
-path2=target
-path3=$(echo $tmpdir | sed -e "s|/[^/]*|../|g")${target}
-okperm=rwixl
-badperm=rwl
-nolinkperm=rwix
-touch $target
+okperm=w
+badperm=rlixm
+
+touch $target
# PASS TEST
-genprofile ${src1}:$okperm ${src2}:$okperm ${src3}:$okperm $target:$nolinkperm
+genprofile ${src}:$okperm
-runchecktest "MATCHING PERM (absolute)" pass $target ${src1}
-runchecktest "MATCHING PERM (same dir)" pass ${path2} ${src2}
-runchecktest "MATCHING PERM (relative)" pass ${path3} ${src3}
+runchecktest "SYMLINK/WRITE PERMS" pass $target ${src}
# FAILURE TEST
-rm -f ${src1} ${src2} ${src3}
-
-genprofile ${src1}:$badperm ${src2}:$badperm ${src3}:$badperm $target:$nolinkperm
-
-runchecktest "NONMATCHING PERM (absolute)" fail $target ${src1}
-runchecktest "NONMATCHING PERM (same dir)" fail ${path2} ${src2}
-runchecktest "NONMATCHING PERM (relative)" fail ${path3} ${src3}
-
-# NOLINK TEST
-
-rm -f ${src1} ${src2} ${src3}
+rm -f ${src}
-genprofile ${src1}:$nolinkperm ${src2}:$nolinkperm ${src3}:$nolinkperm $target:$nolinkperm
+genprofile ${src}:$badperm
-runchecktest "NOLINK PERM (absolute)" fail $target ${src1}
-runchecktest "NOLINK PERM (same dir)" fail ${path2} ${src2}
-runchecktest "NOLINK PERM (relative)" fail ${path3} ${src3}
+runchecktest "SYMLINK/NO-WRITE PERMS" fail $target ${src}
Index: subdomain/Makefile
===================================================================
--- subdomain.orig/Makefile
+++ subdomain/Makefile
@@ -41,6 +41,7 @@ SRC=access.c \
rename.c \
readdir.c \
rw.c \
+ symlink.c \
syscall_mknod.c \
swap.c \
syscall_chroot.c \
@@ -124,6 +125,7 @@ TESTS=access \
swap \
sd_flags \
setattr \
+ symlink \
syscall \
unix_fd_server \
unlink\

View File

@@ -1,147 +0,0 @@
Index: subdomain/link.sh
===================================================================
--- subdomain.orig/link.sh
+++ subdomain/link.sh
@@ -9,9 +9,11 @@
# License.
#=NAME link
-#=DESCRIPTION
-# Link requires 'l' permission and that permissions on the src and target
-# must match. This test verifies matching, non-matching and missing link
+#=DESCRIPTION
+# Link requires 'l' permission on the link and that permissions on the
+#links rwmx perms are a subset of the targets perms, and if x is present
+#that the link and target have the same x qualifiers.
+# This test verifies matching, non-matching and missing link
# permissions in a profile.
#=END
@@ -22,50 +24,88 @@ bin=$pwd
. $bin/prologue.inc
-src=$tmpdir/src
target=$tmpdir/target
+linkfile=$tmpdir/linkfile
okperm=rwixl
badperm=rwl
nolinkperm=rwix
-touch $src
+touch $target
-# PASS TEST
+#test for $1 in $2
+function perm_is_subset () {
+ # zero length substring always matches
+ if [ -z $1 ] ; then
+ echo $2;
+ return 0;
+ fi
+
+ case "$2" in
+ *$1*) echo ${2##${2/$1*/}}; return 0;;
+ esac
+
+ #handle the special cases
+ #ix implies mix
+ local target=${2/ix/mix}
+
+ case "$target" in
+ *$1*) echo ${target##${target/$1*/}}; return 0;;
+ esac
+
+ # permute rw to do string match of rm rwm
+ target=${target/rw/wr}
+ case "$target" in
+ *$1*) echo ${target##${target/$1*/}}; return 0;;
+ esac
+}
+
+PERMS="r w m ix px ux Px Ux l rw rm rix rpx rux rPx rUx rl wm wix wpx wux \
+ wPx wUx wl mix mpx mux mPx mUx ml ixl pxl uxl Pxl Uxl rwm rwix rwpx \
+ rwux rwPx rwUx rwl rmix rmpx rmux rmPx rmUx rml wmix wmpx wmux wmPx \
+ wmUx wml mixl mpxl muxl mPxl mUxl rwmix rwmpx rwmux rwmPx rwmUx \
+ rwml wmixl wmpxl wmuxl wmPxl wmUxl rwmixl rwmpxl rwmuxl rwmPxl \
+ rwmUxl"
+
+
+# unconfined test
+runchecktest "unconfined" pass $target $linkfile
+
+# Link no perms on link or target
+genprofile
+runchecktest "link (no perms) -> target (no perms)" fail $target $linkfile
+rm -rf $linkfile
+
+# link no perms
+for TARGET_PERM in ${PERMS} ; do
+ genprofile $target:$TARGET_PERM
+ runchecktest "link (no perms) -> target ($TARGET_PERM)" fail $target $linkfile
+ rm -rf $linkfile
+done
+
+# target no perms
+for LINK_PERM in ${PERMS} ; do
+ genprofile $linkfile:$LINK_PERM
+ runchecktest "link ($LINK_PERM) -> target (no perms)" fail $target $linkfile
+ rm -rf $linkfile
+done
+
+# all other combination of perms
+for LINK_PERM in ${PERMS} ; do
+ for TARGET_PERM in ${PERMS} ; do
+ l_in_perms=${LINK_PERM/*l/l}
+ perms_no_link=${LINK_PERM/l/}
+ link_subset=`perm_is_subset ${perms_no_link} ${TARGET_PERM}`
+ if [ "$l_in_perms" == "l" -a -n "$perms_no_link" -a -n "$link_subset" ]
+ then
+ expected_result=pass
+ else
+ expected_result=fail
+ fi
+#echo "testing $LINK_PERM -> $TARGET_PERM = $l_in_perms, $perms_no_link, $link_subset $expected_result"
+ genprofile $linkfile:$LINK_PERM $target:$TARGET_PERM
+ runchecktest "link ($LINK_PERM) -> target ($TARGET_PERM)" ${expected_result} $target $linkfile
+ rm -rf $linkfile
-genprofile $src:$okperm $target:$okperm
-runchecktest "MATCHING PERM (rwixl)" pass $src $target
+ done
+done
-# PASS TEST
-
-rm -f $target
-
-genprofile $src:$nolinkperm $target:$okperm
-runchecktest "MATCHING PERM (rwix)" pass $src $target
-
-# PASS TEST
-
-rm -f $target
-
-genprofile $src:r $target:rl
-runchecktest "MATCHING PERM (r)" pass $src $target
-
-# PASS TEST
-
-rm -f $target
-
-genprofile $src:w $target:wl
-runchecktest "MATCHING PERM (w)" pass $src $target
-
-# FAILURE TEST
-
-rm -f $target
-
-genprofile $src:$okperm $target:$badperm
-runchecktest "NONMATCHING PERM" fail $src $target
-
-# NOLINK TEST
-
-rm -f $target
-
-genprofile $src:$okperm $target:$nolinkperm
-runchecktest "NOLINK PERM" fail $src $target

View File

@@ -1,75 +0,0 @@
Index: subdomain/openat.sh
===================================================================
--- subdomain.orig/openat.sh
+++ subdomain/openat.sh
@@ -40,59 +40,59 @@ runchecktest "OPENAT unconfined RW (crea
# PASS TEST (the file shouldn't exist, so open should create it
resettest
-genprofile ${dir}:r ${filepath}:$okperm
+genprofile ${dir}/:r ${filepath}:$okperm
runchecktest "OPENAT RW (create) " pass $dir $file
# PASS TEST
resettest
touch ${filepath}
-genprofile ${dir}:r ${filepath}:$okperm
+genprofile ${dir}/:r ${filepath}:$okperm
runchecktest "OPENAT RW (exists)" pass $dir $file
# FAILURE TEST (1)
resettest
touch ${filepath}
-genprofile ${dir}:r ${filepath}:$badperm1
+genprofile ${dir}/:r ${filepath}:$badperm1
runchecktest "OPENAT R" fail $dir $file
# FAILURE TEST (2)
resettest
touch ${filepath}
-genprofile ${dir}:r ${filepath}:$badperm2
+genprofile ${dir}/:r ${filepath}:$badperm2
runchecktest "OPENAT W (exists)" fail $dir $file
# FAILURE TEST (3)
resettest
-genprofile ${dir}:r ${filepath}:$badperm1 cap:dac_override
+genprofile ${dir}/:r ${filepath}:$badperm1 cap:dac_override
runchecktest "OPENAT R+dac_override" fail $dir $file
# FAILURE TEST (4)
# This is testing for bug: https://bugs.wirex.com/show_bug.cgi?id=2885
# When we open O_CREAT|O_RDWR, we are (were?) allowing only write access
# to be required.
+# This test currently passes when it should fail because of the o_creat bug
resettest
-genprofile ${dir}:r ${filepath}:$badperm2
+genprofile ${dir}/:r ${filepath}:$badperm2
runchecktest "OPENAT W (create)" fail $dir $file
# PASS rename of directory in between opendir/openat
resettest
-genprofile ${dir}/${subdir}:rw ${dir}/otherdir:w ${dir}/otherdir/file:rw
+genprofile ${dir}/${subdir}/:rw ${dir}/otherdir/:w ${dir}/otherdir/file:rw
runchecktest "OPENAT RW (rename/newpath)" pass --rename ${dir}/otherdir ${dir}/${subdir} file
# PASS rename of directory in between opendir/openat - file exists
resettest
touch ${filepath}
-genprofile ${dir}/${subdir}:rw ${dir}/otherdir:w ${dir}/otherdir/file:rw
+genprofile ${dir}/${subdir}/:rw ${dir}/otherdir/:w ${dir}/otherdir/file:rw
runchecktest "OPENAT RW (rename/newpath)" pass --rename ${dir}/otherdir ${dir}/${subdir} file
# FAIL rename of directory in between opendir/openat - use old name
resettest
-genprofile ${dir}/${subdir}:rw ${dir}/otherdir:w ${dir}/${subdir}/file:rw
+genprofile ${dir}/${subdir}/:rw ${dir}/otherdir/:w ${dir}/${subdir}/file:rw
runchecktest "OPENAT RW (rename/newpath)" fail --rename ${dir}/otherdir ${dir}/${subdir} file
-exit
# FAIL rename of directory in between opendir/openat - use old name, file exists
resettest
touch ${filepath}
-genprofile ${dir}/${subdir}:rw ${dir}/otherdir:w ${dir}/${subdir}/file:rw
+genprofile ${dir}/${subdir}/:rw ${dir}/otherdir/:w ${dir}/${subdir}/file:rw
runchecktest "OPENAT RW (rename/newpath)" fail --rename ${dir}/otherdir ${dir}/${subdir} file

View File

@@ -1,104 +0,0 @@
Index: subdomain/capabilities.sh
===================================================================
--- subdomain.orig/capabilities.sh
+++ subdomain/capabilities.sh
@@ -66,7 +66,7 @@ net_raw_net_raw=TRUE
# we completely disable ptrace(), but it's not clear if we should allow it
# when the sys_ptrace cap is specified.
-# syscall_ptrace_sys_ptrace=TRUE
+syscall_ptrace_sys_ptrace=TRUE
# if a test case requires arguments, add them here.
syscall_reboot_args=off
@@ -75,9 +75,11 @@ syscall_setdomainname_args=dumb.example.
syscall_ioperm_args="0 0x3ff"
syscall_iopl_args=3
syscall_chroot_args=${tmpdir}
+syscall_ptrace_args=sub
# if a testcase requires extra subdomain rules, add them here
syscall_chroot_extra_entries="/:r ${tmpdir}:r"
+syscall_ptrace_extra_entries="hat:sub"
testwrapper=changehat_wrapper
Index: subdomain/syscall_ptrace.c
===================================================================
--- subdomain.orig/syscall_ptrace.c
+++ subdomain/syscall_ptrace.c
@@ -21,6 +21,8 @@
#include <limits.h>
#include <string.h>
+#include "changehat.h"
+
#define FALSE 0
#define TRUE !FALSE
@@ -29,7 +31,7 @@ int main(int argc, char *argv[])
pid_t pid;
int retval = 0;
- if (argc != 1){
+ if (argc != 2){
fprintf(stderr, "usage: %s\n", argv[0]);
return 1;
}
@@ -43,6 +45,14 @@ int main(int argc, char *argv[])
while (wait(&status) != pid);
retval = WEXITSTATUS(status);
}else{
+ /* change profile so that ptrace can fail */
+ if (change_hat(argv[1], SD_ID_MAGIC + 1) == -1 &&
+ errno != EPERM) {
+ /* confined process failed to change_hat */
+ fprintf(stderr, "FAIL: changehat %s failed - %s\n",
+ argv[1], strerror(errno));
+ return errno;
+ }
if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1){
fprintf(stderr, "FAIL: ptrace failed - %s\n",
strerror(errno));
Index: subdomain/syscall.sh
===================================================================
--- subdomain.orig/syscall.sh
+++ subdomain/syscall.sh
@@ -28,12 +28,12 @@ bin=$pwd
settest syscall_ptrace
# TEST A1
-runchecktest "PTRACE with no profile" pass
+runchecktest "PTRACE with no profile" pass sub
# TEST A2. ptrace will fail
genprofile
-runchecktest "PTRACE with confinement" fail
+runchecktest "PTRACE with confinement" fail sub
##
## B. MKNOD
Index: subdomain/ptrace.sh
===================================================================
--- subdomain.orig/ptrace.sh
+++ subdomain/ptrace.sh
@@ -28,10 +28,6 @@ bin=$pwd
# using ptrace. This stopped being required or functioning correctly
# somewhere between 2.4.18 and 2.4.20.
#
-# Tests 10 and 11
-# Requires a patch which prevents confined traced task from attempting exec.
-# Unsure of usefulness of this. We are concerned about confined task being
-# the tracer not the tracee
# Test Matrix:
# 1. unconfined parent, unconfined child, parent attaches PASS
@@ -76,5 +72,5 @@ runchecktest "test 9" pass -- /bin/bash
#genprofile image=$helper /bin/true:ux
#runchecktest "test 10" fail -h -n 100 $helper /bin/true
-#genprofile image=$helper /bin/true:rix
-#runchecktest "test 11" fail -h -n 1000 $helper /bin/true
+genprofile image=$helper /bin/true:rix
+runchecktest "test 11" pass -h -n 1000 $helper /bin/true

View File

@@ -1,13 +0,0 @@
vfs-mnt.patch
exec_qual.patch
deleted-open-revalidate.patch
#deleted_no_revalidation-pass.patch
ptrace.patch
dir-files.patch
link_perms.patch
confined.patch
change_hat_profile_access.patch
sysctl.patch
access.patch
chdir.patch
openat.patch

View File

@@ -1,312 +0,0 @@
Index: subdomain/capabilities.sh
===================================================================
--- subdomain.orig/capabilities.sh
+++ subdomain/capabilities.sh
@@ -31,7 +31,7 @@ bin=$pwd
. ./prologue.inc
-TESTS="syscall_ptrace syscall_sysctl syscall_sethostname \
+TESTS="syscall_ptrace syscall_sethostname \
syscall_setdomainname syscall_setpriority syscall_setscheduler \
syscall_reboot syscall_chroot \
syscall_mlockall net_raw"
Index: subdomain/syscall.sh
===================================================================
--- subdomain.orig/syscall.sh
+++ subdomain/syscall.sh
@@ -114,24 +114,9 @@ rm -f $mknod_file
runchecktest "MKNOD sock (permissions)" fail s $mknod_file
##
-## C. SYSCTL
+## D. SETHOSTNAME
##
-settest syscall_sysctl
-
-# TEST C1
-runchecktest "SYSCTL (no confinement)" pass
-
-# TEST C2
-genprofile
-runchecktest "SYSCTL (confinement/read only)" pass ro
-
-# TEST C3. sysctl will fail
-genprofile
-runchecktest "SYSCTL (confinement/write access)" fail
-
-# TEST C3. sysctl write will pass with cap_sys_admin
-genprofile cap:sys_admin
-runchecktest "SYSCTL (confinement/write access/CAP_SYS_ADMIN)" pass
+sh syscall_sysctl.sh
##
## D. SETHOSTNAME
Index: subdomain/syscall_sysctl.sh
===================================================================
--- /dev/null
+++ subdomain/syscall_sysctl.sh
@@ -0,0 +1,145 @@
+#! /bin/bash
+# $Id: syscall.sh 61 2006-05-19 18:32:14Z steve-beattie $
+
+# Copyright (C) 2002-2005 Novell/SUSE
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, version 2 of the
+# License.
+
+#=NAME syscall_sysctl
+#=DESCRIPTION
+# Confined processes are prohibited from executing certain system calls.
+# This test checks sysctl which is mediated like filesystem accesses
+#=END
+
+pwd=`dirname $0`
+pwd=`cd $pwd ; /bin/pwd`
+
+sysctlgood=/proc/sys/kernel/threads-max
+sysctlbad=/proc/sys/kernel/sysrq
+
+bin=$pwd
+
+. $bin/prologue.inc
+
+##
+## C. SYSCTL
+##
+settest syscall_sysctl
+
+runchecktest "SYSCTL (no confinement read only)" pass ro
+
+runchecktest "SYSCTL (no confinement rw)" pass
+
+genprofile $sysctlgood:r
+runchecktest "SYSCTL (confinement/good r w/ r perm)" pass ro
+
+genprofile $sysctlgood:r
+runchecktest "SYSCTL (confinement/good rw w/ r perm)" fail
+
+genprofile $sysctlgood:w
+runchecktest "SYSCTL (confinement/good r w/ w perm)" fail ro
+
+genprofile $sysctlgood:w
+runchecktest "SYSCTL (confinement/good rw w/ w perm)" fail
+
+genprofile $sysctlgood:rw
+runchecktest "SYSCTL (confinement/good r w/ rw perm)" pass ro
+
+genprofile $sysctlgood:rw
+runchecktest "SYSCTL (confinement/good rw w/ rw perm)" pass
+
+genprofile $sysctlbad:r
+runchecktest "SYSCTL (confinement/bad r w/ r perm)" fail ro
+
+genprofile $sysctlbad:r
+runchecktest "SYSCTL (confinement/bad rw w/ r perm)" fail ro
+
+genprofile $sysctlbad:w
+runchecktest "SYSCTL (confinement/bad r w/ w perm)" fail ro
+
+genprofile $sysctlbad:w
+runchecktest "SYSCTL (confinement/bad rw w/ w perm)" fail
+
+genprofile $sysctlbad:rw
+runchecktest "SYSCTL (confinement/bad r w/ rw perm)" fail ro
+
+genprofile $sysctlbad:rw
+runchecktest "SYSCTL (confinement/bad rw w/ rw perm)" fail
+
+# now test /proc/sys/ paths
+
+settest sysctl_proc
+
+#unconfined
+runchecktest "SYSCTL /proc (read no confinement)" pass $sysctlgood r
+value=`cat $sysctlgood`
+runchecktest "SYSCTL /proc (write no confinement)" pass $sysctlgood w $value
+runchecktest "SYSCTL /proc (rw no confinement)" pass $sysctlgood rw
+
+#test with profile giving access to sysctlgood
+genprofile $sysctlgood:r
+runchecktest "SYSCTL /proc (confinement/good r w/ r perm)" pass $sysctlgood r
+
+genprofile $sysctlgood:w
+runchecktest "SYSCTL /proc (confinement/good r w/ w perm)" fail $sysctlgood r
+
+genprofile $sysctlgood:rw
+runchecktest "SYSCTL /proc (confinement/good r w/ rw perm)" pass $sysctlgood r
+
+genprofile $sysctlgood:r
+value=`cat $sysctlgood`
+runchecktest "SYSCTL /proc (confinement/good w w/ r perm)" fail $sysctlgood w $value
+
+genprofile $sysctlgood:w
+value=`cat $sysctlgood`
+runchecktest "SYSCTL /proc (confinement/good w w/ w perm)" pass $sysctlgood w $value
+
+genprofile $sysctlgood:rw
+value=`cat $sysctlgood`
+runchecktest "SYSCTL /proc (confinement/good w w/ rw perm)" pass $sysctlgood w $value
+
+genprofile $sysctlgood:r
+runchecktest "SYSCTL /proc (confinement/good rw w/ r perm)" fail $sysctlgood rw
+
+genprofile $sysctlgood:w
+runchecktest "SYSCTL /proc (confinement/good rw w/ w perm)" fail $sysctlgood rw
+
+genprofile $sysctlgood:rw
+runchecktest "SYSCTL /proc (confinement/good rw w/ rw perm)" pass $sysctlgood rw
+
+#test with profile giving access to sysctlbad but access to sysctlgood
+genprofile $sysctlbad:r
+runchecktest "SYSCTL /proc (confinement/bad r w/ r perm)" fail $sysctlgood r
+
+genprofile $sysctlbad:w
+runchecktest "SYSCTL /proc (confinement/bad r w/ w perm)" fail $sysctlgood r
+
+genprofile $sysctlbad:rw
+runchecktest "SYSCTL /proc (confinement/bad r w/ rw perm)" fail $sysctlgood r
+
+genprofile $sysctlbad:r
+value=`cat $sysctlgood`
+runchecktest "SYSCTL /proc (confinement/bad w w/ r perm)" fail $sysctlgood w $value
+
+genprofile $sysctlbad:w
+value=`cat $sysctlgood`
+runchecktest "SYSCTL /proc (confinement/bad w w/ w perm)" fail $sysctlgood w $value
+
+genprofile $sysctlbad:rw
+value=`cat $sysctlgood`
+runchecktest "SYSCTL /proc (confinement/bad w w/ rw perm)" fail $sysctlgood w $value
+
+genprofile $sysctlbad:r
+runchecktest "SYSCTL /proc (confinement/bad rw w/ r perm)" fail $sysctlgood rw
+
+genprofile $sysctlbad:w
+runchecktest "SYSCTL /proc (confinement/bad rw w/ w perm)" fail $sysctlgood rw
+
+genprofile $sysctlbad:rw
+runchecktest "SYSCTL /proc (confinement/bad rw w/ rw perm)" fail $sysctlgood rw
+
+
+
Index: subdomain/Makefile
===================================================================
--- subdomain.orig/Makefile
+++ subdomain/Makefile
@@ -56,6 +56,7 @@ SRC=access.c \
syscall_setdomainname.c \
syscall_setscheduler.c \
syscall_sysctl.c \
+ sysctl_proc.c \
tcp.c \
unix_fd_client.c \
unix_fd_server.c \
Index: subdomain/sysctl_proc.c
===================================================================
--- /dev/null
+++ subdomain/sysctl_proc.c
@@ -0,0 +1,101 @@
+/* $Id: sysctl_proc.c 61 2006-05-19 18:32:14Z steve-beattie $ */
+
+/*
+ * Copyright (C) 2002-2005 Novell/SUSE
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#define BUFSIZE 4096
+int main(int argc, char *argv[])
+{
+ char read_buffer[BUFSIZE], verify_buffer[BUFSIZE];
+ ssize_t read_size, write_size;
+ int fd;
+
+ if ((argc < 3) || (argc == 4 && strcmp(argv[2],"w")) || argc > 4) {
+ fprintf(stderr, "Usage: %s sysctl_path {r,w,rw} [value]\n", argv[0]);
+ return 1;
+ }
+
+ if (strcmp(argv[2],"r") == 0) {
+ fd = open(argv[1], O_RDONLY);
+ if (fd == -1) {
+ fprintf(stderr, "FAIL: proc sysctl open r failed - %s\n",
+ strerror(errno));
+ return 1;
+ }
+ read_size = read(fd, &read_buffer, sizeof(read_buffer));
+ if (read_size == -1) {
+ fprintf(stderr, "FAIL: proc sysctl read failed - %s\n",
+ strerror(errno));
+ return 1;
+ }
+ }
+
+ if (strcmp(argv[2], "w") == 0) {
+ fd = open(argv[1], O_WRONLY);
+ if (fd == -1) {
+ fprintf(stderr, "FAIL: proc sysctl open w failed - %s\n",
+ strerror(errno));
+ return 1;
+ }
+ write_size = write(fd, argv[3], strlen(argv[3]));
+ if (write_size == -1) {
+ fprintf(stderr, "FAIL: proc sysctl write failed - %s\n",
+ strerror(errno));
+ return 1;
+ }
+
+ }
+
+ if (strcmp(argv[2], "rw") == 0) {
+ fd = open(argv[1], O_RDWR);
+ if (fd == -1) {
+ fprintf(stderr, "FAIL: proc sysctl open rw failed - %s\n",
+ strerror(errno));
+ return 1;
+ }
+ read_size = read(fd, &read_buffer, sizeof(read_buffer));
+ if (read_size == -1) {
+ fprintf(stderr, "FAIL: proc sysctl read(rw) failed - %s\n",
+ strerror(errno));
+ return 1;
+ }
+ lseek(fd, 0, SEEK_SET);
+ write_size = write(fd, &read_buffer, read_size);
+ if (write_size == -1 || write_size != read_size) {
+ fprintf(stderr, "FAIL: proc sysctl write(rw) failed - %s\n",
+ strerror(errno));
+ return 1;
+ }
+
+ lseek(fd, 0, SEEK_SET);
+ read_size = read(fd, &verify_buffer, sizeof(verify_buffer));
+ if (read_size == -1 || read_size != write_size) {
+ fprintf(stderr, "FAIL: proc sysctl verify(rw) failed || %d != %d - %s\n", read_size, write_size,
+ strerror(errno));
+ return 1;
+ }
+ if (memcmp(read_buffer, verify_buffer, read_size) != 0) {
+ fprintf(stderr, "FAIL: proc sysctl verify failed - %s\n",
+ strerror(errno));
+ return 1;
+ }
+ }
+
+ printf("PASS\n");
+
+ return 0;
+}

View File

@@ -1,118 +0,0 @@
Add testcases to test renaming directories as well as files. Remove the
l bit from the ok perms as that's no longer needed.
---
tests/regression/subdomain/rename.sh | 60 +++++++++++++++++++----------------
1 file changed, 34 insertions(+), 26 deletions(-)
Index: subdomain/rename.sh
===================================================================
--- subdomain.orig/rename.sh
+++ subdomain/rename.sh
@@ -9,9 +9,9 @@
# License.
#=NAME rename
-#=DESCRIPTION
-# The rename system call changes the name of a file in the filesystem. The
-# test verifies that this operation (which involves AppArmor write and link
+#=DESCRIPTION
+# The rename system call changes the name of a file in the filesystem.
+# The test verifies that this operation (which involves AppArmor write
# permission checks) functions correctly for a confined process.
#=END
@@ -24,63 +24,71 @@ bin=$pwd
file1=$tmpdir/file1
file2=$tmpdir/file2
+dir1=$tmpdir/dir1
+dir2=$tmpdir/dir2
-okfile1perm=rwl
+okfile1perm=rw
badfile1perm1=r
badfile1perm2=w
okfile2perm=w
badfile2perm=r
-# PASS TEST
+reset_test() {
+ touch $file1
+ chmod 600 $file1
+ test -d $dir1 || mkdir $dir1
+ chmod 700 $dir1
+}
-touch $file1
-chmod 600 $file1
+# PASS TEST
+reset_test
-genprofile $file1:$okfile1perm $file2:$okfile2perm
+genprofile $file1:$okfile1perm $file2:$okfile2perm $dir1:$okfile1perm $dir2:$okfile2perm
-runchecktest "RENAME RWL W" pass $file1 $file2
+runchecktest "RENAME RW W" pass $file1 $file2
+runchecktest "RENAME RW W (dir)" pass $dir1 $dir2
# FAILURE TEST (1) - Bad permissions on target
-touch $file1
-chmod 600 $file1
+reset_test
-genprofile $file1:$okfile1perm $file2:$badfile2perm
+genprofile $file1:$okfile1perm $file2:$badfile2perm $dir1:$okfile1perm $dir2:$badfile2perm
-runchecktest "RENAME RWL R" fail $file1 $file2
+runchecktest "RENAME RW R" fail $file1 $file2
+runchecktest "RENAME RW R (dir)" fail $dir1 $dir2
# FAILURE TEST (2) - no permissions on target
-touch $file1
-chmod 600 $file1
+reset_test
-genprofile $file1:$okfile1perm
+genprofile $file1:$okfile1perm $dir1:$okfile1perm
-runchecktest "RENAME RWL -" fail $file1 $file2
+runchecktest "RENAME RW -" fail $file1 $file2
+runchecktest "RENAME RW - (dir)" fail $dir1 $dir2
# FAILURE TEST (3) - Bad permissions on source
-touch $file1
-chmod 600 $file1
+reset_test
-genprofile $file1:$badfile1perm1 $file2:$okfile2perm
+genprofile $file1:$badfile1perm1 $file2:$okfile2perm $dir1:$badfile1perm1 $dir2:$okfile2perm
runchecktest "RENAME R W" fail $file1 $file2
+runchecktest "RENAME R W (dir)" fail $dir1 $dir2
# FAILURE TEST (4) - Bad permissions on source
-touch $file1
-chmod 600 $file1
+reset_test
-genprofile $file1:$badfile1perm2 $file2:$okfile2perm
+genprofile $file1:$badfile1perm2 $file2:$okfile2perm $dir1:$badfile1perm2 $dir2:$okfile2perm
runchecktest "RENAME W W" fail $file1 $file2
+runchecktest "RENAME W W (dir)" fail $dir1 $dir2
# FAILURE TEST (5) - No permissions on source
-touch $file1
-chmod 600 $file1
+reset_test
-genprofile $file2:$okfile2perm
+genprofile $file2:$okfile2perm $dir2:$okfile2perm
runchecktest "RENAME - W" fail $file1 $file2
+runchecktest "RENAME - W (dir)" fail $dir1 $dir2

View File

@@ -1,53 +0,0 @@
Index: subdomain/mult_mount.sh
===================================================================
--- subdomain.orig/mult_mount.sh
+++ subdomain/mult_mount.sh
@@ -79,17 +79,17 @@ genprofile $dir2:$mkdirperm
runchecktest "OVERLAP MKDIR PASS2" pass mkdir $dir2
cleandir $dir2
+# MKDIR FAIL TESTS
genprofile $dir1:$mkdirperm
-runchecktest "OVERLAP MKDIR PASS3" pass mkdir $dir2
+runchecktest "OVERLAP MKDIR PASS3" fail mkdir $dir2
cleandir $dir2
genprofile $dir2:$mkdirperm
-runchecktest "OVERLAP MKDIR PASS4" pass mkdir $dir1
+runchecktest "OVERLAP MKDIR PASS4" fail mkdir $dir1
cleandir $dir1
-# MKDIR FAIL TESTS
get_current_logposition
genprofile $dir1:$mkdirperm_fail
runchecktest "OVERLAP MKDIR FAIL1" fail mkdir $dir1
@@ -114,11 +114,11 @@ runchecktest "OVERLAP LINK PASS1a" pass
rm -f $file1b
genprofile $file1a:$linkperm $file2b:$linkperm
-runchecktest "OVERLAP LINK PASS2a" pass $file1a $file1b
+runchecktest "OVERLAP LINK PASS2a" fail $file1a $file1b
rm -f $file1b
genprofile $file2a:$linkperm $file1b:$linkperm
-runchecktest "OVERLAP LINK PASS3a" pass $file1a $file1b
+runchecktest "OVERLAP LINK PASS3a" fail $file1a $file1b
rm -f $file1b
# src lacks link perm, ok as long as dest has linkperm
@@ -127,11 +127,11 @@ runchecktest "OVERLAP LINK PASS1b" pass
rm -f $file1b
genprofile $file1a:$readperm $file2b:$linkperm
-runchecktest "OVERLAP LINK PASS2b" pass $file1a $file1b
+runchecktest "OVERLAP LINK PASS2b" fail $file1a $file1b
rm -f $file1b
genprofile $file2a:$readperm $file1b:$linkperm
-runchecktest "OVERLAP LINK PASS3b" pass $file1a $file1b
+runchecktest "OVERLAP LINK PASS3b" fail $file1a $file1b
rm -f $file1b

View File

@@ -1,117 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#include <fcntl.h>
#include <limits.h>
#include <string.h>
#define FALSE 0
#define TRUE !FALSE
#define max(x,y) (x) > (y) ? (x) : (y)
#define MAX_FILES 5
int (*pass)[MAX_FILES];
void test_files(int num_files, char *files[], int index)
{
int fd, i;
for (i = 0; i < num_files; i++) {
fd = open(files[i], O_RDWR);
if (fd == -1) {
if (errno == ENOENT) {
pass[index][i] = -1;
} else {
pass[index][i] = 0;
}
} else {
pass[index][i] = 1;
close(fd);
}
}
}
int main(int argc, char *argv[])
{
int num_files, i, shmid;
pid_t pid;
struct shmid_ds shm_desc;
if (argc < 2) {
fprintf(stderr, "usage: %s program [args] \n", argv[0]);
return 1;
}
num_files = max(argc - 1, MAX_FILES);
shmid = shmget(IPC_PRIVATE, sizeof(int[2][MAX_FILES]), IPC_CREAT);
if (shmid == -1) {
fprintf(stderr, "FAIL: shmget failed %s\n", strerror(errno));
return 1;
}
pass = (int(*)[MAX_FILES])shmat(shmid, NULL, 0);
if (pass == (void *)-1) {
fprintf(stderr, "FAIL: shmat failed %s\n", strerror(errno));
return 1;
}
pid = fork();
if (pid) { /* parent */
int status;
int allpassed = TRUE;
test_files(argc - 1, &argv[1], 0);
while (wait(&status) != pid) ;
for (i = 0; i < argc - 1; i++) {
if (pass[0][i] != pass[1][i] ||
pass[0][i] == -1 || pass[1][i] == -1) {
if (allpassed) {
fprintf(stderr, "FAILED:");
allpassed = FALSE;
}
fprintf(stderr, " file%d(%d:%d)",
i + 1, pass[0][i], pass[1][i]);
}
}
if (allpassed) {
printf("PASS\n");
} else {
fprintf(stderr, "\n");
}
(void)shmdt(pass);
shmctl(shmid, IPC_RMID, &shm_desc);
} else {
test_files(argc - 1, &argv[1], 1);
}
return 0;
}

View File

@@ -1,51 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME fork
#=DESCRIPTION
# Verifies that profiles are duplicated correctly for fork (the subtask
# receives a copy of it's parents profile). The test attempts to access the
# files passed as arguments for both a parent and a child. The test is
# repeated for permissive and restrictive profiles.
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
file1=$tmpdir/file1
file2=$tmpdir/file2
file3=$tmpdir/file3
cap=ipc_owner
okperm=rw
badperm=r
touch $file1 $file2 $file3
# TEST1
genprofile cap:$cap $file1:$okperm $file2:$okperm $file3:$okperm
runchecktest "FORK with rw" pass $file1 $file2 $file3
# TEST2. All will fail, but parent and child will equally fail
genprofile cap:$cap $file1:$badperm $file2:$badperm $file3:$badperm
runchecktest "FORK w/o w" pass $file1 $file2 $file3
# TEST3. Some pass, some fail, but parent and child will equally fail
genprofile cap:$cap $file1:$badperm $file2:$okperm $file3:$badperm
runchecktest "FORK mixed" pass $file1 $file2 $file3

View File

@@ -1,81 +0,0 @@
#! /bin/bash
# $Id:$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME i18n
#=DESCRIPTION
# This script tests some of the basic handling of i18n characters in the
# kernel and (eventually) the parser. We try to open a file with weird bytes
# in the name.
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
okperm=rw
badperm1=r
badperm2=w
globfile=${tmpdir}/file_*_post
settest open
# skip NULL (\x0) and / (\x2F) because they can't be part of filenames
# skip DEL (\x7f) for now until Ican get it properly passed through
for i in $(seq 1 46) $(seq 48 126) $(seq 128 255); do
#for i in $(seq 127 127 ); do
symbol=$(printf "\\$(printf "%03o" $i)")
# Sigh, in the case of \012, bash would strip it out during
# variable assignment. -ENOCLUE why it doesn't work for \177
case "$i" in
10) file=$tmpdir/file_$'\012'_post
;;
127) file=$tmpdir/file_$'\177'_post
;;
*) file=$tmpdir/file_${symbol}_post
;;
esac
parser_file=$tmpdir/file_\\$(printf "%03o" $i)_post
#echo "$i '$symbol' $file $parser_file"
#echo "$file" | od -x
touch "$file"
chmod 600 "$file"
# PASS TEST
genprofile "${globfile}:$okperm"
runchecktest "i18n ($i) OPEN (glob) \"${file}\" RW" pass "$file"
# FAIL TEST
#genprofile "${globfile}:$badperm2"
#runchecktest "i18n ($i) OPEN (glob) \"${file}\" W" fail "$file"
# skip the ':', since it is a delimiter for mkprofile
# We'll test it below in the \octal test.
if [ "${symbol}" != ":" ] ; then
# PASS TEST
genprofile -E "${file}:$okperm"
runchecktest "i18n ($i) OPEN \"${file}\" RW" pass "$file"
# FAIL TEST
#genprofile -E "${file}:$badperm2"
#runchecktest "i18n ($i) OPEN \"${file}\" W" fail "$file"
fi
# PASS TEST
genprofile -E ${parser_file}:$okperm
runchecktest "i18n ($i) OPEN (octal) \"${file}\" RW" pass "$file"
# FAIL TEST
genprofile -E "${parser_file}:$badperm2"
runchecktest "i18n ($i) OPEN (octal) \"${file}\" W" fail "$file"
done

View File

@@ -1,32 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main(int argc, char *argv[])
{
if (argc != 3){
fprintf(stderr, "usage: %s srcfile dstfile\n",
argv[0]);
return 1;
}
if (link(argv[1], argv[2]) == 0){
printf("PASS\n");
}else{
printf("FAIL - %s\n", strerror(errno));
}
return 0;
}

View File

@@ -1,71 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME link
#=DESCRIPTION
# Link requires 'l' permission and that permissions on the src and target
# must match. This test verifies matching, non-matching and missing link
# permissions in a profile.
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
src=$tmpdir/src
target=$tmpdir/target
okperm=rwixl
badperm=rwl
nolinkperm=rwix
touch $src
# PASS TEST
genprofile $src:$okperm $target:$okperm
runchecktest "MATCHING PERM (rwixl)" pass $src $target
# PASS TEST
rm -f $target
genprofile $src:$nolinkperm $target:$okperm
runchecktest "MATCHING PERM (rwix)" pass $src $target
# PASS TEST
rm -f $target
genprofile $src:r $target:rl
runchecktest "MATCHING PERM (r)" pass $src $target
# PASS TEST
rm -f $target
genprofile $src:w $target:wl
runchecktest "MATCHING PERM (w)" pass $src $target
# FAILURE TEST
rm -f $target
genprofile $src:$okperm $target:$badperm
runchecktest "NONMATCHING PERM" fail $src $target
# NOLINK TEST
rm -f $target
genprofile $src:$okperm $target:$nolinkperm
runchecktest "NOLINK PERM" fail $src $target

View File

@@ -1,169 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME longpath
#=DESCRIPTION
# Verify handling of long pathnames.
#=END
genrandname()
{
_goal=$1
_ascii="abcdefghijlkmnopqrstuvwxyz0123456789"
_mod=${#_ascii}
_i=0
for _i in `seq 2 $_goal`
do
_c=$((RANDOM % $_mod))
_s="${_s}${_ascii:$_c:1}"
done
echo $_s
}
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
name_max=255 #NAME_MAX
direlem_max=235 #Length for intermediate dirs, slightly less than name_max
buf_max=4096 #PAGE
# generate 255 character filename
file=`genrandname $name_max`
file2=`genrandname $name_max`
settest open
okperm=rw
linkperm=rwl
cd $tmpdir
mkdir_expected_fail=0
file_expected_fail=0
link_expected_fail=0
iter=1
while true
do
direlem=`genrandname $direlem_max`
_dpath=`pwd`/$direlem
if [ ${#_dpath} -lt 4096 ]
then
dstatus=pass
else
dstatus=fail
fi
settest mkdir
genprofile $tmpdir/**:$okperm
runchecktest "LONGPATH MKDIR ($iter)" $dstatus mkdir $direlem
if [ $dstatus = "pass" ]
then
if [ -d $direlem ]
then
#echo "mkdir ($iter) passed at length ${#_dpath}"
cd $direlem
else
echo "FAIL: $direlem ($_iter) was not created" >&2
fi
else
if [ -d $direlem ]
then
echo "mkdir ($iter) incorrectly generated dir at length ${#_dpath}"
else
#echo "mkdir ($iter) failed at length ${#_dpath}"
mkdir_expected_fail=1
fi
:
fi
_fpath=`pwd`/$file
if [ ${#_fpath} -lt 4096 ]
then
fstatus=pass
else
fstatus=fail
fi
settest open
genprofile $tmpdir/**:$okperm
runchecktest "LONGPATH CREATE ($iter)" $fstatus $file
if [ $fstatus = "pass" ]
then
if [ -f $file ]
then
#echo "file creat ($iter) passed at length ${#_dpath}"
:
else
echo "FAIL: $file ($_iter) was not created" >&2
fi
elif [ $fstatus = "fail" ]
then
if [ -f $file ]
then
echo "file creat ($iter) incorrectly generated file at length ${#_fpath}"
else
#echo "file creat ($iter) failed at length ${#_fpath}"
file_expected_fail=1
fi
fi
settest link
genprofile $tmpdir/**:$linkperm
if [ -f $file ]
then
_f=$file
elif [ -f ../$file ]
then
_f=../$file
else
echo "unable to find file to link" >&2
exit 1
fi
runchecktest "LONGPATH LINK ($iter)" $fstatus $_f $file2
if [ $fstatus = "pass" ]
then
if [ -f $file2 ]
then
#echo "file link ($iter) passed at length ${#_dpath}"
:
else
echo "FAIL: $file2 ($_iter) was not linked" >&2
fi
elif [ $fstatus = "fail" ]
then
if [ -f $file2 ]
then
echo "file link ($iter) incorrectly generated file at length ${#_dpath}"
else
#echo "file link ($iter) failed at length ${#_fpath}"
link_expected_fail=1
fi
fi
if [ $mkdir_expected_fail -eq 1 -a \
$file_expected_fail -eq 1 -a \
$link_expected_fail -eq 1 ]
then
break
fi
: $((iter++))
done

View File

@@ -1,49 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
if (argc != 3){
fprintf(stderr, "usage: %s [mkdir|rmdir] dir\n",
argv[0]);
return 1;
}
if (strcmp(argv[1], "mkdir") == 0) {
if (mkdir(argv[2], S_IRWXU)) {
fprintf(stderr, "FAIL: mkdir %s failed - %s\n",
argv[2],
strerror(errno));
return errno;
}
} else if (strcmp(argv[1], "rmdir") == 0) {
if (rmdir(argv[2])) {
fprintf(stderr, "FAIL: rmdir %s failed - %s\n",
argv[2],
strerror(errno));
return errno;
}
} else {
fprintf(stderr, "usage: %s [mkdir|rmdir] dir\n",
argv[0]);
return 1;
}
printf("PASS\n");
return 0;
}

View File

@@ -1,77 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME mkdir
#=DESCRIPTION mkdir() and rmdir() test
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
dir=$tmpdir/tmpdir
perms=w
excess_perms=wl
badperms=r
# mkdir TEST
# null profile, verify mkdir/rmdir fail
genprofile
runchecktest "MKDIR (confined - no perms)" fail mkdir $dir
# yeah, looks like NOP, but pass/fail of first shouldn't affect second
# use || : to avoid shell trap error if dir doesn't exist
/bin/rmdir $dir 2> /dev/null || :
/bin/mkdir $dir
runchecktest "RMDIR (confined - no perms)" fail rmdir $dir
# profile with read-only permissions, fail
genprofile $dir:$badperms
/bin/rmdir $dir 2> /dev/null || :
runchecktest "MKDIR (confined read-only)" fail mkdir $dir
# yeah, looks like NOP, but pass/fail of first shouldn't affect second
/bin/rmdir $dir 2> /dev/null || :
/bin/mkdir $dir
runchecktest "RMDIR (confined read-only)" fail rmdir $dir
# profile with permissions, shouldn't fail
genprofile $dir:$perms
/bin/rmdir $dir 2> /dev/null || :
runchecktest "MKDIR (confined)" pass mkdir $dir
# yeah, looks like NOP, but pass/fail of first shouldn't affect second
/bin/rmdir $dir 2> /dev/null || :
/bin/mkdir $dir
runchecktest "RMDIR (confined)" pass rmdir $dir
# profile with excess permissions, shouldn't fail
genprofile $dir:$excess_perms
/bin/rmdir $dir 2> /dev/null || :
runchecktest "MKDIR (confined +l)" pass mkdir $dir
# yeah, looks like NOP, but pass/fail of first shouldn't affect second
/bin/rmdir $dir 2> /dev/null || :
/bin/mkdir $dir
runchecktest "RMDIR (confined +l)" pass rmdir $dir

View File

@@ -1,150 +0,0 @@
#! /usr/bin/perl -w
#
# mkprofile.pl -
# generate a formatted profile based on passed in arguments
#
# Gawd, I hate writing perl. It shows, too.
#
my $__VERSION__='$Id: mkprofile.pl 5923 2005-12-14 18:49:16Z steve $';
use strict;
use Getopt::Long;
my $help = '';
my $nowarn = '';
my $escape = '';
my %output_rules;
my $hat = "__no_hat";
my %flags;
GetOptions(
'escape|E' => \$escape,
'nowarn' => \$nowarn,
'help|h' => \$help,
);
sub usage {
print STDERR "$__VERSION__\n";
print STDERR "Usage $0 [--nowarn|--escape] execname [rules]\n";
print STDERR " $0 --help\n";
print STDERR " nowarn: don't warn if execname does not exist\n";
print STDERR " escape: escape stuff that would be treated as regexs\n";
print STDERR " help: print this message\n";
}
&usage && exit 0 if ($help || @ARGV < 1);
sub emit_netdomain {
my $rule = shift;
# only split on single ':'s
my @rules = split (/(?<!:):(?!:)/, $rule);
# convert '::' to ':' -- for port designations
foreach (@rules) { s/::/:/g; }
push (@{$output_rules{$hat}}, " @rules,\n");
}
sub emit_cap {
my $rule = shift;
my @rules = split (/:/, $rule);
if (@rules != 2) {
(!$nowarn) && print STDERR "Warning: invalid capability description '$rule', ignored\n";
} else {
push (@{$output_rules{$hat}}, " capability $rules[1],\n");
}
}
sub emit_file {
my $rule = shift;
my @rules = split (/:/, $rule);
# default: file rules
if (@rules != 2) {
(!$nowarn) && print STDERR "Warning: invalid file access '$rule', ignored\n";
} else {
if ($escape) {
$rules[0]=~ s/(["[\]{}\\\:\#])/\\$1/g;
$rules[0]=~ s/(\#)/\\043/g;
}
if ($rules[0]=~ /[\s\!\"\^]/) {
push (@{$output_rules{$hat}}, " \"$rules[0]\" $rules[1],\n");
} else {
push (@{$output_rules{$hat}}, " $rules[0] $rules[1],\n");
}
}
}
sub emit_flag {
my $rule = shift;
my @rules = split (/:/, $rule);
if (@rules != 2) {
(!$nowarn) && print STDERR "Warning: invalid flag description '$rule', ignored\n";
} else {
push (@{$flags{$hat}},$rules[1]);
}
}
sub emit_hat {
my $rule = shift;
my @rules = split (/:/, $rule);
if (@rules != 2) {
(!$nowarn) && print STDERR "Warning: invalid hat description '$rule', ignored\n";
} else {
$hat = $rules[1];
$output_rules{$hat} = ( );
}
}
my $bin = shift @ARGV;
!(-e $bin || $nowarn) && print STDERR "Warning: execname '$bin': no such file or directory\n";
for my $rule (@ARGV) {
#($fn, @rules) = split (/:/, $rule);
if ($rule =~ /^(tcp|udp)/) {
# netdomain rules
emit_netdomain($rule);
} elsif ($rule =~ /^cap:/) {
emit_cap($rule);
} elsif ($rule =~ /^flag:/) {
emit_flag($rule);
} elsif ($rule =~ /^hat:/) {
emit_hat($rule);
} else {
emit_file($rule);
}
}
sub dump_flags {
my $hat = shift;
if (exists $flags{$hat}) {
print STDOUT " flags=(";
print STDOUT pop(@{$flags{$hat}});
foreach my $flag (@{$flags{$hat}}) {
print STDOUT ", $flag";
}
print STDOUT ") ";
}
}
print STDOUT "# Profile autogenerated by $__VERSION__\n";
print STDOUT "$bin ";
dump_flags('__no_hat');
print STDOUT "{\n";
foreach my $outrule (@{$output_rules{'__no_hat'}}) {
print STDOUT $outrule;
}
foreach my $hat (keys %output_rules) {
if (not $hat =~ /^__no_hat$/) {
print STDOUT "\n ^$hat";
dump_flags($hat);
print STDOUT " {\n";
foreach my $outrule (@{$output_rules{$hat}}) {
print STDOUT " $outrule";
}
print STDOUT " }\n";
}
}
#foreach my $hat keys
#foreach my $outrule (@output_rules) {
# print STDOUT $outrule;
#}
print STDOUT "}\n";

View File

@@ -1,117 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <signal.h>
#include <string.h>
static int gotsigusr1;
void handler(int sig)
{
++gotsigusr1;
}
int main(int argc, char *argv[])
{
int fd, rc, pass;
const char *data="hello world";
char *mptr;
char buf[128];
sigset_t sigset;
if (argc != 2){
fprintf(stderr, "usage: %s file\n",
argv[0]);
return 1;
}
if (signal(SIGUSR1, handler) == SIG_ERR){
fprintf(stderr, "FAIL: internal error signal failed - %s\n",
strerror(errno));
return 1;
}
if (sigemptyset(&sigset) == -1) {
perror ("FAIL: nullifying sigset");
return 1;
}
fd=open(argv[1], O_CREAT|O_EXCL|O_RDWR, S_IWUSR|S_IRUSR);
if (fd == -1){
fprintf(stderr, "FAIL: create %s failed - %s\n",
argv[1],
strerror(errno));
return 1;
}
if (ftruncate(fd, getpagesize()) == -1){
fprintf(stderr, "FAIL: ftruncate %s failed - %s\n",
argv[1],
strerror(errno));
}
mptr=mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (mptr == MAP_FAILED){
fprintf(stderr, "FAIL: mmap failed - %s\n",
strerror(errno));
return 1;
}
pass=1;
nextpass:
(void)memcpy(mptr, data, strlen(data));
if (msync(mptr, strlen(data), MS_SYNC) == -1){
fprintf(stderr, "FAIL: msync failed - %s\n",
strerror(errno));
return 1;
}
(void)lseek(fd, 0, SEEK_SET);
rc=read(fd, buf, strlen(data));
if (rc != strlen(data)){
fprintf(stderr, "FAIL: read failed - %s\n",
strerror(errno));
return 1;
}
if (memcmp(buf, mptr, strlen(data)) != 0){
fprintf(stderr, "FAIL: read comparison failed\n");
}
gotsigusr1=0;
if (pass == 1){
while (!gotsigusr1){
(void)sigsuspend(&sigset);
}
pass++;
goto nextpass;
}
printf("PASS\n");
return 0;
}

View File

@@ -1,64 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME mmap
#=DESCRIPTION
# This test verifies that mmap based access control is also subject to the
# AppArmor profiles access specification. The test needs some
# attention/rethought, It is unclear what it's purpose really is. Also why
# does it fail when the profile is replaced with just read permission as
# no mapped write is reattempted. Also a test should be added which
# causes the initial mmap write to fail (due to lack of write permission).
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
file=$tmpdir/src
okperm=rw
badperm=r
# PASS TEST (pt 1)
genprofile $file:$okperm
runtestbg "READ/WRITE pass1" pass $file
sleep 2
# PASS TEST (pt 2)
kill -USR1 $_pid
checktestbg
rm -f $file
# FAILURE TEST (pt 1)
genprofile $file:$okperm
runtestbg "READ/WRITE pass2" pass $file
sleep 2
genprofile $file:$badperm
# FAILURE TEST (pt 2)
kill -USR1 $_pid
checktestbg

View File

@@ -1,51 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <string.h>
int main(int argc, char *argv[])
{
if (argc != 4) {
fprintf(stderr, "usage: %s [mount|umount] loopdev mountpoint\n",
argv[0]);
return 1;
}
if (strcmp(argv[1], "mount") == 0) {
if (mount(argv[2], argv[3], "ext2", 0xc0ed0000 | MS_MANDLOCK, NULL ) == -1) {
fprintf(stderr, "FAIL: mount %s on %s failed - %s\n",
argv[2], argv[3],
strerror(errno));
return errno;
}
} else if (strcmp(argv[1], "umount") == 0) {
if (umount(argv[3]) == -1) {
fprintf(stderr, "FAIL: umount %s failed - %s\n",
argv[3],
strerror(errno));
return errno;
}
} else {
fprintf(stderr, "usage: %s [mount|umount] loopdev mountpoint\n",
argv[0]);
return 1;
}
printf("PASS\n");
return 0;
}

View File

@@ -1,80 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME mount
#=DESCRIPTION
# This test verifies that the mount syscall is indeed restricted for confined
# processes.
#=END
# I made this a seperate test script because of the need to make a
# loopfile before the tests run.
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
##
## A. MOUNT
##
mount_file=$tmpdir/mountfile
mount_point=$tmpdir/mountpoint
loop_device="unset"
dd if=/dev/zero of=${mount_file} bs=1024 count=512 2> /dev/null
/sbin/mkfs -text2 -F ${mount_file} > /dev/null 2> /dev/null
/bin/mkdir ${mount_point}
# in a modular udev world, the devices won't exist until the loopback
# module is loaded.
if [ ! -b /dev/loop0 ] ; then
modprobe loop
fi
# kinda ugly way of atomically finding a free loop device
for i in $(seq 0 15)
do
if [ "$loop_device" = "unset" ]
then
if /sbin/losetup /dev/loop$i ${mount_file} > /dev/null 2> /dev/null
then
loop_device=/dev/loop$i;
fi
fi
done
if [ "$loop_device" = "unset" ]
then
fatalerror 'Unable to find a free loop device'
fi
# TEST 1. Make sure can mount and umount unconfined
runchecktest "MOUNT (unconfined)" pass mount ${loop_device} ${mount_point}
runchecktest "UMOUNT (unconfined)" pass umount ${loop_device} ${mount_point}
# TEST A2. confine MOUNT
genprofile capability:sys_admin
runchecktest "MOUNT (confined)" fail mount ${loop_device} ${mount_point}
# TEST A3. confine UMOUNT
/bin/mount -text2 ${loop_device} ${mount_point}
runchecktest "UMOUNT (confined)" fail umount ${loop_device} ${mount_point}
# cleanup, umount file
/bin/umount ${loop_device} > /dev/null 2> /dev/null || /sbin/losetup -d ${loop_device} > /dev/null 2> /dev/null
/sbin/losetup -d ${loop_device} > /dev/null 2> /dev/null

View File

@@ -1,167 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME mult_mount
#=DESCRIPTION
# Verify that multiple mounts of the same device are handled correctly
# for various operations.
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
cleandir()
{
if [ -d $1 ]
then
rmdir $1
fi
}
get_current_logposition()
{
:
}
verify_log_record()
{
:
}
image=$tmpdir/image.ext3
mp1=$tmpdir/mnt1
mp2=$tmpdir/mnt2
file1a=$mp1/file
file1b=$mp1/file2
file2a=$mp2/file
file2b=$mp2/file2
dir1=$mp1/dir
dir2=$mp2/dir
mkdirperm=w
mkdirperm_fail=r
linkperm=rl
readperm=r
dd if=/dev/zero of=$image bs=4096 count=20 > /dev/null 2>&1
mkfs.ext2 -F -m 0 -N 10 $image > /dev/null 2>&1
mkdir $mp1 $mp2
mount -o loop $image $mp1
mount --bind $mp1 $mp2
do_onexit="umount $mp2 $mp1"
settest mkdir
# MKDIR PASS TESTS
genprofile $dir1:$mkdirperm
runchecktest "OVERLAP MKDIR PASS1" pass mkdir $dir1
cleandir $dir1
genprofile $dir2:$mkdirperm
runchecktest "OVERLAP MKDIR PASS2" pass mkdir $dir2
cleandir $dir2
genprofile $dir1:$mkdirperm
runchecktest "OVERLAP MKDIR PASS3" pass mkdir $dir2
cleandir $dir2
genprofile $dir2:$mkdirperm
runchecktest "OVERLAP MKDIR PASS4" pass mkdir $dir1
cleandir $dir1
# MKDIR FAIL TESTS
get_current_logposition
genprofile $dir1:$mkdirperm_fail
runchecktest "OVERLAP MKDIR FAIL1" fail mkdir $dir1
verify_log_record
cleandir $dir1
get_current_logposition
genprofile $dir2:$mkdirperm_fail
runchecktest "OVERLAP MKDIR FAIL2" fail mkdir $dir2
verify_log_record
cleandir $dir2
# LINK PASS TESTS
touch $file1a
settest link
# src has link perm (not necessary)
genprofile $file1a:$linkperm $file1b:$linkperm
runchecktest "OVERLAP LINK PASS1a" pass $file1a $file1b
rm -f $file1b
genprofile $file1a:$linkperm $file2b:$linkperm
runchecktest "OVERLAP LINK PASS2a" pass $file1a $file1b
rm -f $file1b
genprofile $file2a:$linkperm $file1b:$linkperm
runchecktest "OVERLAP LINK PASS3a" pass $file1a $file1b
rm -f $file1b
# src lacks link perm, ok as long as dest has linkperm
genprofile $file1a:$readperm $file1b:$linkperm
runchecktest "OVERLAP LINK PASS1b" pass $file1a $file1b
rm -f $file1b
genprofile $file1a:$readperm $file2b:$linkperm
runchecktest "OVERLAP LINK PASS2b" pass $file1a $file1b
rm -f $file1b
genprofile $file2a:$readperm $file1b:$linkperm
runchecktest "OVERLAP LINK PASS3b" pass $file1a $file1b
rm -f $file1b
# LINK FAIL TESTS
# Simple failure, these should fail due to cross device link,
# nothing to do with AA
genprofile $file1a:$linkperm $file2b:$linkperm
runchecktest "OVERLAP LINK FAIL1" fail $file1a $file2b
rm -f $file2b
genprofile $file2a:$linkperm $file1b:$linkperm
runchecktest "OVERLAP LINK FAIL2" fail $file2a $file1b
rm -f $file1b
# dest lacks link perm
get_current_logposition
genprofile $file1a:$linkperm $file1b:$readperm
runchecktest "OVERLAP LINK FAIL3" fail $file1a $file1b
verify_log_record
rm -f $file1b
get_current_logposition
genprofile $file1a:$linkperm $file2b:$readperm
runchecktest "OVERLAP LINK FAIL4" fail $file1a $file1b
verify_log_record
rm -f $file1b
get_current_logposition
genprofile $file2a:$linkperm $file1b:$readperm
runchecktest "OVERLAP LINK FAIL5" fail $file1a $file1b
verify_log_record
rm -f $file1b

View File

@@ -1,155 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include "changehat.h"
const char *data="hello world";
int do_read (int fd)
{
int rc;
char buf[128];
rc=read(fd, buf, sizeof(buf));
if (rc != strlen(data)){
fprintf(stderr, "FAIL: read failed - %s\n",
strerror(errno));
return 1;
}
if (memcmp(buf, data, strlen(data)) != 0){
fprintf(stderr, "FAIL: comparison failed - %s\n",
strerror(errno));
return 1;
}
close(fd);
return 0;
}
int do_write (int fd)
{
int rc;
rc=write(fd, data, strlen(data));
if (rc != strlen(data)){
fprintf(stderr, "FAIL: write failed - %s\n",
strerror(errno));
return 1;
}
close(fd);
return 0;
}
int do_parent (char * hat, char * file)
{
int fd;
fd=open(file, O_RDONLY, 0);
if (fd == -1){
fprintf(stderr, "FAIL: open read %s failed - %s\n",
file,
strerror(errno));
return 1;
}
/* change hat if hatname != nochange */
if (strcmp(hat, "nochange") != 0){
if (change_hat(hat, SD_ID_MAGIC+1) == -1){
fprintf(stderr, "FAIL: changehat %s failed - %s\n",
hat, strerror(errno));
exit(1);
}
}
return(do_read(fd));
}
int do_child (char * hat, char * file)
{
int fd;
fd=open(file, O_WRONLY, 0);
if (fd == -1){
fprintf(stderr, "FAIL: open write %s failed - %s\n",
file,
strerror(errno));
return 1;
}
/* change hat if hatname != nochange */
if (strcmp(hat, "nochange") != 0){
if (change_hat(hat, SD_ID_MAGIC+1) == -1){
fprintf(stderr, "FAIL: changehat %s failed - %s\n",
hat, strerror(errno));
exit(1);
}
}
return (do_write(fd));
}
int main(int argc, char *argv[])
{
int rc;
pid_t pid;
int waitstatus;
int read_error = 0;
if (argc != 3){
fprintf(stderr, "usage: %s hatname filename\n",
argv[0]);
return 1;
}
pid = fork();
if (pid == -1) {
fprintf(stderr, "FAIL: fork failed - %s\n",
strerror(errno));
exit(1);
} else if (pid != 0) {
/* parent */
read_error = do_parent(argv[1], argv[2]);
rc = wait(&waitstatus);
if (rc == -1){
fprintf(stderr, "FAIL: wait failed - %s\n",
strerror(errno));
exit(1);
}
} else {
/* child */
exit(do_child(argv[1], argv[2]));
}
if ((WIFEXITED(waitstatus) != 0) && (WEXITSTATUS(waitstatus) == 0)
&& read_error == 0) {
printf("PASS\n");
} else {
return (WEXITSTATUS(waitstatus) & read_error);
}
return 0;
}

View File

@@ -1,61 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME named_pipe
#=DESCRIPTION
# This test verifies that subdomain file access checks function correctly
# for named piped (nodes in the filesystem created with mknod). The test
# creates a parent/child process relationship which attempt to rendevous via
# the named pipe. The tests are attempted for unconfined and confined
# processes and also for subhats.
#=END
pwd=`dirname $0`
pwd=`cd $pwd ; /bin/pwd`
bin=$pwd
. $bin/prologue.inc
subtest=sub
fifo=${tmpdir}/pipe
okperm=rw
mknod ${fifo} p
# NAMED PIPE - no confinement
runchecktest "NAMED PIPE (no confinement)" pass nochange ${fifo}
# PIPE - confined.
#rm -f ${fifo} && mknod ${fifo} p
genprofile $fifo:${okperm}
runchecktest "NAMED PIPE RW (confinement)" pass nochange ${fifo}
# PIPE - confined - no access.
#rm -f ${fifo} && mknod ${fifo} p
genprofile
runchecktest "NAMED PIPE (confinement)" fail nochange ${fifo}
# PIPE - in a subprofile.
#rm -f ${fifo} && mknod ${fifo} p
genprofile ${fifo}:${okperm} hat:$subtest ${fifo}:${okperm}
runchecktest "NAMED PIPE RW (subprofile)" pass ${subtest} ${fifo}
# PIPE - in a subprofile - no access
#rm -f ${fifo} && mknod ${fifo} p
genprofile ${fifo}:${okperm} hat:$subtest
runchecktest "NAMED PIPE (subprofile)" fail ${subtest} ${fifo}

View File

@@ -1,53 +0,0 @@
/* $Id$ */
/*
* Copyright (C) 2002-2005 Novell/SUSE
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
* License.
*/
/* Basic tcp networking test. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
//#include <netinet/in.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <fcntl.h>
#define HOSTIP "127.0.0.1"
#define HOSTPORT 9876
#define BUFSIZE 4096
#define WAITLEN 1 /* number of seconds for select to wait */
#define DATASOURCE "/dev/urandom"
char data[BUFSIZE];
int
main (int argc, char * argv[]) {
int sockfd;
/* create a socket */
if ((sockfd = socket (PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
perror ("FAIL: Server: can't open raw socket");
return 1;
}
close (sockfd);
printf ("PASS\n");
return 0;
}

View File

@@ -1,33 +0,0 @@
#! /bin/bash
# $Id$
# Copyright (C) 2002-2005 Novell/SUSE
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, version 2 of the
# License.
#=NAME net_raw
#=DESCRIPTION
# AppArmor requires the net_raw capability in order to open a raw socket.
# This test verifies this.
#=END
pwd=$(dirname $0)
pwd=$(cd $pwd ; /bin/pwd)
bin=$pwd
. $bin/prologue.inc
dir=$tmpdir/tmpdir
# NET_RAW FAIL
genprofile
runchecktest "RAW SOCKET (no cap)" fail
# NET_RAW PASS (?)
genprofile cap:net_raw
runchecktest "RAW SOCKET (cap net_raw)" pass

View File

@@ -1,27 +0,0 @@
The multi-run testsuite works as follows:
In the base netdomain testsuite directory, there are two binaries:
test_multi.send and test_multi.receive.
The testcases are in test_multi/[testcase_name].testcase. These testcases
contain key/value pairs separated by a colon:
- send_ip: [ip address the sending program should bind to]
- send_port: [port number the sending program should bind to]
- send_profile: [the netdomain profile string for the sending program.
It can be blank]
- receive_ip: [ip address the receive program should bind to]
- receive_port: [port number the receive program should bind to]
- receive_profile: [the netdomain profile string for the receive
program. It can be blank]
- proto: [udp or tcp]
- message: [A message string that the sending program will send to the
receiving program]
In test_multi/output there are the expected output files:
- [testcase_name].send.out
- [testcase_name].receive.out
When the test suite runs, it will execute the sending and receiving
programs in parallel with the appropriate testcase settings applied to
them. Once the programs have finished executing, the output is diff'd
against the expected output to determine whether or not the test passes.

View File

@@ -1 +0,0 @@
load_lib "netdomain_init.exp"

Some files were not shown because too many files have changed in this diff Show More