mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-05 00:35:13 +00:00
Compare commits
80 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f2fb53c6c3 | ||
|
3ae5213241 | ||
|
053b1df7b1 | ||
|
e9f12f3adb | ||
|
bcd7ee7b97 | ||
|
0144df6b75 | ||
|
41702a0c35 | ||
|
3e71e003c6 | ||
|
28c8a3a760 | ||
|
99755daafb | ||
|
224b9593e9 | ||
|
7dcb4a4f77 | ||
|
c6b8354fc5 | ||
|
1495b65f80 | ||
|
a70161a549 | ||
|
316f992b41 | ||
|
788669490a | ||
|
b68fe11978 | ||
|
b638f453e0 | ||
|
fdb9a6e43f | ||
|
914a0a443f | ||
|
cfa7ec1a79 | ||
|
43e3365a28 | ||
|
e5888e7031 | ||
|
66148c3fa5 | ||
|
162480cfb1 | ||
|
56772306c3 | ||
|
78a7df6711 | ||
|
5d9bb17a3b | ||
|
7cd903dd20 | ||
|
1ce8cd213c | ||
|
df05b82f7d | ||
|
56934923cc | ||
|
30a1e69379 | ||
|
319856b6a5 | ||
|
55a2d35c85 | ||
|
b75ba6902d | ||
|
e41b9b2d54 | ||
|
811625233f | ||
|
bc4a1afac1 | ||
|
512c81b3e1 | ||
|
ac7a848a1f | ||
|
99df4f4c76 | ||
|
0130fcaa24 | ||
|
bc586f7897 | ||
|
49bb2d753e | ||
|
182c3e47fb | ||
|
50aa7293dd | ||
|
79940b8e18 | ||
|
e6d2ada55c | ||
|
60d75132fc | ||
|
ccda637998 | ||
|
44ca6942f0 | ||
|
5e45af1752 | ||
|
f997977e6b | ||
|
848fbae814 | ||
|
368097d8e7 | ||
|
9da95e607e | ||
|
43c4c10501 | ||
|
c0766035df | ||
|
679e670024 | ||
|
0fcb7d032e | ||
|
288c67d639 | ||
|
d24b373138 | ||
|
699ec8434d | ||
|
10d3abf930 | ||
|
82d3b322da | ||
|
bceac420a6 | ||
|
f4b955ce75 | ||
|
66ef169a8b | ||
|
5f0dc143fc | ||
|
9064c1e185 | ||
|
300760a13e | ||
|
c23cd2e389 | ||
|
7176c1433b | ||
|
d88b047b3c | ||
|
6e8d5712c7 | ||
|
500b857d24 | ||
|
93ccf15ce6 | ||
|
e908b415d7 |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -95,6 +95,8 @@ libraries/libapparmor/src/.deps
|
||||
libraries/libapparmor/src/.libs
|
||||
libraries/libapparmor/src/Makefile
|
||||
libraries/libapparmor/src/Makefile.in
|
||||
libraries/libapparmor/src/PMurHash.lo
|
||||
libraries/libapparmor/src/PMurHash.o
|
||||
libraries/libapparmor/src/af_protos.h
|
||||
libraries/libapparmor/src/change_hat.lo
|
||||
libraries/libapparmor/src/features.lo
|
||||
@@ -161,8 +163,14 @@ libraries/libapparmor/swig/python/test/test-suite.log
|
||||
libraries/libapparmor/swig/python/test/test_python.py
|
||||
libraries/libapparmor/swig/python/test/test_python.py.log
|
||||
libraries/libapparmor/swig/python/test/test_python.py.trs
|
||||
libraries/libapparmor/swig/ruby/LibAppArmor.so
|
||||
libraries/libapparmor/swig/ruby/LibAppArmor_wrap.c
|
||||
libraries/libapparmor/swig/ruby/LibAppArmor_wrap.o
|
||||
libraries/libapparmor/swig/ruby/Makefile
|
||||
libraries/libapparmor/swig/ruby/Makefile.in
|
||||
libraries/libapparmor/swig/ruby/Makefile.new
|
||||
libraries/libapparmor/swig/ruby/Makefile.ruby
|
||||
libraries/libapparmor/swig/ruby/mkmf.log
|
||||
libraries/libapparmor/testsuite/.deps
|
||||
libraries/libapparmor/testsuite/.libs
|
||||
libraries/libapparmor/testsuite/Makefile
|
||||
@@ -188,6 +196,7 @@ utils/*.tmp
|
||||
utils/po/*.mo
|
||||
utils/apparmor/*.pyc
|
||||
utils/apparmor/rule/*.pyc
|
||||
utils/test/common_test.pyc
|
||||
utils/test/.coverage
|
||||
utils/test/htmlcov/
|
||||
utils/vim/apparmor.vim
|
||||
|
@@ -1 +1 @@
|
||||
2.12.1
|
||||
2.12.3
|
||||
|
@@ -109,7 +109,7 @@ class AAPythonBindingsTests(unittest.TestCase):
|
||||
|
||||
new_record = dict()
|
||||
for key in [x for x in dir(record) if not (x.startswith('_') or x == 'this')]:
|
||||
value = record.__getattr__(key)
|
||||
value = getattr(record, key)
|
||||
if key == "event" and value in EVENT_MAP:
|
||||
new_record[key] = EVENT_MAP[value]
|
||||
elif key == "version":
|
||||
|
@@ -111,7 +111,7 @@ capabilities(7))
|
||||
|
||||
B<NETWORK RULE> = [ I<QUALIFIERS> ] 'network' [ I<DOMAIN> ] [ I<TYPE> | I<PROTOCOL> ]
|
||||
|
||||
B<DOMAIN> = ( 'inet' | 'ax25' | 'ipx' | 'appletalk' | 'netrom' | 'bridge' | 'atmpvc' | 'x25' | 'inet6' | 'rose' | 'netbeui' | 'security' | 'key' | 'packet' | 'ash' | 'econet' | 'atmsvc' | 'sna' | 'irda' | 'pppox' | 'wanpipe' | 'bluetooth' | 'netlink' | 'unix' | 'rds' | 'llc' | 'can' | 'tipc' | 'iucv' | 'rxrpc' | 'isdn' | 'phonet' | 'ieee802154' | 'caif' | 'alg' | 'nfc' | 'vsock' | 'mpls' | 'ib' | 'kcm' | 'smc' ) ','
|
||||
B<DOMAIN> = ( 'unix' | 'inet' | 'ax25' | 'ipx' | 'appletalk' | 'netrom' | 'bridge' | 'atmpvc' | 'x25' | 'inet6' | 'rose' | 'netbeui' | 'security' | 'key' | 'netlink' | 'packet' | 'ash' | 'econet' | 'atmsvc' | 'rds' | 'sna' | 'irda' | 'pppox' | 'wanpipe' | 'llc' | 'ib' | 'mpls' | 'can' | 'tipc' | 'bluetooth' | 'iucv' | 'rxrpc' | 'isdn' | 'phonet' | 'ieee802154' | 'caif' | 'alg' | 'nfc' | 'vsock' | 'kcm' | 'qipcrtr' | 'smc' | 'xdp' ) ','
|
||||
|
||||
B<TYPE> = ( 'stream' | 'dgram' | 'seqpacket' | 'rdm' | 'raw' | 'packet' )
|
||||
|
||||
@@ -271,7 +271,7 @@ B<EXEC TRANSITION> = ( 'ix' | 'ux' | 'Ux' | 'px' | 'Px' | 'cx' | 'Cx' | 'pix' |
|
||||
B<EXEC TARGET> = name
|
||||
Requires I<EXEC TRANSITION> specified.
|
||||
|
||||
B<LINK RULE> = I<QUALIFIERS> [ 'owner' ] 'link' [ 'subset' ] I<FILEGLOB> ( 'to' | '-E<gt>' ) I<FILEGLOB>
|
||||
B<LINK RULE> = I<QUALIFIERS> [ 'owner' ] 'link' [ 'subset' ] I<FILEGLOB> '-E<gt>' I<FILEGLOB>
|
||||
|
||||
B<ALPHA> = ('a', 'b', 'c', ... 'z', 'A', 'B', ... 'Z')
|
||||
|
||||
|
@@ -143,6 +143,56 @@ messages with the KERN facility. Thus, REJECTING and PERMITTING messages
|
||||
may go to either F</var/log/audit/audit.log> or F</var/log/messages>,
|
||||
depending upon local configuration.
|
||||
|
||||
=head1 DEBUGGING
|
||||
|
||||
AppArmor provides a few facilities to log more information,
|
||||
which can help debugging profiles.
|
||||
|
||||
=head2 Enable debug mode
|
||||
|
||||
When debug mode is enabled, AppArmor will log a few extra messages to
|
||||
dmesg (not via the audit subsystem). For example, the logs will tell
|
||||
whether environment scrubbing has been applied.
|
||||
|
||||
To enable debug mode, run:
|
||||
|
||||
echo 1 > /sys/module/apparmor/parameters/debug
|
||||
|
||||
=head2 Turn off deny audit quieting
|
||||
|
||||
By default, operations that trigger C<deny> rules are not logged.
|
||||
This is called I<deny audit quieting>.
|
||||
|
||||
To turn off deny audit quieting, run:
|
||||
|
||||
echo -n noquiet >/sys/module/apparmor/parameters/audit
|
||||
|
||||
=head2 Force audit mode
|
||||
|
||||
AppArmor can log a message for every operation that triggers a rule
|
||||
configured in the policy. This is called I<force audit mode>.
|
||||
|
||||
B<Warning!> Force audit mode can be extremely noisy even for a single profile,
|
||||
let alone when enabled globally.
|
||||
|
||||
To set a specific profile in force audit mode, add the C<audit> flag:
|
||||
|
||||
profile foo flags=(audit) { ... }
|
||||
|
||||
To enable force audit mode globally, run:
|
||||
|
||||
echo -n all > /sys/module/apparmor/parameters/audit
|
||||
|
||||
If auditd is not running, to avoid losing too many of the extra log
|
||||
messages, you will likely have to turn off rate limiting by doing:
|
||||
|
||||
echo 0 > /proc/sys/kernel/printk_ratelimit
|
||||
|
||||
But even then the kernel ring buffer may overflow and you might
|
||||
lose messages.
|
||||
|
||||
Else, if auditd is running, see auditd(8) and auditd.conf(5).
|
||||
|
||||
=head1 FILES
|
||||
|
||||
=over 4
|
||||
|
@@ -126,9 +126,10 @@ bool aare_rules::add_rule_vec(int deny, uint32_t perms, uint32_t audit,
|
||||
|
||||
/* create a dfa from the ruleset
|
||||
* returns: buffer contain dfa tables, @size set to the size of the tables
|
||||
* else NULL on failure
|
||||
* else NULL on failure, @min_match_len set to the shortest string
|
||||
* that can match the dfa for determining xmatch priority.
|
||||
*/
|
||||
void *aare_rules::create_dfa(size_t *size, dfaflags_t flags)
|
||||
void *aare_rules::create_dfa(size_t *size, int *min_match_len, dfaflags_t flags)
|
||||
{
|
||||
char *buffer = NULL;
|
||||
|
||||
@@ -150,6 +151,7 @@ void *aare_rules::create_dfa(size_t *size, dfaflags_t flags)
|
||||
root = new AltNode(root, new CatNode(tmp, i->first));
|
||||
}
|
||||
}
|
||||
*min_match_len = root->min_match_len();
|
||||
|
||||
/* dumping of the none simplified tree without -O no-expr-simplify
|
||||
* is broken because we need to build the tree above first, and
|
||||
|
@@ -104,7 +104,7 @@ class aare_rules {
|
||||
uint32_t audit, dfaflags_t flags);
|
||||
bool add_rule_vec(int deny, uint32_t perms, uint32_t audit, int count,
|
||||
const char **rulev, dfaflags_t flags);
|
||||
void *create_dfa(size_t *size, dfaflags_t flags);
|
||||
void *create_dfa(size_t *size, int *min_match_len, dfaflags_t flags);
|
||||
};
|
||||
|
||||
#endif /* __LIBAA_RE_RULES_H */
|
||||
|
@@ -123,6 +123,19 @@ public:
|
||||
virtual void compute_firstpos() = 0;
|
||||
virtual void compute_lastpos() = 0;
|
||||
virtual void compute_followpos() { }
|
||||
|
||||
/*
|
||||
* min_match_len determines the smallest string that can match the
|
||||
* syntax tree. This is used to determine the priority of a regex.
|
||||
*/
|
||||
virtual int min_match_len() { return 0; }
|
||||
/*
|
||||
* contains_null returns if the expression tree contains a null character.
|
||||
* Null characters indicate that the rest of the DFA matches the xattrs and
|
||||
* not the path. This is used to compute min_match_len.
|
||||
*/
|
||||
virtual bool contains_null() { return false; }
|
||||
|
||||
virtual int eq(Node *other) = 0;
|
||||
virtual ostream &dump(ostream &os) = 0;
|
||||
void dump_syntax_tree(ostream &os);
|
||||
@@ -257,6 +270,17 @@ public:
|
||||
return os << c;
|
||||
}
|
||||
|
||||
int min_match_len()
|
||||
{
|
||||
if (c == 0) {
|
||||
// Null character indicates end of string.
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool contains_null() { return c == 0; }
|
||||
|
||||
uchar c;
|
||||
};
|
||||
|
||||
@@ -298,6 +322,24 @@ public:
|
||||
return os << ']';
|
||||
}
|
||||
|
||||
int min_match_len()
|
||||
{
|
||||
if (contains_null()) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool contains_null()
|
||||
{
|
||||
for (Chars::iterator i = chars.begin(); i != chars.end(); i++) {
|
||||
if (*i == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Chars chars;
|
||||
};
|
||||
|
||||
@@ -346,6 +388,24 @@ public:
|
||||
return os << ']';
|
||||
}
|
||||
|
||||
int min_match_len()
|
||||
{
|
||||
if (contains_null()) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool contains_null()
|
||||
{
|
||||
for (Chars::iterator i = chars.begin(); i != chars.end(); i++) {
|
||||
if (*i == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Chars chars;
|
||||
};
|
||||
|
||||
@@ -369,6 +429,8 @@ public:
|
||||
return 0;
|
||||
}
|
||||
ostream &dump(ostream &os) { return os << "."; }
|
||||
|
||||
bool contains_null() { return true; }
|
||||
};
|
||||
|
||||
/* Match a node zero or more times. (This is a unary operator.) */
|
||||
@@ -396,6 +458,8 @@ public:
|
||||
child[0]->dump(os);
|
||||
return os << ")*";
|
||||
}
|
||||
|
||||
bool contains_null() { return child[0]->contains_null(); }
|
||||
};
|
||||
|
||||
/* Match a node one or more times. (This is a unary operator.) */
|
||||
@@ -423,6 +487,8 @@ public:
|
||||
child[0]->dump(os);
|
||||
return os << ")+";
|
||||
}
|
||||
int min_match_len() { return child[0]->min_match_len(); }
|
||||
bool contains_null() { return child[0]->contains_null(); }
|
||||
};
|
||||
|
||||
/* Match a pair of consecutive nodes. */
|
||||
@@ -470,6 +536,22 @@ public:
|
||||
return os;
|
||||
}
|
||||
void normalize(int dir);
|
||||
int min_match_len()
|
||||
{
|
||||
int len = child[0]->min_match_len();
|
||||
if (child[0]->contains_null()) {
|
||||
// Null characters are used to indicate when the DFA transitions
|
||||
// from matching the path to matching the xattrs. If the left child
|
||||
// contains a null character, the right side doesn't contribute to
|
||||
// the path match.
|
||||
return len;
|
||||
}
|
||||
return len + child[1]->min_match_len();
|
||||
}
|
||||
bool contains_null()
|
||||
{
|
||||
return child[0]->contains_null() || child[1]->contains_null();
|
||||
}
|
||||
};
|
||||
|
||||
/* Match one of two alternative nodes. */
|
||||
@@ -507,6 +589,20 @@ public:
|
||||
return os;
|
||||
}
|
||||
void normalize(int dir);
|
||||
int min_match_len()
|
||||
{
|
||||
int m1, m2;
|
||||
m1 = child[0]->min_match_len();
|
||||
m2 = child[1]->min_match_len();
|
||||
if (m1 < m2) {
|
||||
return m1;
|
||||
}
|
||||
return m2;
|
||||
}
|
||||
bool contains_null()
|
||||
{
|
||||
return child[0]->contains_null() || child[1]->contains_null();
|
||||
}
|
||||
};
|
||||
|
||||
class SharedNode: public ImportantNode {
|
||||
|
@@ -171,13 +171,23 @@ extern int preprocess_only;
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
#define PDEBUG(fmt, args...) fprintf(stderr, "parser: " fmt, ## args)
|
||||
#define PDEBUG(fmt, args...) \
|
||||
do { \
|
||||
int pdebug_error = errno; \
|
||||
fprintf(stderr, "parser: " fmt, ## args); \
|
||||
errno = pdebug_error; \
|
||||
} while (0)
|
||||
#else
|
||||
#define PDEBUG(fmt, args...) /* Do nothing */
|
||||
#endif
|
||||
#define NPDEBUG(fmt, args...) /* Do nothing */
|
||||
|
||||
#define PERROR(fmt, args...) fprintf(stderr, fmt, ## args)
|
||||
#define PERROR(fmt, args...) \
|
||||
do { \
|
||||
int perror_error = errno; \
|
||||
fprintf(stderr, fmt, ## args); \
|
||||
errno = perror_error; \
|
||||
} while (0)
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (1)
|
||||
|
@@ -605,7 +605,7 @@ include/{WS} {
|
||||
|
||||
{CARET} { PUSH_AND_RETURN(SUB_ID, TOK_CARET); }
|
||||
|
||||
{ARROW} { RETURN_TOKEN(TOK_ARROW); }
|
||||
{ARROW} { PUSH_AND_RETURN(SUB_ID_WS, TOK_ARROW); }
|
||||
|
||||
{EQUALS} { PUSH_AND_RETURN(ASSIGN_MODE, TOK_EQUALS); }
|
||||
|
||||
|
@@ -439,8 +439,6 @@ static int process_arg(int c, char *optarg)
|
||||
}
|
||||
break;
|
||||
case 'O':
|
||||
skip_read_cache = 1;
|
||||
|
||||
if (!handle_flag_table(optflag_table, optarg,
|
||||
&dfaflags)) {
|
||||
PERROR("%s: Invalid --Optimize option %s\n",
|
||||
@@ -899,8 +897,11 @@ do { \
|
||||
work_sync_one(RESULT); \
|
||||
} while (0)
|
||||
|
||||
/* returns -1 if work_spawn fails, not a return value of any unit of work */
|
||||
#define work_spawn(WORK, RESULT) \
|
||||
do { \
|
||||
({ \
|
||||
int localrc = 0; \
|
||||
do { \
|
||||
/* what to do to avoid fork() overhead when single threaded \
|
||||
if (jobs == 1) { \
|
||||
// no parallel work so avoid fork() overhead \
|
||||
@@ -937,11 +938,17 @@ do { \
|
||||
fprintf(stderr, " JOBS SPAWN: created %ld ...\n", njobs); \
|
||||
} else { \
|
||||
/* error */ \
|
||||
if (debug_jobs) \
|
||||
fprintf(stderr, " JOBS SPAWN: failed error: %d) ...\n", errno); \
|
||||
if (debug_jobs) { \
|
||||
int error = errno; \
|
||||
fprintf(stderr, " JOBS SPAWN: failed error: %d) ...\n", errno); \
|
||||
errno = error; \
|
||||
} \
|
||||
RESULT(errno); \
|
||||
localrc = -1; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0); \
|
||||
localrc; \
|
||||
})
|
||||
|
||||
|
||||
/* sadly C forces us to do this with exit, long_jump or returning error
|
||||
@@ -1018,11 +1025,15 @@ static int profile_dir_cb(int dirfd unused, const char *name, struct stat *st,
|
||||
if (!S_ISDIR(st->st_mode) && !is_blacklisted(name, NULL)) {
|
||||
struct dir_cb_data *cb_data = (struct dir_cb_data *)data;
|
||||
autofree char *path = NULL;
|
||||
if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0)
|
||||
if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0) {
|
||||
PERROR(_("Out of memory"));
|
||||
work_spawn(process_profile(option, cb_data->kernel_interface,
|
||||
path, cb_data->cachedir),
|
||||
handle_work_result);
|
||||
handle_work_result(errno);
|
||||
return -1;
|
||||
}
|
||||
rc = work_spawn(process_profile(option,
|
||||
cb_data->kernel_interface,
|
||||
path, cb_data->cachedir),
|
||||
handle_work_result);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -1036,11 +1047,15 @@ static int binary_dir_cb(int dirfd unused, const char *name, struct stat *st,
|
||||
if (!S_ISDIR(st->st_mode) && !is_blacklisted(name, NULL)) {
|
||||
struct dir_cb_data *cb_data = (struct dir_cb_data *)data;
|
||||
autofree char *path = NULL;
|
||||
if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0)
|
||||
if (asprintf(&path, "%s/%s", cb_data->dirname, name) < 0) {
|
||||
PERROR(_("Out of memory"));
|
||||
work_spawn(process_binary(option, cb_data->kernel_interface,
|
||||
path),
|
||||
handle_work_result);
|
||||
handle_work_result(errno);
|
||||
return -1;
|
||||
}
|
||||
rc = work_spawn(process_binary(option,
|
||||
cb_data->kernel_interface,
|
||||
path),
|
||||
handle_work_result);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -1157,11 +1172,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
/* skip stdin if we've seen other command line arguments */
|
||||
if (i == argc && optind != argc)
|
||||
continue;
|
||||
goto cleanup;
|
||||
|
||||
if (profilename && stat(profilename, &stat_file) == -1) {
|
||||
last_error = errno;
|
||||
PERROR("File %s not found, skipping...\n", profilename);
|
||||
continue;
|
||||
if (abort_on_error)
|
||||
break;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (profilename && S_ISDIR(stat_file.st_mode)) {
|
||||
@@ -1176,20 +1194,27 @@ int main(int argc, char *argv[])
|
||||
cb = binary_input ? binary_dir_cb : profile_dir_cb;
|
||||
if ((retval = dirat_for_each(AT_FDCWD, profilename,
|
||||
&cb_data, cb))) {
|
||||
last_error = errno;
|
||||
PDEBUG("Failed loading profiles from %s\n",
|
||||
profilename);
|
||||
if (abort_on_error)
|
||||
break;
|
||||
}
|
||||
} else if (binary_input) {
|
||||
/* ignore return as error is handled in work_spawn */
|
||||
work_spawn(process_binary(option, kernel_interface,
|
||||
profilename),
|
||||
handle_work_result);
|
||||
} else {
|
||||
/* ignore return as error is handled in work_spawn */
|
||||
work_spawn(process_profile(option, kernel_interface,
|
||||
profilename, cacheloc),
|
||||
handle_work_result);
|
||||
}
|
||||
|
||||
if (profilename) free(profilename);
|
||||
cleanup:
|
||||
if (profilename)
|
||||
free(profilename);
|
||||
profilename = NULL;
|
||||
}
|
||||
work_sync(handle_work_result);
|
||||
|
@@ -473,17 +473,13 @@ static int process_profile_name_xmatch(Profile *prof)
|
||||
ptype = convert_aaregex_to_pcre(alt->name, 0,
|
||||
glob_default,
|
||||
tbuf, &len);
|
||||
if (ptype == ePatternBasic)
|
||||
len = strlen(alt->name);
|
||||
if (len < prof->xmatch_len)
|
||||
prof->xmatch_len = len;
|
||||
if (!rules->add_rule(tbuf.c_str(), 0, AA_MAY_EXEC, 0, dfaflags)) {
|
||||
delete rules;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
prof->xmatch = rules->create_dfa(&prof->xmatch_size, dfaflags);
|
||||
prof->xmatch = rules->create_dfa(&prof->xmatch_size, &prof->xmatch_len, dfaflags);
|
||||
delete rules;
|
||||
if (!prof->xmatch)
|
||||
return FALSE;
|
||||
@@ -679,8 +675,9 @@ int process_profile_regex(Profile *prof)
|
||||
goto out;
|
||||
|
||||
if (prof->dfa.rules->rule_count > 0) {
|
||||
int xmatch_len = 0;
|
||||
prof->dfa.dfa = prof->dfa.rules->create_dfa(&prof->dfa.size,
|
||||
dfaflags);
|
||||
&xmatch_len, dfaflags);
|
||||
delete prof->dfa.rules;
|
||||
prof->dfa.rules = NULL;
|
||||
if (!prof->dfa.dfa)
|
||||
@@ -815,7 +812,9 @@ int process_profile_policydb(Profile *prof)
|
||||
goto out;
|
||||
|
||||
if (prof->policy.rules->rule_count > 0) {
|
||||
prof->policy.dfa = prof->policy.rules->create_dfa(&prof->policy.size, dfaflags);
|
||||
int xmatch_len = 0;
|
||||
prof->policy.dfa = prof->policy.rules->create_dfa(&prof->policy.size,
|
||||
&xmatch_len, dfaflags);
|
||||
delete prof->policy.rules;
|
||||
|
||||
prof->policy.rules = NULL;
|
||||
|
@@ -113,6 +113,8 @@ skip_profile() {
|
||||
local profile=$1
|
||||
if [ "${profile%.rpmnew}" != "${profile}" -o \
|
||||
"${profile%.rpmsave}" != "${profile}" -o \
|
||||
"${profile%.orig}" != "${profile}" -o \
|
||||
"${profile%.rej}" != "${profile}" -o \
|
||||
-e "${PROFILE_DIR}/disable/`basename ${profile}`" -o \
|
||||
"${profile%\~}" != "${profile}" ] ; then
|
||||
return 1
|
||||
@@ -401,14 +403,16 @@ remove_profiles() {
|
||||
# We filter child profiles as removing the parent will remove
|
||||
# the children
|
||||
sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | \
|
||||
LC_COLLATE=C sort | grep -v // | while read profile ; do
|
||||
echo -n "$profile" > "$SFS_MOUNTPOINT/.remove"
|
||||
rc=$?
|
||||
if [ ${rc} -ne 0 ] ; then
|
||||
retval=${rc}
|
||||
fi
|
||||
done
|
||||
return ${retval}
|
||||
LC_COLLATE=C sort | grep -v // | {
|
||||
while read profile ; do
|
||||
echo -n "$profile" > "$SFS_MOUNTPOINT/.remove"
|
||||
rc=$?
|
||||
if [ ${rc} -ne 0 ] ; then
|
||||
retval=${rc}
|
||||
fi
|
||||
done
|
||||
return ${retval}
|
||||
}
|
||||
}
|
||||
|
||||
apparmor_stop() {
|
||||
|
@@ -131,9 +131,13 @@ sub test_profile {
|
||||
} elsif ($coredump) {
|
||||
ok(0, "$profile: Produced core dump (signal $signal): $description");
|
||||
} elsif ($istodo) {
|
||||
TODO: {
|
||||
local $TODO = "Unfixed testcase.";
|
||||
ok($expass ? !$result : $result, "TODO: $profile: $description");
|
||||
if ($expass != $result) {
|
||||
fail("TODO passed unexpectedly: $profile: $description");
|
||||
} else {
|
||||
TODO: {
|
||||
local $TODO = "Unfixed testcase.";
|
||||
ok($expass ? !$result : $result, "TODO: $profile: $description");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ok($expass ? !$result : $result, "$profile: $description");
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#=DESCRIPTION abi testing - abi path quotes in <> with spaces
|
||||
#=EXRESULT PASS
|
||||
#=TODO
|
||||
#=DISABLED - results in "superfluous TODO", but fails after removing TODO
|
||||
|
||||
abi < "abi/4.19">,
|
||||
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#=DESCRIPTION abi testing - abi path quotes in <> with spaces
|
||||
#=EXRESULT PASS
|
||||
#=TODO
|
||||
#=DISABLED - results in "superfluous TODO", but fails after removing TODO
|
||||
|
||||
abi < "abi/4.19" >,
|
||||
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#=DESCRIPTION reference variables in rules that also have alternations
|
||||
#=EXRESULT PASS
|
||||
#=TODO
|
||||
# This test needs check on @{FOO} attachment having leading / post var expansion
|
||||
|
||||
@{FOO}=/bar /baz
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#=DESCRIPTION reference variables is null
|
||||
#=EXRESULT FAIL
|
||||
#=TODO
|
||||
#needs post var expansion check that variable contained a value
|
||||
|
||||
@{FOO}=
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#=DESCRIPTION reference variables is null
|
||||
#=EXRESULT FAIL
|
||||
#=TODO
|
||||
#needs post var expansion check that variable contained a value
|
||||
|
||||
@{FOO}=
|
||||
|
@@ -1,7 +1,6 @@
|
||||
#
|
||||
#=DESCRIPTION test for conflict resolution in minimization phase of dfa gen
|
||||
#=EXRESULT PASS
|
||||
#=TODO
|
||||
#
|
||||
/usr/bin/foo {
|
||||
|
||||
|
@@ -1,7 +1,6 @@
|
||||
#
|
||||
#=DESCRIPTION test for conflict resolution in minimization phase of dfa gen
|
||||
#=EXRESULT FAIL
|
||||
#=TODO
|
||||
#
|
||||
/usr/bin/foo {
|
||||
/b* px,
|
||||
|
@@ -29,6 +29,7 @@ DESTDIR=/
|
||||
PROFILES_DEST=${DESTDIR}/etc/apparmor.d
|
||||
EXTRAS_DEST=${DESTDIR}/usr/share/apparmor/extra-profiles/
|
||||
PROFILES_SOURCE=./apparmor.d
|
||||
ABSTRACTIONS_SOURCE=./apparmor.d/abstractions
|
||||
EXTRAS_SOURCE=./apparmor/profiles/extras/
|
||||
|
||||
SUBDIRS=$(shell find ${PROFILES_SOURCE} -type d -print)
|
||||
@@ -84,6 +85,8 @@ docs:
|
||||
|
||||
IGNORE_FILES=${EXTRAS_SOURCE}/README
|
||||
CHECK_PROFILES=$(filter-out ${IGNORE_FILES} ${SUBDIRS}, $(wildcard ${PROFILES_SOURCE}/*) $(wildcard ${EXTRAS_SOURCE}/*))
|
||||
# use find because Make wildcard is not recursive:
|
||||
CHECK_ABSTRACTIONS=$(shell find ${ABSTRACTIONS_SOURCE} -type f -print)
|
||||
|
||||
.PHONY: check
|
||||
check: check-parser check-logprof
|
||||
@@ -96,6 +99,14 @@ check-parser: local
|
||||
${PARSER} -S -b ${PWD}/apparmor.d $${profile} > /dev/null || exit 1; \
|
||||
done
|
||||
|
||||
@echo "*** Checking abstractions from ${ABSTRACTIONS_SOURCE} against apparmor_parser"
|
||||
$(Q)for abstraction in ${CHECK_ABSTRACTIONS} ; do \
|
||||
[ -n "${VERBOSE}" ] && echo "Testing $${abstraction}" ; \
|
||||
echo "#include <tunables/global> profile test { #include <$${abstraction}> }" \
|
||||
| ${PARSER} -S -b ${PWD}/apparmor.d -I ${PWD} > /dev/null \
|
||||
|| exit 1; \
|
||||
done
|
||||
|
||||
.PHONY: check-logprof
|
||||
check-logprof: local
|
||||
@echo "*** Checking profiles from ${PROFILES_SOURCE} against logprof"
|
||||
|
@@ -7,9 +7,9 @@
|
||||
# Allow unconfined processes to send us signals by default
|
||||
signal (receive) peer=unconfined,
|
||||
# Allow apache to send us signals by default
|
||||
signal (receive) peer=/usr/{bin,sbin}/apache2,
|
||||
signal (receive) peer=apache2,
|
||||
# Allow other hats to signal by default
|
||||
signal peer=/usr/{bin,sbin}/apache2//*,
|
||||
signal peer=apache2//*,
|
||||
# Allow us to signal ourselves
|
||||
signal peer=@{profile_name},
|
||||
|
||||
|
@@ -41,9 +41,14 @@
|
||||
/usr/share/sounds/** r,
|
||||
|
||||
owner @{HOME}/.esd_auth r,
|
||||
/etc/asound.conf r,
|
||||
owner @{HOME}/.asoundrc r,
|
||||
/etc/esound/esd.conf r,
|
||||
|
||||
# libao
|
||||
/etc/libao.conf r,
|
||||
owner @{HOME}/.libao r,
|
||||
|
||||
# libcanberra
|
||||
owner @{HOME}/.cache/event-sound-cache.* rwk,
|
||||
|
||||
@@ -68,6 +73,7 @@ owner /tmp/pulse-*/* rw,
|
||||
/etc/sound/** r,
|
||||
|
||||
# openal
|
||||
/etc/alsa/conf.d/{,*} r,
|
||||
/etc/openal/alsoft.conf r,
|
||||
owner @{HOME}/.alsoftrc r,
|
||||
/usr/{,local/}share/openal/hrtf/{,**} r,
|
||||
|
@@ -90,8 +90,8 @@
|
||||
@{PROC}/meminfo r,
|
||||
@{PROC}/stat r,
|
||||
@{PROC}/cpuinfo r,
|
||||
/sys/devices/system/cpu/ r,
|
||||
/sys/devices/system/cpu/online r,
|
||||
@{sys}/devices/system/cpu/ r,
|
||||
@{sys}/devices/system/cpu/online r,
|
||||
|
||||
# glibc's *printf protections read the maps file
|
||||
@{PROC}/@{pid}/{maps,auxv,status} r,
|
||||
|
@@ -14,6 +14,6 @@
|
||||
deny capability block_suspend,
|
||||
|
||||
# dovecot's master can send us signals
|
||||
signal receive peer=/usr/{bin,sbin}/dovecot,
|
||||
signal receive peer=dovecot,
|
||||
|
||||
/{var/,}run/dovecot/config rw,
|
||||
|
@@ -18,7 +18,9 @@
|
||||
/usr/share/fonts/** r,
|
||||
|
||||
/etc/fonts/** r,
|
||||
/usr/share/fontconfig/conf.avail/** r,
|
||||
# Debian, openSUSE paths are different
|
||||
/usr/share/{fontconfig,fonts-config,*-fonts}/conf.avail/{,**} r,
|
||||
/usr/share/ghostscript/fonts/{,**} r,
|
||||
|
||||
/opt/kde3/share/fonts/** r,
|
||||
|
||||
@@ -42,8 +44,8 @@
|
||||
owner @{HOME}/.local/share/fonts/ r,
|
||||
owner @{HOME}/.local/share/fonts/** r,
|
||||
owner @{HOME}/.fonts.cache-2 mr,
|
||||
owner @{HOME}/.{,cache/}fontconfig/ r,
|
||||
owner @{HOME}/.{,cache/}fontconfig/** mrl,
|
||||
owner @{HOME}/.{,cache/}fontconfig/ rw,
|
||||
owner @{HOME}/.{,cache/}fontconfig/** mrwl,
|
||||
owner @{HOME}/.fonts.conf.d/ r,
|
||||
owner @{HOME}/.fonts.conf.d/** r,
|
||||
owner @{HOME}/.config/fontconfig/ r,
|
||||
|
@@ -42,6 +42,7 @@
|
||||
/usr/lib/@{multiarch}/gdk-pixbuf-*/** mr,
|
||||
|
||||
# per-user gtk configuration
|
||||
owner @{HOME}/.config/gtk-3.0/ w,
|
||||
owner @{HOME}/.config/gtk-3.0/* r,
|
||||
owner @{HOME}/.gnome/Gnome r,
|
||||
owner @{HOME}/.gtk r,
|
||||
@@ -52,6 +53,7 @@
|
||||
owner @{HOME}/.themes/** r,
|
||||
|
||||
# for gtk file dialog
|
||||
owner @{HOME}/.config/gtk-2.0/ w,
|
||||
owner @{HOME}/.config/gtk-2.0/** r,
|
||||
owner @{HOME}/.config/gtk-2.0/gtkfilechooser.ini* rw,
|
||||
|
||||
@@ -62,6 +64,9 @@
|
||||
# per-user font business
|
||||
owner @{HOME}/.fonts.cache-* rwl,
|
||||
|
||||
# GtkComposeTable
|
||||
owner @{HOME}/.cache/gtk-3.0/** r,
|
||||
|
||||
# icon caches
|
||||
/var/cache/**/icon-theme.cache r,
|
||||
/usr/share/**/icon-theme.cache r,
|
||||
|
@@ -23,7 +23,10 @@
|
||||
/etc/kderc r,
|
||||
/etc/kde3/* r,
|
||||
/etc/kde4rc r,
|
||||
/etc/xdg/kdeglobals r,
|
||||
/etc/xdg/Trolltech.conf r,
|
||||
/usr/share/knotifications5/*.notifyrc r, # KNotification::sendEvent()
|
||||
/usr/share/kubuntu-default-settings/kf5-settings/* r,
|
||||
|
||||
owner @{HOME}/.DCOPserver_* r,
|
||||
owner @{HOME}/.ICEauthority r,
|
||||
@@ -31,7 +34,14 @@ owner @{HOME}/.fonts.* lrw,
|
||||
owner @{HOME}/.kde{,4}/share/config/kdeglobals rw,
|
||||
owner @{HOME}/.kde{,4}/share/config/*.lock rwl,
|
||||
owner @{HOME}/.qt/** rw,
|
||||
owner @{HOME}/.cache/ksycoca5_??_* r, # KDE System Configuration Cache
|
||||
owner @{HOME}/.config/Trolltech.conf rwk,
|
||||
owner @{HOME}/.config/baloofilerc r, # indexing options (excludes, etc), used by KFileWidget
|
||||
owner @{HOME}/.config/dolphinrc r, # settings used by KFileWidget
|
||||
owner @{HOME}/.config/kde.org/libphonon.conf r, # for KNotifications::sendEvent()
|
||||
owner @{HOME}/.config/kdeglobals r, # global settings, used by Breeze style, etc.
|
||||
owner @{HOME}/.config/klanguageoverridesrc r, # per-application languages, for KDEPrivate::initializeLanguages() from libKF5XmlGui.so
|
||||
owner @{HOME}/.config/trashrc r, # Used by KFileWidget
|
||||
|
||||
/usr/share/icons/ r,
|
||||
/usr/share/icons/** r,
|
||||
|
@@ -18,4 +18,7 @@
|
||||
/etc/sasl2/* r,
|
||||
/usr/lib{,32,64}/sasl2/* r,
|
||||
|
||||
# local LDAP name service daemon
|
||||
/{,var/}run/nslcd/socket rw,
|
||||
|
||||
#include <abstractions/ssl_certs>
|
||||
|
@@ -39,7 +39,7 @@
|
||||
/etc/resolv.conf r,
|
||||
# On systems where /etc/resolv.conf is managed programmatically, it is
|
||||
# a symlink to /{,var/}run/(whatever program is managing it)/resolv.conf.
|
||||
/{,var/}run/{resolvconf,NetworkManager,systemd/resolve,connman}/resolv.conf r,
|
||||
/{,var/}run/{resolvconf,NetworkManager,systemd/resolve,connman,netconfig}/resolv.conf r,
|
||||
/etc/resolvconf/run/resolv.conf r,
|
||||
/{,var/}run/systemd/resolve/stub-resolv.conf r,
|
||||
|
||||
|
@@ -4,6 +4,8 @@
|
||||
# configuration queries
|
||||
capability ipc_lock,
|
||||
|
||||
/usr/share/nvidia/nvidia-application-profiles* r,
|
||||
|
||||
# libvdpau config file for nvidia workarounds
|
||||
/etc/vdpau_wrapper.cfg r,
|
||||
|
||||
|
@@ -17,8 +17,10 @@
|
||||
|
||||
# postfix's master can send us signals
|
||||
signal receive peer=/usr/lib/postfix/master,
|
||||
signal receive peer=postfix-master,
|
||||
|
||||
unix (send, receive) peer=(label=/usr/lib/postfix/master),
|
||||
unix (send, receive) peer=(label=postfix-master),
|
||||
|
||||
/etc/mailname r,
|
||||
/etc/postfix/*.cf r,
|
||||
|
@@ -6,6 +6,7 @@
|
||||
# lot of false positives when reading contents of directories)
|
||||
deny @{HOME}/.*history mrwkl,
|
||||
deny @{HOME}/.fetchmail* mrwkl,
|
||||
deny @{HOME}/.mutt** mrwkl,
|
||||
deny @{HOME}/.viminfo* mrwkl,
|
||||
deny @{HOME}/.*~ mrwkl,
|
||||
deny @{HOME}/.*.swp mrwkl,
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include <abstractions/private-files>
|
||||
|
||||
# potentially extremely sensitive files
|
||||
audit deny @{HOME}/.aws/{,**} mrwkl,
|
||||
audit deny @{HOME}/.gnupg/{,**} mrwkl,
|
||||
audit deny @{HOME}/.ssh/{,**} mrwkl,
|
||||
audit deny @{HOME}/.gnome2_private/{,**} mrwkl,
|
||||
|
@@ -15,9 +15,9 @@
|
||||
/usr/lib{,32,64}/python{2.[4-7],3.[0-9]}/{site,dist}-packages/ r,
|
||||
/usr/lib{,32,64}/python3.[0-9]/lib-dynload/*.so mr,
|
||||
|
||||
/usr/local/lib{,32,64}/python{2.[4-7],3.[0-9]}/**.{pyc,so} mr,
|
||||
/usr/local/lib{,32,64}/python{2.[4-7],3.[0-9]}/**.{egg,py,pth} r,
|
||||
/usr/local/lib{,32,64}/python{2.[4-7],3.[0-9]}/{site,dist}-packages/ r,
|
||||
/usr/local/lib{,32,64}/python{2.[4-7],3,3.[0-9]}/**.{pyc,so} mr,
|
||||
/usr/local/lib{,32,64}/python{2.[4-7],3,3.[0-9]}/**.{egg,py,pth} r,
|
||||
/usr/local/lib{,32,64}/python{2.[4-7],3,3.[0-9]}/{site,dist}-packages/ r,
|
||||
/usr/local/lib{,32,64}/python3.[0-9]/lib-dynload/*.so mr,
|
||||
|
||||
# Site-wide configuration
|
||||
@@ -28,7 +28,7 @@
|
||||
/{var,usr}/lib/{pyshared,pycentral,python-support}/** r,
|
||||
/usr/lib/{pyshared,pycentral,python-support}/**.so mr,
|
||||
/var/lib/{pyshared,pycentral,python-support}/**.pyc mr,
|
||||
/usr/{,local/}lib/python3/dist-packages/**.so mr,
|
||||
/usr/lib/python3/dist-packages/**.so mr,
|
||||
|
||||
# wx paths
|
||||
/usr/lib/wx/python/*.pth r,
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
# User files
|
||||
|
||||
owner @{HOME}/.config/QtProject/qtlogging.ini r,
|
||||
owner @{HOME}/.config/QtProject.conf r, # common settings for QFileDialog, etc (application might need write access)
|
||||
owner @{HOME}/.cache/qt_compose_cache_{little,big}_endian_* r, # for "platforminputcontexts" plugins
|
||||
|
||||
|
@@ -3,5 +3,6 @@
|
||||
|
||||
# User files
|
||||
|
||||
owner @{HOME}/.cache/qt_compose_cache_{little,big}_endian_* rw,
|
||||
owner @{HOME}/.cache/qt_compose_cache_{little,big}_endian_* rwl -> @{HOME}/.cache/#[0-9]*[0-9],
|
||||
owner @{HOME}/.cache/#[0-9]*[0-9] rw, # QSaveFile (anonymous shared memory)
|
||||
|
||||
|
@@ -3,9 +3,9 @@
|
||||
|
||||
# User files
|
||||
|
||||
owner @{HOME}/.config/#[0-9]* rw,
|
||||
owner @{HOME}/.config/QtProject.conf rw,
|
||||
owner @{HOME}/.config/QtProject.conf.?????? l -> @{HOME}/.config/#[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9],
|
||||
owner @{HOME}/.config/QtProject.conf.?????? rw, # for temporary files like QtProject.conf.Aqrgeb
|
||||
owner @{HOME}/.config/#[0-9]*[0-9] rw,
|
||||
owner @{HOME}/.config/QtProject.conf rwl -> @{HOME}/.config/#[0-9]*[0-9],
|
||||
# for temporary files like QtProject.conf.Aqrgeb
|
||||
owner @{HOME}/.config/QtProject.conf.?????? rwl -> @{HOME}/.config/#[0-9]*[0-9],
|
||||
owner @{HOME}/.config/QtProject.conf.lock rwk,
|
||||
|
||||
|
@@ -29,6 +29,12 @@
|
||||
/var/lib/acme/certs/*/cert r,
|
||||
|
||||
# dehydrated
|
||||
/etc/dehydrated/certs/*/cert-*.pem r,
|
||||
/etc/dehydrated/certs/*/chain-*.pem r,
|
||||
/etc/dehydrated/certs/*/fullchain-*.pem r,
|
||||
/{etc,var/lib}/dehydrated/certs/*/cert*.pem r,
|
||||
/{etc,var/lib}/dehydrated/certs/*/chain*.pem r,
|
||||
/{etc,var/lib}/dehydrated/certs/*/fullchain*.pem r,
|
||||
/{etc,var/lib}/dehydrated/certs/*/ocsp*.der r,
|
||||
|
||||
# certbot
|
||||
/etc/letsencrypt/archive/*/cert*.pem r,
|
||||
/etc/letsencrypt/archive/*/chain*.pem r,
|
||||
/etc/letsencrypt/archive/*/fullchain*.pem r,
|
||||
|
@@ -22,4 +22,7 @@
|
||||
/var/lib/acme/keys/** r,
|
||||
|
||||
# dehydrated
|
||||
/etc/dehydrated/certs/*/privkey-*.pem r,
|
||||
/{etc,var/lib}/dehydrated/certs/*/privkey*.pem r,
|
||||
|
||||
# certbot / letsencrypt
|
||||
/etc/letsencrypt/archive/*/privkey*.pem r,
|
||||
|
@@ -41,8 +41,8 @@
|
||||
@{PROC}/@{pid}/ r,
|
||||
@{PROC}/@{pid}/fd/ r,
|
||||
@{PROC}/filesystems r,
|
||||
/sys/devices/system/cpu/ r,
|
||||
/sys/devices/system/cpu/** r,
|
||||
@{sys}/devices/system/cpu/ r,
|
||||
@{sys}/devices/system/cpu/** r,
|
||||
/usr/share/** r,
|
||||
/var/lib/dbus/machine-id r,
|
||||
|
||||
@@ -88,8 +88,8 @@
|
||||
@{PROC}/@{pid}/ r,
|
||||
@{PROC}/@{pid}/fd/ r,
|
||||
@{PROC}/filesystems r,
|
||||
/sys/devices/system/cpu/ r,
|
||||
/sys/devices/system/cpu/** r,
|
||||
@{sys}/devices/system/cpu/ r,
|
||||
@{sys}/devices/system/cpu/** r,
|
||||
/usr/share/** r,
|
||||
/var/lib/dbus/machine-id r,
|
||||
|
||||
|
@@ -17,6 +17,9 @@
|
||||
/usr/bin/gwenview Cxr -> sanitized_helper,
|
||||
|
||||
#include <abstractions/ubuntu-media-players>
|
||||
owner @{HOME}/.adobe/ w,
|
||||
owner @{HOME}/.adobe/** rw,
|
||||
owner @{HOME}/.macromedia/ w,
|
||||
owner @{HOME}/.macromedia/** rw,
|
||||
/opt/real/RealPlayer/mozilla/nphelix.so rm,
|
||||
/usr/bin/lpstat Cxr -> sanitized_helper,
|
||||
|
@@ -2,5 +2,5 @@
|
||||
# video device access
|
||||
|
||||
# System devices
|
||||
/sys/class/video4linux r,
|
||||
/sys/class/video4linux/** r,
|
||||
@{sys}/class/video4linux r,
|
||||
@{sys}/class/video4linux/** r,
|
||||
|
15
profiles/apparmor.d/abstractions/vulkan
Normal file
15
profiles/apparmor.d/abstractions/vulkan
Normal file
@@ -0,0 +1,15 @@
|
||||
# vim:syntax=apparmor
|
||||
# Vulkan access requirements
|
||||
|
||||
# System files
|
||||
/dev/dri/ r, # libvulkan_radeon.so, libvulkan_intel.so (Mesa)
|
||||
/etc/vulkan/icd.d/{,*.json} r,
|
||||
/etc/vulkan/{explicit,implicit}_layer.d/{,*.json} r,
|
||||
# for drmGetMinorNameForFD() from libvulkan_intel.so (Mesa)
|
||||
@{sys}/devices/pci[0-9]*/*/drm/ r,
|
||||
/usr/share/vulkan/icd.d/{,*.json} r,
|
||||
/usr/share/vulkan/{explicit,implicit}_layer.d/{,*.json} r,
|
||||
|
||||
# User files
|
||||
owner @{HOME}/.local/share/vulkan/implicit_layer.d/{,*.json} r,
|
||||
|
@@ -20,13 +20,13 @@
|
||||
/etc/phpsysinfo/config.php r,
|
||||
/etc/udev/udev.conf r,
|
||||
@{PROC}/** r,
|
||||
/sys/bus/ r,
|
||||
/sys/bus/pci/devices/ r,
|
||||
/sys/bus/pci/slots/ r,
|
||||
/sys/bus/pci/slots/** r,
|
||||
/sys/bus/usb/devices/ r,
|
||||
/sys/class/ r,
|
||||
/sys/devices/** r,
|
||||
@{sys}/bus/ r,
|
||||
@{sys}/bus/pci/devices/ r,
|
||||
@{sys}/bus/pci/slots/ r,
|
||||
@{sys}/bus/pci/slots/** r,
|
||||
@{sys}/bus/usb/devices/ r,
|
||||
@{sys}/class/ r,
|
||||
@{sys}/devices/** r,
|
||||
/usr/bin/ r,
|
||||
/usr/bin/apt-cache ixr,
|
||||
/usr/bin/dpkg-query ixr,
|
||||
|
@@ -21,6 +21,7 @@ profile syslog-ng /{usr/,}{bin,sbin}/syslog-ng {
|
||||
#include <abstractions/nameservice>
|
||||
#include <abstractions/mysql>
|
||||
#include <abstractions/openssl>
|
||||
#include <abstractions/python>
|
||||
|
||||
capability chown,
|
||||
capability dac_override,
|
||||
@@ -47,7 +48,7 @@ profile syslog-ng /{usr/,}{bin,sbin}/syslog-ng {
|
||||
/etc/hosts.deny r,
|
||||
/etc/hosts.allow r,
|
||||
/{usr/,}{bin,sbin}/syslog-ng mr,
|
||||
/sys/devices/system/cpu/online r,
|
||||
@{sys}/devices/system/cpu/online r,
|
||||
/usr/share/syslog-ng/** r,
|
||||
/var/lib/syslog-ng/syslog-ng-?????.qf rw,
|
||||
# chrooted applications
|
||||
|
@@ -18,7 +18,10 @@
|
||||
capability setuid,
|
||||
capability sys_chroot,
|
||||
|
||||
unix (receive, send) type=stream peer=(label=dovecot),
|
||||
|
||||
/run/dovecot/anvil rw,
|
||||
/run/dovecot/anvil-auth-penalty rw,
|
||||
/usr/lib/dovecot/anvil mr,
|
||||
|
||||
# Site-specific additions and overrides. See local/README for details.
|
||||
|
@@ -25,6 +25,7 @@
|
||||
capability dac_override,
|
||||
capability dac_read_search,
|
||||
capability setuid,
|
||||
capability sys_chroot,
|
||||
|
||||
/etc/my.cnf r,
|
||||
/etc/my.cnf.d/ r,
|
||||
@@ -32,6 +33,7 @@
|
||||
|
||||
/etc/dovecot/* r,
|
||||
/usr/lib/dovecot/auth mr,
|
||||
/var/lib/dovecot/auth-chroot/* r,
|
||||
|
||||
# kerberos replay cache
|
||||
/var/tmp/imap_* rw,
|
||||
@@ -40,6 +42,7 @@
|
||||
/var/tmp/smtp_* rw,
|
||||
|
||||
/run/dovecot/auth-master rw,
|
||||
/run/dovecot/auth-userdb rw,
|
||||
/run/dovecot/auth-worker rw,
|
||||
/run/dovecot/login/login rw,
|
||||
/{var/,}run/dovecot/auth-token-secret.dat{,.tmp} rw,
|
||||
@@ -47,7 +50,7 @@
|
||||
/{var/,}run/dovecot/stats-user rw,
|
||||
/{var/,}run/dovecot/anvil-auth-penalty rw,
|
||||
|
||||
/var/spool/postfix/private/auth w,
|
||||
/var/spool/postfix/private/auth rw,
|
||||
|
||||
# Site-specific additions and overrides. See local/README for details.
|
||||
#include <local/usr.lib.dovecot.auth>
|
||||
|
@@ -29,14 +29,15 @@
|
||||
/run/dovecot/auth-userdb rw,
|
||||
/usr/bin/doveconf mrix,
|
||||
/usr/lib/dovecot/dovecot-lda mrix,
|
||||
/usr/{bin,sbin}/sendmail Cx,
|
||||
/usr/{bin,sbin}/sendmail Cx -> sendmail,
|
||||
/usr/share/dovecot/protocols.d/ r,
|
||||
/usr/share/dovecot/protocols.d/** r,
|
||||
|
||||
# Site-specific additions and overrides. See local/README for details.
|
||||
#include <local/usr.lib.dovecot.dovecot-lda>
|
||||
|
||||
|
||||
profile /usr/{bin,sbin}/sendmail flags=(attach_disconnected) {
|
||||
profile sendmail /usr/{bin,sbin}/sendmail flags=(attach_disconnected) {
|
||||
# this profile is based on the usr.sbin.sendmail profile in extras
|
||||
# and should support both postfix' and sendmail's sendmail binary
|
||||
|
||||
|
@@ -17,9 +17,11 @@
|
||||
#include <abstractions/nameservice>
|
||||
#include <abstractions/dovecot-common>
|
||||
#include <abstractions/openssl>
|
||||
#include <abstractions/ssl_certs>
|
||||
#include <abstractions/ssl_keys>
|
||||
|
||||
capability dac_override,
|
||||
capability dac_read_search,
|
||||
capability setuid,
|
||||
|
||||
@{DOVECOT_MAILSTORE}/ rw,
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
network inet stream,
|
||||
network inet6 stream,
|
||||
network unix stream,
|
||||
|
||||
/usr/lib/dovecot/managesieve-login mr,
|
||||
/{,var/}run/dovecot/login-master-notify* rw,
|
||||
|
@@ -22,8 +22,11 @@
|
||||
capability setuid,
|
||||
capability sys_chroot,
|
||||
|
||||
network unix stream,
|
||||
|
||||
/usr/lib/dovecot/pop3-login mr,
|
||||
/{,var/}run/dovecot/anvil rw,
|
||||
/{,var/}run/dovecot/login-master-notify* rw,
|
||||
/{,var/}run/dovecot/login/ r,
|
||||
/{,var/}run/dovecot/login/* rw,
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# Author: Marc Deslauriers <marc.deslauriers@ubuntu.com>
|
||||
|
||||
#include <tunables/global>
|
||||
/usr/{bin,sbin}/apache2 flags=(attach_disconnected) {
|
||||
profile apache2 /usr/{bin,sbin}/apache2 flags=(attach_disconnected) {
|
||||
|
||||
# This profile is completely permissive.
|
||||
# It is designed to target specific applications using mod_apparmor,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#include <tunables/global>
|
||||
/usr/{bin,sbin}/avahi-daemon {
|
||||
profile avahi-daemon /usr/{bin,sbin}/avahi-daemon {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/consoles>
|
||||
#include <abstractions/dbus>
|
||||
|
@@ -12,7 +12,13 @@
|
||||
@{TFTP_DIR}=/var/tftp /srv/tftpboot
|
||||
|
||||
#include <tunables/global>
|
||||
profile dnsmasq /usr/{bin,sbin}/dnsmasq flags=(attach_disconnected) {
|
||||
|
||||
# This profile has the name "/usr/sbin/dnsmasq", but attaches to both /usr/bin/dnsmasq and /usr/sbin/dnsmasq.
|
||||
# We are sorry for the confusion ;-) but this trick is needed to support distributions with merged bin and sbin
|
||||
# while not breaking the libvirtd profile that has rules with peer=/usr/sbin/dnsmasq
|
||||
# Future versions of AppArmor (> 2.13.x) will have "dnsmasq" as profile name.
|
||||
|
||||
profile /usr/sbin/dnsmasq /usr/{bin,sbin}/dnsmasq flags=(attach_disconnected) {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/dbus>
|
||||
#include <abstractions/nameservice>
|
||||
@@ -28,7 +34,11 @@ profile dnsmasq /usr/{bin,sbin}/dnsmasq flags=(attach_disconnected) {
|
||||
network inet6 raw,
|
||||
|
||||
signal (receive) peer=/usr/{bin,sbin}/libvirtd,
|
||||
signal (receive) peer=/usr/sbin/libvirtd,
|
||||
signal (receive) peer=libvirtd,
|
||||
ptrace (readby) peer=/usr/{bin,sbin}/libvirtd,
|
||||
ptrace (readby) peer=/usr/sbin/libvirtd,
|
||||
ptrace (readby) peer=libvirtd,
|
||||
|
||||
owner /dev/tty rw,
|
||||
|
||||
@@ -45,7 +55,7 @@ profile dnsmasq /usr/{bin,sbin}/dnsmasq flags=(attach_disconnected) {
|
||||
|
||||
/usr/{bin,sbin}/dnsmasq mr,
|
||||
|
||||
/var/log/*dnsmasq.log w,
|
||||
/var/log/dnsmasq*.log w,
|
||||
|
||||
/usr/share/dnsmasq/ r,
|
||||
/usr/share/dnsmasq/* r,
|
||||
@@ -96,6 +106,7 @@ profile dnsmasq /usr/{bin,sbin}/dnsmasq flags=(attach_disconnected) {
|
||||
/{,var/}run/sendsigs.omit.d/*dnsmasq.pid w,
|
||||
/{,var/}run/NetworkManager/dnsmasq.conf r,
|
||||
/{,var/}run/NetworkManager/dnsmasq.pid w,
|
||||
/{,var/}run/NetworkManager/NetworkManager.pid w,
|
||||
|
||||
profile libvirt_leaseshelper {
|
||||
#include <abstractions/base>
|
||||
@@ -107,9 +118,9 @@ profile dnsmasq /usr/{bin,sbin}/dnsmasq flags=(attach_disconnected) {
|
||||
owner @{PROC}/@{pid}/net/psched r,
|
||||
owner @{PROC}/@{pid}/status r,
|
||||
|
||||
/sys/devices/system/cpu/ r,
|
||||
/sys/devices/system/node/ r,
|
||||
/sys/devices/system/node/*/meminfo r,
|
||||
@{sys}/devices/system/cpu/ r,
|
||||
@{sys}/devices/system/node/ r,
|
||||
@{sys}/devices/system/node/*/meminfo r,
|
||||
|
||||
# libvirt lease and status files for dnsmasq
|
||||
/var/lib/libvirt/dnsmasq/*.leases rw,
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
#include <tunables/global>
|
||||
|
||||
/usr/{bin,sbin}/dovecot flags=(attach_disconnected) {
|
||||
profile dovecot /usr/{bin,sbin}/dovecot flags=(attach_disconnected) {
|
||||
#include <abstractions/authentication>
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/dovecot-common>
|
||||
@@ -31,13 +31,16 @@
|
||||
capability sys_chroot,
|
||||
capability sys_resource,
|
||||
|
||||
signal send set=(int,quit) peer=/usr/lib/dovecot/*,
|
||||
signal send set=(int,quit,term) peer=/usr/lib/dovecot/*,
|
||||
|
||||
unix (receive, send) type=stream peer=(label=/usr/lib/dovecot/anvil),
|
||||
|
||||
/etc/dovecot/** r,
|
||||
/etc/mtab r,
|
||||
/etc/lsb-release r,
|
||||
/etc/SuSE-release r,
|
||||
@{PROC}/@{pid}/mounts r,
|
||||
@{PROC}/sys/fs/suid_dumpable r,
|
||||
/usr/bin/doveconf rix,
|
||||
/usr/lib/dovecot/anvil mrPx,
|
||||
/usr/lib/dovecot/auth mrPx,
|
||||
|
@@ -11,12 +11,13 @@
|
||||
|
||||
#include <tunables/global>
|
||||
|
||||
/usr/{bin,sbin}/identd {
|
||||
profile identd /usr/{bin,sbin}/identd {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/nameservice>
|
||||
capability net_bind_service,
|
||||
capability setgid,
|
||||
capability setuid,
|
||||
network netlink dgram,
|
||||
/etc/identd.conf r,
|
||||
/etc/identd.key r,
|
||||
/etc/identd.pid w,
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <tunables/global>
|
||||
|
||||
/usr/{bin,sbin}/mdnsd {
|
||||
profile mdnsd /usr/{bin,sbin}/mdnsd {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/consoles>
|
||||
#include <abstractions/nameservice>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#include <tunables/global>
|
||||
|
||||
/usr/{bin,sbin}/nmbd {
|
||||
profile nmbd /usr/{bin,sbin}/nmbd {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/nameservice>
|
||||
#include <abstractions/samba>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
#include <tunables/global>
|
||||
/usr/{bin,sbin}/nscd {
|
||||
profile nscd /usr/{bin,sbin}/nscd {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/consoles>
|
||||
#include <abstractions/nameservice>
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <tunables/global>
|
||||
#include <tunables/ntpd>
|
||||
/usr/{bin,sbin}/{,open}ntpd flags=(attach_disconnected) {
|
||||
profile ntpd /usr/{bin,sbin}/{,open}ntpd flags=(attach_disconnected) {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/nameservice>
|
||||
#include <abstractions/openssl>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#include <tunables/global>
|
||||
|
||||
/usr/{bin,sbin}/smbd {
|
||||
profile smbd /usr/{bin,sbin}/smbd {
|
||||
#include <abstractions/authentication>
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/consoles>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# Last Modified: Tue Jan 3 00:17:40 2012
|
||||
#include <tunables/global>
|
||||
|
||||
/usr/{bin,sbin}/smbldap-useradd {
|
||||
profile smbldap-useradd /usr/{bin,sbin}/smbldap-useradd {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/bash>
|
||||
#include <abstractions/nameservice>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#include <tunables/global>
|
||||
|
||||
/usr/{bin,sbin}/winbindd {
|
||||
profile winbindd /usr/{bin,sbin}/winbindd {
|
||||
#include <abstractions/base>
|
||||
#include <abstractions/nameservice>
|
||||
#include <abstractions/samba>
|
||||
|
@@ -3,7 +3,7 @@
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2002-2005 Novell/SUSE
|
||||
# Copyright (C) 2014 Christian Boltz
|
||||
# Copyright (C) 2014-2019 Christian Boltz
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
@@ -30,13 +30,14 @@
|
||||
/etc/my.cnf.d/ r,
|
||||
/etc/my.cnf.d/*.cnf r,
|
||||
/root/.my.cnf r,
|
||||
/sys/devices/system/cpu/online r,
|
||||
/usr/lib{,32,64}/**.so mr,
|
||||
/usr/sbin/mysqld r,
|
||||
/usr/sbin/mysqld mr,
|
||||
/usr/share/mariadb/*/errmsg.sys r,
|
||||
/usr/share/mysql-community-server/*/errmsg.sys r,
|
||||
/usr/share/mysql/** r,
|
||||
/var/lib/mysql/ r,
|
||||
/var/lib/mysql/** rwl,
|
||||
/var/lib/mysql/** rwlk,
|
||||
/var/log/mysql/mysqld-upgrade-run.log w,
|
||||
/var/log/mysql/mysqld.log w,
|
||||
/var/log/mysql/mysqld.log-20* w,
|
||||
|
@@ -17,7 +17,7 @@
|
||||
#include <abstractions/consoles>
|
||||
#include <abstractions/postfix-common>
|
||||
/etc/aliases r,
|
||||
/etc/aliases.db rwl,
|
||||
/etc/aliases.db rwlk,
|
||||
/etc/postfix r,
|
||||
/etc/postfix/main.cf r,
|
||||
/etc/postfix/aliases r,
|
||||
|
@@ -132,10 +132,10 @@ sub gen_binary($) {
|
||||
my $hashbang = head($bin);
|
||||
if ($hashbang && $hashbang =~ /^#!\s*(\S+)/) {
|
||||
my $interpreter = $1;
|
||||
gen_file("$interpreter:rix");
|
||||
gen_file(realpath($interpreter) . ":rix");
|
||||
gen_elf_binary($interpreter);
|
||||
} else {
|
||||
gen_elf_binary($bin)
|
||||
gen_elf_binary(realpath($bin))
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -67,21 +67,9 @@ 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
|
||||
# find the next free loop device and mount it
|
||||
loop_device=$(losetup -f) || fatalerror 'Unable to find a free loop device'
|
||||
/sbin/losetup "$loop_device" ${mount_file} > /dev/null 2> /dev/null
|
||||
|
||||
|
||||
# TEST 1. Make sure can mount and umount unconfined
|
||||
|
@@ -30,26 +30,29 @@ bin=$pwd
|
||||
|
||||
helper=$pwd/ptrace_helper
|
||||
|
||||
bin_true=${tmpdir}/true
|
||||
cp -pL /bin/true ${tmpdir}/true
|
||||
|
||||
# -n number of syscalls to perform
|
||||
# -c have the child call ptrace_me, else parent does ptrace_attach
|
||||
# -h transition child to ptrace_helper before doing ptrace (used to test
|
||||
# x transitions with ptrace)
|
||||
# test base line of unconfined tracing unconfined
|
||||
runchecktest "test 1" pass -n 100 /bin/true
|
||||
runchecktest "test 1 -c" pass -c -n 100 /bin/true
|
||||
runchecktest "test 1" pass -n 100 ${bin_true}
|
||||
runchecktest "test 1 -c" pass -c -n 100 ${bin_true}
|
||||
runchecktest "test 1 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 1 -hc" pass -h -c -n 100 $helper
|
||||
runchecktest "test 1 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 1 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 1 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 1 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
# test that unconfined can ptrace before profile attaches
|
||||
genprofile image=/bin/true signal:ALL
|
||||
runchecktest "test 2" pass -n 100 /bin/true
|
||||
runchecktest "test 2 -c" pass -c -n 100 /bin/true
|
||||
genprofile image=${bin_true} signal:ALL
|
||||
runchecktest "test 2" pass -n 100 ${bin_true}
|
||||
runchecktest "test 2 -c" pass -c -n 100 ${bin_true}
|
||||
runchecktest "test 2 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 2 -hc" pass -h -c -n 100 $helper
|
||||
runchecktest "test 2 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 2 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 2 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 2 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
|
||||
if [ "$(kernel_features ptrace)" == "true" -a "$(parser_supports 'ptrace,')" == "true" ] ; then
|
||||
|
@@ -13,133 +13,133 @@
|
||||
genprofile image=$helper
|
||||
runchecktest "test 3 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 3 -hc " pass -h -c -n 100 $helper
|
||||
# can't exec /bin/true so fail
|
||||
runchecktest "test 3 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 3 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
# can't exec ${bin_true} so fail
|
||||
runchecktest "test 3 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 3 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
# lack of 'r' perm is currently not working
|
||||
genprofile image=$helper $helper:ix
|
||||
runchecktest "test 4 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 4 -hc " pass -h -c -n 100 $helper
|
||||
# can't exec /bin/true so fail
|
||||
runchecktest "test 4 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 4 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
# can't exec ${bin_true} so fail
|
||||
runchecktest "test 4 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 4 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
genprofile image=$helper $helper:rix
|
||||
runchecktest "test 5 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 5 -hc " pass -h -c -n 100 $helper
|
||||
# can't exec /bin/true so fail
|
||||
runchecktest "test 5 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 5 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
# can't exec ${bin_true} so fail
|
||||
runchecktest "test 5 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 5 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
genprofile image=$helper $helper:ix /bin/true:rix
|
||||
genprofile image=$helper $helper:ix ${bin_true}:rix
|
||||
runchecktest "test 6 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 6 -hc " pass -h -c -n 100 $helper
|
||||
runchecktest "test 6 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 6 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 6 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 6 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#traced child can ptrace_me to unconfined have unconfined trace them
|
||||
genprofile image=/bin/true
|
||||
runchecktest "test 7" pass -n 100 /bin/true
|
||||
genprofile image=${bin_true}
|
||||
runchecktest "test 7" pass -n 100 ${bin_true}
|
||||
# pass - ptrace_attach is done in unconfined helper
|
||||
runchecktest "test 7 -c " pass -c -n 100 /bin/true
|
||||
runchecktest "test 7 -c " pass -c -n 100 ${bin_true}
|
||||
runchecktest "test 7 -h" pass -h -n 100 $helper
|
||||
# pass - ptrace_attach is done in unconfined helper
|
||||
runchecktest "test 7 -hc " pass -h -c -n 100 $helper
|
||||
runchecktest "test 7 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 7 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 7 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 7 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
genprofile image=$helper $helper:ix /bin/true:rix
|
||||
runchecktest "test 7a" pass -n 100 /bin/true
|
||||
genprofile image=$helper $helper:ix ${bin_true}:rix
|
||||
runchecktest "test 7a" pass -n 100 ${bin_true}
|
||||
# pass - ptrace_attach is allowed from confined process to unconfined
|
||||
runchecktest "test 7a -c " pass -c -n 100 /bin/true
|
||||
runchecktest "test 7a -c " pass -c -n 100 ${bin_true}
|
||||
runchecktest "test 7a -h" pass -h -n 100 $helper
|
||||
# pass - ptrace_attach is allowed from confined process to unconfined
|
||||
runchecktest "test 7a -hc " pass -h -c -n 100 $helper
|
||||
runchecktest "test 7a -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 7a -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 7a -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 7a -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#traced helper from unconfined
|
||||
genprofile image=$helper $helper:ix /bin/true:rpx -- image=/bin/true
|
||||
runchecktest "test 8" pass -n 100 /bin/true
|
||||
genprofile image=$helper $helper:ix ${bin_true}:rpx -- image=${bin_true}
|
||||
runchecktest "test 8" pass -n 100 ${bin_true}
|
||||
# pass - ptrace_attach is done before exec
|
||||
runchecktest "test 8 -c " pass -c -n 100 /bin/true
|
||||
runchecktest "test 8 -c " pass -c -n 100 ${bin_true}
|
||||
runchecktest "test 8 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 8 -hc " pass -h -c -n 100 $helper
|
||||
# pass - can px if tracer can ptrace target
|
||||
runchecktest "test 8 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 8 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 8 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 8 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#traced helper from unconfined
|
||||
genprofile image=$helper $helper:ix /bin/true:rux -- image=/bin/true
|
||||
runchecktest "test 9" pass -n 100 /bin/true
|
||||
genprofile image=$helper $helper:ix ${bin_true}:rux -- image=${bin_true}
|
||||
runchecktest "test 9" pass -n 100 ${bin_true}
|
||||
# pass - ptrace_attach is done before exec
|
||||
runchecktest "test 9 -c " pass -c -n 100 /bin/true
|
||||
runchecktest "test 9 -c " pass -c -n 100 ${bin_true}
|
||||
runchecktest "test 9 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 9 -hc " pass -h -c -n 100 $helper
|
||||
# pass - can ux if tracer can ptrace target
|
||||
runchecktest "test 9 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 9 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 9 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 9 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
genprofile
|
||||
# fail due to no exec permission
|
||||
runchecktest "test 10" fail -n 100 /bin/true
|
||||
runchecktest "test 10 -c" fail -c -n 100 /bin/true
|
||||
runchecktest "test 10" fail -n 100 ${bin_true}
|
||||
runchecktest "test 10 -c" fail -c -n 100 ${bin_true}
|
||||
runchecktest "test 10 -h" fail -h -n 100 $helper
|
||||
runchecktest "test 10 -hc" fail -h -c -n 100 $helper
|
||||
runchecktest "test 10 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 10 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 10 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 10 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
genprofile /bin/true:ix $helper:ix
|
||||
genprofile ${bin_true}:ix $helper:ix
|
||||
# fail due to missing r permission
|
||||
#runchecktest "test 11" fail -n 100 /bin/true
|
||||
#runchecktest "test 11 -c" fail -c -n 100 /bin/true
|
||||
#runchecktest "test 11" fail -n 100 ${bin_true}
|
||||
#runchecktest "test 11 -c" fail -c -n 100 ${bin_true}
|
||||
#runchecktest "test 11 -h" fail -h -n 100 $helper
|
||||
#runchecktest "test 11 -hc" fail -h -c -n 100 $helper
|
||||
#runchecktest "test 11 -h prog" fail -h -n 100 $helper /bin/true
|
||||
#runchecktest "test 11 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
#runchecktest "test 11 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
#runchecktest "test 11 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
# pass allowed to ix self
|
||||
genprofile /bin/true:rix $helper:rix
|
||||
runchecktest "test 12" pass -n 100 /bin/true
|
||||
runchecktest "test 12 -c" pass -c -n 100 /bin/true
|
||||
genprofile ${bin_true}:rix $helper:rix
|
||||
runchecktest "test 12" pass -n 100 ${bin_true}
|
||||
runchecktest "test 12 -c" pass -c -n 100 ${bin_true}
|
||||
runchecktest "test 12 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 12 -hc" pass -h -c -n 100 $helper
|
||||
runchecktest "test 12 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 12 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 12 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 12 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#ptraced confined app can't px - fails to unset profile
|
||||
genprofile image=$helper $helper:rix /bin/true:rpx
|
||||
runchecktest "test 13 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile image=$helper $helper:rix ${bin_true}:rpx
|
||||
runchecktest "test 13 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
|
||||
#ptraced confined app can ux - if the tracer is unconfined
|
||||
#
|
||||
genprofile image=$helper $helper:rix /bin/true:rux
|
||||
runchecktest "test 14a -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 14a -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile image=$helper $helper:rix ${bin_true}:rux
|
||||
runchecktest "test 14a -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 14a -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
#ptraced confined app can't ux - if the tracer can't trace unconfined
|
||||
genprofile $helper:rpx -- image=$helper $helper:rix /bin/true:rux
|
||||
runchecktest "test 14b -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 14b -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile $helper:rpx -- image=$helper $helper:rix ${bin_true}:rux
|
||||
runchecktest "test 14b -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 14b -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#confined app can't ptrace an unconfined app
|
||||
genprofile $helper:rux
|
||||
runchecktest "test 15 -h" fail -h -n 100 $helper
|
||||
runchecktest "test 15 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 15 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
#an unconfined app can't ask a confined app to trace it
|
||||
runchecktest "test 15 -hc" fail -h -c -n 100 $helper
|
||||
runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#confined app can't ptrace an app confined by a different profile
|
||||
genprofile $helper:rpx -- image=$helper
|
||||
runchecktest "test 15 -h" fail -h -n 100 $helper
|
||||
runchecktest "test 15 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 15 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
#a confined app can't ask another confined app with a different profile to
|
||||
#trace it
|
||||
runchecktest "test 15 -hc" fail -h -c -n 100 $helper
|
||||
runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
|
||||
|
||||
|
@@ -25,186 +25,186 @@ genprofile image=$helper signal:ALL ptrace:tracedby:peer=unconfined
|
||||
|
||||
runchecktest "test 3 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 3 -hc " pass -h -c -n 100 $helper
|
||||
# can't exec /bin/true so fail
|
||||
runchecktest "test 3 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 3 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
# can't exec ${bin_true} so fail
|
||||
runchecktest "test 3 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 3 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
# lack of 'r' perm is currently not working
|
||||
genprofile image=$helper $helper:ix signal:ALL
|
||||
runchecktest "test 4 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 4 -hc " pass -h -c -n 100 $helper
|
||||
# can't exec /bin/true so fail
|
||||
runchecktest "test 4 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 4 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
# can't exec ${bin_true} so fail
|
||||
runchecktest "test 4 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 4 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
genprofile image=$helper $helper:rix signal:ALL
|
||||
runchecktest "test 5 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 5 -hc " pass -h -c -n 100 $helper
|
||||
# can't exec /bin/true so fail
|
||||
runchecktest "test 5 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 5 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
# can't exec ${bin_true} so fail
|
||||
runchecktest "test 5 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 5 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
genprofile image=$helper $helper:ix /bin/true:rix signal:ALL
|
||||
genprofile image=$helper $helper:ix ${bin_true}:rix signal:ALL
|
||||
runchecktest "test 6 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 6 -hc " pass -h -c -n 100 $helper
|
||||
runchecktest "test 6 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 6 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 6 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 6 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#traced child can ptrace_me to unconfined have unconfined trace them
|
||||
genprofile image=/bin/true signal:ALL
|
||||
runchecktest "test 7" pass -n 100 /bin/true
|
||||
genprofile image=${bin_true} signal:ALL
|
||||
runchecktest "test 7" pass -n 100 ${bin_true}
|
||||
# pass - ptrace_attach is done in unconfined helper
|
||||
runchecktest "test 7 -c " pass -c -n 100 /bin/true
|
||||
runchecktest "test 7 -c " pass -c -n 100 ${bin_true}
|
||||
runchecktest "test 7 -h" pass -h -n 100 $helper
|
||||
# pass - ptrace_attach is done in unconfined helper
|
||||
runchecktest "test 7 -hc " pass -h -c -n 100 $helper
|
||||
runchecktest "test 7 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 7 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 7 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 7 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
genprofile image=$helper $helper:ix /bin/true:rix signal:ALL
|
||||
runchecktest "test 7a" pass -n 100 /bin/true
|
||||
genprofile image=$helper $helper:ix ${bin_true}:rix signal:ALL
|
||||
runchecktest "test 7a" pass -n 100 ${bin_true}
|
||||
# pass - ptrace_attach is allowed from confined process to unconfined
|
||||
runchecktest "test 7a -c " pass -c -n 100 /bin/true
|
||||
runchecktest "test 7a -c " pass -c -n 100 ${bin_true}
|
||||
runchecktest "test 7a -h" pass -h -n 100 $helper
|
||||
# pass - ptrace_attach is allowed from confined process to unconfined
|
||||
runchecktest "test 7a -hc " pass -h -c -n 100 $helper
|
||||
runchecktest "test 7a -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 7a -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 7a -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 7a -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#traced helper from unconfined
|
||||
genprofile image=$helper $helper:ix /bin/true:rpx signal:ALL -- image=/bin/true signal:ALL
|
||||
runchecktest "test 8" pass -n 100 /bin/true
|
||||
genprofile image=$helper $helper:ix ${bin_true}:rpx signal:ALL -- image=${bin_true} signal:ALL
|
||||
runchecktest "test 8" pass -n 100 ${bin_true}
|
||||
# pass - ptrace_attach is done before exec
|
||||
runchecktest "test 8 -c " pass -c -n 100 /bin/true
|
||||
runchecktest "test 8 -c " pass -c -n 100 ${bin_true}
|
||||
runchecktest "test 8 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 8 -hc " pass -h -c -n 100 $helper
|
||||
# pass - can px if tracer can ptrace target
|
||||
runchecktest "test 8 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 8 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 8 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 8 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#traced helper from unconfined
|
||||
genprofile image=$helper $helper:ix /bin/true:rux signal:ALL -- image=/bin/true signal:ALL
|
||||
runchecktest "test 9" pass -n 100 /bin/true
|
||||
genprofile image=$helper $helper:ix ${bin_true}:rux signal:ALL -- image=${bin_true} signal:ALL
|
||||
runchecktest "test 9" pass -n 100 ${bin_true}
|
||||
# pass - ptrace_attach is done before exec
|
||||
runchecktest "test 9 -c " pass -c -n 100 /bin/true
|
||||
runchecktest "test 9 -c " pass -c -n 100 ${bin_true}
|
||||
runchecktest "test 9 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 9 -hc " pass -h -c -n 100 $helper
|
||||
# pass - can ux if tracer can ptrace target
|
||||
runchecktest "test 9 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 9 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 9 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 9 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
genprofile signal:ALL
|
||||
# fail due to no exec permission
|
||||
runchecktest "test 10" fail -n 100 /bin/true
|
||||
runchecktest "test 10 -c" fail -c -n 100 /bin/true
|
||||
runchecktest "test 10" fail -n 100 ${bin_true}
|
||||
runchecktest "test 10 -c" fail -c -n 100 ${bin_true}
|
||||
runchecktest "test 10 -h" fail -h -n 100 $helper
|
||||
runchecktest "test 10 -hc" fail -h -c -n 100 $helper
|
||||
runchecktest "test 10 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 10 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 10 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 10 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
genprofile /bin/true:ix $helper:ix signal:ALL
|
||||
genprofile ${bin_true}:ix $helper:ix signal:ALL
|
||||
# fail due to missing r permission
|
||||
#runchecktest "test 11" fail -n 100 /bin/true
|
||||
#runchecktest "test 11 -c" fail -c -n 100 /bin/true
|
||||
#runchecktest "test 11" fail -n 100 ${bin_true}
|
||||
#runchecktest "test 11 -c" fail -c -n 100 ${bin_true}
|
||||
#runchecktest "test 11 -h" fail -h -n 100 $helper
|
||||
#runchecktest "test 11 -hc" fail -h -c -n 100 $helper
|
||||
#runchecktest "test 11 -h prog" fail -h -n 100 $helper /bin/true
|
||||
#runchecktest "test 11 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
#runchecktest "test 11 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
#runchecktest "test 11 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
# fail was pass in v5 allowed to ix self
|
||||
genprofile /bin/true:rix $helper:rix signal:ALL
|
||||
runchecktest "test 12" fail -n 100 /bin/true
|
||||
runchecktest "test 12 -c" fail -c -n 100 /bin/true
|
||||
genprofile ${bin_true}:rix $helper:rix signal:ALL
|
||||
runchecktest "test 12" fail -n 100 ${bin_true}
|
||||
runchecktest "test 12 -c" fail -c -n 100 ${bin_true}
|
||||
runchecktest "test 12 -h" fail -h -n 100 $helper
|
||||
runchecktest "test 12 -hc" fail -h -c -n 100 $helper
|
||||
runchecktest "test 12 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 12 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 12 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 12 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#ptraced confined app traced by unconfined can px
|
||||
genprofile image=$helper $helper:rix /bin/true:rpx signal:ALL -- image=/bin/true /bin/true:rix
|
||||
runchecktest "test 13u -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13u -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile image=$helper $helper:rix ${bin_true}:rpx signal:ALL -- image=${bin_true} ${bin_true}:rix
|
||||
runchecktest "test 13u -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13u -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#ptraced confined app traced by profile without ptrace on targeted can't px
|
||||
genprofile /bin/true:rpx signal:ALL -- image=/bin/true /bin/true:rix
|
||||
runchecktest "test 13 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile ${bin_true}:rpx signal:ALL -- image=${bin_true} ${bin_true}:rix
|
||||
runchecktest "test 13 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
|
||||
#ptraced confined app can ux - if the tracer is unconfined
|
||||
#
|
||||
genprofile image=$helper $helper:rix /bin/true:rux signal:ALL
|
||||
runchecktest "test 14a -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 14a -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile image=$helper $helper:rix ${bin_true}:rux signal:ALL
|
||||
runchecktest "test 14a -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 14a -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
#ptraced confined app can't ux - if the tracer can't trace unconfined
|
||||
genprofile $helper:rpx signal:ALL -- image=$helper $helper:rix /bin/true:rux signal:ALL
|
||||
runchecktest "test 14b -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 14b -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile $helper:rpx signal:ALL -- image=$helper $helper:rix ${bin_true}:rux signal:ALL
|
||||
runchecktest "test 14b -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 14b -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#confined app can't ptrace an unconfined app
|
||||
genprofile $helper:rux signal:ALL
|
||||
runchecktest "test 15 -h" fail -h -n 100 $helper
|
||||
runchecktest "test 15 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 15 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
#an unconfined app can't ask a confined app to trace it
|
||||
runchecktest "test 15 -hc" fail -h -c -n 100 $helper
|
||||
runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#confined app can't ptrace an app confined by a different profile
|
||||
genprofile $helper:rpx signal:ALL -- image=$helper signal:ALL
|
||||
runchecktest "test 15 -h" fail -h -n 100 $helper
|
||||
runchecktest "test 15 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 15 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
#a confined app can't ask another confined app with a different profile to
|
||||
#trace it
|
||||
runchecktest "test 15 -hc" fail -h -c -n 100 $helper
|
||||
runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 15 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
################### cap:sys_ptrace doesn't change results from above ##########################
|
||||
# fail was pass in v5 allowed to ix self
|
||||
genprofile /bin/true:rix $helper:rix signal:ALL cap:sys_ptrace
|
||||
runchecktest "test 12c" fail -n 100 /bin/true
|
||||
runchecktest "test 12c -c" fail -c -n 100 /bin/true
|
||||
genprofile ${bin_true}:rix $helper:rix signal:ALL cap:sys_ptrace
|
||||
runchecktest "test 12c" fail -n 100 ${bin_true}
|
||||
runchecktest "test 12c -c" fail -c -n 100 ${bin_true}
|
||||
runchecktest "test 12c -h" fail -h -n 100 $helper
|
||||
runchecktest "test 12c -hc" fail -h -c -n 100 $helper
|
||||
runchecktest "test 12c -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 12c -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 12c -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 12c -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#ptraced confined app traced by unconfined can px
|
||||
genprofile image=$helper $helper:rix /bin/true:rpx signal:ALL cap:sys_ptrace -- image=/bin/true /bin/true:rix cap:sys_ptrace
|
||||
runchecktest "test 13cu -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13cu -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile image=$helper $helper:rix ${bin_true}:rpx signal:ALL cap:sys_ptrace -- image=${bin_true} ${bin_true}:rix cap:sys_ptrace
|
||||
runchecktest "test 13cu -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13cu -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#ptraced confined app traced by profile without ptrace on targeted can't px
|
||||
genprofile /bin/true:rpx signal:ALL cap:sys_ptrace -- image=/bin/true /bin/true:rix cap:sys_ptrace
|
||||
runchecktest "test 13c -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13c -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile ${bin_true}:rpx signal:ALL cap:sys_ptrace -- image=${bin_true} ${bin_true}:rix cap:sys_ptrace
|
||||
runchecktest "test 13c -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13c -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
|
||||
#ptraced confined app can ux - if the tracer is unconfined
|
||||
#
|
||||
genprofile image=$helper $helper:rix /bin/true:rux signal:ALL cap:sys_ptrace
|
||||
runchecktest "test 14ca -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 14ca -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile image=$helper $helper:rix ${bin_true}:rux signal:ALL cap:sys_ptrace
|
||||
runchecktest "test 14ca -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 14ca -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
#ptraced confined app can't ux - if the tracer can't trace unconfined
|
||||
genprofile $helper:rpx signal:ALL -- image=$helper $helper:rix /bin/true:rux signal:ALL
|
||||
runchecktest "test 14cb -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 14cb -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile $helper:rpx signal:ALL -- image=$helper $helper:rix ${bin_true}:rux signal:ALL
|
||||
runchecktest "test 14cb -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 14cb -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#confined app can't ptrace an unconfined app
|
||||
genprofile $helper:rux signal:ALL cap:sys_ptrace
|
||||
runchecktest "test 15c -h" fail -h -n 100 $helper
|
||||
runchecktest "test 15c -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 15c -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
#an unconfined app can't ask a confined app to trace it
|
||||
runchecktest "test 15c -hc" fail -h -c -n 100 $helper
|
||||
runchecktest "test 15c -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 15c -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#confined app can't ptrace an app confined by a different profile
|
||||
genprofile $helper:rpx signal:ALL cap:sys_ptrace -- image=$helper signal:ALL cap:sys_ptrace
|
||||
runchecktest "test 15c -h" fail -h -n 100 $helper
|
||||
runchecktest "test 15c -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 15c -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
#a confined app can't ask another confined app with a different profile to
|
||||
#trace it
|
||||
runchecktest "test 15c -hc" fail -h -c -n 100 $helper
|
||||
runchecktest "test 15c -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 15c -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
|
||||
################################################################################
|
||||
@@ -213,163 +213,163 @@ runchecktest "test 15c -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
|
||||
##### Now do tests with ptrace rules in profiles #######
|
||||
# pass in v5 allowed to ix self
|
||||
genprofile /bin/true:rix $helper:rix signal:ALL ptrace:ALL
|
||||
runchecktest "test 12p" pass -n 100 /bin/true
|
||||
runchecktest "test 12p -c" pass -c -n 100 /bin/true
|
||||
genprofile ${bin_true}:rix $helper:rix signal:ALL ptrace:ALL
|
||||
runchecktest "test 12p" pass -n 100 ${bin_true}
|
||||
runchecktest "test 12p -c" pass -c -n 100 ${bin_true}
|
||||
runchecktest "test 12p -h" pass -h -n 100 $helper
|
||||
runchecktest "test 12p -hc" pass -h -c -n 100 $helper
|
||||
runchecktest "test 12p -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 12p -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rix $helper:rix signal:ALL ptrace:peer=$test
|
||||
runchecktest "test 12p1" pass -n 100 /bin/true
|
||||
runchecktest "test 12p1 -c" pass -c -n 100 /bin/true
|
||||
runchecktest "test 12p -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 12p -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rix $helper:rix signal:ALL ptrace:peer=$test
|
||||
runchecktest "test 12p1" pass -n 100 ${bin_true}
|
||||
runchecktest "test 12p1 -c" pass -c -n 100 ${bin_true}
|
||||
runchecktest "test 12p1 -h" pass -h -n 100 $helper
|
||||
runchecktest "test 12p1 -hc" pass -h -c -n 100 $helper
|
||||
runchecktest "test 12p1 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 12p1 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rix $helper:rix signal:ALL ptrace:peer=notaprofile
|
||||
runchecktest "test 12p2" fail -n 100 /bin/true
|
||||
runchecktest "test 12p2 -c" fail -c -n 100 /bin/true
|
||||
runchecktest "test 12p1 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 12p1 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rix $helper:rix signal:ALL ptrace:peer=notaprofile
|
||||
runchecktest "test 12p2" fail -n 100 ${bin_true}
|
||||
runchecktest "test 12p2 -c" fail -c -n 100 ${bin_true}
|
||||
runchecktest "test 12p2 -h" fail -h -n 100 $helper
|
||||
runchecktest "test 12p2 -hc" fail -h -c -n 100 $helper
|
||||
runchecktest "test 12p2 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 12p2 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 12p2 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 12p2 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
|
||||
#ptraced confined app traced by profile can px
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix
|
||||
runchecktest "test 13p1 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p2 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby
|
||||
runchecktest "test 13p3 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p4 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=$test
|
||||
runchecktest "test 13p5 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p6 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=notaprofile
|
||||
runchecktest "test 13p7 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p8 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:trace
|
||||
runchecktest "test 13p9 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pa -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:peer=$test
|
||||
runchecktest "test 13pb -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pc -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:peer=notaprofile
|
||||
runchecktest "test 13pd -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pe -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix
|
||||
runchecktest "test 13p1 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p2 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix ptrace:tracedby
|
||||
runchecktest "test 13p3 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p4 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix ptrace:tracedby:peer=$test
|
||||
runchecktest "test 13p5 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p6 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix ptrace:tracedby:peer=notaprofile
|
||||
runchecktest "test 13p7 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p8 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix ptrace:trace
|
||||
runchecktest "test 13p9 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pa -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix ptrace:trace:peer=$test
|
||||
runchecktest "test 13pb -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pc -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix ptrace:trace:peer=notaprofile
|
||||
runchecktest "test 13pd -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pe -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix
|
||||
runchecktest "test 13p11 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p21 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby
|
||||
runchecktest "test 13p31 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p41 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=$test
|
||||
runchecktest "test 13p51 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p61 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=notaprofile
|
||||
runchecktest "test 13p71 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p81 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:trace
|
||||
runchecktest "test 13p91 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pa1 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:peer=$test
|
||||
runchecktest "test 13pb1 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pc1 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=/bin/true -- image=/bin/true /bin/true:rix ptrace:trace:peer=notaprofile
|
||||
runchecktest "test 13pd1 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pe1 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix
|
||||
runchecktest "test 13p11 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p21 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix ptrace:tracedby
|
||||
runchecktest "test 13p31 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p41 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix ptrace:tracedby:peer=$test
|
||||
runchecktest "test 13p51 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p61 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix ptrace:tracedby:peer=notaprofile
|
||||
runchecktest "test 13p71 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p81 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix ptrace:trace
|
||||
runchecktest "test 13p91 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pa1 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix ptrace:trace:peer=$test
|
||||
runchecktest "test 13pb1 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pc1 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:trace:peer=${bin_true} -- image=${bin_true} ${bin_true}:rix ptrace:trace:peer=notaprofile
|
||||
runchecktest "test 13pd1 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pe1 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix
|
||||
runchecktest "test 13p12 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p22 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:tracedby
|
||||
runchecktest "test 13p32 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p42 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=$test
|
||||
runchecktest "test 13p52 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p62 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=notaprofile
|
||||
runchecktest "test 13p72 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p82 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:trace
|
||||
runchecktest "test 13p92 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pa2 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:trace:peer=$test
|
||||
runchecktest "test 13pb2 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pc2 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=/bin/true /bin/true:rix ptrace:trace:peer=notaprofile
|
||||
runchecktest "test 13pd2 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pe2 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=${bin_true} ${bin_true}:rix
|
||||
runchecktest "test 13p12 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p22 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=${bin_true} ${bin_true}:rix ptrace:tracedby
|
||||
runchecktest "test 13p32 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p42 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=${bin_true} ${bin_true}:rix ptrace:tracedby:peer=$test
|
||||
runchecktest "test 13p52 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p62 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=${bin_true} ${bin_true}:rix ptrace:tracedby:peer=notaprofile
|
||||
runchecktest "test 13p72 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p82 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=${bin_true} ${bin_true}:rix ptrace:trace
|
||||
runchecktest "test 13p92 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pa2 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=${bin_true} ${bin_true}:rix ptrace:trace:peer=$test
|
||||
runchecktest "test 13pb2 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pc2 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:ALL -- image=${bin_true} ${bin_true}:rix ptrace:trace:peer=notaprofile
|
||||
runchecktest "test 13pd2 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pe2 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix
|
||||
runchecktest "test 13p13 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p23 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:tracedby
|
||||
runchecktest "test 13p33 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p43 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=$test
|
||||
runchecktest "test 13p53 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p63 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=notaprofile
|
||||
runchecktest "test 13p73 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p83 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:trace
|
||||
runchecktest "test 13p93 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pa3 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:trace:peer=$test
|
||||
runchecktest "test 13pb3 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pc3 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=/bin/true /bin/true:rix ptrace:trace:peer=notaprofile
|
||||
runchecktest "test 13pd3 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pe3 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=${bin_true} ${bin_true}:rix
|
||||
runchecktest "test 13p13 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p23 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=${bin_true} ${bin_true}:rix ptrace:tracedby
|
||||
runchecktest "test 13p33 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p43 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=${bin_true} ${bin_true}:rix ptrace:tracedby:peer=$test
|
||||
runchecktest "test 13p53 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p63 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=${bin_true} ${bin_true}:rix ptrace:tracedby:peer=notaprofile
|
||||
runchecktest "test 13p73 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p83 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=${bin_true} ${bin_true}:rix ptrace:trace
|
||||
runchecktest "test 13p93 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pa3 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=${bin_true} ${bin_true}:rix ptrace:trace:peer=$test
|
||||
runchecktest "test 13pb3 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pc3 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby -- image=${bin_true} ${bin_true}:rix ptrace:trace:peer=notaprofile
|
||||
runchecktest "test 13pd3 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pe3 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix
|
||||
runchecktest "test 13p14 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p24 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby
|
||||
runchecktest "test 13p34 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p44 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=$test
|
||||
runchecktest "test 13p54 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p64 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=notaprofile
|
||||
runchecktest "test 13p74 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p84 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:trace
|
||||
runchecktest "test 13p94 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pa4 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:peer=$test
|
||||
runchecktest "test 13pb4 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pc4 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:peer=notaprofile
|
||||
runchecktest "test 13pd4 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pe4 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=${bin_true} ${bin_true}:rix
|
||||
runchecktest "test 13p14 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p24 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=${bin_true} ${bin_true}:rix ptrace:tracedby
|
||||
runchecktest "test 13p34 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p44 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=${bin_true} ${bin_true}:rix ptrace:tracedby:peer=$test
|
||||
runchecktest "test 13p54 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p64 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=${bin_true} ${bin_true}:rix ptrace:tracedby:peer=notaprofile
|
||||
runchecktest "test 13p74 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p84 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=${bin_true} ${bin_true}:rix ptrace:trace
|
||||
runchecktest "test 13p94 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pa4 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=${bin_true} ${bin_true}:rix ptrace:trace:peer=$test
|
||||
runchecktest "test 13pb4 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pc4 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:tracedby:peer=notaprofile -- image=${bin_true} ${bin_true}:rix ptrace:trace:peer=notaprofile
|
||||
runchecktest "test 13pd4 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pe4 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix
|
||||
runchecktest "test 13p15 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p25 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby
|
||||
runchecktest "test 13p35 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p45 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=$test
|
||||
runchecktest "test 13p55 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p65 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:tracedby:peer=notaprofile
|
||||
runchecktest "test 13p75 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13p85 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:trace
|
||||
runchecktest "test 13p95 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pa5 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:peer=$test
|
||||
runchecktest "test 13pb5 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pc5 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile /bin/true:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=/bin/true /bin/true:rix ptrace:trace:peer=notaprofile
|
||||
runchecktest "test 13pd5 -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 13pe5 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=${bin_true} ${bin_true}:rix
|
||||
runchecktest "test 13p15 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p25 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=${bin_true} ${bin_true}:rix ptrace:tracedby
|
||||
runchecktest "test 13p35 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p45 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=${bin_true} ${bin_true}:rix ptrace:tracedby:peer=$test
|
||||
runchecktest "test 13p55 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p65 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=${bin_true} ${bin_true}:rix ptrace:tracedby:peer=notaprofile
|
||||
runchecktest "test 13p75 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13p85 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=${bin_true} ${bin_true}:rix ptrace:trace
|
||||
runchecktest "test 13p95 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pa5 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=${bin_true} ${bin_true}:rix ptrace:trace:peer=$test
|
||||
runchecktest "test 13pb5 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pc5 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
genprofile ${bin_true}:rpx $helper:rix signal:ALL ptrace:peer=$test ptrace:peer=notaprofile -- image=${bin_true} ${bin_true}:rix ptrace:trace:peer=notaprofile
|
||||
runchecktest "test 13pd5 -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 13pe5 -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
|
||||
### todo Variations of below tests
|
||||
@@ -377,30 +377,30 @@ runchecktest "test 13pe5 -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
|
||||
#ptraced confined app can ux - if the tracer is unconfined
|
||||
#
|
||||
genprofile image=$helper $helper:rix /bin/true:rux signal:ALL
|
||||
runchecktest "test 14pa -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test 14pa -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile image=$helper $helper:rix ${bin_true}:rux signal:ALL
|
||||
runchecktest "test 14pa -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 14pa -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
#ptraced confined app can't ux - if the tracer can't trace unconfined
|
||||
genprofile $helper:rpx signal:ALL -- image=$helper $helper:rix /bin/true:rux signal:ALL
|
||||
runchecktest "test 14pb -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 14pb -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
genprofile $helper:rpx signal:ALL -- image=$helper $helper:rix ${bin_true}:rux signal:ALL
|
||||
runchecktest "test 14pb -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test 14pb -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#confined app can't ptrace an unconfined app
|
||||
genprofile $helper:rux signal:ALL
|
||||
runchecktest "test 15p -h" fail -h -n 100 $helper
|
||||
runchecktest "test 15p -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 15p -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
#an unconfined app can't ask a confined app to trace it
|
||||
runchecktest "test 15p -hc" fail -h -c -n 100 $helper
|
||||
runchecktest "test 15p -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 15p -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
#confined app can't ptrace an app confined by a different profile
|
||||
genprofile $helper:rpx signal:ALL -- image=$helper signal:ALL
|
||||
runchecktest "test 15p -h" fail -h -n 100 $helper
|
||||
runchecktest "test 15p -h prog" fail -h -n 100 $helper /bin/true
|
||||
runchecktest "test 15p -h prog" fail -h -n 100 $helper ${bin_true}
|
||||
#a confined app can't ask another confined app with a different profile to
|
||||
#trace it
|
||||
runchecktest "test 15p -hc" fail -h -c -n 100 $helper
|
||||
runchecktest "test 15p -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
runchecktest "test 15p -hc prog" fail -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
# Test LP: #1390592
|
||||
# The bug was a policy compilation bug that triggers in a rule such as
|
||||
@@ -408,9 +408,9 @@ runchecktest "test 15p -hc prog" fail -h -c -n 100 $helper /bin/true
|
||||
# a-f|A-F|0-9 to trigger the bug. A parser affected by this bug will create a
|
||||
# bad binary policy that causes the kernel to unexpectedly deny the ptrace
|
||||
# 'trace' of a process confined by profile ABC.
|
||||
genprofile "$helper rpx -> ABC" signal:ALL ptrace:trace:peer=ABC -- image=ABC addimage:$helper /bin/true:rix signal:ALL ptrace:tracedby:peer=$test
|
||||
runchecktest "test LP: #1390592 -h prog" pass -h -n 100 $helper /bin/true
|
||||
runchecktest "test LP: #1390592 -hc prog" pass -h -c -n 100 $helper /bin/true
|
||||
genprofile "$helper rpx -> ABC" signal:ALL ptrace:trace:peer=ABC -- image=ABC addimage:$helper ${bin_true}:rix signal:ALL ptrace:tracedby:peer=$test
|
||||
runchecktest "test LP: #1390592 -h prog" pass -h -n 100 $helper ${bin_true}
|
||||
runchecktest "test LP: #1390592 -hc prog" pass -h -c -n 100 $helper ${bin_true}
|
||||
|
||||
## TODO: ptrace read tests
|
||||
## TODO: ptrace + change_profile
|
||||
|
@@ -107,7 +107,7 @@ apparmor.check_qualifiers(program)
|
||||
|
||||
apparmor.loadincludes()
|
||||
|
||||
profile_filename = apparmor.get_profile_filename(program)
|
||||
profile_filename = apparmor.get_profile_filename_from_attachment(program, True)
|
||||
if os.path.exists(profile_filename):
|
||||
apparmor.helpers[program] = apparmor.get_profile_flags(profile_filename, program)
|
||||
else:
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#! /usr/bin/python3
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (C) 2013 Kshitij Gupta <kgupta8592@gmail.com>
|
||||
# Copyright (C) 2014-2017 Christian Boltz <apparmor@cboltz.de>
|
||||
# Copyright (C) 2014-2018 Christian Boltz <apparmor@cboltz.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
@@ -57,7 +57,7 @@ def reset_aa():
|
||||
apparmor.aa.aa = apparmor.aa.hasher()
|
||||
apparmor.aa.filelist = apparmor.aa.hasher()
|
||||
apparmor.aa.include = dict()
|
||||
apparmor.aa.existing_profiles = apparmor.aa.hasher()
|
||||
apparmor.aa.active_profiles = apparmor.aa.ProfileList()
|
||||
apparmor.aa.original_aa = apparmor.aa.hasher()
|
||||
|
||||
def find_profiles_from_files(files):
|
||||
@@ -75,7 +75,7 @@ def find_files_from_profiles(profiles):
|
||||
apparmor.aa.read_profiles()
|
||||
|
||||
for profile_name in profiles:
|
||||
profile_to_filename[profile_name] = apparmor.aa.get_profile_filename(profile_name)
|
||||
profile_to_filename[profile_name] = apparmor.aa.get_profile_filename_from_profile_name(profile_name, True)
|
||||
|
||||
reset_aa()
|
||||
|
||||
|
@@ -92,7 +92,8 @@ System-wide configuration for B<aa-notify> is done via
|
||||
# only people in use_group can use aa-notify
|
||||
use_group="admin"
|
||||
|
||||
Per-user configuration is done via ~/.apparmor/notify.conf:
|
||||
Per-user configuration is done via $XDG_CONFIG_HOME/apparmor/notify.conf (or
|
||||
the deprecated ~/.apparmor/notify.conf if it exists):
|
||||
|
||||
# set to 'yes' to enable AppArmor DENIED notifications
|
||||
show_notifications="yes"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (C) 2013 Kshitij Gupta <kgupta8592@gmail.com>
|
||||
# Copyright (C) 2014-2017 Christian Boltz <apparmor@cboltz.de>
|
||||
# Copyright (C) 2014-2018 Christian Boltz <apparmor@cboltz.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
@@ -49,6 +49,8 @@ from apparmor.regex import (RE_PROFILE_START, RE_PROFILE_END, RE_PROFILE_LINK,
|
||||
RE_PROFILE_UNIX, RE_RULE_HAS_COMMA, RE_HAS_COMMENT_SPLIT,
|
||||
strip_quotes, parse_profile_start_line, re_match_include )
|
||||
|
||||
from apparmor.profile_list import ProfileList
|
||||
|
||||
from apparmor.profile_storage import ProfileStorage, add_or_remove_flag, ruletypes, write_abi
|
||||
|
||||
import apparmor.rules as aarules
|
||||
@@ -88,7 +90,8 @@ extra_profile_dir = None
|
||||
# To keep track of previously included profile fragments
|
||||
include = dict()
|
||||
|
||||
existing_profiles = dict()
|
||||
active_profiles = ProfileList()
|
||||
extra_profiles = ProfileList()
|
||||
|
||||
# To store the globs entered by users so they can be provided again
|
||||
# format: user_globs['/foo*'] = AARE('/foo*')
|
||||
@@ -216,11 +219,29 @@ def find_executable(bin_path):
|
||||
return full_bin
|
||||
return None
|
||||
|
||||
def get_profile_filename(profile):
|
||||
"""Returns the full profile name"""
|
||||
if existing_profiles.get(profile, False):
|
||||
return existing_profiles[profile]
|
||||
elif profile.startswith('/'):
|
||||
def get_profile_filename_from_profile_name(profile, get_new=False):
|
||||
"""Returns the full profile name for the given profile name"""
|
||||
|
||||
filename = active_profiles.filename_from_profile_name(profile)
|
||||
if filename:
|
||||
return filename
|
||||
|
||||
if get_new:
|
||||
return get_new_profile_filename(profile)
|
||||
|
||||
def get_profile_filename_from_attachment(profile, get_new=False):
|
||||
"""Returns the full profile name for the given attachment"""
|
||||
|
||||
filename = active_profiles.filename_from_attachment(profile)
|
||||
if filename:
|
||||
return filename
|
||||
|
||||
if get_new:
|
||||
return get_new_profile_filename(profile)
|
||||
|
||||
def get_new_profile_filename(profile):
|
||||
'''Compose filename for a new profile'''
|
||||
if profile.startswith('/'):
|
||||
# Remove leading /
|
||||
profile = profile[1:]
|
||||
else:
|
||||
@@ -237,7 +258,7 @@ def name_to_prof_filename(prof_filename):
|
||||
else:
|
||||
bin_path = find_executable(prof_filename)
|
||||
if bin_path:
|
||||
prof_filename = get_profile_filename(bin_path)
|
||||
prof_filename = get_profile_filename_from_attachment(bin_path, True)
|
||||
if os.path.isfile(prof_filename):
|
||||
return (prof_filename, bin_path)
|
||||
|
||||
@@ -463,7 +484,7 @@ def create_new_profile(localfile, is_stub=False):
|
||||
|
||||
def delete_profile(local_prof):
|
||||
"""Deletes the specified file from the disk and remove it from our list"""
|
||||
profile_file = get_profile_filename(local_prof)
|
||||
profile_file = get_profile_filename_from_profile_name(local_prof, True)
|
||||
if os.path.isfile(profile_file):
|
||||
os.remove(profile_file)
|
||||
if aa.get(local_prof, False):
|
||||
@@ -497,13 +518,15 @@ def get_profile(prof_name):
|
||||
if inactive_profile:
|
||||
uname = 'Inactive local profile for %s' % prof_name
|
||||
inactive_profile[prof_name][prof_name]['flags'] = 'complain'
|
||||
orig_filename = inactive_profile[prof_name][prof_name]['filename'] # needed for CMD_VIEW_PROFILE
|
||||
inactive_profile[prof_name][prof_name]['filename'] = ''
|
||||
profile_hash[uname]['username'] = uname
|
||||
profile_hash[uname]['profile_type'] = 'INACTIVE_LOCAL'
|
||||
profile_hash[uname]['profile'] = serialize_profile(inactive_profile[prof_name], prof_name, None)
|
||||
profile_hash[uname]['profile_data'] = inactive_profile
|
||||
|
||||
existing_profiles.pop(prof_name) # remove profile filename from list to force storing in /etc/apparmor.d/ instead of extra_profile_dir
|
||||
# no longer necessary after splitting active and extra profiles
|
||||
# existing_profiles.pop(prof_name) # remove profile filename from list to force storing in /etc/apparmor.d/ instead of extra_profile_dir
|
||||
|
||||
# If no profiles in repo and no inactive profiles
|
||||
if not profile_hash.keys():
|
||||
@@ -537,11 +560,7 @@ def get_profile(prof_name):
|
||||
q.selected = options.index(options[arg])
|
||||
if ans == 'CMD_VIEW_PROFILE':
|
||||
pager = get_pager()
|
||||
proc = subprocess.Popen(pager, stdin=subprocess.PIPE)
|
||||
# proc.communicate('Profile submitted by %s:\n\n%s\n\n' %
|
||||
# (options[arg], p['profile']))
|
||||
proc.communicate(p['profile'].encode())
|
||||
proc.kill()
|
||||
subprocess.call([pager, orig_filename])
|
||||
elif ans == 'CMD_USE_PROFILE':
|
||||
if p['profile_type'] == 'INACTIVE_LOCAL':
|
||||
profile_data = p['profile_data']
|
||||
@@ -559,7 +578,7 @@ def activate_repo_profiles(url, profiles, complain):
|
||||
attach_profile_data(aa, profile_data)
|
||||
write_profile(pname)
|
||||
if complain:
|
||||
fname = get_profile_filename(pname)
|
||||
fname = get_profile_filename_from_profile_name(pname, True)
|
||||
change_profile_flags(profile_dir + fname, None, 'complain', True)
|
||||
aaui.UI_Info(_('Setting %s to complain mode.') % pname)
|
||||
except Exception as e:
|
||||
@@ -591,7 +610,7 @@ def autodep(bin_name, pname=''):
|
||||
# Create a new profile if no existing profile
|
||||
if not profile_data:
|
||||
profile_data = create_new_profile(pname)
|
||||
file = get_profile_filename(pname)
|
||||
file = get_profile_filename_from_profile_name(pname, True)
|
||||
profile_data[pname][pname]['filename'] = None # will be stored in /etc/apparmor.d when saving, so it shouldn't carry the extra_profile_dir filename
|
||||
attach_profile_data(aa, profile_data)
|
||||
attach_profile_data(original_aa, profile_data)
|
||||
@@ -691,15 +710,16 @@ def profile_exists(program):
|
||||
"""Returns True if profile exists, False otherwise"""
|
||||
# Check cache of profiles
|
||||
|
||||
if existing_profiles.get(program, False):
|
||||
if active_profiles.filename_from_attachment(program):
|
||||
return True
|
||||
# Check the disk for profile
|
||||
prof_path = get_profile_filename(program)
|
||||
prof_path = get_profile_filename_from_attachment(program, True)
|
||||
#print(prof_path)
|
||||
if os.path.isfile(prof_path):
|
||||
# Add to cache of profile
|
||||
existing_profiles[program] = prof_path
|
||||
return True
|
||||
raise AppArmorBug('Reached strange condition in profile_exists(), please open a bugreport!')
|
||||
# active_profiles[program] = prof_path
|
||||
# return True
|
||||
return False
|
||||
|
||||
def sync_profile():
|
||||
@@ -972,7 +992,7 @@ def handle_children(profile, hat, root):
|
||||
hat = default_hat
|
||||
elif ans == 'CMD_DENY':
|
||||
# As unknown hat is denied no entry for it should be made
|
||||
return None
|
||||
continue
|
||||
|
||||
elif typ == 'capability':
|
||||
# If capability then we (should) have pid, profile, hat, program, mode, capability
|
||||
@@ -1088,9 +1108,9 @@ def handle_children(profile, hat, root):
|
||||
options += 'd'
|
||||
# Define the default option
|
||||
default = None
|
||||
if 'p' in options and os.path.exists(get_profile_filename(exec_target)):
|
||||
if 'p' in options and os.path.exists(get_profile_filename_from_attachment(exec_target, True)):
|
||||
default = 'CMD_px'
|
||||
sys.stdout.write(_('Target profile exists: %s\n') % get_profile_filename(exec_target))
|
||||
sys.stdout.write(_('Target profile exists: %s\n') % get_profile_filename_from_attachment(exec_target, True))
|
||||
elif 'i' in options:
|
||||
default = 'CMD_ix'
|
||||
elif 'c' in options:
|
||||
@@ -1104,7 +1124,7 @@ def handle_children(profile, hat, root):
|
||||
parent_uses_ld_xxx = check_for_LD_XXX(profile)
|
||||
|
||||
sev_db.unload_variables()
|
||||
sev_db.load_variables(get_profile_filename(profile))
|
||||
sev_db.load_variables(get_profile_filename_from_profile_name(profile, True))
|
||||
severity = sev_db.rank_path(exec_target, 'x')
|
||||
|
||||
# Prompt portion starts
|
||||
@@ -1228,7 +1248,7 @@ def handle_children(profile, hat, root):
|
||||
profile_changes[pid] = '%s' % profile
|
||||
|
||||
# Check profile exists for px
|
||||
if not os.path.exists(get_profile_filename(exec_target)):
|
||||
if not os.path.exists(get_profile_filename_from_attachment(exec_target, True)):
|
||||
ynans = 'y'
|
||||
if 'i' in exec_mode:
|
||||
ynans = aaui.UI_YesNo(_('A profile for %s does not exist.\nDo you want to create one?') % exec_target, 'n')
|
||||
@@ -1362,7 +1382,7 @@ def ask_the_questions(log_dict):
|
||||
UI_SelectUpdatedRepoProfile(profile, p)
|
||||
|
||||
sev_db.unload_variables()
|
||||
sev_db.load_variables(get_profile_filename(profile))
|
||||
sev_db.load_variables(get_profile_filename_from_profile_name(profile, True))
|
||||
|
||||
# Sorted list of hats with the profile name coming first
|
||||
hats = list(filter(lambda key: key != profile, sorted(log_dict[aamode][profile].keys())))
|
||||
@@ -1755,21 +1775,25 @@ def set_logfile(filename):
|
||||
|
||||
if filename:
|
||||
logfile = filename
|
||||
else:
|
||||
elif 'logfiles' in cfg['settings']:
|
||||
# This line can only run if the 'logfile' exists in settings, otherwise
|
||||
# it will yield a Python KeyError
|
||||
logfile = conf.find_first_file(cfg['settings']['logfiles']) or '/var/log/syslog'
|
||||
else:
|
||||
logfile = '/var/log/syslog'
|
||||
|
||||
if not os.path.exists(logfile):
|
||||
if filename:
|
||||
raise AppArmorException(_('The logfile %s does not exist. Please check the path') % logfile)
|
||||
raise AppArmorException(_('The logfile %s does not exist. Please check the path.') % logfile)
|
||||
else:
|
||||
raise AppArmorException('Can\'t find system log "%s".' % (logfile))
|
||||
raise AppArmorException('Can\'t find system log "%s". Please check permissions.' % (logfile))
|
||||
elif os.path.isdir(logfile):
|
||||
raise AppArmorException(_('%s is a directory. Please specify a file as logfile') % logfile)
|
||||
|
||||
def do_logprof_pass(logmark='', passno=0, log_pid=log_pid):
|
||||
# set up variables for this pass
|
||||
# transitions = hasher()
|
||||
global existing_profiles
|
||||
global active_profiles
|
||||
global sev_db
|
||||
# aa = hasher()
|
||||
# profile_changes = hasher()
|
||||
@@ -1786,13 +1810,13 @@ def do_logprof_pass(logmark='', passno=0, log_pid=log_pid):
|
||||
if not sev_db:
|
||||
sev_db = apparmor.severity.Severity(CONFDIR + '/severity.db', _('unknown'))
|
||||
#print(pid)
|
||||
#print(existing_profiles)
|
||||
#print(active_profiles)
|
||||
##if not repo_cf and cfg['repostory']['url']:
|
||||
## repo_cfg = read_config('repository.conf')
|
||||
## if not repo_cfg['repository'].get('enabled', False) or repo_cfg['repository]['enabled'] not in ['yes', 'no']:
|
||||
## UI_ask_to_enable_repo()
|
||||
|
||||
log_reader = apparmor.logparser.ReadLog(log_pid, logfile, existing_profiles, profile_dir)
|
||||
log_reader = apparmor.logparser.ReadLog(log_pid, logfile, active_profiles, profile_dir)
|
||||
log = log_reader.read_log(logmark)
|
||||
#read_log(logmark)
|
||||
|
||||
@@ -1867,13 +1891,11 @@ def save_profiles():
|
||||
if aa[which][which].get('filename', False):
|
||||
oldprofile = aa[which][which]['filename']
|
||||
else:
|
||||
oldprofile = get_profile_filename(which)
|
||||
oldprofile = get_profile_filename_from_attachment(which, True)
|
||||
|
||||
try:
|
||||
newprofile = serialize_profile_from_old_profile(aa[which], which, '')
|
||||
except AttributeError:
|
||||
# see https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/1528139
|
||||
newprofile = "###\n###\n### Internal error while generating diff, please use '%s' instead\n###\n###\n" % _('View Changes b/w (C)lean profiles')
|
||||
serialize_options = {}
|
||||
serialize_options['METADATA'] = True
|
||||
newprofile = serialize_profile(aa[which], which, serialize_options)
|
||||
|
||||
aaui.UI_Changes(oldprofile, newprofile, comments=True)
|
||||
|
||||
@@ -2085,9 +2107,29 @@ def read_profile(file, active_profile):
|
||||
if profile_data and active_profile:
|
||||
attach_profile_data(aa, profile_data)
|
||||
attach_profile_data(original_aa, profile_data)
|
||||
|
||||
for profile in profile_data: # TODO: also honor hats
|
||||
name = profile_data[profile][profile]['name']
|
||||
attachment = profile_data[profile][profile]['attachment']
|
||||
filename = profile_data[profile][profile]['filename']
|
||||
|
||||
if not attachment and name.startswith('/'):
|
||||
active_profiles.add(filename, name, name) # use name as name and attachment
|
||||
else:
|
||||
active_profiles.add(filename, name, attachment)
|
||||
|
||||
elif profile_data:
|
||||
attach_profile_data(extras, profile_data)
|
||||
|
||||
for profile in profile_data: # TODO: also honor hats
|
||||
name = profile_data[profile][profile]['name']
|
||||
attachment = profile_data[profile][profile]['attachment']
|
||||
filename = profile_data[profile][profile]['filename']
|
||||
|
||||
if not attachment and name.startswith('/'):
|
||||
extra_profiles.add(filename, name, name) # use name as name and attachment
|
||||
else:
|
||||
extra_profiles.add(filename, name, attachment)
|
||||
|
||||
def attach_profile_data(profiles, profile_data):
|
||||
# Make deep copy of data to avoid changes to
|
||||
@@ -2179,9 +2221,6 @@ def parse_profile_data(data, file, do_include):
|
||||
if pps_set_hat_external:
|
||||
profile_data[profile][hat]['external'] = True
|
||||
|
||||
# Profile stored
|
||||
existing_profiles[profile] = file
|
||||
|
||||
# save profile name and filename
|
||||
profile_data[profile][hat]['name'] = profile
|
||||
profile_data[profile][hat]['filename'] = file
|
||||
@@ -2506,6 +2545,11 @@ def parse_profile_data(data, file, do_include):
|
||||
else:
|
||||
raise AppArmorException(_('Syntax Error: Unknown line found in file %(file)s line %(lineno)s:\n %(line)s') % { 'file': file, 'lineno': lineno + 1, 'line': line })
|
||||
|
||||
if lastline:
|
||||
# lastline gets merged into line (and reset to None) when reading the next line.
|
||||
# If it isn't empty, this means there's something unparseable at the end of the profile
|
||||
raise AppArmorException(_('Syntax Error: Unknown line found in file %(file)s line %(lineno)s:\n %(line)s') % { 'file': file, 'lineno': lineno + 1, 'line': lastline })
|
||||
|
||||
# Below is not required I'd say
|
||||
if not do_include:
|
||||
for hatglob in cfg['required_hats'].keys():
|
||||
@@ -2886,7 +2930,11 @@ def serialize_profile(profile_data, name, options):
|
||||
# comment.replace('\\n', '\n')
|
||||
# string += comment + '\n'
|
||||
|
||||
prof_filename = get_profile_filename(name)
|
||||
if options and options.get('is_attachment'):
|
||||
prof_filename = get_profile_filename_from_attachment(name, True)
|
||||
else:
|
||||
prof_filename = get_profile_filename_from_profile_name(name, True)
|
||||
|
||||
if filelist.get(prof_filename, False):
|
||||
data += write_abi(filelist[prof_filename], 0)
|
||||
data += write_alias(filelist[prof_filename], 0)
|
||||
@@ -2920,429 +2968,18 @@ def serialize_parse_profile_start(line, file, lineno, profile, hat, prof_data_pr
|
||||
|
||||
return (profile, hat, attachment, flags, in_contained_hat, correct)
|
||||
|
||||
def serialize_profile_from_old_profile(profile_data, name, options):
|
||||
data = []
|
||||
string = ''
|
||||
include_metadata = False
|
||||
include_flags = True
|
||||
prof_filename = get_profile_filename(name)
|
||||
|
||||
write_filelist = deepcopy(filelist[prof_filename])
|
||||
write_prof_data = deepcopy(profile_data)
|
||||
|
||||
# XXX profile_data / write_prof_data contain only one profile with its hats
|
||||
# XXX this will explode if a file contains multiple profiles, see https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/1528139
|
||||
# XXX fixing this needs lots of write_prof_data[hat] -> write_prof_data[profile][hat] changes (and of course also a change in the calling code)
|
||||
# XXX (the better option is a full rewrite of serialize_profile_from_old_profile())
|
||||
|
||||
if options: # and type(options) == dict:
|
||||
if options.get('METADATA', False):
|
||||
include_metadata = True
|
||||
if options.get('NO_FLAGS', False):
|
||||
include_flags = False
|
||||
|
||||
if include_metadata:
|
||||
string = '# Last Modified: %s\n' % time.asctime()
|
||||
|
||||
if (profile_data[name].get('repo', False) and
|
||||
profile_data[name]['repo']['url'] and
|
||||
profile_data[name]['repo']['user'] and
|
||||
profile_data[name]['repo']['id']):
|
||||
repo = profile_data[name]['repo']
|
||||
string += '# REPOSITORY: %s %s %s\n' % (repo['url'], repo['user'], repo['id'])
|
||||
elif profile_data[name]['repo']['neversubmit']:
|
||||
string += '# REPOSITORY: NEVERSUBMIT\n'
|
||||
|
||||
if not os.path.isfile(prof_filename):
|
||||
raise AppArmorException(_("Can't find existing profile to modify"))
|
||||
|
||||
# profiles_list = filelist[prof_filename].keys() # XXX
|
||||
|
||||
with open_file_read(prof_filename) as f_in:
|
||||
profile = None
|
||||
hat = None
|
||||
write_methods = {'abi': write_abi,
|
||||
'alias': write_alias,
|
||||
'lvar': write_list_vars,
|
||||
'include': write_includes,
|
||||
'rlimit': write_rlimits,
|
||||
'capability': write_capabilities,
|
||||
'network': write_netdomain,
|
||||
'dbus': write_dbus,
|
||||
'mount': write_mount,
|
||||
'signal': write_signal,
|
||||
'ptrace': write_ptrace,
|
||||
'pivot_root': write_pivot_root,
|
||||
'unix': write_unix,
|
||||
'link': write_links,
|
||||
'file': write_file,
|
||||
'change_profile': write_change_profile,
|
||||
}
|
||||
default_write_order = [ 'alias',
|
||||
'lvar',
|
||||
'include',
|
||||
'rlimit',
|
||||
'capability',
|
||||
'network',
|
||||
'dbus',
|
||||
'mount',
|
||||
'signal',
|
||||
'ptrace',
|
||||
'pivot_root',
|
||||
'unix',
|
||||
'link',
|
||||
'file',
|
||||
'change_profile',
|
||||
]
|
||||
# prof_correct = True # XXX correct?
|
||||
segments = {'alias': False,
|
||||
'lvar': False,
|
||||
'include': False,
|
||||
'rlimit': False,
|
||||
'capability': False,
|
||||
'network': False,
|
||||
'dbus': False,
|
||||
'mount': False,
|
||||
'signal': True, # not handled otherwise yet
|
||||
'ptrace': True, # not handled otherwise yet
|
||||
'pivot_root': False,
|
||||
'unix': False,
|
||||
'link': False,
|
||||
'file': False,
|
||||
'change_profile': False,
|
||||
'include_local_started': False, # unused
|
||||
}
|
||||
|
||||
def write_prior_segments(prof_data, segments, line):
|
||||
data = []
|
||||
for segs in list(filter(lambda x: segments[x], segments.keys())):
|
||||
depth = len(line) - len(line.lstrip())
|
||||
data += write_methods[segs](prof_data, int(depth / 2))
|
||||
segments[segs] = False
|
||||
# delete rules from prof_data to avoid duplication (they are in data now)
|
||||
if prof_data['allow'].get(segs, False):
|
||||
prof_data['allow'].pop(segs)
|
||||
if prof_data['deny'].get(segs, False):
|
||||
prof_data['deny'].pop(segs)
|
||||
if prof_data.get(segs, False):
|
||||
t = type(prof_data[segs])
|
||||
prof_data[segs] = t()
|
||||
return data
|
||||
|
||||
#data.append('reading prof')
|
||||
for line in f_in:
|
||||
correct = True
|
||||
line = line.rstrip('\n')
|
||||
#data.append(' ')#data.append('read: '+line)
|
||||
if RE_PROFILE_START.search(line):
|
||||
|
||||
(profile, hat, attachment, flags, in_contained_hat, correct) = serialize_parse_profile_start(
|
||||
line, prof_filename, None, profile, hat, write_prof_data[hat]['profile'], write_prof_data[hat]['external'], correct)
|
||||
|
||||
if not write_prof_data[hat]['name'] == profile:
|
||||
correct = False
|
||||
|
||||
if not write_filelist['profiles'][profile][hat] is True:
|
||||
correct = False
|
||||
|
||||
if not write_prof_data[hat]['flags'] == flags:
|
||||
correct = False
|
||||
|
||||
#Write the profile start
|
||||
if correct:
|
||||
if write_filelist:
|
||||
data += write_alias(write_filelist, 0)
|
||||
data += write_list_vars(write_filelist, 0)
|
||||
data += write_includes(write_filelist, 0)
|
||||
data.append(line)
|
||||
else:
|
||||
if write_prof_data[hat]['name'] == profile:
|
||||
depth = len(line) - len(line.lstrip())
|
||||
data += write_header(write_prof_data[name], int(depth / 2), name, False, include_flags)
|
||||
|
||||
elif RE_PROFILE_END.search(line):
|
||||
# DUMP REMAINDER OF PROFILE
|
||||
if profile:
|
||||
depth = int(len(line) - len(line.lstrip()) / 2) + 1
|
||||
|
||||
# first write sections that were modified
|
||||
#for segs in write_methods.keys():
|
||||
for segs in default_write_order:
|
||||
if segments[segs]:
|
||||
data += write_methods[segs](write_prof_data[name], depth)
|
||||
segments[segs] = False
|
||||
# delete rules from write_prof_data to avoid duplication (they are in data now)
|
||||
if write_prof_data[name]['allow'].get(segs, False):
|
||||
write_prof_data[name]['allow'].pop(segs)
|
||||
if write_prof_data[name]['deny'].get(segs, False):
|
||||
write_prof_data[name]['deny'].pop(segs)
|
||||
if write_prof_data[name].get(segs, False):
|
||||
t = type(write_prof_data[name][segs])
|
||||
write_prof_data[name][segs] = t()
|
||||
|
||||
# then write everything else
|
||||
for segs in default_write_order:
|
||||
data += write_methods[segs](write_prof_data[name], depth)
|
||||
|
||||
write_prof_data.pop(name)
|
||||
|
||||
#Append local includes
|
||||
data.append(line)
|
||||
|
||||
if not in_contained_hat:
|
||||
# Embedded hats
|
||||
depth = int((len(line) - len(line.lstrip())) / 2)
|
||||
pre2 = ' ' * (depth + 1)
|
||||
for hat in list(filter(lambda x: x != name, sorted(profile_data.keys()))):
|
||||
if not profile_data[hat]['external']:
|
||||
data.append('')
|
||||
if profile_data[hat]['profile']:
|
||||
data += list(map(str, write_header(profile_data[hat], depth + 1, hat, True, include_flags)))
|
||||
else:
|
||||
data += list(map(str, write_header(profile_data[hat], depth + 1, '^' + hat, True, include_flags)))
|
||||
|
||||
data += list(map(str, write_rules(profile_data[hat], depth + 2)))
|
||||
|
||||
data.append('%s}' % pre2)
|
||||
|
||||
# External hats
|
||||
for hat in list(filter(lambda x: x != name, sorted(profile_data.keys()))):
|
||||
if profile_data[hat].get('external', False):
|
||||
data.append('')
|
||||
data += list(map(lambda x: ' %s' % x, write_piece(profile_data, depth - 1, name, name, include_flags)))
|
||||
data.append(' }')
|
||||
|
||||
if in_contained_hat:
|
||||
#Hat processed, remove it
|
||||
hat = profile
|
||||
in_contained_hat = False
|
||||
else:
|
||||
profile = None
|
||||
|
||||
elif CapabilityRule.match(line):
|
||||
cap = CapabilityRule.parse(line)
|
||||
if write_prof_data[hat]['capability'].is_covered(cap, True, True):
|
||||
if not segments['capability'] and True in segments.values():
|
||||
data += write_prior_segments(write_prof_data[name], segments, line)
|
||||
segments['capability'] = True
|
||||
write_prof_data[hat]['capability'].delete(cap)
|
||||
data.append(line)
|
||||
else:
|
||||
# To-Do
|
||||
pass
|
||||
elif RE_PROFILE_LINK.search(line):
|
||||
matches = RE_PROFILE_LINK.search(line).groups()
|
||||
audit = False
|
||||
if matches[0]:
|
||||
audit = True
|
||||
allow = 'allow'
|
||||
if matches[1] and matches[1].strip() == 'deny':
|
||||
allow = 'deny'
|
||||
|
||||
subset = matches[3]
|
||||
link = strip_quotes(matches[6])
|
||||
value = strip_quotes(matches[7])
|
||||
if not write_prof_data[hat][allow]['link'][link]['to'] == value:
|
||||
correct = False
|
||||
if not write_prof_data[hat][allow]['link'][link]['mode'] & apparmor.aamode.AA_MAY_LINK:
|
||||
correct = False
|
||||
if subset and not write_prof_data[hat][allow]['link'][link]['mode'] & apparmor.aamode.AA_LINK_SUBSET:
|
||||
correct = False
|
||||
if audit and not write_prof_data[hat][allow]['link'][link]['audit'] & apparmor.aamode.AA_LINK_SUBSET:
|
||||
correct = False
|
||||
|
||||
if correct:
|
||||
if not segments['link'] and True in segments.values():
|
||||
data += write_prior_segments(write_prof_data[name], segments, line)
|
||||
segments['link'] = True
|
||||
write_prof_data[hat][allow]['link'].pop(link)
|
||||
data.append(line)
|
||||
else:
|
||||
# To-Do
|
||||
pass
|
||||
|
||||
elif ChangeProfileRule.match(line):
|
||||
change_profile_obj = ChangeProfileRule.parse(line)
|
||||
if write_prof_data[hat]['change_profile'].is_covered(change_profile_obj, True, True):
|
||||
if not segments['change_profile'] and True in segments.values():
|
||||
data += write_prior_segments(write_prof_data[name], segments, line)
|
||||
segments['change_profile'] = True
|
||||
write_prof_data[hat]['change_profile'].delete(change_profile_obj)
|
||||
data.append(line)
|
||||
|
||||
elif RE_PROFILE_ALIAS.search(line):
|
||||
matches = RE_PROFILE_ALIAS.search(line).groups()
|
||||
|
||||
from_name = strip_quotes(matches[0])
|
||||
to_name = strip_quotes(matches[1])
|
||||
|
||||
if profile:
|
||||
if not write_prof_data[hat]['alias'][from_name] == to_name:
|
||||
correct = False
|
||||
else:
|
||||
if not write_filelist['alias'][from_name] == to_name:
|
||||
correct = False
|
||||
|
||||
if correct:
|
||||
if not segments['alias'] and True in segments.values():
|
||||
data += write_prior_segments(write_prof_data[name], segments, line)
|
||||
segments['alias'] = True
|
||||
if profile:
|
||||
write_prof_data[hat]['alias'].pop(from_name)
|
||||
else:
|
||||
write_filelist['alias'].pop(from_name)
|
||||
data.append(line)
|
||||
else:
|
||||
#To-Do
|
||||
pass
|
||||
|
||||
elif RlimitRule.match(line):
|
||||
rlimit_obj = RlimitRule.parse(line)
|
||||
|
||||
if write_prof_data[hat]['rlimit'].is_covered(rlimit_obj, True, True):
|
||||
if not segments['rlimit'] and True in segments.values():
|
||||
data += write_prior_segments(write_prof_data[name], segments, line)
|
||||
segments['rlimit'] = True
|
||||
write_prof_data[hat]['rlimit'].delete(rlimit_obj)
|
||||
data.append(line)
|
||||
else:
|
||||
#To-Do
|
||||
pass
|
||||
|
||||
elif RE_PROFILE_BOOLEAN.search(line):
|
||||
matches = RE_PROFILE_BOOLEAN.search(line).groups()
|
||||
bool_var = matches[0]
|
||||
value = matches[1]
|
||||
|
||||
if not write_prof_data[hat]['lvar'][bool_var] == value:
|
||||
correct = False
|
||||
|
||||
if correct:
|
||||
if not segments['lvar'] and True in segments.values():
|
||||
data += write_prior_segments(write_prof_data[name], segments, line)
|
||||
segments['lvar'] = True
|
||||
write_prof_data[hat]['lvar'].pop(bool_var)
|
||||
data.append(line)
|
||||
else:
|
||||
#To-Do
|
||||
pass
|
||||
elif RE_PROFILE_VARIABLE.search(line):
|
||||
matches = RE_PROFILE_VARIABLE.search(line).groups()
|
||||
list_var = strip_quotes(matches[0])
|
||||
var_operation = matches[1]
|
||||
value = strip_quotes(matches[2])
|
||||
var_set = hasher()
|
||||
if var_operation == '+=':
|
||||
correct = False # adding proper support for "add to variable" needs big changes
|
||||
# (like storing a variable's "history" - where it was initially defined and what got added where)
|
||||
# so just skip any comparison and assume a non-match
|
||||
elif profile:
|
||||
store_list_var(var_set, list_var, value, var_operation, prof_filename)
|
||||
if not var_set[list_var] == write_prof_data['lvar'].get(list_var, False):
|
||||
correct = False
|
||||
else:
|
||||
store_list_var(var_set, list_var, value, var_operation, prof_filename)
|
||||
if not var_set[list_var] == write_filelist['lvar'].get(list_var, False):
|
||||
correct = False
|
||||
|
||||
if correct:
|
||||
if not segments['lvar'] and True in segments.values():
|
||||
data += write_prior_segments(write_prof_data[name], segments, line)
|
||||
segments['lvar'] = True
|
||||
if profile:
|
||||
write_prof_data[hat]['lvar'].pop(list_var)
|
||||
else:
|
||||
write_filelist['lvar'].pop(list_var)
|
||||
data.append(line)
|
||||
else:
|
||||
#To-Do
|
||||
pass
|
||||
|
||||
elif re_match_include(line):
|
||||
include_name = re_match_include(line)
|
||||
if profile:
|
||||
if write_prof_data[hat]['include'].get(include_name, False):
|
||||
if not segments['include'] and True in segments.values():
|
||||
data += write_prior_segments(write_prof_data[name], segments, line)
|
||||
segments['include'] = True
|
||||
write_prof_data[hat]['include'].pop(include_name)
|
||||
data.append(line)
|
||||
else:
|
||||
if write_filelist['include'].get(include_name, False):
|
||||
write_filelist['include'].pop(include_name)
|
||||
data.append(line)
|
||||
|
||||
elif NetworkRule.match(line):
|
||||
network_obj = NetworkRule.parse(line)
|
||||
if write_prof_data[hat]['network'].is_covered(network_obj, True, True):
|
||||
if not segments['network'] and True in segments.values():
|
||||
data += write_prior_segments(write_prof_data[name], segments, line)
|
||||
segments['network'] = True
|
||||
write_prof_data[hat]['network'].delete(network_obj)
|
||||
data.append(line)
|
||||
|
||||
elif RE_PROFILE_CHANGE_HAT.search(line):
|
||||
# "^hat," declarations are no longer supported, ignore them and don't write out the line
|
||||
# (parse_profile_data() already prints a warning about that)
|
||||
pass
|
||||
elif RE_PROFILE_HAT_DEF.search(line):
|
||||
matches = RE_PROFILE_HAT_DEF.search(line)
|
||||
in_contained_hat = True
|
||||
hat = matches.group('hat')
|
||||
hat = strip_quotes(hat)
|
||||
flags = matches.group('flags')
|
||||
|
||||
if not write_prof_data[hat]['flags'] == flags:
|
||||
correct = False
|
||||
if not write_filelist['profile'][profile][hat]:
|
||||
correct = False
|
||||
if correct:
|
||||
data.append(line)
|
||||
else:
|
||||
#To-Do
|
||||
pass
|
||||
elif FileRule.match(line):
|
||||
# leading permissions could look like a keyword, therefore handle file rules after everything else
|
||||
file_obj = FileRule.parse(line)
|
||||
|
||||
if write_prof_data[hat]['file'].is_covered(file_obj, True, True):
|
||||
if not segments['file'] and True in segments.values():
|
||||
data += write_prior_segments(write_prof_data[name], segments, line)
|
||||
segments['file'] = True
|
||||
write_prof_data[hat]['file'].delete(file_obj)
|
||||
data.append(line)
|
||||
else:
|
||||
#To-Do
|
||||
pass
|
||||
|
||||
else:
|
||||
if correct:
|
||||
data.append(line)
|
||||
else:
|
||||
#To-Do
|
||||
pass
|
||||
# data.append('prof done')
|
||||
# if write_filelist:
|
||||
# data += write_alias(write_filelist, 0)
|
||||
# data += write_list_vars(write_filelist, 0)
|
||||
# data += write_includes(write_filelist, 0)
|
||||
# data.append('from filelist over')
|
||||
# data += write_piece(write_prof_data, 0, name, name, include_flags)
|
||||
|
||||
string += '\n'.join(data)
|
||||
|
||||
return string + '\n'
|
||||
|
||||
def write_profile_ui_feedback(profile):
|
||||
def write_profile_ui_feedback(profile, is_attachment=False):
|
||||
aaui.UI_Info(_('Writing updated profile for %s.') % profile)
|
||||
write_profile(profile)
|
||||
write_profile(profile, is_attachment)
|
||||
|
||||
def write_profile(profile):
|
||||
def write_profile(profile, is_attachment=False):
|
||||
prof_filename = None
|
||||
if aa[profile][profile].get('filename', False):
|
||||
prof_filename = aa[profile][profile]['filename']
|
||||
elif is_attachment:
|
||||
prof_filename = get_profile_filename_from_attachment(profile, True)
|
||||
else:
|
||||
prof_filename = get_profile_filename(profile)
|
||||
prof_filename = get_profile_filename_from_profile_name(profile, True)
|
||||
|
||||
newprof = tempfile.NamedTemporaryFile('w', suffix='~', delete=False, dir=profile_dir)
|
||||
if os.path.exists(prof_filename):
|
||||
@@ -3352,8 +2989,7 @@ def write_profile(profile):
|
||||
#os.chmod(newprof.name, permission_600)
|
||||
pass
|
||||
|
||||
serialize_options = {}
|
||||
serialize_options['METADATA'] = True
|
||||
serialize_options = {'METADATA': True, 'is_attachment': is_attachment}
|
||||
|
||||
profile_string = serialize_profile(aa[profile], profile, serialize_options)
|
||||
newprof.write(profile_string)
|
||||
@@ -3476,7 +3112,7 @@ def reload_base(bin_path):
|
||||
if not check_for_apparmor():
|
||||
return None
|
||||
|
||||
prof_filename = get_profile_filename(bin_path)
|
||||
prof_filename = get_profile_filename_from_profile_name(bin_path, True)
|
||||
|
||||
# XXX use reload_profile() from tools.py instead (and don't hide output in /dev/null)
|
||||
subprocess.call("cat '%s' | %s -I%s -r >/dev/null 2>&1" % (prof_filename, parser, profile_dir), shell=True)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (C) 2013 Kshitij Gupta <kgupta8592@gmail.com>
|
||||
# Copyright (C) 2015-2016 Christian Boltz <apparmor@cboltz.de>
|
||||
# Copyright (C) 2015-2018 Christian Boltz <apparmor@cboltz.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
@@ -12,7 +12,6 @@
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
@@ -43,11 +42,11 @@ class ReadLog:
|
||||
# used to pre-filter log lines so that we hand over only relevant lines to LibAppArmor parsing
|
||||
RE_LOG_ALL = re.compile('(' + '|'.join(RE_log_parts) + ')')
|
||||
|
||||
def __init__(self, pid, filename, existing_profiles, profile_dir):
|
||||
def __init__(self, pid, filename, active_profiles, profile_dir):
|
||||
self.filename = filename
|
||||
self.profile_dir = profile_dir
|
||||
self.pid = pid
|
||||
self.existing_profiles = existing_profiles
|
||||
self.active_profiles = active_profiles
|
||||
self.log = []
|
||||
self.debug_logger = DebugLogger('ReadLog')
|
||||
self.LOG = None
|
||||
@@ -446,24 +445,7 @@ class ReadLog:
|
||||
def profile_exists(self, program):
|
||||
"""Returns True if profile exists, False otherwise"""
|
||||
# Check cache of profiles
|
||||
if self.existing_profiles.get(program, False):
|
||||
if self.active_profiles.filename_from_profile_name(program):
|
||||
return True
|
||||
# Check the disk for profile
|
||||
prof_path = self.get_profile_filename(program)
|
||||
#print(prof_path)
|
||||
if os.path.isfile(prof_path):
|
||||
# Add to cache of profile
|
||||
self.existing_profiles[program] = prof_path
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_profile_filename(self, profile):
|
||||
"""Returns the full profile name"""
|
||||
if profile.startswith('/'):
|
||||
# Remove leading /
|
||||
profile = profile[1:]
|
||||
else:
|
||||
profile = "profile_" + profile
|
||||
profile = profile.replace('/', '.')
|
||||
full_profilename = self.profile_dir + '/' + profile
|
||||
return full_profilename
|
||||
return False
|
||||
|
73
utils/apparmor/profile_list.py
Normal file
73
utils/apparmor/profile_list.py
Normal file
@@ -0,0 +1,73 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (C) 2018 Christian Boltz <apparmor@cboltz.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
from apparmor.aare import AARE
|
||||
from apparmor.common import AppArmorBug, AppArmorException
|
||||
|
||||
# setup module translations
|
||||
from apparmor.translations import init_translation
|
||||
_ = init_translation()
|
||||
|
||||
|
||||
class ProfileList:
|
||||
''' Stores the list of profiles (both name and attachment) and in which files they live '''
|
||||
|
||||
def __init__(self):
|
||||
self.profile_names = {} # profile name -> filename
|
||||
self.attachments = {} # attachment -> filename
|
||||
self.attachments_AARE = {} # AARE(attachment) -> filename
|
||||
|
||||
def add(self, filename, profile_name, attachment):
|
||||
''' Add the given profile and attachment to the list '''
|
||||
|
||||
if not filename:
|
||||
raise AppArmorBug('Empty filename given to ProfileList')
|
||||
|
||||
if not profile_name and not attachment:
|
||||
raise AppArmorBug('Neither profile name or attachment given')
|
||||
|
||||
if profile_name in self.profile_names:
|
||||
raise AppArmorException(_('Profile %(profile_name)s exists in %(filename)s and %(filename2)s' % {'profile_name': profile_name, 'filename': filename, 'filename2': self.profile_names[profile_name]}))
|
||||
|
||||
if attachment in self.attachments:
|
||||
raise AppArmorException(_('Profile for %(profile_name)s exists in %(filename)s and %(filename2)s' % {'profile_name': attachment, 'filename': filename, 'filename2': self.attachments[attachment]}))
|
||||
|
||||
if profile_name:
|
||||
self.profile_names[profile_name] = filename
|
||||
|
||||
if attachment:
|
||||
self.attachments[attachment] = filename
|
||||
self.attachments_AARE[attachment] = AARE(attachment, True)
|
||||
|
||||
def filename_from_profile_name(self, name):
|
||||
''' Return profile filename for the given profile name, or None '''
|
||||
|
||||
return self.profile_names.get(name, None)
|
||||
|
||||
def filename_from_attachment(self, attachment):
|
||||
''' Return profile filename for the given attachment/executable path, or None '''
|
||||
|
||||
if not attachment.startswith( ('/', '@', '{') ):
|
||||
raise AppArmorBug('Called filename_from_attachment with non-path attachment: %s' % attachment)
|
||||
|
||||
# plain path
|
||||
if self.attachments.get(attachment):
|
||||
return self.attachments[attachment]
|
||||
|
||||
# try AARE matches to cover profile names with alternations and wildcards
|
||||
for path in self.attachments.keys():
|
||||
if self.attachments_AARE[path].match(attachment):
|
||||
return self.attachments[path] # XXX this returns the first match, not necessarily the best one
|
||||
|
||||
return None # nothing found
|
@@ -26,8 +26,8 @@ _ = init_translation()
|
||||
|
||||
network_domain_keywords = [ 'unspec', 'unix', 'inet', 'ax25', 'ipx', 'appletalk', 'netrom', 'bridge', 'atmpvc', 'x25', 'inet6',
|
||||
'rose', 'netbeui', 'security', 'key', 'netlink', 'packet', 'ash', 'econet', 'atmsvc', 'rds', 'sna',
|
||||
'irda', 'pppox', 'wanpipe', 'llc', 'can', 'tipc', 'bluetooth', 'iucv', 'rxrpc', 'isdn', 'phonet',
|
||||
'ieee802154', 'caif', 'alg', 'nfc', 'vsock', 'mpls', 'ib', 'kcm', 'smc' ]
|
||||
'irda', 'pppox', 'wanpipe', 'llc', 'ib', 'mpls', 'can', 'tipc', 'bluetooth', 'iucv', 'rxrpc', 'isdn',
|
||||
'phonet', 'ieee802154', 'caif', 'alg', 'nfc', 'vsock', 'kcm', 'qipcrtr', 'smc', 'xdp' ]
|
||||
|
||||
network_type_keywords = ['stream', 'dgram', 'seqpacket', 'rdm', 'raw', 'packet']
|
||||
network_protocol_keywords = ['tcp', 'udp', 'icmp']
|
||||
|
@@ -1,5 +1,6 @@
|
||||
# ----------------------------------------------------------------------
|
||||
# Copyright (C) 2013 Kshitij Gupta <kgupta8592@gmail.com>
|
||||
# Copyright (C) 2015-2018 Christian Boltz <apparmor@cboltz.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
@@ -66,12 +67,12 @@ class aa_tools:
|
||||
profile = fq_path
|
||||
else:
|
||||
program = fq_path
|
||||
profile = apparmor.get_profile_filename(fq_path)
|
||||
profile = apparmor.get_profile_filename_from_attachment(fq_path, True)
|
||||
else:
|
||||
which = apparmor.which(p)
|
||||
if which is not None:
|
||||
program = apparmor.get_full_path(which)
|
||||
profile = apparmor.get_profile_filename(program)
|
||||
profile = apparmor.get_profile_filename_from_attachment(program, True)
|
||||
elif os.path.exists(os.path.join(apparmor.profile_dir, p)):
|
||||
program = None
|
||||
profile = apparmor.get_full_path(os.path.join(apparmor.profile_dir, p)).strip()
|
||||
@@ -190,7 +191,7 @@ class aa_tools:
|
||||
|
||||
apparmor.check_qualifiers(program)
|
||||
|
||||
if os.path.exists(apparmor.get_profile_filename(program)) and not self.force:
|
||||
if os.path.exists(apparmor.get_profile_filename_from_attachment(program, True)) and not self.force:
|
||||
aaui.UI_Info(_('Profile for %s already exists - skipping.') % program)
|
||||
else:
|
||||
apparmor.autodep(program)
|
||||
@@ -198,7 +199,7 @@ class aa_tools:
|
||||
apparmor.reload(program)
|
||||
|
||||
def clean_profile(self, program):
|
||||
filename = apparmor.get_profile_filename(program)
|
||||
filename = apparmor.get_profile_filename_from_attachment(program, True)
|
||||
import apparmor.cleanprofile as cleanprofile
|
||||
prof = cleanprofile.Prof(filename)
|
||||
cleanprof = cleanprofile.CleanProf(True, prof, prof)
|
||||
@@ -220,14 +221,14 @@ class aa_tools:
|
||||
while ans != 'CMD_SAVE_CHANGES':
|
||||
ans, arg = q.promptUser()
|
||||
if ans == 'CMD_SAVE_CHANGES':
|
||||
apparmor.write_profile_ui_feedback(program)
|
||||
apparmor.write_profile_ui_feedback(program, True)
|
||||
self.reload_profile(filename)
|
||||
elif ans == 'CMD_VIEW_CHANGES':
|
||||
#oldprofile = apparmor.serialize_profile(apparmor.original_aa[program], program, '')
|
||||
newprofile = apparmor.serialize_profile(apparmor.aa[program], program, '')
|
||||
newprofile = apparmor.serialize_profile(apparmor.aa[program], program, {'is_attachment': True})
|
||||
aaui.UI_Changes(filename, newprofile, comments=True)
|
||||
else:
|
||||
apparmor.write_profile_ui_feedback(program)
|
||||
apparmor.write_profile_ui_feedback(program, True)
|
||||
self.reload_profile(filename)
|
||||
else:
|
||||
raise apparmor.AppArmorException(_('The profile for %s does not exists. Nothing to clean.') % program)
|
||||
|
@@ -5,7 +5,7 @@ import sys
|
||||
if len(sys.argv) != 2:
|
||||
raise Exception('wrong number of arguments in fake_ldd')
|
||||
|
||||
if sys.argv[1] == '/AATest/bin/bash' or sys.argv[1] == '/bin/bash':
|
||||
if sys.argv[1] in ['/AATest/bin/bash', '/bin/bash', '/usr/bin/bash']:
|
||||
print(' linux-vdso.so.1 (0x00007ffcf97f4000)')
|
||||
print(' libreadline.so.6 => /AATest/lib64/libreadline.so.6 (0x00007f2c41324000)')
|
||||
print(' libtinfo.so.6 => /AATest/lib64/libtinfo.so.6 (0x00007f2c410f9000)')
|
||||
|
@@ -135,6 +135,9 @@ class AaTest_create_new_profile(AATest):
|
||||
apparmor.aa.load_include('abstractions/bash')
|
||||
|
||||
exp_interpreter_path, exp_abstraction = expected
|
||||
# damn symlinks!
|
||||
if exp_interpreter_path:
|
||||
exp_interpreter_path = os.path.realpath(exp_interpreter_path)
|
||||
|
||||
program = self.writeTmpfile('script', params)
|
||||
profile = create_new_profile(program)
|
||||
@@ -178,11 +181,8 @@ class AaTest_get_interpreter_and_abstraction(AATest):
|
||||
interpreter_path, abstraction = get_interpreter_and_abstraction(program)
|
||||
|
||||
# damn symlinks!
|
||||
if exp_interpreter_path and os.path.islink(exp_interpreter_path):
|
||||
dirname = os.path.dirname(exp_interpreter_path)
|
||||
exp_interpreter_path = os.readlink(exp_interpreter_path)
|
||||
if not exp_interpreter_path.startswith('/'):
|
||||
exp_interpreter_path = os.path.join(dirname, exp_interpreter_path)
|
||||
if exp_interpreter_path:
|
||||
exp_interpreter_path = os.path.realpath(exp_interpreter_path)
|
||||
|
||||
self.assertEqual(interpreter_path, exp_interpreter_path)
|
||||
self.assertEqual(abstraction, exp_abstraction)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#! /usr/bin/python3
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2015 Christian Boltz <apparmor@cboltz.de>
|
||||
# Copyright (C) 2015-2018 Christian Boltz <apparmor@cboltz.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
@@ -17,6 +17,7 @@ from apparmor.common import open_file_read
|
||||
|
||||
import apparmor.aa
|
||||
from apparmor.logparser import ReadLog
|
||||
from apparmor.profile_list import ProfileList
|
||||
|
||||
class TestLibapparmorTestMulti(AATest):
|
||||
'''Parse all libraries/libapparmor/testsuite/test_multi tests and compare the result with the *.out files'''
|
||||
@@ -222,9 +223,15 @@ class TestLogToProfile(AATest):
|
||||
if '//' in profile:
|
||||
profile, hat = profile.split('//')
|
||||
|
||||
apparmor.aa.existing_profiles = {profile: profile_dummy_file}
|
||||
apparmor.aa.active_profiles = ProfileList()
|
||||
|
||||
log_reader = ReadLog(dict(), logfile, apparmor.aa.existing_profiles, '')
|
||||
# optional for now, might be needed one day
|
||||
# if profile.startswith('/'):
|
||||
# apparmor.aa.active_profiles.add(profile_dummy_file, profile, profile)
|
||||
# else:
|
||||
apparmor.aa.active_profiles.add(profile_dummy_file, profile, '')
|
||||
|
||||
log_reader = ReadLog(dict(), logfile, apparmor.aa.active_profiles, '')
|
||||
log = log_reader.read_log('')
|
||||
|
||||
for root in log:
|
||||
|
@@ -17,9 +17,9 @@ import unittest
|
||||
from collections import namedtuple
|
||||
from common_test import AATest, setup_all_loops
|
||||
|
||||
from apparmor.rule.network import NetworkRule, NetworkRuleset
|
||||
from apparmor.rule.network import NetworkRule, NetworkRuleset, network_domain_keywords
|
||||
from apparmor.rule import BaseRule
|
||||
from apparmor.common import AppArmorException, AppArmorBug
|
||||
from apparmor.common import AppArmorException, AppArmorBug, cmd
|
||||
from apparmor.logparser import ReadLog
|
||||
from apparmor.translations import init_translation
|
||||
_ = init_translation()
|
||||
@@ -27,6 +27,30 @@ _ = init_translation()
|
||||
exp = namedtuple('exp', ['audit', 'allow_keyword', 'deny', 'comment',
|
||||
'domain', 'all_domains', 'type_or_protocol', 'all_type_or_protocols'])
|
||||
|
||||
# --- check if the keyword list is up to date --- #
|
||||
|
||||
class NetworkKeywordsTest(AATest):
|
||||
def test_network_keyword_list(self):
|
||||
rc, output = cmd('../../common/list_af_names.sh')
|
||||
self.assertEqual(rc, 0)
|
||||
|
||||
af_names = []
|
||||
af_pairs = output.replace('AF_', '').strip().lower().split(",")
|
||||
for af_pair in af_pairs:
|
||||
af_name = af_pair.lstrip().split(" ")[0]
|
||||
# skip max af name definition
|
||||
if len(af_name) > 0 and af_name != "max":
|
||||
af_names.append(af_name)
|
||||
|
||||
missing_af_names = []
|
||||
for keyword in af_names:
|
||||
if keyword not in network_domain_keywords:
|
||||
# keywords missing in the system are ok (= older kernel), but network_domain_keywords needs to have the full list
|
||||
missing_af_names.append(keyword)
|
||||
|
||||
self.assertEqual(missing_af_names, [], 'Missing af_names in NetworkRule network_domain_keywords. This test is likely running '
|
||||
'on an newer kernel and will require updating the list of network domain keywords in utils/apparmor/rule/network.py')
|
||||
|
||||
# --- tests for single NetworkRule --- #
|
||||
|
||||
class NetworkTest(AATest):
|
||||
|
@@ -40,11 +40,6 @@ skip_startswith = (
|
||||
# testcases that should raise an exception, but don't
|
||||
exception_not_raised = [
|
||||
# most abi/bad_* aren't detected as bad by the basic implementation in the tools
|
||||
'abi/bad_1.sd',
|
||||
'abi/bad_2.sd',
|
||||
'abi/bad_3.sd',
|
||||
'abi/bad_4.sd',
|
||||
'abi/bad_5.sd',
|
||||
'abi/bad_10.sd',
|
||||
'abi/bad_11.sd',
|
||||
'abi/bad_12.sd',
|
||||
@@ -155,13 +150,9 @@ exception_not_raised = [
|
||||
'unix/bad_regex_04.sd',
|
||||
'unix/bad_shutdown_1.sd',
|
||||
'unix/bad_shutdown_2.sd',
|
||||
'vars/boolean/boolean_bad_1.sd',
|
||||
'vars/boolean/boolean_bad_2.sd',
|
||||
'vars/boolean/boolean_bad_3.sd',
|
||||
'vars/boolean/boolean_bad_4.sd',
|
||||
'vars/boolean/boolean_bad_6.sd',
|
||||
'vars/boolean/boolean_bad_7.sd',
|
||||
'vars/boolean/boolean_bad_8.sd',
|
||||
'vars/vars_bad_3.sd',
|
||||
'vars/vars_bad_4.sd',
|
||||
'vars/vars_bad_5.sd',
|
||||
@@ -200,7 +191,6 @@ exception_not_raised = [
|
||||
'vars/vars_recursion_2.sd',
|
||||
'vars/vars_recursion_3.sd',
|
||||
'vars/vars_recursion_4.sd',
|
||||
'vars/vars_simple_assignment_10.sd',
|
||||
'vars/vars_simple_assignment_3.sd',
|
||||
'vars/vars_simple_assignment_8.sd',
|
||||
'vars/vars_simple_assignment_9.sd',
|
||||
|
114
utils/test/test-profile-list.py
Normal file
114
utils/test/test-profile-list.py
Normal file
@@ -0,0 +1,114 @@
|
||||
#! /usr/bin/python3
|
||||
# ------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2018 Christian Boltz <apparmor@cboltz.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of version 2 of the GNU General Public
|
||||
# License published by the Free Software Foundation.
|
||||
#
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
import unittest
|
||||
from common_test import AATest, setup_all_loops
|
||||
|
||||
from apparmor.common import AppArmorBug, AppArmorException
|
||||
from apparmor.profile_list import ProfileList
|
||||
|
||||
class TestAdd(AATest):
|
||||
def AASetup(self):
|
||||
self.pl = ProfileList()
|
||||
|
||||
def testEmpty(self):
|
||||
self.assertEqual(self.pl.profile_names, {})
|
||||
self.assertEqual(self.pl.attachments, {})
|
||||
|
||||
def testAdd_1(self):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo')
|
||||
self.assertEqual(self.pl.profile_names, {'foo': '/etc/apparmor.d/bin.foo'})
|
||||
self.assertEqual(self.pl.attachments, {'/bin/foo': '/etc/apparmor.d/bin.foo'})
|
||||
|
||||
def testAdd_2(self):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', None, '/bin/foo')
|
||||
self.assertEqual(self.pl.profile_names, {})
|
||||
self.assertEqual(self.pl.attachments, {'/bin/foo': '/etc/apparmor.d/bin.foo'})
|
||||
|
||||
def testAdd_3(self):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', 'foo', None)
|
||||
self.assertEqual(self.pl.profile_names, {'foo': '/etc/apparmor.d/bin.foo'})
|
||||
self.assertEqual(self.pl.attachments, {})
|
||||
|
||||
|
||||
def testAddError_1(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
self.pl.add('', 'foo', '/bin/foo') # no filename
|
||||
|
||||
def testAddError_2(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', None, None) # neither attachment or profile name
|
||||
|
||||
def testAddError_twice_1(self):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo')
|
||||
with self.assertRaises(AppArmorException):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo')
|
||||
|
||||
def testAddError_twice_2(self):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo')
|
||||
with self.assertRaises(AppArmorException):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', 'foo', None)
|
||||
|
||||
def testAddError_twice_3(self):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', None, '/bin/foo')
|
||||
with self.assertRaises(AppArmorException):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo')
|
||||
|
||||
def testAddError_twice_4(self):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', None, '/bin/foo')
|
||||
with self.assertRaises(AppArmorException):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo')
|
||||
|
||||
def testAddError_twice_5(self):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', 'foo', None)
|
||||
with self.assertRaises(AppArmorException):
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo')
|
||||
|
||||
class TestFilename_from_profile_name(AATest):
|
||||
tests = [
|
||||
('foo', '/etc/apparmor.d/bin.foo'),
|
||||
('/bin/foo', None),
|
||||
('bar', None),
|
||||
]
|
||||
|
||||
def AASetup(self):
|
||||
self.pl = ProfileList()
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo')
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
self.assertEqual(self.pl.filename_from_profile_name(params), expected)
|
||||
|
||||
class TestFilename_from_attachment(AATest):
|
||||
tests = [
|
||||
('/bin/foo', '/etc/apparmor.d/bin.foo'),
|
||||
('/bin/baz', '/etc/apparmor.d/bin.baz'),
|
||||
('/bin/foobar', '/etc/apparmor.d/bin.foobar'),
|
||||
('@{foo}', None), # XXX variables not supported yet (and @{foo} isn't defined in this test)
|
||||
('/bin/404', None),
|
||||
]
|
||||
|
||||
def AASetup(self):
|
||||
self.pl = ProfileList()
|
||||
self.pl.add('/etc/apparmor.d/bin.foo', 'foo', '/bin/foo')
|
||||
self.pl.add('/etc/apparmor.d/bin.baz', 'baz', '/bin/ba*')
|
||||
self.pl.add('/etc/apparmor.d/bin.foobar', 'foobar', '/bin/foo{bar,baz}')
|
||||
|
||||
def _run_test(self, params, expected):
|
||||
self.assertEqual(self.pl.filename_from_attachment(params), expected)
|
||||
|
||||
def test_non_path_attachment(self):
|
||||
with self.assertRaises(AppArmorBug):
|
||||
self.pl.filename_from_attachment('foo')
|
||||
|
||||
|
||||
setup_all_loops(__name__)
|
||||
if __name__ == '__main__':
|
||||
unittest.main(verbosity=1)
|
Reference in New Issue
Block a user