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:
@@ -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;
|
||||
}
|
@@ -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 }
|
@@ -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
|
@@ -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
|
@@ -1 +0,0 @@
|
||||
/* create clone testprogram */
|
@@ -1 +0,0 @@
|
||||
# create clone testruns
|
@@ -1,2 +0,0 @@
|
||||
/* Inherited exec
|
||||
* This test to be completed */
|
@@ -1,2 +0,0 @@
|
||||
# Inherited exec
|
||||
# This test case driver to be completed
|
@@ -1,2 +0,0 @@
|
||||
/* Unconstrained exec
|
||||
* This test to be completed */
|
@@ -1,2 +0,0 @@
|
||||
# Unconstrained exec
|
||||
# This test case driver to be completed
|
@@ -1,2 +0,0 @@
|
||||
read and write of a filedescriptor received over a unix domain socket,
|
||||
both inside and outside of a change_hat.
|
@@ -1,2 +0,0 @@
|
||||
|
||||
|
@@ -1 +0,0 @@
|
||||
create signal (kill) tests
|
@@ -1 +0,0 @@
|
||||
create signal (kill) tests
|
@@ -1 +0,0 @@
|
||||
pread and pwrite
|
@@ -1 +0,0 @@
|
||||
readv and writev scatter gather io
|
@@ -1 +0,0 @@
|
||||
add tests for sendfile
|
@@ -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)
|
||||
*/
|
@@ -1 +0,0 @@
|
||||
/* this test to be completed */
|
@@ -1 +0,0 @@
|
||||
# this test case driver to be completed
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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;
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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);
|
||||
}
|
@@ -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
|
@@ -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;
|
||||
}
|
@@ -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)"
|
@@ -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;
|
||||
}
|
@@ -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}
|
||||
|
@@ -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]));
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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;
|
||||
}
|
||||
|
@@ -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=.
|
@@ -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
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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;
|
||||
}
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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))
|
@@ -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
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
@@ -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}
|
@@ -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
|
@@ -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
|
||||
|
@@ -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
|
@@ -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\
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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;
|
||||
+}
|
@@ -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
|
@@ -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
|
||||
|
||||
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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";
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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;
|
||||
}
|
@@ -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
|
@@ -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
|
@@ -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;
|
||||
}
|
@@ -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}
|
@@ -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;
|
||||
}
|
@@ -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
|
||||
|
@@ -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.
|
@@ -1 +0,0 @@
|
||||
load_lib "netdomain_init.exp"
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user