mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-04 16:25:10 +00:00
Compare commits
155 Commits
v3.0.7
...
apparmor-3
Author | SHA1 | Date | |
---|---|---|---|
|
21093ca008 | ||
|
3877683071 | ||
|
2bb1abe9c4 | ||
|
e583abc6cc | ||
|
ae60878492 | ||
|
dc5e9352f1 | ||
|
e7d5937213 | ||
|
bdb650bf98 | ||
|
a5523e3c87 | ||
|
602e4f6b9f | ||
|
aa986e3de3 | ||
|
06ead7294a | ||
|
cb9a152e2a | ||
|
6ebf1cb0ef | ||
|
e8b45df48a | ||
|
19b3052b42 | ||
|
6e06d2216b | ||
|
1b0f51d0ce | ||
|
feb4e75e47 | ||
|
f686f7c0ff | ||
|
eeca73e675 | ||
|
fa7eb62c62 | ||
|
11f1928938 | ||
|
deca4adfed | ||
|
c712509d41 | ||
|
0e4540ac91 | ||
|
54c6343b0f | ||
|
ac7c791ca3 | ||
|
09402d2123 | ||
|
dcb3493d19 | ||
|
8d6174e300 | ||
|
d18bc59f49 | ||
|
b69add4f29 | ||
|
7e0465593a | ||
|
e5758891e6 | ||
|
ff6489bfdf | ||
|
0b5a270045 | ||
|
70ade00801 | ||
|
7fc875af09 | ||
|
7e45341ccd | ||
|
d8bb0435c2 | ||
|
4eac7dd99c | ||
|
6ac6524beb | ||
|
3955b5a499 | ||
|
b7d0b5e0e4 | ||
|
1fb230f11f | ||
|
68930e61d8 | ||
|
0a26ce3acd | ||
|
abcf4a8756 | ||
|
caccb88a9b | ||
|
ff455062a1 | ||
|
0be90d66be | ||
|
dc614a04cb | ||
|
c509d9e3cc | ||
|
afe0226e67 | ||
|
1ada934819 | ||
|
4d3831d1d5 | ||
|
b8094eb9fa | ||
|
fa60f195a6 | ||
|
a769ed11de | ||
|
f87fb39108 | ||
|
c4f58178ec | ||
|
570e26b720 | ||
|
3b7078ac16 | ||
|
f4f6dd970e | ||
|
22deec81f5 | ||
|
50dff3a507 | ||
|
bc27a33d3e | ||
|
a61f2802cb | ||
|
b85046648b | ||
|
0c52805b3d | ||
|
d6db84b120 | ||
|
419541d5c8 | ||
|
26f1776094 | ||
|
be6a31c327 | ||
|
a8fc656db2 | ||
|
fa85a532a8 | ||
|
72c3aa5378 | ||
|
2b980348a6 | ||
|
3bba4eeb20 | ||
|
090ed4185c | ||
|
24256fc73b | ||
|
8047a7e2a5 | ||
|
c2d64e90b9 | ||
|
ddc0a0128a | ||
|
f18750b4ac | ||
|
c5c6a78474 | ||
|
4fad40d5b0 | ||
|
3d46978dee | ||
|
eae16fb03f | ||
|
7183ff3ef1 | ||
|
ba1aba4c00 | ||
|
0b85c03649 | ||
|
4d93ec6489 | ||
|
356740ac4f | ||
|
a3ad1cd62e | ||
|
a03acd0ff1 | ||
|
f9349fe462 | ||
|
540117e4a1 | ||
|
646d73300f | ||
|
472596186f | ||
|
de0762ad2c | ||
|
2597b5bc54 | ||
|
a9624311c0 | ||
|
262fd11359 | ||
|
d240142bb2 | ||
|
d73e244ed7 | ||
|
ebe10fbb90 | ||
|
af9d04d24b | ||
|
39e7c30ae4 | ||
|
d266f7f84c | ||
|
4f0dd10e5e | ||
|
a5f8b065a8 | ||
|
9f9edbeeb2 | ||
|
147c4f4703 | ||
|
dd5edd8f9f | ||
|
56d1b65e7f | ||
|
c919db4042 | ||
|
b6cfad04c0 | ||
|
24bdf3855f | ||
|
a9ef414655 | ||
|
2b97de1b2c | ||
|
a80e3dc432 | ||
|
de739160c1 | ||
|
698c3f313f | ||
|
ca6191d158 | ||
|
d2905d907a | ||
|
da9a4aa20a | ||
|
e7bf292343 | ||
|
099ad8186a | ||
|
aa10832801 | ||
|
504df28245 | ||
|
a072082626 | ||
|
6d3cb1b78d | ||
|
8ec5f81382 | ||
|
1312cf4768 | ||
|
474a12ebe8 | ||
|
8b8fe03f1e | ||
|
57994dfcda | ||
|
18cf5bffde | ||
|
d71b9ade1a | ||
|
e6ed0b6c42 | ||
|
e92a8c8f1b | ||
|
ea681c4638 | ||
|
010b0bd081 | ||
|
6a0f7e813c | ||
|
d9ea198fe4 | ||
|
7ebb259610 | ||
|
e1714b9631 | ||
|
e8c7f0f84f | ||
|
505a3fbc59 | ||
|
b4c7e18f55 | ||
|
66118dc3e0 | ||
|
79044b98e4 | ||
|
ae1c30e337 |
12
.gitignore
vendored
12
.gitignore
vendored
@@ -10,6 +10,17 @@ binutils/aa-status
|
|||||||
binutils/aa-status.8
|
binutils/aa-status.8
|
||||||
binutils/cJSON.o
|
binutils/cJSON.o
|
||||||
binutils/po/*.mo
|
binutils/po/*.mo
|
||||||
|
changehat/mod_apparmor/.libs
|
||||||
|
changehat/mod_apparmor/mod_apparmor.8
|
||||||
|
changehat/mod_apparmor/mod_apparmor.8.html
|
||||||
|
changehat/mod_apparmor/mod_apparmor.la
|
||||||
|
changehat/mod_apparmor/mod_apparmor.lo
|
||||||
|
changehat/mod_apparmor/mod_apparmor.slo
|
||||||
|
changehat/mod_apparmor/mod_apparmor.so
|
||||||
|
changehat/mod_apparmor/pod2htmd.tmp
|
||||||
|
changehat/pam_apparmor/get_options.o
|
||||||
|
changehat/pam_apparmor/pam_apparmor.o
|
||||||
|
changehat/pam_apparmor/pam_apparmor.so
|
||||||
parser/po/*.mo
|
parser/po/*.mo
|
||||||
parser/af_names.h
|
parser/af_names.h
|
||||||
parser/cap_names.h
|
parser/cap_names.h
|
||||||
@@ -196,7 +207,6 @@ libraries/libapparmor/testsuite/libaalogparse.test/Makefile
|
|||||||
libraries/libapparmor/testsuite/libaalogparse.test/Makefile.in
|
libraries/libapparmor/testsuite/libaalogparse.test/Makefile.in
|
||||||
libraries/libapparmor/testsuite/test_multi/out
|
libraries/libapparmor/testsuite/test_multi/out
|
||||||
libraries/libapparmor/testsuite/test_multi_multi-test_multi.o
|
libraries/libapparmor/testsuite/test_multi_multi-test_multi.o
|
||||||
changehat/mod_apparmor/.libs
|
|
||||||
utils/*.8
|
utils/*.8
|
||||||
utils/*.8.html
|
utils/*.8.html
|
||||||
utils/*.5
|
utils/*.5
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
image: ubuntu:latest
|
image: ubuntu:latest
|
||||||
before_script:
|
before_script:
|
||||||
- export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install --no-install-recommends -y build-essential apache2-dev autoconf automake bison dejagnu flex libpam-dev libtool perl liblocale-gettext-perl pkg-config python-all-dev python3-all-dev pyflakes3 ruby-dev swig lsb-release python3-notify2 python3-psutil python3-setuptools zlib1g-dev
|
- export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install --no-install-recommends -y build-essential apache2-dev autoconf autoconf-archive automake bison dejagnu flex libpam-dev libtool perl liblocale-gettext-perl pkg-config python3-all-dev pyflakes3 ruby-dev swig lsb-release python3-notify2 python3-psutil python3-setuptools zlib1g-dev
|
||||||
- lsb_release -a
|
- lsb_release -a
|
||||||
- uname -a
|
- uname -a
|
||||||
|
|
||||||
|
@@ -454,6 +454,7 @@ static int detailed_output(FILE *json) {
|
|||||||
const char *process_statuses[] = {"enforce", "complain", "unconfined", "mixed", "kill"};
|
const char *process_statuses[] = {"enforce", "complain", "unconfined", "mixed", "kill"};
|
||||||
int ret;
|
int ret;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
int need_finish = 0;
|
||||||
|
|
||||||
ret = get_profiles(&profiles, &nprofiles);
|
ret = get_profiles(&profiles, &nprofiles);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@@ -534,16 +535,20 @@ static int detailed_output(FILE *json) {
|
|||||||
} else {
|
} else {
|
||||||
fprintf(json, "%s\"%s\": [{\"profile\": \"%s\", \"pid\": \"%s\", \"status\": \"%s\"}",
|
fprintf(json, "%s\"%s\": [{\"profile\": \"%s\", \"pid\": \"%s\", \"status\": \"%s\"}",
|
||||||
// first element will be a unique executable
|
// first element will be a unique executable
|
||||||
i == 0 && j == 0 ? "" : "], ",
|
j == 0 && !need_finish ? "" : "], ",
|
||||||
filtered[j].exe, filtered[j].profile, filtered[j].pid, filtered[j].mode);
|
filtered[j].exe, filtered[j].profile, filtered[j].pid, filtered[j].mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
need_finish = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free_processes(filtered, nfiltered);
|
free_processes(filtered, nfiltered);
|
||||||
}
|
}
|
||||||
if (json) {
|
if (json) {
|
||||||
fprintf(json, "%s}}\n", nprocesses > 0 ? "]" : "");
|
if (need_finish > 0) {
|
||||||
|
fprintf(json, "]");
|
||||||
|
}
|
||||||
|
fprintf(json, "}}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@@ -1 +1 @@
|
|||||||
3.0.7
|
3.0.13
|
||||||
|
@@ -92,6 +92,13 @@ if test "$ac_cv_prog_cc_c99" = "no"; then
|
|||||||
AC_MSG_ERROR([C99 mode is required to build libapparmor])
|
AC_MSG_ERROR([C99 mode is required to build libapparmor])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
EXTRA_CFLAGS="-Wall $(EXTRA_WARNINGS) -fPIC"
|
||||||
|
AX_CHECK_COMPILE_FLAG([-flto-partition=none], , , [-Werror])
|
||||||
|
AS_VAR_IF([ax_cv_check_cflags__Werror__flto_partition_none], [yes],
|
||||||
|
[EXTRA_CFLAGS="$EXTRA_CFLAGS -flto-partition=none"]
|
||||||
|
,)
|
||||||
|
AC_SUBST([AM_CFLAGS], ["$EXTRA_CFLAGS"])
|
||||||
|
|
||||||
AC_OUTPUT(
|
AC_OUTPUT(
|
||||||
Makefile
|
Makefile
|
||||||
doc/Makefile
|
doc/Makefile
|
||||||
|
@@ -116,6 +116,14 @@ The specified I<file/task> does not exist or is not visible.
|
|||||||
|
|
||||||
The confinement data is too large to fit in the supplied buffer.
|
The confinement data is too large to fit in the supplied buffer.
|
||||||
|
|
||||||
|
=item B<ENOPROTOOPT>
|
||||||
|
|
||||||
|
The kernel doesn't support the SO_PEERLABEL option in sockets. This happens
|
||||||
|
mainly when the kernel lacks 'fine grained unix mediation' support. It also
|
||||||
|
can happen on LSM stacking kernels where another LSM has claimed this
|
||||||
|
interface and decides to return this error, although this is really a
|
||||||
|
corner case.
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head1 NOTES
|
=head1 NOTES
|
||||||
|
@@ -109,12 +109,12 @@ To immediately stack a profile named "profile_a", as performed with
|
|||||||
aa_stack_profile("profile_a"), the equivalent of this shell command can be
|
aa_stack_profile("profile_a"), the equivalent of this shell command can be
|
||||||
used:
|
used:
|
||||||
|
|
||||||
$ echo -n "stackprofile profile_a" > /proc/self/attr/current
|
$ echo -n "stack profile_a" > /proc/self/attr/current
|
||||||
|
|
||||||
To stack a profile named "profile_a" at the next exec, as performed with
|
To stack a profile named "profile_a" at the next exec, as performed with
|
||||||
aa_stack_onexec("profile_a"), the equivalent of this shell command can be used:
|
aa_stack_onexec("profile_a"), the equivalent of this shell command can be used:
|
||||||
|
|
||||||
$ echo -n "stackexec profile_a" > /proc/self/attr/exec
|
$ echo -n "stack profile_a" > /proc/self/attr/exec
|
||||||
|
|
||||||
These raw AppArmor filesystem operations must only be used when using
|
These raw AppArmor filesystem operations must only be used when using
|
||||||
libapparmor is not a viable option.
|
libapparmor is not a viable option.
|
||||||
@@ -184,6 +184,7 @@ with apparmor_parser(8):
|
|||||||
/etc/passwd r,
|
/etc/passwd r,
|
||||||
|
|
||||||
# Needed for aa_stack_profile()
|
# Needed for aa_stack_profile()
|
||||||
|
change-profile -> &i_cant_be_trusted_anymore,
|
||||||
/usr/lib/libapparmor*.so* mr,
|
/usr/lib/libapparmor*.so* mr,
|
||||||
/proc/[0-9]*/attr/current w,
|
/proc/[0-9]*/attr/current w,
|
||||||
}
|
}
|
||||||
|
@@ -159,6 +159,8 @@ typedef struct
|
|||||||
char *fs_type;
|
char *fs_type;
|
||||||
char *flags;
|
char *flags;
|
||||||
char *src_name;
|
char *src_name;
|
||||||
|
|
||||||
|
char *class;
|
||||||
} aa_log_record;
|
} aa_log_record;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -27,8 +27,9 @@ INCLUDES = $(all_includes)
|
|||||||
# http://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
|
# http://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
|
||||||
#
|
#
|
||||||
AA_LIB_CURRENT = 9
|
AA_LIB_CURRENT = 9
|
||||||
AA_LIB_REVISION = 3
|
AA_LIB_REVISION = 6
|
||||||
AA_LIB_AGE = 8
|
AA_LIB_AGE = 8
|
||||||
|
EXPECTED_SO_NAME = libapparmor.so.1.8.6
|
||||||
|
|
||||||
SUFFIXES = .pc.in .pc
|
SUFFIXES = .pc.in .pc
|
||||||
|
|
||||||
@@ -38,7 +39,6 @@ include $(COMMONDIR)/Make.rules
|
|||||||
BUILT_SOURCES = grammar.h scanner.h af_protos.h
|
BUILT_SOURCES = grammar.h scanner.h af_protos.h
|
||||||
AM_LFLAGS = -v
|
AM_LFLAGS = -v
|
||||||
AM_YFLAGS = -d -p aalogparse_
|
AM_YFLAGS = -d -p aalogparse_
|
||||||
AM_CFLAGS = -Wall $(EXTRA_WARNINGS) -fPIC -flto-partition=none
|
|
||||||
AM_CPPFLAGS = -D_GNU_SOURCE -I$(top_srcdir)/include/
|
AM_CPPFLAGS = -D_GNU_SOURCE -I$(top_srcdir)/include/
|
||||||
scanner.h: scanner.l
|
scanner.h: scanner.l
|
||||||
$(LEX) -v $<
|
$(LEX) -v $<
|
||||||
@@ -46,7 +46,7 @@ scanner.h: scanner.l
|
|||||||
scanner.c: scanner.l
|
scanner.c: scanner.l
|
||||||
|
|
||||||
af_protos.h:
|
af_protos.h:
|
||||||
echo '#include <netinet/in.h>' | $(CC) $(CPPFLAGS) -E -dM - | LC_ALL=C sed -n -e "/IPPROTO_MAX/d" -e "s/^\#define[ \\t]\\+IPPROTO_\\([A-Z0-9_]\\+\\)\\(.*\\)$$/AA_GEN_PROTO_ENT(\\UIPPROTO_\\1, \"\\L\\1\")/p" > $@
|
echo '#include <netinet/in.h>' | $(CC) $(CPPFLAGS) -E -dD - | LC_ALL=C sed -n -e "/IPPROTO_MAX/d" -e "s/^\#define[ \\t]\\+IPPROTO_\\([A-Z0-9_]\\+\\)\\(.*\\)$$/AA_GEN_PROTO_ENT(\\UIPPROTO_\\1, \"\\L\\1\")/p" > $@
|
||||||
|
|
||||||
lib_LTLIBRARIES = libapparmor.la
|
lib_LTLIBRARIES = libapparmor.la
|
||||||
noinst_HEADERS = grammar.h parser.h scanner.h af_protos.h private.h PMurHash.h
|
noinst_HEADERS = grammar.h parser.h scanner.h af_protos.h private.h PMurHash.h
|
||||||
@@ -77,4 +77,8 @@ tst_kernel_LDFLAGS = -pthread
|
|||||||
check_PROGRAMS = tst_aalogmisc tst_features tst_kernel
|
check_PROGRAMS = tst_aalogmisc tst_features tst_kernel
|
||||||
TESTS = $(check_PROGRAMS)
|
TESTS = $(check_PROGRAMS)
|
||||||
|
|
||||||
|
.PHONY: check-local
|
||||||
|
check-local:
|
||||||
|
test -f ./.libs/$(EXPECTED_SO_NAME) || { echo '*** unexpected .so name/number for libapparmor (expected $(EXPECTED_SO_NAME), the actual filename is shown below) ***' ; ls -l ./.libs/libapparmor.so.*.* ; exit 1; }
|
||||||
|
|
||||||
EXTRA_DIST = grammar.y scanner.l libapparmor.map libapparmor.pc
|
EXTRA_DIST = grammar.y scanner.l libapparmor.map libapparmor.pc
|
||||||
|
@@ -398,6 +398,10 @@ static bool walk_one(const char **str, const struct component *component,
|
|||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
cur++;
|
cur++;
|
||||||
|
|
||||||
|
/* Partial match, continue to search */
|
||||||
|
if (i == component->len && !isbrace_space_or_nul(*cur))
|
||||||
|
i = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return false if a full match was not found */
|
/* Return false if a full match was not found */
|
||||||
|
@@ -159,7 +159,9 @@ aa_record_event_type lookup_aa_event(unsigned int type)
|
|||||||
%token TOK_KEY_NAMESPACE
|
%token TOK_KEY_NAMESPACE
|
||||||
%token TOK_KEY_ERROR
|
%token TOK_KEY_ERROR
|
||||||
%token TOK_KEY_FSUID
|
%token TOK_KEY_FSUID
|
||||||
|
%token TOK_KEY_FSUID_UPPER
|
||||||
%token TOK_KEY_OUID
|
%token TOK_KEY_OUID
|
||||||
|
%token TOK_KEY_OUID_UPPER
|
||||||
%token TOK_KEY_UID
|
%token TOK_KEY_UID
|
||||||
%token TOK_KEY_AUID
|
%token TOK_KEY_AUID
|
||||||
%token TOK_KEY_SAUID
|
%token TOK_KEY_SAUID
|
||||||
@@ -185,6 +187,7 @@ aa_record_event_type lookup_aa_event(unsigned int type)
|
|||||||
%token TOK_KEY_FSTYPE
|
%token TOK_KEY_FSTYPE
|
||||||
%token TOK_KEY_FLAGS
|
%token TOK_KEY_FLAGS
|
||||||
%token TOK_KEY_SRCNAME
|
%token TOK_KEY_SRCNAME
|
||||||
|
%token TOK_KEY_CLASS
|
||||||
|
|
||||||
%token TOK_SOCKLOGD_KERNEL
|
%token TOK_SOCKLOGD_KERNEL
|
||||||
%token TOK_SYSLOG_KERNEL
|
%token TOK_SYSLOG_KERNEL
|
||||||
@@ -351,6 +354,10 @@ key: TOK_KEY_OPERATION TOK_EQUALS TOK_QUOTED_STRING
|
|||||||
{ ret_record->fsuid = $3;}
|
{ ret_record->fsuid = $3;}
|
||||||
| TOK_KEY_OUID TOK_EQUALS TOK_DIGITS
|
| TOK_KEY_OUID TOK_EQUALS TOK_DIGITS
|
||||||
{ ret_record->ouid = $3;}
|
{ ret_record->ouid = $3;}
|
||||||
|
| TOK_KEY_FSUID_UPPER TOK_EQUALS TOK_QUOTED_STRING
|
||||||
|
{ free($3);} /* Ignore - fsuid username */
|
||||||
|
| TOK_KEY_OUID_UPPER TOK_EQUALS TOK_QUOTED_STRING
|
||||||
|
{ free($3);} /* Ignore - ouid username */
|
||||||
| TOK_KEY_SAUID TOK_EQUALS TOK_DIGITS
|
| TOK_KEY_SAUID TOK_EQUALS TOK_DIGITS
|
||||||
{ /* Ignore - Source audit ID from user AVC messages */ }
|
{ /* Ignore - Source audit ID from user AVC messages */ }
|
||||||
| TOK_KEY_HOSTNAME TOK_EQUALS safe_string
|
| TOK_KEY_HOSTNAME TOK_EQUALS safe_string
|
||||||
@@ -425,6 +432,8 @@ key: TOK_KEY_OPERATION TOK_EQUALS TOK_QUOTED_STRING
|
|||||||
ret_record->event = AA_RECORD_INVALID;
|
ret_record->event = AA_RECORD_INVALID;
|
||||||
ret_record->info = $1;
|
ret_record->info = $1;
|
||||||
}
|
}
|
||||||
|
| TOK_KEY_CLASS TOK_EQUALS TOK_QUOTED_STRING
|
||||||
|
{ ret_record->class = $3; }
|
||||||
;
|
;
|
||||||
|
|
||||||
apparmor_event:
|
apparmor_event:
|
||||||
|
@@ -103,6 +103,8 @@ void free_record(aa_log_record *record)
|
|||||||
free(record->flags);
|
free(record->flags);
|
||||||
if (record->src_name != NULL)
|
if (record->src_name != NULL)
|
||||||
free(record->src_name);
|
free(record->src_name);
|
||||||
|
if (record->class != NULL)
|
||||||
|
free(record->class);
|
||||||
|
|
||||||
free(record);
|
free(record);
|
||||||
}
|
}
|
||||||
|
@@ -72,7 +72,7 @@ void string_buf_append(unsigned int length, char *text)
|
|||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
ws [ \t\r\n]
|
ws [ \t\r\n\x1d]
|
||||||
|
|
||||||
equals "="
|
equals "="
|
||||||
digit [[:digit:]]
|
digit [[:digit:]]
|
||||||
@@ -121,6 +121,8 @@ key_namespace "namespace"
|
|||||||
key_mask "mask"
|
key_mask "mask"
|
||||||
key_denied_mask "denied_mask"
|
key_denied_mask "denied_mask"
|
||||||
key_requested_mask "requested_mask"
|
key_requested_mask "requested_mask"
|
||||||
|
key_denied "denied"
|
||||||
|
key_requested "requested"
|
||||||
key_attribute "attribute"
|
key_attribute "attribute"
|
||||||
key_task "task"
|
key_task "task"
|
||||||
key_parent "parent"
|
key_parent "parent"
|
||||||
@@ -138,7 +140,9 @@ key_sock_type "sock_type"
|
|||||||
key_protocol "protocol"
|
key_protocol "protocol"
|
||||||
key_error "error"
|
key_error "error"
|
||||||
key_fsuid "fsuid"
|
key_fsuid "fsuid"
|
||||||
|
key_fsuid_upper "FSUID"
|
||||||
key_ouid "ouid"
|
key_ouid "ouid"
|
||||||
|
key_ouid_upper "OUID"
|
||||||
key_uid "uid"
|
key_uid "uid"
|
||||||
key_auid "auid"
|
key_auid "auid"
|
||||||
key_sauid "sauid"
|
key_sauid "sauid"
|
||||||
@@ -161,11 +165,13 @@ key_dest "dest"
|
|||||||
key_path "path"
|
key_path "path"
|
||||||
key_interface "interface"
|
key_interface "interface"
|
||||||
key_member "member"
|
key_member "member"
|
||||||
|
key_method "method"
|
||||||
key_signal "signal"
|
key_signal "signal"
|
||||||
key_peer "peer"
|
key_peer "peer"
|
||||||
key_fstype "fstype"
|
key_fstype "fstype"
|
||||||
key_flags "flags"
|
key_flags "flags"
|
||||||
key_srcname "srcname"
|
key_srcname "srcname"
|
||||||
|
key_class "class"
|
||||||
audit "audit"
|
audit "audit"
|
||||||
|
|
||||||
/* network addrs */
|
/* network addrs */
|
||||||
@@ -307,6 +313,8 @@ yy_flex_debug = 0;
|
|||||||
{key_mask} { return(TOK_KEY_MASK); }
|
{key_mask} { return(TOK_KEY_MASK); }
|
||||||
{key_denied_mask} { return(TOK_KEY_DENIED_MASK); }
|
{key_denied_mask} { return(TOK_KEY_DENIED_MASK); }
|
||||||
{key_requested_mask} { return(TOK_KEY_REQUESTED_MASK); }
|
{key_requested_mask} { return(TOK_KEY_REQUESTED_MASK); }
|
||||||
|
{key_denied} { return(TOK_KEY_DENIED_MASK); }
|
||||||
|
{key_requested} { return(TOK_KEY_REQUESTED_MASK); }
|
||||||
{key_attribute} { BEGIN(sub_id); return(TOK_KEY_ATTRIBUTE); }
|
{key_attribute} { BEGIN(sub_id); return(TOK_KEY_ATTRIBUTE); }
|
||||||
{key_task} { return(TOK_KEY_TASK); }
|
{key_task} { return(TOK_KEY_TASK); }
|
||||||
{key_parent} { return(TOK_KEY_PARENT); }
|
{key_parent} { return(TOK_KEY_PARENT); }
|
||||||
@@ -324,7 +332,9 @@ yy_flex_debug = 0;
|
|||||||
{key_protocol} { return(TOK_KEY_PROTOCOL); }
|
{key_protocol} { return(TOK_KEY_PROTOCOL); }
|
||||||
{key_error} { return(TOK_KEY_ERROR); }
|
{key_error} { return(TOK_KEY_ERROR); }
|
||||||
{key_fsuid} { return(TOK_KEY_FSUID); }
|
{key_fsuid} { return(TOK_KEY_FSUID); }
|
||||||
|
{key_fsuid_upper} { return(TOK_KEY_FSUID_UPPER); }
|
||||||
{key_ouid} { return(TOK_KEY_OUID); }
|
{key_ouid} { return(TOK_KEY_OUID); }
|
||||||
|
{key_ouid_upper} { return(TOK_KEY_OUID_UPPER); }
|
||||||
{key_uid} { return(TOK_KEY_UID); }
|
{key_uid} { return(TOK_KEY_UID); }
|
||||||
{key_auid} { return(TOK_KEY_AUID); }
|
{key_auid} { return(TOK_KEY_AUID); }
|
||||||
{key_sauid} { return(TOK_KEY_SAUID); }
|
{key_sauid} { return(TOK_KEY_SAUID); }
|
||||||
@@ -346,11 +356,13 @@ yy_flex_debug = 0;
|
|||||||
{key_path} { return(TOK_KEY_PATH); }
|
{key_path} { return(TOK_KEY_PATH); }
|
||||||
{key_interface} { return(TOK_KEY_INTERFACE); }
|
{key_interface} { return(TOK_KEY_INTERFACE); }
|
||||||
{key_member} { return(TOK_KEY_MEMBER); }
|
{key_member} { return(TOK_KEY_MEMBER); }
|
||||||
|
{key_method} { return(TOK_KEY_MEMBER); }
|
||||||
{key_signal} { BEGIN(sub_id); return(TOK_KEY_SIGNAL); }
|
{key_signal} { BEGIN(sub_id); return(TOK_KEY_SIGNAL); }
|
||||||
{key_peer} { BEGIN(safe_string); return(TOK_KEY_PEER); }
|
{key_peer} { BEGIN(safe_string); return(TOK_KEY_PEER); }
|
||||||
{key_fstype} { return(TOK_KEY_FSTYPE); }
|
{key_fstype} { return(TOK_KEY_FSTYPE); }
|
||||||
{key_flags} { BEGIN(safe_string); return(TOK_KEY_FLAGS); }
|
{key_flags} { BEGIN(safe_string); return(TOK_KEY_FLAGS); }
|
||||||
{key_srcname} { BEGIN(safe_string); return(TOK_KEY_SRCNAME); }
|
{key_srcname} { BEGIN(safe_string); return(TOK_KEY_SRCNAME); }
|
||||||
|
{key_class} { BEGIN(safe_string); return(TOK_KEY_CLASS); }
|
||||||
|
|
||||||
{socklogd_kernel} { BEGIN(dmesg_timestamp); return(TOK_SOCKLOGD_KERNEL); }
|
{socklogd_kernel} { BEGIN(dmesg_timestamp); return(TOK_SOCKLOGD_KERNEL); }
|
||||||
{syslog_kernel} { BEGIN(dmesg_timestamp); return(TOK_SYSLOG_KERNEL); }
|
{syslog_kernel} { BEGIN(dmesg_timestamp); return(TOK_SYSLOG_KERNEL); }
|
||||||
|
@@ -135,7 +135,7 @@ static int do_test_walk_one(const char **str, const struct component *component,
|
|||||||
|
|
||||||
static int test_walk_one(void)
|
static int test_walk_one(void)
|
||||||
{
|
{
|
||||||
struct component c;
|
struct component c = (struct component) { NULL, 0 };
|
||||||
const char *str;
|
const char *str;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
@@ -55,7 +55,7 @@ extern int aa_getprocattr_raw(pid_t tid, const char *attr, char *buf, int len,
|
|||||||
extern int aa_getprocattr(pid_t tid, const char *attr, char **buf, char **mode);
|
extern int aa_getprocattr(pid_t tid, const char *attr, char **buf, char **mode);
|
||||||
extern int aa_gettaskcon(pid_t target, char **label, char **mode);
|
extern int aa_gettaskcon(pid_t target, char **label, char **mode);
|
||||||
extern int aa_getcon(char **label, char **mode);
|
extern int aa_getcon(char **label, char **mode);
|
||||||
extern int aa_getpeercon_raw(int fd, char *buf, int *len, char **mode);
|
extern int aa_getpeercon_raw(int fd, char *buf, socklen_t *len, char **mode);
|
||||||
extern int aa_getpeercon(int fd, char **label, char **mode);
|
extern int aa_getpeercon(int fd, char **label, char **mode);
|
||||||
extern int aa_query_label(uint32_t mask, char *query, size_t size, int *allow,
|
extern int aa_query_label(uint32_t mask, char *query, size_t size, int *allow,
|
||||||
int *audit);
|
int *audit);
|
||||||
|
@@ -34,6 +34,7 @@ OUTPUT_MAP = {
|
|||||||
'Local port': 'net_local_port',
|
'Local port': 'net_local_port',
|
||||||
'Foreign port': 'net_foreign_port',
|
'Foreign port': 'net_foreign_port',
|
||||||
'Audit subid': 'audit_sub_id',
|
'Audit subid': 'audit_sub_id',
|
||||||
|
'Class': '_class',
|
||||||
}
|
}
|
||||||
|
|
||||||
# FIXME: pull this automatically out of LibAppArmor, but swig
|
# FIXME: pull this automatically out of LibAppArmor, but swig
|
||||||
@@ -108,7 +109,7 @@ class AAPythonBindingsTests(unittest.TestCase):
|
|||||||
'''parse the swig created record and construct a dict from it'''
|
'''parse the swig created record and construct a dict from it'''
|
||||||
|
|
||||||
new_record = dict()
|
new_record = dict()
|
||||||
for key in [x for x in dir(record) if not (x.startswith('_') or x == 'this')]:
|
for key in [x for x in dir(record) if not (x.startswith('__') or x == 'this')]:
|
||||||
value = getattr(record, key)
|
value = getattr(record, key)
|
||||||
if key == "event" and value in EVENT_MAP:
|
if key == "event" and value in EVENT_MAP:
|
||||||
new_record[key] = EVENT_MAP[value]
|
new_record[key] = EVENT_MAP[value]
|
||||||
|
@@ -134,6 +134,8 @@ int print_results(aa_log_record *record)
|
|||||||
print_string("Flags", record->flags);
|
print_string("Flags", record->flags);
|
||||||
print_string("Src name", record->src_name);
|
print_string("Src name", record->src_name);
|
||||||
|
|
||||||
|
print_string("Class", record->class);
|
||||||
|
|
||||||
print_long("Epoch", record->epoch, 0);
|
print_long("Epoch", record->epoch, 0);
|
||||||
print_long("Audit subid", (long) record->audit_sub_id, 0);
|
print_long("Audit subid", (long) record->audit_sub_id, 0);
|
||||||
return(0);
|
return(0);
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
type=AVC msg=audit(1661734785.992:270): apparmor="ALLOWED" operation="open" profile="/usr/bin/dolphin" name="/home/otis/.config/kdedefaults/kdeglobals" pid=3483 comm="dolphin" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0FSUID="otis" OUID="root"
|
@@ -0,0 +1,15 @@
|
|||||||
|
START
|
||||||
|
File: 0x1d-uppercase-FSUID-OUID.in
|
||||||
|
Event type: AA_RECORD_ALLOWED
|
||||||
|
Audit ID: 1661734785.992:270
|
||||||
|
Operation: open
|
||||||
|
Mask: r
|
||||||
|
Denied Mask: r
|
||||||
|
fsuid: 1000
|
||||||
|
ouid: 0
|
||||||
|
Profile: /usr/bin/dolphin
|
||||||
|
Name: /home/otis/.config/kdedefaults/kdeglobals
|
||||||
|
Command: dolphin
|
||||||
|
PID: 3483
|
||||||
|
Epoch: 1661734785
|
||||||
|
Audit subid: 270
|
@@ -0,0 +1,4 @@
|
|||||||
|
/usr/bin/dolphin {
|
||||||
|
/home/otis/.config/kdedefaults/kdeglobals r,
|
||||||
|
|
||||||
|
}
|
1
libraries/libapparmor/testsuite/test_multi/file_xm.in
Normal file
1
libraries/libapparmor/testsuite/test_multi/file_xm.in
Normal file
@@ -0,0 +1 @@
|
|||||||
|
type=AVC msg=audit(1676978994.840:1493): apparmor="DENIED" operation="link" profile="cargo" name="/var/tmp/portage/dev-lang/rust-1.67.1/work/rustc-1.67.1-src/build/bootstrap/debug/libbootstrap.rlib" pid=12412 comm="cargo" requested_mask="xm" denied_mask="xm" fsuid=250 ouid=250 target="/var/tmp/portage/dev-lang/rust-1.67.1/work/rustc-1.67.1-src/build/bootstrap/debug/deps/libbootstrap-4542dd99e796257e.rlib"FSUID="portage" OUID="portage"
|
16
libraries/libapparmor/testsuite/test_multi/file_xm.out
Normal file
16
libraries/libapparmor/testsuite/test_multi/file_xm.out
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
START
|
||||||
|
File: file_xm.in
|
||||||
|
Event type: AA_RECORD_DENIED
|
||||||
|
Audit ID: 1676978994.840:1493
|
||||||
|
Operation: link
|
||||||
|
Mask: xm
|
||||||
|
Denied Mask: xm
|
||||||
|
fsuid: 250
|
||||||
|
ouid: 250
|
||||||
|
Profile: cargo
|
||||||
|
Name: /var/tmp/portage/dev-lang/rust-1.67.1/work/rustc-1.67.1-src/build/bootstrap/debug/libbootstrap.rlib
|
||||||
|
Command: cargo
|
||||||
|
Name2: /var/tmp/portage/dev-lang/rust-1.67.1/work/rustc-1.67.1-src/build/bootstrap/debug/deps/libbootstrap-4542dd99e796257e.rlib
|
||||||
|
PID: 12412
|
||||||
|
Epoch: 1676978994
|
||||||
|
Audit subid: 1493
|
@@ -0,0 +1,4 @@
|
|||||||
|
profile cargo {
|
||||||
|
owner /var/tmp/portage/dev-lang/rust-1.67.1/work/rustc-1.67.1-src/build/bootstrap/debug/libbootstrap.rlib m,
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1 @@
|
|||||||
|
Dec 15 17:32:17 kinetic kernel: [4835959.046111] audit: type=1107 audit(1671125537.724:209): pid=7308 uid=0 auid=4294967295 ses=4294967295 msg='apparmor="DENIED" operation="dbus_method_call" bus="session" path="/org/freedesktop/DBus" interface="org.freedesktop.DBus" method="Hello" mask="send" label="/tmp/apparmor/tests/regression/apparmor/dbus_message" peer_label="unconfined" exe="/usr/local/bin/dbus-broker" sauid=0 hostname=? addr=? terminal=?'
|
@@ -0,0 +1,15 @@
|
|||||||
|
START
|
||||||
|
File: testcase_dbus_11.in
|
||||||
|
Event type: AA_RECORD_DENIED
|
||||||
|
Audit ID: 1671125537.724:209
|
||||||
|
Operation: dbus_method_call
|
||||||
|
Denied Mask: send
|
||||||
|
Profile: /tmp/apparmor/tests/regression/apparmor/dbus_message
|
||||||
|
Peer profile: unconfined
|
||||||
|
Command: /usr/local/bin/dbus-broker
|
||||||
|
DBus bus: session
|
||||||
|
DBus path: /org/freedesktop/DBus
|
||||||
|
DBus interface: org.freedesktop.DBus
|
||||||
|
DBus member: Hello
|
||||||
|
Epoch: 1671125537
|
||||||
|
Audit subid: 209
|
@@ -0,0 +1,4 @@
|
|||||||
|
/tmp/apparmor/tests/regression/apparmor/dbus_message {
|
||||||
|
dbus send bus=session path=/org/freedesktop/DBus interface=org.freedesktop.DBus member=Hello peer=(label=unconfined),
|
||||||
|
|
||||||
|
}
|
@@ -70,7 +70,10 @@ CFLAGS = -g -pg -fprofile-arcs -ftest-coverage
|
|||||||
endif
|
endif
|
||||||
endif #CFLAGS
|
endif #CFLAGS
|
||||||
|
|
||||||
CFLAGS += -flto-partition=none
|
HAVE_FLTO_PARTITION_NONE:=$(shell ${CC} -E -flto-partition=none /dev/null 1>/dev/null 2>&1 && echo true)
|
||||||
|
ifeq ($(HAVE_FLTO_PARTITION_NONE),true)
|
||||||
|
CFLAGS += -flto-partition=none
|
||||||
|
endif
|
||||||
|
|
||||||
EXTRA_CXXFLAGS = ${CFLAGS} ${CPPFLAGS} ${CXX_WARNINGS} -std=gnu++0x
|
EXTRA_CXXFLAGS = ${CFLAGS} ${CPPFLAGS} ${CXX_WARNINGS} -std=gnu++0x
|
||||||
EXTRA_CFLAGS = ${EXTRA_CXXFLAGS} ${CPP_WARNINGS}
|
EXTRA_CFLAGS = ${EXTRA_CXXFLAGS} ${CPP_WARNINGS}
|
||||||
@@ -386,11 +389,11 @@ DISTRO=$(shell if [ -f /etc/slackware-version ] ; then \
|
|||||||
elif [ -f /etc/debian_version ] ; then \
|
elif [ -f /etc/debian_version ] ; then \
|
||||||
echo debian ;\
|
echo debian ;\
|
||||||
elif which rpm > /dev/null ; then \
|
elif which rpm > /dev/null ; then \
|
||||||
if [ "$(rpm --eval '0%{?suse_version}')" != "0" ] ; then \
|
if [ "$$(rpm --eval '0%{?suse_version}')" != "0" ] ; then \
|
||||||
echo suse ;\
|
echo suse ;\
|
||||||
elif [ "$(rpm --eval '%{_host_vendor}')" = redhat ] ; then \
|
elif [ "$$(rpm --eval '%{_host_vendor}')" = redhat ] ; then \
|
||||||
echo rhel4 ;\
|
echo rhel4 ;\
|
||||||
elif [ "$(rpm --eval '0%{?fedora}')" != "0" ] ; then \
|
elif [ "$$(rpm --eval '0%{?fedora}')" != "0" ] ; then \
|
||||||
echo rhel4 ;\
|
echo rhel4 ;\
|
||||||
else \
|
else \
|
||||||
echo unknown ;\
|
echo unknown ;\
|
||||||
|
@@ -111,8 +111,7 @@ unix_rule::unix_rule(unsigned int type_p, bool audit_p, bool denied):
|
|||||||
|
|
||||||
unix_rule::unix_rule(int mode_p, struct cond_entry *conds,
|
unix_rule::unix_rule(int mode_p, struct cond_entry *conds,
|
||||||
struct cond_entry *peer_conds):
|
struct cond_entry *peer_conds):
|
||||||
af_rule("unix"), addr(NULL), peer_addr(NULL),
|
af_rule("unix"), addr(NULL), peer_addr(NULL)
|
||||||
audit(0), deny(0)
|
|
||||||
{
|
{
|
||||||
move_conditionals(conds);
|
move_conditionals(conds);
|
||||||
move_peer_conditionals(peer_conds);
|
move_peer_conditionals(peer_conds);
|
||||||
@@ -136,7 +135,7 @@ ostream &unix_rule::dump_local(ostream &os)
|
|||||||
{
|
{
|
||||||
af_rule::dump_local(os);
|
af_rule::dump_local(os);
|
||||||
if (addr)
|
if (addr)
|
||||||
os << "addr='" << addr << "'";
|
os << " addr='" << addr << "'";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +143,7 @@ ostream &unix_rule::dump_peer(ostream &os)
|
|||||||
{
|
{
|
||||||
af_rule::dump_peer(os);
|
af_rule::dump_peer(os);
|
||||||
if (peer_addr)
|
if (peer_addr)
|
||||||
os << "addr='" << peer_addr << "'";
|
os << " addr='" << peer_addr << "'";
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,9 +36,6 @@ class unix_rule: public af_rule {
|
|||||||
public:
|
public:
|
||||||
char *addr;
|
char *addr;
|
||||||
char *peer_addr;
|
char *peer_addr;
|
||||||
int mode;
|
|
||||||
int audit;
|
|
||||||
bool deny;
|
|
||||||
|
|
||||||
unix_rule(unsigned int type_p, bool audit_p, bool denied);
|
unix_rule(unsigned int type_p, bool audit_p, bool denied);
|
||||||
unix_rule(int mode, struct cond_entry *conds,
|
unix_rule(int mode, struct cond_entry *conds,
|
||||||
|
@@ -172,7 +172,7 @@ B<MOUNT FLAGS EXPRESSION> = ( I<MOUNT FLAGS LIST> | I<MOUNT EXPRESSION> )
|
|||||||
|
|
||||||
B<MOUNT FLAGS LIST> = Comma separated list of I<MOUNT FLAGS>.
|
B<MOUNT FLAGS LIST> = Comma separated list of I<MOUNT FLAGS>.
|
||||||
|
|
||||||
B<MOUNT FLAGS> = ( 'ro' | 'rw' | 'nosuid' | 'suid' | 'nodev' | 'dev' | 'noexec' | 'exec' | 'sync' | 'async' | 'remount' | 'mand' | 'nomand' | 'dirsync' | 'noatime' | 'atime' | 'nodiratime' | 'diratime' | 'bind' | 'rbind' | 'move' | 'verbose' | 'silent' | 'loud' | 'acl' | 'noacl' | 'unbindable' | 'runbindable' | 'private' | 'rprivate' | 'slave' | 'rslave' | 'shared' | 'rshared' | 'relatime' | 'norelatime' | 'iversion' | 'noiversion' | 'strictatime' | 'nouser' | 'user' )
|
B<MOUNT FLAGS> = ( 'ro' | 'rw' | 'nosuid' | 'suid' | 'nodev' | 'dev' | 'noexec' | 'exec' | 'sync' | 'async' | 'remount' | 'mand' | 'nomand' | 'dirsync' | 'noatime' | 'atime' | 'nodiratime' | 'diratime' | 'bind' | 'rbind' | 'move' | 'verbose' | 'silent' | 'loud' | 'acl' | 'noacl' | 'unbindable' | 'runbindable' | 'private' | 'rprivate' | 'slave' | 'rslave' | 'shared' | 'rshared' | 'relatime' | 'norelatime' | 'iversion' | 'noiversion' | 'strictatime' | 'nostrictatime' | 'lazytime' | 'nolazytime' | 'nouser' | 'user' | 'symfollow' | 'nosymfollow' )
|
||||||
|
|
||||||
B<MOUNT EXPRESSION> = ( I<ALPHANUMERIC> | I<AARE> ) ...
|
B<MOUNT EXPRESSION> = ( I<ALPHANUMERIC> | I<AARE> ) ...
|
||||||
|
|
||||||
@@ -1786,7 +1786,7 @@ An example AppArmor profile:
|
|||||||
/usr/lib/** r,
|
/usr/lib/** r,
|
||||||
/tmp/foo.pid wr,
|
/tmp/foo.pid wr,
|
||||||
/tmp/foo.* lrw,
|
/tmp/foo.* lrw,
|
||||||
/@{HOME}/.foo_file rw,
|
@{HOME}/.foo_file rw,
|
||||||
/usr/bin/baz Cx -> baz,
|
/usr/bin/baz Cx -> baz,
|
||||||
|
|
||||||
# a comment about foo's hat (subprofile), bar.
|
# a comment about foo's hat (subprofile), bar.
|
||||||
|
@@ -299,11 +299,11 @@ Enable various warnings during policy compilation. A single warn flag
|
|||||||
can be specified per --warn option, but the --warn flag can be passed
|
can be specified per --warn option, but the --warn flag can be passed
|
||||||
multiple times.
|
multiple times.
|
||||||
|
|
||||||
apparmor_parser --warn=rules-not-enforced ...
|
apparmor_parser --warn=rule-not-enforced ...
|
||||||
|
|
||||||
A specific warning can be disabled by prepending I<no>- to the flag
|
A specific warning can be disabled by prepending I<no>- to the flag
|
||||||
|
|
||||||
apparmor_parser --warn=no-rules-not-enforced ...
|
apparmor_parser --warn=no-rule-not-enforced ...
|
||||||
|
|
||||||
Use --help=warn to see a full list of which warn flags are supported.
|
Use --help=warn to see a full list of which warn flags are supported.
|
||||||
|
|
||||||
|
@@ -193,9 +193,8 @@ void CHFA::insert_state(vector<pair<size_t, size_t> > &free_list,
|
|||||||
State *default_state = dfa.nonmatching;
|
State *default_state = dfa.nonmatching;
|
||||||
ssize_t base = 0;
|
ssize_t base = 0;
|
||||||
int resize;
|
int resize;
|
||||||
|
|
||||||
StateTrans &trans = from->trans;
|
StateTrans &trans = from->trans;
|
||||||
ssize_t c = trans.begin()->first.c;
|
ssize_t c;
|
||||||
ssize_t prev = 0;
|
ssize_t prev = 0;
|
||||||
ssize_t x = first_free;
|
ssize_t x = first_free;
|
||||||
|
|
||||||
@@ -204,6 +203,7 @@ void CHFA::insert_state(vector<pair<size_t, size_t> > &free_list,
|
|||||||
if (trans.empty())
|
if (trans.empty())
|
||||||
goto do_insert;
|
goto do_insert;
|
||||||
|
|
||||||
|
c = trans.begin()->first.c;
|
||||||
repeat:
|
repeat:
|
||||||
resize = 0;
|
resize = 0;
|
||||||
/* get the first free entry that won't underflow */
|
/* get the first free entry that won't underflow */
|
||||||
@@ -251,10 +251,18 @@ repeat:
|
|||||||
first_free = next;
|
first_free = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_insert:
|
/* these flags will only be set on states that have transitions */
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
base |= MATCH_FLAG_OOB_TRANSITION;
|
base |= MATCH_FLAG_OOB_TRANSITION;
|
||||||
}
|
}
|
||||||
|
do_insert:
|
||||||
|
/* While a state without transitions could have the diff encode
|
||||||
|
* flag set, it would be pointless resulting in just an extra
|
||||||
|
* state transition in the encoding chain, and so it should be
|
||||||
|
* considered an error
|
||||||
|
* TODO: add check that state without transitions isn't being
|
||||||
|
* given a diffencode flag
|
||||||
|
*/
|
||||||
if (from->flags & DiffEncodeFlag)
|
if (from->flags & DiffEncodeFlag)
|
||||||
base |= DiffEncodeBit32;
|
base |= DiffEncodeBit32;
|
||||||
default_base.push_back(make_pair(default_state, base));
|
default_base.push_back(make_pair(default_state, base));
|
||||||
|
@@ -189,6 +189,19 @@ void Node::dump_syntax_tree(ostream &os)
|
|||||||
* a b c T
|
* a b c T
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static Node *simplify_eps_pair(Node *t)
|
||||||
|
{
|
||||||
|
if (dynamic_cast<TwoChildNode *>(t) &&
|
||||||
|
t->child[0] == &epsnode &&
|
||||||
|
t->child[1] == &epsnode) {
|
||||||
|
t->release();
|
||||||
|
return &epsnode;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
static void rotate_node(Node *t, int dir)
|
static void rotate_node(Node *t, int dir)
|
||||||
{
|
{
|
||||||
// (a | b) | c -> a | (b | c)
|
// (a | b) | c -> a | (b | c)
|
||||||
@@ -197,7 +210,9 @@ static void rotate_node(Node *t, int dir)
|
|||||||
t->child[dir] = left->child[dir];
|
t->child[dir] = left->child[dir];
|
||||||
left->child[dir] = left->child[!dir];
|
left->child[dir] = left->child[!dir];
|
||||||
left->child[!dir] = t->child[!dir];
|
left->child[!dir] = t->child[!dir];
|
||||||
t->child[!dir] = left;
|
|
||||||
|
// check that rotation didn't create (E | E)
|
||||||
|
t->child[!dir] = simplify_eps_pair(left);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return False if no work done */
|
/* return False if no work done */
|
||||||
@@ -209,13 +224,7 @@ int TwoChildNode::normalize_eps(int dir)
|
|||||||
// Ea -> aE
|
// Ea -> aE
|
||||||
// Test for E | (E | E) and E . (E . E) which will
|
// Test for E | (E | E) and E . (E . E) which will
|
||||||
// result in an infinite loop
|
// result in an infinite loop
|
||||||
Node *c = child[!dir];
|
Node *c = simplify_eps_pair(child[!dir]);
|
||||||
if (dynamic_cast<TwoChildNode *>(c) &&
|
|
||||||
&epsnode == c->child[dir] &&
|
|
||||||
&epsnode == c->child[!dir]) {
|
|
||||||
c->release();
|
|
||||||
c = &epsnode;
|
|
||||||
}
|
|
||||||
child[!dir] = child[dir];
|
child[!dir] = child[dir];
|
||||||
child[dir] = c;
|
child[dir] = c;
|
||||||
return 1;
|
return 1;
|
||||||
|
733
parser/mount.cc
733
parser/mount.cc
@@ -98,6 +98,9 @@
|
|||||||
* nomand
|
* nomand
|
||||||
* #define MS_DIRSYNC 128 Directory modifications are synchronous
|
* #define MS_DIRSYNC 128 Directory modifications are synchronous
|
||||||
* dirsync
|
* dirsync
|
||||||
|
* #define MS_NOSYMFOLLOW 256 Do not follow symlinks
|
||||||
|
* symfollow
|
||||||
|
* nosymfollow
|
||||||
* #define MS_NOATIME 1024 Do not update access times
|
* #define MS_NOATIME 1024 Do not update access times
|
||||||
* noatime
|
* noatime
|
||||||
* atime
|
* atime
|
||||||
@@ -139,6 +142,9 @@
|
|||||||
* #define MS_STRICTATIME (1<<24) Always perform atime updates
|
* #define MS_STRICTATIME (1<<24) Always perform atime updates
|
||||||
* strictatime
|
* strictatime
|
||||||
* nostrictatime
|
* nostrictatime
|
||||||
|
* #define MS_LAZYTIME (1<<25) Update the on-disk [acm]times lazily
|
||||||
|
* lazytime
|
||||||
|
* nolazytime
|
||||||
* #define MS_NOSEC (1<<28)
|
* #define MS_NOSEC (1<<28)
|
||||||
* #define MS_BORN (1<<29)
|
* #define MS_BORN (1<<29)
|
||||||
* #define MS_ACTIVE (1<<30)
|
* #define MS_ACTIVE (1<<30)
|
||||||
@@ -246,6 +252,8 @@ static struct mnt_keyword_table mnt_opts_table[] = {
|
|||||||
{"mand", MS_MAND, 0},
|
{"mand", MS_MAND, 0},
|
||||||
{"nomand", 0, MS_MAND},
|
{"nomand", 0, MS_MAND},
|
||||||
{"dirsync", MS_DIRSYNC, 0},
|
{"dirsync", MS_DIRSYNC, 0},
|
||||||
|
{"symfollow", 0, MS_NOSYMFOLLOW},
|
||||||
|
{"nosymfollow", MS_NOSYMFOLLOW, 0},
|
||||||
{"atime", 0, MS_NOATIME},
|
{"atime", 0, MS_NOATIME},
|
||||||
{"noatime", MS_NOATIME, 0},
|
{"noatime", MS_NOATIME, 0},
|
||||||
{"diratime", 0, MS_NODIRATIME},
|
{"diratime", 0, MS_NODIRATIME},
|
||||||
@@ -283,6 +291,9 @@ static struct mnt_keyword_table mnt_opts_table[] = {
|
|||||||
{"iversion", MS_IVERSION, 0},
|
{"iversion", MS_IVERSION, 0},
|
||||||
{"noiversion", 0, MS_IVERSION},
|
{"noiversion", 0, MS_IVERSION},
|
||||||
{"strictatime", MS_STRICTATIME, 0},
|
{"strictatime", MS_STRICTATIME, 0},
|
||||||
|
{"nostrictatime", 0, MS_STRICTATIME},
|
||||||
|
{"lazytime", MS_LAZYTIME, 0},
|
||||||
|
{"nolazytime", 0, MS_LAZYTIME},
|
||||||
{"user", 0, (unsigned int) MS_NOUSER},
|
{"user", 0, (unsigned int) MS_NOUSER},
|
||||||
{"nouser", (unsigned int) MS_NOUSER, 0},
|
{"nouser", (unsigned int) MS_NOUSER, 0},
|
||||||
|
|
||||||
@@ -298,6 +309,22 @@ static struct mnt_keyword_table mnt_conds_table[] = {
|
|||||||
{NULL, 0, 0}
|
{NULL, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static ostream &dump_flags(ostream &os,
|
||||||
|
pair <unsigned int, unsigned int> flags)
|
||||||
|
{
|
||||||
|
for (int i = 0; mnt_opts_table[i].keyword; i++) {
|
||||||
|
if ((flags.first & mnt_opts_table[i].set) ||
|
||||||
|
(flags.second & mnt_opts_table[i].clear))
|
||||||
|
os << mnt_opts_table[i].keyword;
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
ostream &operator<<(ostream &os, pair<unsigned int, unsigned int> flags)
|
||||||
|
{
|
||||||
|
return dump_flags(os, flags);
|
||||||
|
}
|
||||||
|
|
||||||
static int find_mnt_keyword(struct mnt_keyword_table *table, const char *name)
|
static int find_mnt_keyword(struct mnt_keyword_table *table, const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -320,7 +347,7 @@ int is_valid_mnt_cond(const char *name, int src)
|
|||||||
|
|
||||||
static unsigned int extract_flags(struct value_list **list, unsigned int *inv)
|
static unsigned int extract_flags(struct value_list **list, unsigned int *inv)
|
||||||
{
|
{
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0, invflags = 0;
|
||||||
*inv = 0;
|
*inv = 0;
|
||||||
|
|
||||||
struct value_list *entry, *tmp, *prev = NULL;
|
struct value_list *entry, *tmp, *prev = NULL;
|
||||||
@@ -329,11 +356,11 @@ static unsigned int extract_flags(struct value_list **list, unsigned int *inv)
|
|||||||
i = find_mnt_keyword(mnt_opts_table, entry->value);
|
i = find_mnt_keyword(mnt_opts_table, entry->value);
|
||||||
if (i != -1) {
|
if (i != -1) {
|
||||||
flags |= mnt_opts_table[i].set;
|
flags |= mnt_opts_table[i].set;
|
||||||
*inv |= mnt_opts_table[i].clear;
|
invflags |= mnt_opts_table[i].clear;
|
||||||
PDEBUG(" extracting mount flag %s req: 0x%x inv: 0x%x"
|
PDEBUG(" extracting mount flag %s req: 0x%x inv: 0x%x"
|
||||||
" => req: 0x%x inv: 0x%x\n",
|
" => req: 0x%x inv: 0x%x\n",
|
||||||
entry->value, mnt_opts_table[i].set,
|
entry->value, mnt_opts_table[i].set,
|
||||||
mnt_opts_table[i].clear, flags, *inv);
|
mnt_opts_table[i].clear, flags, invflags);
|
||||||
if (prev)
|
if (prev)
|
||||||
prev->next = tmp;
|
prev->next = tmp;
|
||||||
if (entry == *list)
|
if (entry == *list)
|
||||||
@@ -344,9 +371,27 @@ static unsigned int extract_flags(struct value_list **list, unsigned int *inv)
|
|||||||
prev = entry;
|
prev = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inv)
|
||||||
|
*inv = invflags;
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool conflicting_flags(unsigned int flags, unsigned int inv)
|
||||||
|
{
|
||||||
|
if (flags & inv) {
|
||||||
|
for (int i = 0; i < 31; i++) {
|
||||||
|
unsigned int mask = 1 << i;
|
||||||
|
if ((flags & inv) & mask) {
|
||||||
|
cerr << "conflicting flag values = "
|
||||||
|
<< flags << ", " << inv << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static struct value_list *extract_fstype(struct cond_entry **conds)
|
static struct value_list *extract_fstype(struct cond_entry **conds)
|
||||||
{
|
{
|
||||||
struct value_list *list = NULL;
|
struct value_list *list = NULL;
|
||||||
@@ -369,22 +414,19 @@ static struct value_list *extract_fstype(struct cond_entry **conds)
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct value_list *extract_options(struct cond_entry **conds, int eq)
|
static struct cond_entry *extract_options(struct cond_entry **conds, int eq)
|
||||||
{
|
{
|
||||||
struct value_list *list = NULL;
|
struct cond_entry *list = NULL, *entry, *tmp, *prev = NULL;
|
||||||
|
|
||||||
struct cond_entry *entry, *tmp, *prev = NULL;
|
|
||||||
|
|
||||||
list_for_each_safe(*conds, entry, tmp) {
|
list_for_each_safe(*conds, entry, tmp) {
|
||||||
if ((strcmp(entry->name, "options") == 0 ||
|
if ((strcmp(entry->name, "options") == 0 ||
|
||||||
strcmp(entry->name, "option") == 0) &&
|
strcmp(entry->name, "option") == 0) &&
|
||||||
entry->eq == eq) {
|
entry->eq == eq) {
|
||||||
list_remove_at(*conds, prev, entry);
|
list_remove_at(*conds, prev, entry);
|
||||||
PDEBUG(" extracting option %s\n", entry->name);
|
PDEBUG(" extracting %s %s\n", entry->name, entry->eq ?
|
||||||
list_append(entry->vals, list);
|
"=" : "in");
|
||||||
list = entry->vals;
|
list_append(entry, list);
|
||||||
entry->vals = NULL;
|
list = entry;
|
||||||
free_cond_entry(entry);
|
|
||||||
} else
|
} else
|
||||||
prev = entry;
|
prev = entry;
|
||||||
}
|
}
|
||||||
@@ -392,60 +434,129 @@ static struct value_list *extract_options(struct cond_entry **conds, int eq)
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void perror_conds(const char *rule, struct cond_entry *conds)
|
||||||
|
{
|
||||||
|
struct cond_entry *entry;
|
||||||
|
|
||||||
|
list_for_each(conds, entry) {
|
||||||
|
PERROR( "unsupported %s condition '%s%s(...)'\n", rule, entry->name, entry->eq ? "=" : " in ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void perror_vals(const char *rule, struct value_list *vals)
|
||||||
|
{
|
||||||
|
struct value_list *entry;
|
||||||
|
|
||||||
|
list_for_each(vals, entry) {
|
||||||
|
PERROR( "unsupported %s value '%s'\n", rule, entry->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void process_one_option(struct cond_entry *&opts, unsigned int &flags,
|
||||||
|
unsigned int &inv_flags)
|
||||||
|
{
|
||||||
|
struct cond_entry *entry;
|
||||||
|
struct value_list *vals;
|
||||||
|
|
||||||
|
entry = list_pop(opts);
|
||||||
|
vals = entry->vals;
|
||||||
|
entry->vals = NULL;
|
||||||
|
/* fail if there are any unknown optional flags */
|
||||||
|
if (opts) {
|
||||||
|
PERROR(" unsupported multiple 'mount options %s(...)'\n", entry->eq ? "=" : " in ");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
free_cond_entry(entry);
|
||||||
|
|
||||||
|
flags = extract_flags(&vals, &inv_flags);
|
||||||
|
if (vals) {
|
||||||
|
perror_vals("mount option", vals);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p,
|
mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p,
|
||||||
struct cond_entry *dst_conds unused, char *mnt_point_p,
|
struct cond_entry *dst_conds unused, char *mnt_point_p,
|
||||||
int allow_p):
|
int allow_p):
|
||||||
mnt_point(mnt_point_p), device(device_p), trans(NULL), opts(NULL),
|
mnt_point(mnt_point_p), device(device_p), trans(NULL), opts(NULL),
|
||||||
flags(0), inv_flags(0), audit(0), deny(0)
|
flagsv(0), opt_flagsv(0), audit(0), deny(0)
|
||||||
{
|
{
|
||||||
/* FIXME: dst_conds are ignored atm */
|
/* FIXME: dst_conds are ignored atm */
|
||||||
dev_type = extract_fstype(&src_conds);
|
dev_type = extract_fstype(&src_conds);
|
||||||
|
|
||||||
if (src_conds) {
|
if (src_conds) {
|
||||||
struct value_list *list = extract_options(&src_conds, 0);
|
/* move options in () to local list */
|
||||||
|
struct cond_entry *opts_in = extract_options(&src_conds, 0);
|
||||||
|
|
||||||
opts = extract_options(&src_conds, 1);
|
if (opts_in) {
|
||||||
if (opts)
|
unsigned int tmpflags = 0, tmpinv_flags = 0;
|
||||||
flags = extract_flags(&opts, &inv_flags);
|
struct cond_entry *entry;
|
||||||
|
|
||||||
if (list) {
|
while ((entry = list_pop(opts_in))) {
|
||||||
unsigned int tmpflags, tmpinv_flags = 0;
|
process_one_option(entry, tmpflags,
|
||||||
|
tmpinv_flags);
|
||||||
tmpflags = extract_flags(&list, &tmpinv_flags);
|
/* optional flags if set/clear mean the same
|
||||||
/* these flags are optional so set both */
|
* thing and can be represented by a single
|
||||||
tmpflags |= tmpinv_flags;
|
* bitset, also there is no need to check for
|
||||||
tmpinv_flags |= tmpflags;
|
* conflicting flags when they are optional
|
||||||
|
*/
|
||||||
flags |= tmpflags;
|
opt_flagsv.push_back(tmpflags | tmpinv_flags);
|
||||||
inv_flags |= tmpinv_flags;
|
}
|
||||||
|
|
||||||
if (opts)
|
|
||||||
list_append(opts, list);
|
|
||||||
else if (list)
|
|
||||||
opts = list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* move options=() to opts list */
|
||||||
|
struct cond_entry *opts_eq = extract_options(&src_conds, 1);
|
||||||
|
if (opts_eq) {
|
||||||
|
unsigned int tmpflags = 0, tmpinv_flags = 0;
|
||||||
|
struct cond_entry *entry;
|
||||||
|
|
||||||
|
while ((entry = list_pop(opts_eq))) {
|
||||||
|
process_one_option(entry, tmpflags,
|
||||||
|
tmpinv_flags);
|
||||||
|
/* throw away tmpinv_flags, only needed in
|
||||||
|
* consistancy check
|
||||||
|
*/
|
||||||
|
if (allow_p & AA_DUMMY_REMOUNT)
|
||||||
|
tmpflags |= MS_REMOUNT;
|
||||||
|
|
||||||
|
if (conflicting_flags(tmpflags, tmpinv_flags)) {
|
||||||
|
PERROR("conflicting flags in the rule\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
flagsv.push_back(tmpflags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src_conds) {
|
||||||
|
perror_conds("mount", src_conds);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(flagsv.size() + opt_flagsv.size())) {
|
||||||
|
/* no flag options, and not remount, allow everything */
|
||||||
|
if (allow_p & AA_DUMMY_REMOUNT) {
|
||||||
|
flagsv.push_back(MS_REMOUNT);
|
||||||
|
opt_flagsv.push_back(MS_REMOUNT_FLAGS & ~MS_REMOUNT);
|
||||||
|
} else {
|
||||||
|
flagsv.push_back(MS_ALL_FLAGS);
|
||||||
|
opt_flagsv.push_back(MS_ALL_FLAGS);
|
||||||
|
}
|
||||||
|
} else if (!(flagsv.size())) {
|
||||||
|
/* no flags but opts set */
|
||||||
|
if (allow_p & AA_DUMMY_REMOUNT)
|
||||||
|
flagsv.push_back(MS_REMOUNT);
|
||||||
|
else
|
||||||
|
flagsv.push_back(0);
|
||||||
|
} else if (!(opt_flagsv.size())) {
|
||||||
|
opt_flagsv.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allow_p & AA_DUMMY_REMOUNT) {
|
if (allow_p & AA_DUMMY_REMOUNT) {
|
||||||
allow_p = AA_MAY_MOUNT;
|
allow_p = AA_MAY_MOUNT;
|
||||||
flags |= MS_REMOUNT;
|
|
||||||
inv_flags = 0;
|
|
||||||
} else if (!(flags | inv_flags)) {
|
|
||||||
/* no flag options, and not remount, allow everything */
|
|
||||||
flags = MS_ALL_FLAGS;
|
|
||||||
inv_flags = MS_ALL_FLAGS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
allow = allow_p;
|
allow = allow_p;
|
||||||
|
|
||||||
if (src_conds) {
|
|
||||||
PERROR(" unsupported mount conditions\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (opts) {
|
|
||||||
PERROR(" unsupported mount options\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream &mnt_rule::dump(ostream &os)
|
ostream &mnt_rule::dump(ostream &os)
|
||||||
@@ -459,7 +570,11 @@ ostream &mnt_rule::dump(ostream &os)
|
|||||||
else
|
else
|
||||||
os << "error: unknonwn mount perm";
|
os << "error: unknonwn mount perm";
|
||||||
|
|
||||||
os << " (0x" << hex << flags << " - 0x" << inv_flags << ") ";
|
for (unsigned int i = 0; i < flagsv.size(); i++)
|
||||||
|
os << " flags=(0x" << hex << flagsv[i] << ")";
|
||||||
|
for (unsigned int i = 0; i < opt_flagsv.size(); i++)
|
||||||
|
os << " flags in (0x" << hex << opt_flagsv[i] << ")";
|
||||||
|
|
||||||
if (dev_type) {
|
if (dev_type) {
|
||||||
os << " type=";
|
os << " type=";
|
||||||
print_value_list(dev_type);
|
print_value_list(dev_type);
|
||||||
@@ -515,7 +630,7 @@ int mnt_rule::expand_variables(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int build_mnt_flags(char *buffer, int size, unsigned int flags,
|
static int build_mnt_flags(char *buffer, int size, unsigned int flags,
|
||||||
unsigned int inv_flags)
|
unsigned int opt_flags)
|
||||||
{
|
{
|
||||||
char *p = buffer;
|
char *p = buffer;
|
||||||
int i, len = 0;
|
int i, len = 0;
|
||||||
@@ -528,7 +643,7 @@ static int build_mnt_flags(char *buffer, int size, unsigned int flags,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
for (i = 0; i <= 31; ++i) {
|
for (i = 0; i <= 31; ++i) {
|
||||||
if ((flags & inv_flags) & (1 << i))
|
if ((opt_flags) & (1 << i))
|
||||||
len = snprintf(p, size, "(\\x%02x|)", i + 1);
|
len = snprintf(p, size, "(\\x%02x|)", i + 1);
|
||||||
else if (flags & (1 << i))
|
else if (flags & (1 << i))
|
||||||
len = snprintf(p, size, "\\x%02x", i + 1);
|
len = snprintf(p, size, "\\x%02x", i + 1);
|
||||||
@@ -583,7 +698,9 @@ void mnt_rule::warn_once(const char *name)
|
|||||||
rule_t::warn_once(name, "mount rules not enforce");
|
rule_t::warn_once(name, "mount rules not enforce");
|
||||||
}
|
}
|
||||||
|
|
||||||
int mnt_rule::gen_policy_re(Profile &prof)
|
|
||||||
|
int mnt_rule::gen_policy_remount(Profile &prof, int &count,
|
||||||
|
unsigned int flags, unsigned int opt_flags)
|
||||||
{
|
{
|
||||||
std::string mntbuf;
|
std::string mntbuf;
|
||||||
std::string devbuf;
|
std::string devbuf;
|
||||||
@@ -592,8 +709,320 @@ int mnt_rule::gen_policy_re(Profile &prof)
|
|||||||
std::string optsbuf;
|
std::string optsbuf;
|
||||||
char class_mount_hdr[64];
|
char class_mount_hdr[64];
|
||||||
const char *vec[5];
|
const char *vec[5];
|
||||||
|
int tmpallow;
|
||||||
|
|
||||||
|
sprintf(class_mount_hdr, "\\x%02x", AA_CLASS_MOUNT);
|
||||||
|
|
||||||
|
/* remount can't be conditional on device and type */
|
||||||
|
/* rule class single byte header */
|
||||||
|
mntbuf.assign(class_mount_hdr);
|
||||||
|
if (mnt_point) {
|
||||||
|
/* both device && mnt_point or just mnt_point */
|
||||||
|
if (!convert_entry(mntbuf, mnt_point))
|
||||||
|
goto fail;
|
||||||
|
vec[0] = mntbuf.c_str();
|
||||||
|
} else {
|
||||||
|
if (!convert_entry(mntbuf, device))
|
||||||
|
goto fail;
|
||||||
|
vec[0] = mntbuf.c_str();
|
||||||
|
}
|
||||||
|
/* skip device */
|
||||||
|
vec[1] = default_match_pattern;
|
||||||
|
/* skip type */
|
||||||
|
vec[2] = default_match_pattern;
|
||||||
|
|
||||||
|
if (!build_mnt_flags(flagsbuf, PATH_MAX, flags & MS_REMOUNT_FLAGS,
|
||||||
|
opt_flags & MS_REMOUNT_FLAGS))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
vec[3] = flagsbuf;
|
||||||
|
|
||||||
|
if (opts)
|
||||||
|
tmpallow = AA_MATCH_CONT;
|
||||||
|
else
|
||||||
|
tmpallow = allow;
|
||||||
|
|
||||||
|
/* rule for match without required data || data MATCH_CONT */
|
||||||
|
if (!prof.policy.rules->add_rule_vec(deny, tmpallow,
|
||||||
|
audit | AA_AUDIT_MNT_DATA, 4,
|
||||||
|
vec, dfaflags, false))
|
||||||
|
goto fail;
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (opts) {
|
||||||
|
/* rule with data match required */
|
||||||
|
optsbuf.clear();
|
||||||
|
if (!build_mnt_opts(optsbuf, opts))
|
||||||
|
goto fail;
|
||||||
|
vec[4] = optsbuf.c_str();
|
||||||
|
if (!prof.policy.rules->add_rule_vec(deny, allow,
|
||||||
|
audit | AA_AUDIT_MNT_DATA,
|
||||||
|
5, vec, dfaflags, false))
|
||||||
|
goto fail;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RULE_OK;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return RULE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mnt_rule::gen_policy_bind_mount(Profile &prof, int &count,
|
||||||
|
unsigned int flags, unsigned int opt_flags)
|
||||||
|
{
|
||||||
|
std::string mntbuf;
|
||||||
|
std::string devbuf;
|
||||||
|
std::string typebuf;
|
||||||
|
char flagsbuf[PATH_MAX + 3];
|
||||||
|
std::string optsbuf;
|
||||||
|
char class_mount_hdr[64];
|
||||||
|
const char *vec[5];
|
||||||
|
|
||||||
|
sprintf(class_mount_hdr, "\\x%02x", AA_CLASS_MOUNT);
|
||||||
|
|
||||||
|
/* bind mount rules can't be conditional on dev_type or data */
|
||||||
|
/* rule class single byte header */
|
||||||
|
mntbuf.assign(class_mount_hdr);
|
||||||
|
if (!convert_entry(mntbuf, mnt_point))
|
||||||
|
goto fail;
|
||||||
|
vec[0] = mntbuf.c_str();
|
||||||
|
if (!clear_and_convert_entry(devbuf, device))
|
||||||
|
goto fail;
|
||||||
|
vec[1] = devbuf.c_str();
|
||||||
|
/* skip type */
|
||||||
|
vec[2] = default_match_pattern;
|
||||||
|
|
||||||
|
if (!build_mnt_flags(flagsbuf, PATH_MAX, flags & MS_BIND_FLAGS,
|
||||||
|
opt_flags & MS_BIND_FLAGS))
|
||||||
|
goto fail;
|
||||||
|
vec[3] = flagsbuf;
|
||||||
|
if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec,
|
||||||
|
dfaflags, false))
|
||||||
|
goto fail;
|
||||||
|
count++;
|
||||||
|
|
||||||
|
return RULE_OK;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return RULE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mnt_rule::gen_policy_change_mount_type(Profile &prof, int &count,
|
||||||
|
unsigned int flags,
|
||||||
|
unsigned int opt_flags)
|
||||||
|
{
|
||||||
|
std::string mntbuf;
|
||||||
|
std::string devbuf;
|
||||||
|
std::string typebuf;
|
||||||
|
char flagsbuf[PATH_MAX + 3];
|
||||||
|
std::string optsbuf;
|
||||||
|
char class_mount_hdr[64];
|
||||||
|
const char *vec[5];
|
||||||
|
char *mountpoint = mnt_point;
|
||||||
|
|
||||||
|
sprintf(class_mount_hdr, "\\x%02x", AA_CLASS_MOUNT);
|
||||||
|
|
||||||
|
/* change type base rules can specify the mount point by using
|
||||||
|
* the parser token position reserved to device. that's why if
|
||||||
|
* the mount point is not specified, we use device in its
|
||||||
|
* place. this is a deprecated behavior.
|
||||||
|
*
|
||||||
|
* change type base rules can not be conditional on device
|
||||||
|
* (source), device type or data
|
||||||
|
*/
|
||||||
|
/* rule class single byte header */
|
||||||
|
mntbuf.assign(class_mount_hdr);
|
||||||
|
if (flags && flags != MS_ALL_FLAGS && device && mnt_point) {
|
||||||
|
PERROR("source and mount point cannot be used at the "
|
||||||
|
"same time for propagation type flags");
|
||||||
|
goto fail;
|
||||||
|
} else if (device && !mnt_point) {
|
||||||
|
mountpoint = device;
|
||||||
|
}
|
||||||
|
if (!convert_entry(mntbuf, mountpoint))
|
||||||
|
goto fail;
|
||||||
|
vec[0] = mntbuf.c_str();
|
||||||
|
/* skip device and type */
|
||||||
|
vec[1] = default_match_pattern;
|
||||||
|
vec[2] = default_match_pattern;
|
||||||
|
|
||||||
|
if (!build_mnt_flags(flagsbuf, PATH_MAX, flags & MS_MAKE_FLAGS,
|
||||||
|
opt_flags & MS_MAKE_FLAGS))
|
||||||
|
goto fail;
|
||||||
|
vec[3] = flagsbuf;
|
||||||
|
if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec,
|
||||||
|
dfaflags, false))
|
||||||
|
goto fail;
|
||||||
|
count++;
|
||||||
|
|
||||||
|
return RULE_OK;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return RULE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mnt_rule::gen_policy_move_mount(Profile &prof, int &count,
|
||||||
|
unsigned int flags, unsigned int opt_flags)
|
||||||
|
{
|
||||||
|
std::string mntbuf;
|
||||||
|
std::string devbuf;
|
||||||
|
std::string typebuf;
|
||||||
|
char flagsbuf[PATH_MAX + 3];
|
||||||
|
std::string optsbuf;
|
||||||
|
char class_mount_hdr[64];
|
||||||
|
const char *vec[5];
|
||||||
|
|
||||||
|
sprintf(class_mount_hdr, "\\x%02x", AA_CLASS_MOUNT);
|
||||||
|
|
||||||
|
/* mount move rules can not be conditional on dev_type,
|
||||||
|
* or data
|
||||||
|
*/
|
||||||
|
/* rule class single byte header */
|
||||||
|
mntbuf.assign(class_mount_hdr);
|
||||||
|
if (!convert_entry(mntbuf, mnt_point))
|
||||||
|
goto fail;
|
||||||
|
vec[0] = mntbuf.c_str();
|
||||||
|
if (!clear_and_convert_entry(devbuf, device))
|
||||||
|
goto fail;
|
||||||
|
vec[1] = devbuf.c_str();
|
||||||
|
/* skip type */
|
||||||
|
vec[2] = default_match_pattern;
|
||||||
|
|
||||||
|
if (!build_mnt_flags(flagsbuf, PATH_MAX, flags & MS_MOVE_FLAGS,
|
||||||
|
opt_flags & MS_MOVE_FLAGS))
|
||||||
|
goto fail;
|
||||||
|
vec[3] = flagsbuf;
|
||||||
|
if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec,
|
||||||
|
dfaflags, false))
|
||||||
|
goto fail;
|
||||||
|
count++;
|
||||||
|
|
||||||
|
return RULE_OK;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return RULE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mnt_rule::gen_policy_new_mount(Profile &prof, int &count,
|
||||||
|
unsigned int flags, unsigned int opt_flags)
|
||||||
|
{
|
||||||
|
std::string mntbuf;
|
||||||
|
std::string devbuf;
|
||||||
|
std::string typebuf;
|
||||||
|
char flagsbuf[PATH_MAX + 3];
|
||||||
|
std::string optsbuf;
|
||||||
|
char class_mount_hdr[64];
|
||||||
|
const char *vec[5];
|
||||||
|
int tmpallow;
|
||||||
|
|
||||||
|
sprintf(class_mount_hdr, "\\x%02x", AA_CLASS_MOUNT);
|
||||||
|
|
||||||
|
/* rule class single byte header */
|
||||||
|
mntbuf.assign(class_mount_hdr);
|
||||||
|
if (!convert_entry(mntbuf, mnt_point))
|
||||||
|
goto fail;
|
||||||
|
vec[0] = mntbuf.c_str();
|
||||||
|
if (!clear_and_convert_entry(devbuf, device))
|
||||||
|
goto fail;
|
||||||
|
vec[1] = devbuf.c_str();
|
||||||
|
typebuf.clear();
|
||||||
|
if (!build_list_val_expr(typebuf, dev_type))
|
||||||
|
goto fail;
|
||||||
|
vec[2] = typebuf.c_str();
|
||||||
|
|
||||||
|
if (!build_mnt_flags(flagsbuf, PATH_MAX, flags & MS_NEW_FLAGS,
|
||||||
|
opt_flags & MS_NEW_FLAGS))
|
||||||
|
goto fail;
|
||||||
|
vec[3] = flagsbuf;
|
||||||
|
|
||||||
|
if (opts)
|
||||||
|
tmpallow = AA_MATCH_CONT;
|
||||||
|
else
|
||||||
|
tmpallow = allow;
|
||||||
|
|
||||||
|
/* rule for match without required data || data MATCH_CONT */
|
||||||
|
if (!prof.policy.rules->add_rule_vec(deny, tmpallow,
|
||||||
|
audit | AA_AUDIT_MNT_DATA, 4,
|
||||||
|
vec, dfaflags, false))
|
||||||
|
goto fail;
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (opts) {
|
||||||
|
/* rule with data match required */
|
||||||
|
optsbuf.clear();
|
||||||
|
if (!build_mnt_opts(optsbuf, opts))
|
||||||
|
goto fail;
|
||||||
|
vec[4] = optsbuf.c_str();
|
||||||
|
if (!prof.policy.rules->add_rule_vec(deny, allow,
|
||||||
|
audit | AA_AUDIT_MNT_DATA,
|
||||||
|
5, vec, dfaflags, false))
|
||||||
|
goto fail;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RULE_OK;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return RULE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mnt_rule::gen_flag_rules(Profile &prof, int &count, unsigned int flags,
|
||||||
|
unsigned int opt_flags)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* XXX: added !flags to cover cases like:
|
||||||
|
* mount options in (bind) /d -> /4,
|
||||||
|
*/
|
||||||
|
if ((allow & AA_MAY_MOUNT) && (!flags || flags == MS_ALL_FLAGS)) {
|
||||||
|
/* no mount flags specified, generate multiple rules */
|
||||||
|
if (!device && !dev_type &&
|
||||||
|
gen_policy_remount(prof, count, flags, opt_flags) == RULE_ERROR)
|
||||||
|
return RULE_ERROR;
|
||||||
|
if (!dev_type && !opts &&
|
||||||
|
gen_policy_bind_mount(prof, count, flags, opt_flags) == RULE_ERROR)
|
||||||
|
return RULE_ERROR;
|
||||||
|
if ((!device || !mnt_point) && !dev_type && !opts &&
|
||||||
|
gen_policy_change_mount_type(prof, count, flags, opt_flags) == RULE_ERROR)
|
||||||
|
return RULE_ERROR;
|
||||||
|
if (!dev_type && !opts &&
|
||||||
|
gen_policy_move_mount(prof, count, flags, opt_flags) == RULE_ERROR)
|
||||||
|
return RULE_ERROR;
|
||||||
|
|
||||||
|
return gen_policy_new_mount(prof, count, flags, opt_flags);
|
||||||
|
} else if ((allow & AA_MAY_MOUNT) && (flags & MS_REMOUNT)
|
||||||
|
&& !device && !dev_type) {
|
||||||
|
return gen_policy_remount(prof, count, flags, opt_flags);
|
||||||
|
} else if ((allow & AA_MAY_MOUNT) && (flags & MS_BIND)
|
||||||
|
&& !dev_type && !opts) {
|
||||||
|
return gen_policy_bind_mount(prof, count, flags, opt_flags);
|
||||||
|
} else if ((allow & AA_MAY_MOUNT) &&
|
||||||
|
(flags & (MS_MAKE_CMDS))
|
||||||
|
&& (!device || !mnt_point) && !dev_type && !opts) {
|
||||||
|
return gen_policy_change_mount_type(prof, count, flags, opt_flags);
|
||||||
|
} else if ((allow & AA_MAY_MOUNT) && (flags & MS_MOVE)
|
||||||
|
&& !dev_type && !opts) {
|
||||||
|
return gen_policy_move_mount(prof, count, flags, opt_flags);
|
||||||
|
} else if ((allow & AA_MAY_MOUNT) &&
|
||||||
|
((flags | opt_flags) & ~MS_CMDS)) {
|
||||||
|
/* generic mount if flags are set that are not covered by
|
||||||
|
* above commands
|
||||||
|
*/
|
||||||
|
return gen_policy_new_mount(prof, count, flags, opt_flags);
|
||||||
|
} /* else must be RULE_OK for some rules */
|
||||||
|
|
||||||
|
return RULE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mnt_rule::gen_policy_re(Profile &prof)
|
||||||
|
{
|
||||||
|
std::string mntbuf;
|
||||||
|
std::string devbuf;
|
||||||
|
std::string typebuf;
|
||||||
|
std::string optsbuf;
|
||||||
|
char class_mount_hdr[64];
|
||||||
|
const char *vec[5];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
unsigned int tmpflags, tmpinv_flags;
|
|
||||||
|
|
||||||
if (!features_supports_mount) {
|
if (!features_supports_mount) {
|
||||||
warn_once(prof.name);
|
warn_once(prof.name);
|
||||||
@@ -605,202 +1034,10 @@ int mnt_rule::gen_policy_re(Profile &prof)
|
|||||||
/* a single mount rule may result in multiple matching rules being
|
/* a single mount rule may result in multiple matching rules being
|
||||||
* created in the backend to cover all the possible choices
|
* created in the backend to cover all the possible choices
|
||||||
*/
|
*/
|
||||||
|
for (size_t i = 0; i < flagsv.size(); i++) {
|
||||||
if ((allow & AA_MAY_MOUNT) && (flags & MS_REMOUNT)
|
for (size_t j = 0; j < opt_flagsv.size(); j++) {
|
||||||
&& !device && !dev_type) {
|
if (gen_flag_rules(prof, count, flagsv[i], opt_flagsv[j]) == RULE_ERROR)
|
||||||
int tmpallow;
|
|
||||||
/* remount can't be conditional on device and type */
|
|
||||||
/* rule class single byte header */
|
|
||||||
mntbuf.assign(class_mount_hdr);
|
|
||||||
if (mnt_point) {
|
|
||||||
/* both device && mnt_point or just mnt_point */
|
|
||||||
if (!convert_entry(mntbuf, mnt_point))
|
|
||||||
goto fail;
|
goto fail;
|
||||||
vec[0] = mntbuf.c_str();
|
|
||||||
} else {
|
|
||||||
if (!convert_entry(mntbuf, device))
|
|
||||||
goto fail;
|
|
||||||
vec[0] = mntbuf.c_str();
|
|
||||||
}
|
|
||||||
/* skip device */
|
|
||||||
vec[1] = default_match_pattern;
|
|
||||||
/* skip type */
|
|
||||||
vec[2] = default_match_pattern;
|
|
||||||
|
|
||||||
tmpflags = flags;
|
|
||||||
tmpinv_flags = inv_flags;
|
|
||||||
if (tmpflags != MS_ALL_FLAGS)
|
|
||||||
tmpflags &= MS_REMOUNT_FLAGS;
|
|
||||||
if (tmpinv_flags != MS_ALL_FLAGS)
|
|
||||||
tmpflags &= MS_REMOUNT_FLAGS;
|
|
||||||
if (!build_mnt_flags(flagsbuf, PATH_MAX, tmpflags, tmpinv_flags))
|
|
||||||
goto fail;
|
|
||||||
vec[3] = flagsbuf;
|
|
||||||
|
|
||||||
if (opts)
|
|
||||||
tmpallow = AA_MATCH_CONT;
|
|
||||||
else
|
|
||||||
tmpallow = allow;
|
|
||||||
|
|
||||||
/* rule for match without required data || data MATCH_CONT */
|
|
||||||
if (!prof.policy.rules->add_rule_vec(deny, tmpallow,
|
|
||||||
audit | AA_AUDIT_MNT_DATA, 4,
|
|
||||||
vec, dfaflags, false))
|
|
||||||
goto fail;
|
|
||||||
count++;
|
|
||||||
|
|
||||||
if (opts) {
|
|
||||||
/* rule with data match required */
|
|
||||||
optsbuf.clear();
|
|
||||||
if (!build_mnt_opts(optsbuf, opts))
|
|
||||||
goto fail;
|
|
||||||
vec[4] = optsbuf.c_str();
|
|
||||||
if (!prof.policy.rules->add_rule_vec(deny, allow,
|
|
||||||
audit | AA_AUDIT_MNT_DATA,
|
|
||||||
5, vec, dfaflags, false))
|
|
||||||
goto fail;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((allow & AA_MAY_MOUNT) && (flags & MS_BIND)
|
|
||||||
&& !dev_type && !opts) {
|
|
||||||
/* bind mount rules can't be conditional on dev_type or data */
|
|
||||||
/* rule class single byte header */
|
|
||||||
mntbuf.assign(class_mount_hdr);
|
|
||||||
if (!convert_entry(mntbuf, mnt_point))
|
|
||||||
goto fail;
|
|
||||||
vec[0] = mntbuf.c_str();
|
|
||||||
if (!clear_and_convert_entry(devbuf, device))
|
|
||||||
goto fail;
|
|
||||||
vec[1] = devbuf.c_str();
|
|
||||||
/* skip type */
|
|
||||||
vec[2] = default_match_pattern;
|
|
||||||
|
|
||||||
tmpflags = flags;
|
|
||||||
tmpinv_flags = inv_flags;
|
|
||||||
if (tmpflags != MS_ALL_FLAGS)
|
|
||||||
tmpflags &= MS_BIND_FLAGS;
|
|
||||||
if (tmpinv_flags != MS_ALL_FLAGS)
|
|
||||||
tmpflags &= MS_BIND_FLAGS;
|
|
||||||
if (!build_mnt_flags(flagsbuf, PATH_MAX, tmpflags, tmpinv_flags))
|
|
||||||
goto fail;
|
|
||||||
vec[3] = flagsbuf;
|
|
||||||
if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec,
|
|
||||||
dfaflags, false))
|
|
||||||
goto fail;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
if ((allow & AA_MAY_MOUNT) &&
|
|
||||||
(flags & (MS_UNBINDABLE | MS_PRIVATE | MS_SLAVE | MS_SHARED))
|
|
||||||
&& !device && !dev_type && !opts) {
|
|
||||||
/* change type base rules can not be conditional on device,
|
|
||||||
* device type or data
|
|
||||||
*/
|
|
||||||
/* rule class single byte header */
|
|
||||||
mntbuf.assign(class_mount_hdr);
|
|
||||||
if (!convert_entry(mntbuf, mnt_point))
|
|
||||||
goto fail;
|
|
||||||
vec[0] = mntbuf.c_str();
|
|
||||||
/* skip device and type */
|
|
||||||
vec[1] = default_match_pattern;
|
|
||||||
vec[2] = default_match_pattern;
|
|
||||||
|
|
||||||
tmpflags = flags;
|
|
||||||
tmpinv_flags = inv_flags;
|
|
||||||
if (tmpflags != MS_ALL_FLAGS)
|
|
||||||
tmpflags &= MS_MAKE_FLAGS;
|
|
||||||
if (tmpinv_flags != MS_ALL_FLAGS)
|
|
||||||
tmpflags &= MS_MAKE_FLAGS;
|
|
||||||
if (!build_mnt_flags(flagsbuf, PATH_MAX, tmpflags, tmpinv_flags))
|
|
||||||
goto fail;
|
|
||||||
vec[3] = flagsbuf;
|
|
||||||
if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec,
|
|
||||||
dfaflags, false))
|
|
||||||
goto fail;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
if ((allow & AA_MAY_MOUNT) && (flags & MS_MOVE)
|
|
||||||
&& !dev_type && !opts) {
|
|
||||||
/* mount move rules can not be conditional on dev_type,
|
|
||||||
* or data
|
|
||||||
*/
|
|
||||||
/* rule class single byte header */
|
|
||||||
mntbuf.assign(class_mount_hdr);
|
|
||||||
if (!convert_entry(mntbuf, mnt_point))
|
|
||||||
goto fail;
|
|
||||||
vec[0] = mntbuf.c_str();
|
|
||||||
if (!clear_and_convert_entry(devbuf, device))
|
|
||||||
goto fail;
|
|
||||||
vec[1] = devbuf.c_str();
|
|
||||||
/* skip type */
|
|
||||||
vec[2] = default_match_pattern;
|
|
||||||
|
|
||||||
tmpflags = flags;
|
|
||||||
tmpinv_flags = inv_flags;
|
|
||||||
if (tmpflags != MS_ALL_FLAGS)
|
|
||||||
tmpflags &= MS_MOVE_FLAGS;
|
|
||||||
if (tmpinv_flags != MS_ALL_FLAGS)
|
|
||||||
tmpflags &= MS_MOVE_FLAGS;
|
|
||||||
if (!build_mnt_flags(flagsbuf, PATH_MAX, tmpflags, tmpinv_flags))
|
|
||||||
goto fail;
|
|
||||||
vec[3] = flagsbuf;
|
|
||||||
if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec,
|
|
||||||
dfaflags, false))
|
|
||||||
goto fail;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
if ((allow & AA_MAY_MOUNT) &&
|
|
||||||
(flags | inv_flags) & ~MS_CMDS) {
|
|
||||||
int tmpallow;
|
|
||||||
/* generic mount if flags are set that are not covered by
|
|
||||||
* above commands
|
|
||||||
*/
|
|
||||||
/* rule class single byte header */
|
|
||||||
mntbuf.assign(class_mount_hdr);
|
|
||||||
if (!convert_entry(mntbuf, mnt_point))
|
|
||||||
goto fail;
|
|
||||||
vec[0] = mntbuf.c_str();
|
|
||||||
if (!clear_and_convert_entry(devbuf, device))
|
|
||||||
goto fail;
|
|
||||||
vec[1] = devbuf.c_str();
|
|
||||||
typebuf.clear();
|
|
||||||
if (!build_list_val_expr(typebuf, dev_type))
|
|
||||||
goto fail;
|
|
||||||
vec[2] = typebuf.c_str();
|
|
||||||
|
|
||||||
tmpflags = flags;
|
|
||||||
tmpinv_flags = inv_flags;
|
|
||||||
if (tmpflags != MS_ALL_FLAGS)
|
|
||||||
tmpflags &= ~MS_CMDS;
|
|
||||||
if (tmpinv_flags != MS_ALL_FLAGS)
|
|
||||||
tmpinv_flags &= ~MS_CMDS;
|
|
||||||
if (!build_mnt_flags(flagsbuf, PATH_MAX, tmpflags, tmpinv_flags))
|
|
||||||
goto fail;
|
|
||||||
vec[3] = flagsbuf;
|
|
||||||
|
|
||||||
if (opts)
|
|
||||||
tmpallow = AA_MATCH_CONT;
|
|
||||||
else
|
|
||||||
tmpallow = allow;
|
|
||||||
|
|
||||||
/* rule for match without required data || data MATCH_CONT */
|
|
||||||
if (!prof.policy.rules->add_rule_vec(deny, tmpallow,
|
|
||||||
audit | AA_AUDIT_MNT_DATA, 4,
|
|
||||||
vec, dfaflags, false))
|
|
||||||
goto fail;
|
|
||||||
count++;
|
|
||||||
|
|
||||||
if (opts) {
|
|
||||||
/* rule with data match required */
|
|
||||||
optsbuf.clear();
|
|
||||||
if (!build_mnt_opts(optsbuf, opts))
|
|
||||||
goto fail;
|
|
||||||
vec[4] = optsbuf.c_str();
|
|
||||||
if (!prof.policy.rules->add_rule_vec(deny, allow,
|
|
||||||
audit | AA_AUDIT_MNT_DATA,
|
|
||||||
5, vec, dfaflags, false))
|
|
||||||
goto fail;
|
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (allow & AA_MAY_UMOUNT) {
|
if (allow & AA_MAY_UMOUNT) {
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#define __AA_MOUNT_H
|
#define __AA_MOUNT_H
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "rule.h"
|
#include "rule.h"
|
||||||
@@ -39,6 +40,8 @@
|
|||||||
#define MS_MAND (1 << 6)
|
#define MS_MAND (1 << 6)
|
||||||
#define MS_NOMAND 0
|
#define MS_NOMAND 0
|
||||||
#define MS_DIRSYNC (1 << 7)
|
#define MS_DIRSYNC (1 << 7)
|
||||||
|
#define MS_SYMFOLLOW 0
|
||||||
|
#define MS_NOSYMFOLLOW (1 << 8)
|
||||||
#define MS_NODIRSYNC 0
|
#define MS_NODIRSYNC 0
|
||||||
#define MS_NOATIME (1 << 10)
|
#define MS_NOATIME (1 << 10)
|
||||||
#define MS_ATIME 0
|
#define MS_ATIME 0
|
||||||
@@ -61,6 +64,7 @@
|
|||||||
#define MS_IVERSION (1 << 23)
|
#define MS_IVERSION (1 << 23)
|
||||||
#define MS_NOIVERSION 0
|
#define MS_NOIVERSION 0
|
||||||
#define MS_STRICTATIME (1 << 24)
|
#define MS_STRICTATIME (1 << 24)
|
||||||
|
#define MS_LAZYTIME (1 << 25)
|
||||||
#define MS_NOUSER (1 << 31)
|
#define MS_NOUSER (1 << 31)
|
||||||
#define MS_USER 0
|
#define MS_USER 0
|
||||||
|
|
||||||
@@ -74,12 +78,14 @@
|
|||||||
|
|
||||||
#define MS_ALL_FLAGS (MS_RDONLY | MS_NOSUID | MS_NODEV | MS_NOEXEC | \
|
#define MS_ALL_FLAGS (MS_RDONLY | MS_NOSUID | MS_NODEV | MS_NOEXEC | \
|
||||||
MS_SYNC | MS_REMOUNT | MS_MAND | MS_DIRSYNC | \
|
MS_SYNC | MS_REMOUNT | MS_MAND | MS_DIRSYNC | \
|
||||||
|
MS_NOSYMFOLLOW | \
|
||||||
MS_NOATIME | MS_NODIRATIME | MS_BIND | MS_RBIND | \
|
MS_NOATIME | MS_NODIRATIME | MS_BIND | MS_RBIND | \
|
||||||
MS_MOVE | MS_VERBOSE | MS_ACL | \
|
MS_MOVE | MS_VERBOSE | MS_ACL | \
|
||||||
MS_UNBINDABLE | MS_RUNBINDABLE | \
|
MS_UNBINDABLE | MS_RUNBINDABLE | \
|
||||||
MS_PRIVATE | MS_RPRIVATE | \
|
MS_PRIVATE | MS_RPRIVATE | \
|
||||||
MS_SLAVE | MS_RSLAVE | MS_SHARED | MS_RSHARED | \
|
MS_SLAVE | MS_RSLAVE | MS_SHARED | MS_RSHARED | \
|
||||||
MS_RELATIME | MS_IVERSION | MS_STRICTATIME | MS_USER)
|
MS_RELATIME | MS_IVERSION | MS_STRICTATIME | \
|
||||||
|
MS_LAZYTIME | MS_USER)
|
||||||
|
|
||||||
/* set of flags we don't use but define (but not with the kernel values)
|
/* set of flags we don't use but define (but not with the kernel values)
|
||||||
* for MNT_FLAGS
|
* for MNT_FLAGS
|
||||||
@@ -94,16 +100,15 @@
|
|||||||
MS_KERNMOUNT | MS_STRICTATIME)
|
MS_KERNMOUNT | MS_STRICTATIME)
|
||||||
|
|
||||||
#define MS_BIND_FLAGS (MS_BIND | MS_RBIND)
|
#define MS_BIND_FLAGS (MS_BIND | MS_RBIND)
|
||||||
#define MS_MAKE_FLAGS ((MS_UNBINDABLE | MS_RUNBINDABLE | \
|
#define MS_MAKE_CMDS (MS_UNBINDABLE | MS_RUNBINDABLE | \
|
||||||
MS_PRIVATE | MS_RPRIVATE | \
|
MS_PRIVATE | MS_RPRIVATE | \
|
||||||
MS_SLAVE | MS_RSLAVE | MS_SHARED | MS_RSHARED) | \
|
MS_SLAVE | MS_RSLAVE | MS_SHARED | MS_RSHARED)
|
||||||
(MS_ALL_FLAGS & ~(MNT_FLAGS)))
|
#define MS_MAKE_FLAGS (MS_ALL_FLAGS & ~(MNT_FLAGS))
|
||||||
#define MS_MOVE_FLAGS (MS_MOVE)
|
#define MS_MOVE_FLAGS (MS_MOVE)
|
||||||
|
|
||||||
#define MS_CMDS (MS_MOVE | MS_REMOUNT | MS_BIND | MS_RBIND | \
|
#define MS_CMDS (MS_MOVE | MS_REMOUNT | MS_BIND | MS_RBIND | MS_MAKE_CMDS)
|
||||||
MS_UNBINDABLE | MS_RUNBINDABLE | MS_PRIVATE | MS_RPRIVATE | \
|
|
||||||
MS_SLAVE | MS_RSLAVE | MS_SHARED | MS_RSHARED)
|
|
||||||
#define MS_REMOUNT_FLAGS (MS_ALL_FLAGS & ~(MS_CMDS & ~MS_REMOUNT & ~MS_BIND & ~MS_RBIND))
|
#define MS_REMOUNT_FLAGS (MS_ALL_FLAGS & ~(MS_CMDS & ~MS_REMOUNT & ~MS_BIND & ~MS_RBIND))
|
||||||
|
#define MS_NEW_FLAGS (MS_ALL_FLAGS & ~MS_CMDS)
|
||||||
|
|
||||||
#define MNT_SRC_OPT 1
|
#define MNT_SRC_OPT 1
|
||||||
#define MNT_DST_OPT 2
|
#define MNT_DST_OPT 2
|
||||||
@@ -121,6 +126,19 @@
|
|||||||
|
|
||||||
|
|
||||||
class mnt_rule: public rule_t {
|
class mnt_rule: public rule_t {
|
||||||
|
int gen_policy_remount(Profile &prof, int &count, unsigned int flags,
|
||||||
|
unsigned int opt_flags);
|
||||||
|
int gen_policy_bind_mount(Profile &prof, int &count, unsigned int flags,
|
||||||
|
unsigned int opt_flags);
|
||||||
|
int gen_policy_change_mount_type(Profile &prof, int &count,
|
||||||
|
unsigned int flags,
|
||||||
|
unsigned int opt_flags);
|
||||||
|
int gen_policy_move_mount(Profile &prof, int &count, unsigned int flags,
|
||||||
|
unsigned int opt_flags);
|
||||||
|
int gen_policy_new_mount(Profile &prof, int &count, unsigned int flags,
|
||||||
|
unsigned int opt_flags);
|
||||||
|
int gen_flag_rules(Profile &prof, int &count, unsigned int flags,
|
||||||
|
unsigned int opt_flags);
|
||||||
public:
|
public:
|
||||||
char *mnt_point;
|
char *mnt_point;
|
||||||
char *device;
|
char *device;
|
||||||
@@ -128,7 +146,7 @@ public:
|
|||||||
struct value_list *dev_type;
|
struct value_list *dev_type;
|
||||||
struct value_list *opts;
|
struct value_list *opts;
|
||||||
|
|
||||||
unsigned int flags, inv_flags;
|
std::vector<unsigned int> flagsv, opt_flagsv;
|
||||||
|
|
||||||
int allow, audit;
|
int allow, audit;
|
||||||
int deny;
|
int deny;
|
||||||
|
@@ -229,6 +229,7 @@ do { \
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define list_first(LIST) (LIST)
|
||||||
#define list_for_each(LIST, ENTRY) \
|
#define list_for_each(LIST, ENTRY) \
|
||||||
for ((ENTRY) = (LIST); (ENTRY); (ENTRY) = (ENTRY)->next)
|
for ((ENTRY) = (LIST); (ENTRY); (ENTRY) = (ENTRY)->next)
|
||||||
#define list_for_each_safe(LIST, ENTRY, TMP) \
|
#define list_for_each_safe(LIST, ENTRY, TMP) \
|
||||||
@@ -262,6 +263,16 @@ do { \
|
|||||||
prev; \
|
prev; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define list_pop(LIST) \
|
||||||
|
({ \
|
||||||
|
typeof(LIST) _entry = (LIST); \
|
||||||
|
if (LIST) { \
|
||||||
|
(LIST) = (LIST)->next; \
|
||||||
|
_entry->next = NULL; \
|
||||||
|
} \
|
||||||
|
_entry; \
|
||||||
|
})
|
||||||
|
|
||||||
#define list_remove_at(LIST, PREV, ENTRY) \
|
#define list_remove_at(LIST, PREV, ENTRY) \
|
||||||
if (PREV) \
|
if (PREV) \
|
||||||
(PREV)->next = (ENTRY)->next; \
|
(PREV)->next = (ENTRY)->next; \
|
||||||
|
@@ -165,6 +165,7 @@ FILE *search_path(char *filename, char **fullpath, bool *skip)
|
|||||||
if (g_includecache->find(buf)) {
|
if (g_includecache->find(buf)) {
|
||||||
/* hit do not want to re-include */
|
/* hit do not want to re-include */
|
||||||
*skip = true;
|
*skip = true;
|
||||||
|
free(buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -274,7 +274,7 @@ static inline void sd_write_aligned_blob(std::ostringstream &buf, void *b, int b
|
|||||||
buf.write((const char *) b, b_size);
|
buf.write((const char *) b, b_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sd_write_strn(std::ostringstream &buf, char *b, int size, const char *name)
|
static void sd_write_strn(std::ostringstream &buf, const char *b, int size, const char *name)
|
||||||
{
|
{
|
||||||
sd_write_name(buf, name);
|
sd_write_name(buf, name);
|
||||||
sd_write8(buf, SD_STRING);
|
sd_write8(buf, SD_STRING);
|
||||||
@@ -282,7 +282,7 @@ static void sd_write_strn(std::ostringstream &buf, char *b, int size, const char
|
|||||||
buf.write(b, size);
|
buf.write(b, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sd_write_string(std::ostringstream &buf, char *b, const char *name)
|
static inline void sd_write_string(std::ostringstream &buf, const char *b, const char *name)
|
||||||
{
|
{
|
||||||
sd_write_strn(buf, b, strlen(b) + 1, name);
|
sd_write_strn(buf, b, strlen(b) + 1, name);
|
||||||
}
|
}
|
||||||
@@ -401,11 +401,7 @@ void sd_serialize_profile(std::ostringstream &buf, Profile *profile,
|
|||||||
sd_write_struct(buf, "profile");
|
sd_write_struct(buf, "profile");
|
||||||
if (flattened) {
|
if (flattened) {
|
||||||
assert(profile->parent);
|
assert(profile->parent);
|
||||||
autofree char *name = (char *) malloc(3 + strlen(profile->name) + strlen(profile->parent->name));
|
sd_write_string(buf, profile->get_name(false).c_str(), NULL);
|
||||||
if (!name)
|
|
||||||
return;
|
|
||||||
sprintf(name, "%s//%s", profile->parent->name, profile->name);
|
|
||||||
sd_write_string(buf, name, NULL);
|
|
||||||
} else {
|
} else {
|
||||||
sd_write_string(buf, profile->name, NULL);
|
sd_write_string(buf, profile->name, NULL);
|
||||||
}
|
}
|
||||||
|
@@ -167,10 +167,10 @@ void include_filename(char *filename, int search, bool if_exists)
|
|||||||
include_file = search_path(filename, &fullpath, &cached);
|
include_file = search_path(filename, &fullpath, &cached);
|
||||||
if (!include_file && cached) {
|
if (!include_file && cached) {
|
||||||
goto skip;
|
goto skip;
|
||||||
} else if (preprocess_only) {
|
|
||||||
fprintf(yyout, "\n\n##included <%s>\n", filename);
|
|
||||||
} else if (!include_file && preprocess_only) {
|
} else if (!include_file && preprocess_only) {
|
||||||
fprintf(yyout, "\n\n##failed include <%s>\n", filename);
|
fprintf(yyout, "\n\n##failed include <%s>\n", filename);
|
||||||
|
} else if (preprocess_only) {
|
||||||
|
fprintf(yyout, "\n\n##included <%s>\n", filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (g_includecache->find(filename)) {
|
} else if (g_includecache->find(filename)) {
|
||||||
|
@@ -1112,7 +1112,7 @@ int process_profile(int option, aa_kernel_interface *kernel_interface,
|
|||||||
retval = process_binary(option, kernel_interface,
|
retval = process_binary(option, kernel_interface,
|
||||||
cachename);
|
cachename);
|
||||||
if (!retval || skip_bad_cache_rebuild)
|
if (!retval || skip_bad_cache_rebuild)
|
||||||
return retval;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1175,7 +1175,8 @@ int process_profile(int option, aa_kernel_interface *kernel_interface,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
/* cleanup */
|
||||||
|
reset_parser(profilename);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1577,6 +1578,7 @@ int main(int argc, char *argv[])
|
|||||||
if (ofile)
|
if (ofile)
|
||||||
fclose(ofile);
|
fclose(ofile);
|
||||||
aa_policy_cache_unref(policy_cache);
|
aa_policy_cache_unref(policy_cache);
|
||||||
|
aa_kernel_interface_unref(kernel_interface);
|
||||||
|
|
||||||
return last_error;
|
return last_error;
|
||||||
}
|
}
|
||||||
|
@@ -486,13 +486,18 @@ static int process_profile_name_xmatch(Profile *prof)
|
|||||||
&prof->xmatch_len);
|
&prof->xmatch_len);
|
||||||
if (ptype == ePatternBasic)
|
if (ptype == ePatternBasic)
|
||||||
prof->xmatch_len = strlen(name);
|
prof->xmatch_len = strlen(name);
|
||||||
if (!prof->attachment)
|
|
||||||
free(name);
|
|
||||||
|
|
||||||
if (ptype == ePatternInvalid) {
|
if (ptype == ePatternInvalid) {
|
||||||
PERROR(_("%s: Invalid profile name '%s' - bad regular expression\n"), progname, name);
|
PERROR(_("%s: Invalid profile name '%s' - bad regular expression\n"), progname, name);
|
||||||
|
if (!prof->attachment)
|
||||||
|
free(name);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else if (ptype == ePatternBasic && !(prof->altnames || prof->attachment || prof->xattrs.list)) {
|
}
|
||||||
|
|
||||||
|
if (!prof->attachment)
|
||||||
|
free(name);
|
||||||
|
|
||||||
|
if (ptype == ePatternBasic && !(prof->altnames || prof->attachment || prof->xattrs.list)) {
|
||||||
/* no regex so do not set xmatch */
|
/* no regex so do not set xmatch */
|
||||||
prof->xmatch = NULL;
|
prof->xmatch = NULL;
|
||||||
prof->xmatch_len = 0;
|
prof->xmatch_len = 0;
|
||||||
|
@@ -1773,7 +1773,7 @@ static int abi_features_base(struct aa_features **features, char *filename, bool
|
|||||||
{
|
{
|
||||||
autofclose FILE *f = NULL;
|
autofclose FILE *f = NULL;
|
||||||
struct stat my_stat;
|
struct stat my_stat;
|
||||||
char *fullpath = NULL;
|
autofree char *fullpath = NULL;
|
||||||
bool cached;
|
bool cached;
|
||||||
|
|
||||||
if (search) {
|
if (search) {
|
||||||
|
@@ -99,11 +99,12 @@ is_container_with_internal_policy() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# LXD and LXC set up AppArmor namespaces starting with "lxd-" and
|
# LXD, Incus and LXC set up AppArmor namespaces starting with "lxd-",
|
||||||
# "lxc-", respectively. Return non-zero for all other namespace
|
# "incus-" and "lxc-", respectively. Return non-zero for all other
|
||||||
# identifiers.
|
# namespace identifiers.
|
||||||
read -r ns_name < "$ns_name_path"
|
read -r ns_name < "$ns_name_path"
|
||||||
if [ "${ns_name#lxd-*}" = "$ns_name" ] && \
|
if [ "${ns_name#lxd-*}" = "$ns_name" ] && \
|
||||||
|
[ "${ns_name#incus-*}" = "$ns_name" ] && \
|
||||||
[ "${ns_name#lxc-*}" = "$ns_name" ]; then
|
[ "${ns_name#lxc-*}" = "$ns_name" ]; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
@@ -643,6 +643,16 @@ verify_binary_equality "attachment slash filtering" \
|
|||||||
@{FOO}=/foo
|
@{FOO}=/foo
|
||||||
/t @{BAR}/@{FOO} { }"
|
/t @{BAR}/@{FOO} { }"
|
||||||
|
|
||||||
|
# This can potentially fail as ideally it requires a better dfa comparison
|
||||||
|
# routine as it can generates hormomorphic dfas. The enumeration of the
|
||||||
|
# dfas dumped will be different, even if the binary is the same
|
||||||
|
# Note: this test in the future will require -O filter-deny and
|
||||||
|
# -O minimize and -O remove-unreachable.
|
||||||
|
verify_binary_equality "mount specific deny doesn't affect non-overlapping" \
|
||||||
|
"/t { mount options=bind /e/ -> /**, }" \
|
||||||
|
"/t { audit deny mount /s/** -> /**,
|
||||||
|
mount options=bind /e/ -> /**, }"
|
||||||
|
|
||||||
if [ $fails -ne 0 ] || [ $errors -ne 0 ]
|
if [ $fails -ne 0 ] || [ $errors -ne 0 ]
|
||||||
then
|
then
|
||||||
printf "ERRORS: %d\nFAILS: %d\n" $errors $fails 2>&1
|
printf "ERRORS: %d\nFAILS: %d\n" $errors $fails 2>&1
|
||||||
|
7
parser/tst/simple_tests/mount/bad_1.sd
Normal file
7
parser/tst/simple_tests/mount/bad_1.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic mount rule with incompatible options
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(rw, ro) -> /foo,
|
||||||
|
}
|
7
parser/tst/simple_tests/mount/bad_2.sd
Normal file
7
parser/tst/simple_tests/mount/bad_2.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic mount rule with incompatible options
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(rw ro) -> /foo,
|
||||||
|
}
|
7
parser/tst/simple_tests/mount/bad_3.sd
Normal file
7
parser/tst/simple_tests/mount/bad_3.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic mount rule with incompatible options
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(rw ro) fstype=procfs -> /foo,
|
||||||
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
#=Description basic mount rule
|
#=Description basic mount rule with incompatible options
|
||||||
#=EXRESULT PASS
|
#=EXRESULT FAIL
|
||||||
#
|
#
|
||||||
/usr/bin/foo {
|
/usr/bin/foo {
|
||||||
mount options=(rw ro) fstype=(procfs) none -> /foo,
|
mount options=(rw ro) fstype=(procfs) none -> /foo,
|
7
parser/tst/simple_tests/mount/bad_opt_29.sd
Normal file
7
parser/tst/simple_tests/mount/bad_opt_29.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic mount rule conflicting = options
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(strictatime, nostrictatime) -> /foo,
|
||||||
|
}
|
7
parser/tst/simple_tests/mount/bad_opt_30.sd
Normal file
7
parser/tst/simple_tests/mount/bad_opt_30.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic mount rule conflicting = options
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(lazytime, nolazytime) -> /foo,
|
||||||
|
}
|
7
parser/tst/simple_tests/mount/bad_opt_31.sd
Normal file
7
parser/tst/simple_tests/mount/bad_opt_31.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic mount rule conflicting = options
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(symfollow, nosymfollow) -> /foo,
|
||||||
|
}
|
6
parser/tst/simple_tests/mount/bad_opt_32.sd
Normal file
6
parser/tst/simple_tests/mount/bad_opt_32.sd
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
#=Description test we fail make rules with source and mntpnt associated with MR 1054
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(slave) /snap/bin/** -> /**,
|
||||||
|
}
|
6
parser/tst/simple_tests/mount/bad_opt_35.sd
Normal file
6
parser/tst/simple_tests/mount/bad_opt_35.sd
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
#=Description test we fail make rules with source and mntpnt associated with MR 1054
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(rslave) /snap/bin/** -> /**,
|
||||||
|
}
|
6
parser/tst/simple_tests/mount/bad_opt_36.sd
Normal file
6
parser/tst/simple_tests/mount/bad_opt_36.sd
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
#=Description test we fail make rules with source and mntpnt associated with MR 1054
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(unbindable) /snap/bin/** -> /**,
|
||||||
|
}
|
6
parser/tst/simple_tests/mount/bad_opt_37.sd
Normal file
6
parser/tst/simple_tests/mount/bad_opt_37.sd
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
#=Description test we fail make rules with source and mntpnt associated with MR 1054
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(runbindable) /snap/bin/** -> /**,
|
||||||
|
}
|
6
parser/tst/simple_tests/mount/bad_opt_38.sd
Normal file
6
parser/tst/simple_tests/mount/bad_opt_38.sd
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
#=Description test we fail make rules with source and mntpnt associated with MR 1054
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(private) /snap/bin/** -> /**,
|
||||||
|
}
|
6
parser/tst/simple_tests/mount/bad_opt_39.sd
Normal file
6
parser/tst/simple_tests/mount/bad_opt_39.sd
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
#=Description test we fail make rules with source and mntpnt associated with MR 1054
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(rprivate) /snap/bin/** -> /**,
|
||||||
|
}
|
6
parser/tst/simple_tests/mount/bad_opt_40.sd
Normal file
6
parser/tst/simple_tests/mount/bad_opt_40.sd
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
#=Description test we fail make rules with source and mntpnt associated with MR 1054
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(shared) /snap/bin/** -> /**,
|
||||||
|
}
|
6
parser/tst/simple_tests/mount/bad_opt_41.sd
Normal file
6
parser/tst/simple_tests/mount/bad_opt_41.sd
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
#=Description test we fail make rules with source and mntpnt associated with MR 1054
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(rshared) /snap/bin/** -> /**,
|
||||||
|
}
|
@@ -3,5 +3,5 @@
|
|||||||
#=EXRESULT PASS
|
#=EXRESULT PASS
|
||||||
#
|
#
|
||||||
/usr/bin/foo {
|
/usr/bin/foo {
|
||||||
mount options=(rw, ro) -> /foo,
|
mount options=(rw nosuid) -> /foo,
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +0,0 @@
|
|||||||
#
|
|
||||||
#=Description basic mount rule
|
|
||||||
#=EXRESULT PASS
|
|
||||||
#
|
|
||||||
/usr/bin/foo {
|
|
||||||
mount options=(rw ro) -> /foo,
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
#
|
|
||||||
#=Description basic mount rule
|
|
||||||
#=EXRESULT PASS
|
|
||||||
#
|
|
||||||
/usr/bin/foo {
|
|
||||||
mount options=(rw ro) fstype=procfs -> /foo,
|
|
||||||
}
|
|
8
parser/tst/simple_tests/mount/ok_opt_56.sd
Normal file
8
parser/tst/simple_tests/mount/ok_opt_56.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "nostrictatime" mount option
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=nostrictatime /a -> /1,
|
||||||
|
mount options=(nostrictatime) /b -> /2,
|
||||||
|
mount options in (nostrictatime) /d -> /4,
|
||||||
|
}
|
8
parser/tst/simple_tests/mount/ok_opt_57.sd
Normal file
8
parser/tst/simple_tests/mount/ok_opt_57.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "lazytime" mount option
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=lazytime /a -> /1,
|
||||||
|
mount options=(lazytime) /b -> /2,
|
||||||
|
mount options in (lazytime) /d -> /4,
|
||||||
|
}
|
8
parser/tst/simple_tests/mount/ok_opt_58.sd
Normal file
8
parser/tst/simple_tests/mount/ok_opt_58.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "nolazytime" mount option
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=nolazytime /a -> /1,
|
||||||
|
mount options=(nolazytime) /b -> /2,
|
||||||
|
mount options in (nolazytime) /d -> /4,
|
||||||
|
}
|
7
parser/tst/simple_tests/mount/ok_opt_59.sd
Normal file
7
parser/tst/simple_tests/mount/ok_opt_59.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "strictatime" mount option in combination
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(rw,strictatime) /c -> /3,
|
||||||
|
mount options in (ro,strictatime) /e -> /5,
|
||||||
|
}
|
7
parser/tst/simple_tests/mount/ok_opt_60.sd
Normal file
7
parser/tst/simple_tests/mount/ok_opt_60.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "nostrictatime" mount option in combination
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(rw,nostrictatime) /c -> /3,
|
||||||
|
mount options in (ro,nostrictatime) /e -> /5,
|
||||||
|
}
|
7
parser/tst/simple_tests/mount/ok_opt_61.sd
Normal file
7
parser/tst/simple_tests/mount/ok_opt_61.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "lazytime" mount option in combination
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(rw,lazytime) /c -> /3,
|
||||||
|
mount options in (ro,lazytime) /e -> /5,
|
||||||
|
}
|
7
parser/tst/simple_tests/mount/ok_opt_62.sd
Normal file
7
parser/tst/simple_tests/mount/ok_opt_62.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "nolazytime" mount option in combination
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(rw,nolazytime) /c -> /3,
|
||||||
|
mount options in (ro,nolazytime) /e -> /5,
|
||||||
|
}
|
7
parser/tst/simple_tests/mount/ok_opt_63.sd
Normal file
7
parser/tst/simple_tests/mount/ok_opt_63.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic mount rule conflicting options with in
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options in (strictatime, nostrictatime) -> /foo,
|
||||||
|
}
|
7
parser/tst/simple_tests/mount/ok_opt_64.sd
Normal file
7
parser/tst/simple_tests/mount/ok_opt_64.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic mount rule conflicting options with in
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options in (lazytime, nolazytime) -> /foo,
|
||||||
|
}
|
8
parser/tst/simple_tests/mount/ok_opt_65.sd
Normal file
8
parser/tst/simple_tests/mount/ok_opt_65.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "nosymfollow" mount option
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=nosymfollow /a -> /1,
|
||||||
|
mount options=(nosymfollow) /b -> /2,
|
||||||
|
mount options in (nosymfollow) /d -> /4,
|
||||||
|
}
|
7
parser/tst/simple_tests/mount/ok_opt_66.sd
Normal file
7
parser/tst/simple_tests/mount/ok_opt_66.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "symfollow" mount option in combination
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(rw,symfollow) /c -> /3,
|
||||||
|
mount options in (ro,symfollow) /e -> /5,
|
||||||
|
}
|
7
parser/tst/simple_tests/mount/ok_opt_67.sd
Normal file
7
parser/tst/simple_tests/mount/ok_opt_67.sd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
#=Description basic mount rule conflicting options with in
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options in (symfollow, nosymfollow) -> /foo,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_68.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_68.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "unbindable" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=unbindable /1,
|
||||||
|
mount options=(unbindable) /2,
|
||||||
|
mount options=(rw,unbindable) /3,
|
||||||
|
mount options in (unbindable) /4,
|
||||||
|
mount options in (ro,unbindable) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_69.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_69.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "runbindable" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=runbindable /1,
|
||||||
|
mount options=(runbindable) /2,
|
||||||
|
mount options=(rw,runbindable) /3,
|
||||||
|
mount options in (runbindable) /4,
|
||||||
|
mount options in (ro,runbindable) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_70.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_70.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "rprivate" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=rprivate /1,
|
||||||
|
mount options=(rprivate) /2,
|
||||||
|
mount options=(rw,rprivate) /3,
|
||||||
|
mount options in (rprivate) /4,
|
||||||
|
mount options in (ro,rprivate) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_71.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_71.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "private" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=private /1,
|
||||||
|
mount options=(private) /2,
|
||||||
|
mount options=(rw,private) /3,
|
||||||
|
mount options in (private) /4,
|
||||||
|
mount options in (ro,private) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_72.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_72.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "slave" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=slave /1,
|
||||||
|
mount options=(slave) /2,
|
||||||
|
mount options=(rw,slave) /3,
|
||||||
|
mount options in (slave) /4,
|
||||||
|
mount options in (ro,slave) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_73.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_73.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "rslave" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=rslave /1,
|
||||||
|
mount options=(rslave) /2,
|
||||||
|
mount options=(rw,rslave) /3,
|
||||||
|
mount options in (rslave) /4,
|
||||||
|
mount options in (ro,rslave) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_74.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_74.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "shared" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=shared /1,
|
||||||
|
mount options=(shared) /2,
|
||||||
|
mount options=(rw,shared) /3,
|
||||||
|
mount options in (shared) /4,
|
||||||
|
mount options in (ro,shared) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_75.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_75.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "rshared" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=rshared /1,
|
||||||
|
mount options=(rshared) /2,
|
||||||
|
mount options=(rw,rshared) /3,
|
||||||
|
mount options in (rshared) /4,
|
||||||
|
mount options in (ro,rshared) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_76.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_76.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "make-unbindable" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=make-unbindable /1,
|
||||||
|
mount options=(make-unbindable) /2,
|
||||||
|
mount options=(rw,make-unbindable) /3,
|
||||||
|
mount options in (make-unbindable) /4,
|
||||||
|
mount options in (ro,make-unbindable) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_77.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_77.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "make-runbindable" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=make-runbindable /1,
|
||||||
|
mount options=(make-runbindable) /2,
|
||||||
|
mount options=(rw,make-runbindable) /3,
|
||||||
|
mount options in (make-runbindable) /4,
|
||||||
|
mount options in (ro,make-runbindable) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_78.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_78.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "make-private" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=make-private /1,
|
||||||
|
mount options=(make-private) /2,
|
||||||
|
mount options=(rw,make-private) /3,
|
||||||
|
mount options in (make-private) /4,
|
||||||
|
mount options in (ro,make-private) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_79.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_79.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "make-rprivate" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=make-rprivate /1,
|
||||||
|
mount options=(make-rprivate) /2,
|
||||||
|
mount options=(rw,make-rprivate) /3,
|
||||||
|
mount options in (make-rprivate) /4,
|
||||||
|
mount options in (ro,make-rprivate) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_80.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_80.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "make-slave" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=make-slave /1,
|
||||||
|
mount options=(make-slave) /2,
|
||||||
|
mount options=(rw,make-slave) /3,
|
||||||
|
mount options in (make-slave) /4,
|
||||||
|
mount options in (ro,make-slave) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_81.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_81.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "make-shared" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=make-shared /1,
|
||||||
|
mount options=(make-shared) /2,
|
||||||
|
mount options=(rw,make-shared) /3,
|
||||||
|
mount options in (make-shared) /4,
|
||||||
|
mount options in (ro,make-shared) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_82.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_82.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "make-rslave" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=make-rslave /1,
|
||||||
|
mount options=(make-rslave) /2,
|
||||||
|
mount options=(rw,make-rslave) /3,
|
||||||
|
mount options in (make-rslave) /4,
|
||||||
|
mount options in (ro,make-rslave) /5,
|
||||||
|
}
|
10
parser/tst/simple_tests/mount/ok_opt_83.sd
Normal file
10
parser/tst/simple_tests/mount/ok_opt_83.sd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#
|
||||||
|
#=Description basic rules to test the "make-rshared" mount option passing mount point as source (should emit a deprecation warning)
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=make-rshared /1,
|
||||||
|
mount options=(make-rshared) /2,
|
||||||
|
mount options=(rw,make-rshared) /3,
|
||||||
|
mount options in (make-rshared) /4,
|
||||||
|
mount options in (ro,make-rshared) /5,
|
||||||
|
}
|
8
parser/tst/simple_tests/mount/ok_opt_84.sd
Normal file
8
parser/tst/simple_tests/mount/ok_opt_84.sd
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=Description test we can parse rules associated with MR 1054
|
||||||
|
#=EXRESULT PASS
|
||||||
|
/usr/bin/foo {
|
||||||
|
mount options=(slave) /**,
|
||||||
|
mount options=(slave) -> /**,
|
||||||
|
mount /snap/bin/** -> /**,
|
||||||
|
}
|
25
parser/tst/simple_tests/regressions/ok_normalize.sd
Normal file
25
parser/tst/simple_tests/regressions/ok_normalize.sd
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#
|
||||||
|
#=Description caused an infinite loop in expr normalization
|
||||||
|
#=EXRESULT PASS
|
||||||
|
|
||||||
|
# This test triggers an infinite loop bug in expr normalization
|
||||||
|
# Note: this test might be able to be reduced more but, each element appears
|
||||||
|
# to be required to trigger the bug.
|
||||||
|
# that is the initial var assignment, += with the "comment" at the end
|
||||||
|
# (which is a separate bug), the expansion in the 2nd variable and then
|
||||||
|
# the use of the 2nd variable.
|
||||||
|
# This seems to be due to difference in consistency check between expansion
|
||||||
|
# at parse time and variable expansion.
|
||||||
|
# eg. expanding @{exec_path} manually will result in a failure to parse
|
||||||
|
# see: https://gitlab.com/apparmor/apparmor/-/issues/398
|
||||||
|
|
||||||
|
@{var}=*-linux-gnu*
|
||||||
|
@{var}+=*-suse-linux* #aa:only opensuse
|
||||||
|
|
||||||
|
@{exec_path} = /{,@{var}/}t
|
||||||
|
|
||||||
|
profile test {
|
||||||
|
|
||||||
|
|
||||||
|
@{exec_path} mr,
|
||||||
|
}
|
@@ -47,10 +47,10 @@ else
|
|||||||
PYTHONPATH=../utils/:$(PYTHON_DIST_BUILD_PATH)
|
PYTHONPATH=../utils/:$(PYTHON_DIST_BUILD_PATH)
|
||||||
PARSER?=../parser/apparmor_parser
|
PARSER?=../parser/apparmor_parser
|
||||||
# use ../utils logprof
|
# use ../utils logprof
|
||||||
LOGPROF?=LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) PYTHONPATH=$(PYTHONPATH) $(PYTHON) ../utils/aa-logprof
|
LOGPROF?=LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) PYTHONPATH=$(PYTHONPATH) $(PYTHON) ../utils/aa-logprof --configdir ../utils/
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# $(PWD) is wrong when using "make -C profiles" - explicitely set it here to get the right value
|
# $(PWD) is wrong when using "make -C profiles" - explicitly set it here to get the right value
|
||||||
PWD=$(shell pwd)
|
PWD=$(shell pwd)
|
||||||
|
|
||||||
.PHONY: test-dependencies
|
.PHONY: test-dependencies
|
||||||
@@ -83,7 +83,7 @@ local:
|
|||||||
fn=$$(basename $$profile); \
|
fn=$$(basename $$profile); \
|
||||||
echo "# Site-specific additions and overrides for '$$fn'" > ${PROFILES_SOURCE}/local/$$fn; \
|
echo "# Site-specific additions and overrides for '$$fn'" > ${PROFILES_SOURCE}/local/$$fn; \
|
||||||
grep "include[[:space:]]\\+if[[:space:]]\\+exists[[:space:]]\\+<local/$$fn>" "$$profile" >/dev/null || { echo "$$profile doesn't contain include if exists <local/$$fn>" ; exit 1; } ; \
|
grep "include[[:space:]]\\+if[[:space:]]\\+exists[[:space:]]\\+<local/$$fn>" "$$profile" >/dev/null || { echo "$$profile doesn't contain include if exists <local/$$fn>" ; exit 1; } ; \
|
||||||
done; \
|
done
|
||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: local
|
install: local
|
||||||
@@ -119,7 +119,7 @@ CHECK_PROFILES=$(filter-out ${IGNORE_FILES} ${SUBDIRS}, $(wildcard ${PROFILES_SO
|
|||||||
CHECK_ABSTRACTIONS=$(shell find ${ABSTRACTIONS_SOURCE} -type f -print)
|
CHECK_ABSTRACTIONS=$(shell find ${ABSTRACTIONS_SOURCE} -type f -print)
|
||||||
|
|
||||||
.PHONY: check
|
.PHONY: check
|
||||||
check: check-parser check-logprof check-abstractions.d
|
check: check-parser check-logprof check-abstractions.d check-extras
|
||||||
|
|
||||||
.PHONY: check-parser
|
.PHONY: check-parser
|
||||||
check-parser: test-dependencies local
|
check-parser: test-dependencies local
|
||||||
@@ -151,3 +151,11 @@ check-abstractions.d:
|
|||||||
test "$$file" = 'ubuntu-helpers' && continue ; \
|
test "$$file" = 'ubuntu-helpers' && continue ; \
|
||||||
grep -q "^ include if exists <abstractions/$${file}.d>$$" $$file || { echo "$$file does not contain 'include if exists <abstractions/$${file}.d>'"; exit 1; } ; \
|
grep -q "^ include if exists <abstractions/$${file}.d>$$" $$file || { echo "$$file does not contain 'include if exists <abstractions/$${file}.d>'"; exit 1; } ; \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
.PHONY: check-extras
|
||||||
|
check-extras:
|
||||||
|
@echo "*** Checking if all extra profiles contain include if exists <local/*>"
|
||||||
|
$(Q)cd ${EXTRAS_SOURCE} && for file in * ; do \
|
||||||
|
test "$$file" = 'README' && continue ; \
|
||||||
|
grep -q "^ include if exists <local/$${file}>$$" $$file || { echo "$$file does not contain 'include if exists <local/$${file}>'"; exit 1; } ; \
|
||||||
|
done
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
owner @{run}/user/*/gdm/Xauthority r,
|
owner @{run}/user/*/gdm/Xauthority r,
|
||||||
owner @{run}/user/*/X11/Xauthority r,
|
owner @{run}/user/*/X11/Xauthority r,
|
||||||
owner @{run}/user/*/xauth_* r,
|
owner @{run}/user/*/xauth_* r,
|
||||||
|
owner /tmp/xauth_?????? r,
|
||||||
|
|
||||||
# the unix socket to use to connect to the display
|
# the unix socket to use to connect to the display
|
||||||
/tmp/.X11-unix/* rw,
|
/tmp/.X11-unix/* rw,
|
||||||
|
@@ -85,5 +85,8 @@ owner @{HOME}/.local/share/openal/hrtf/{,**} r,
|
|||||||
# wildmidi
|
# wildmidi
|
||||||
/etc/wildmidi/wildmidi.cfg r,
|
/etc/wildmidi/wildmidi.cfg r,
|
||||||
|
|
||||||
|
# pipewire
|
||||||
|
/usr/share/pipewire/client{,-rt}.conf r,
|
||||||
|
|
||||||
# Include additions to the abstraction
|
# Include additions to the abstraction
|
||||||
include if exists <abstractions/audio.d>
|
include if exists <abstractions/audio.d>
|
||||||
|
@@ -31,6 +31,22 @@
|
|||||||
/{usr/,}lib/@{multiarch}/security/pam_*.so mr,
|
/{usr/,}lib/@{multiarch}/security/pam_*.so mr,
|
||||||
/{usr/,}lib/@{multiarch}/security/ r,
|
/{usr/,}lib/@{multiarch}/security/ r,
|
||||||
|
|
||||||
|
# pam_unix
|
||||||
|
owner /proc/@{pid}/loginuid r,
|
||||||
|
/{,usr/}{,s}bin/unix_chkpwd Px,
|
||||||
|
|
||||||
|
# pam_env
|
||||||
|
@{etc_ro}/environment r,
|
||||||
|
|
||||||
|
# pam_limit
|
||||||
|
@{etc_ro}/security/limits.d/ r,
|
||||||
|
@{etc_ro}/security/limits.d/*.conf r,
|
||||||
|
|
||||||
|
# gssapi
|
||||||
|
@{etc_ro}/gss/mech r,
|
||||||
|
@{etc_ro}/gss/mech.d/ r,
|
||||||
|
@{etc_ro}/gss/mech.d/*.conf r,
|
||||||
|
|
||||||
# kerberos
|
# kerberos
|
||||||
include <abstractions/kerberosclient>
|
include <abstractions/kerberosclient>
|
||||||
# SuSE's pwdutils are different:
|
# SuSE's pwdutils are different:
|
||||||
|
@@ -36,8 +36,8 @@
|
|||||||
/usr/share/locale-langpack/** r,
|
/usr/share/locale-langpack/** r,
|
||||||
/usr/share/locale/** r,
|
/usr/share/locale/** r,
|
||||||
/usr/share/**/locale/** r,
|
/usr/share/**/locale/** r,
|
||||||
/usr/share/zoneinfo/ r,
|
/usr/share/zoneinfo{,-icu}/ r,
|
||||||
/usr/share/zoneinfo/** r,
|
/usr/share/zoneinfo{,-icu}/** r,
|
||||||
/usr/share/X11/locale/** r,
|
/usr/share/X11/locale/** r,
|
||||||
@{run}/systemd/journal/dev-log w,
|
@{run}/systemd/journal/dev-log w,
|
||||||
# systemd native journal API (see sd_journal_print(4))
|
# systemd native journal API (see sd_journal_print(4))
|
||||||
@@ -62,6 +62,7 @@
|
|||||||
@{etc_ro}/ld.so.conf r,
|
@{etc_ro}/ld.so.conf r,
|
||||||
@{etc_ro}/ld.so.conf.d/{,*.conf} r,
|
@{etc_ro}/ld.so.conf.d/{,*.conf} r,
|
||||||
@{etc_ro}/ld.so.preload r,
|
@{etc_ro}/ld.so.preload r,
|
||||||
|
@{etc_ro}/ld-musl-*.path r,
|
||||||
/{usr/,}lib{,32,64}/ld{,32,64}-*.so mr,
|
/{usr/,}lib{,32,64}/ld{,32,64}-*.so mr,
|
||||||
/{usr/,}lib/@{multiarch}/ld{,32,64}-*.so mr,
|
/{usr/,}lib/@{multiarch}/ld{,32,64}-*.so mr,
|
||||||
/{usr/,}lib/tls/i686/{cmov,nosegneg}/ld-*.so mr,
|
/{usr/,}lib/tls/i686/{cmov,nosegneg}/ld-*.so mr,
|
||||||
@@ -95,19 +96,23 @@
|
|||||||
# best place -- but many profiles require it, and it is quite harmless.
|
# best place -- but many profiles require it, and it is quite harmless.
|
||||||
@{PROC}/sys/kernel/ngroups_max r,
|
@{PROC}/sys/kernel/ngroups_max r,
|
||||||
|
|
||||||
|
# Used to determine if Linux is running in FIPS mode
|
||||||
|
@{PROC}/sys/crypto/fips_enabled r,
|
||||||
|
|
||||||
# glibc's sysconf(3) routine to determine free memory, etc
|
# glibc's sysconf(3) routine to determine free memory, etc
|
||||||
@{PROC}/meminfo r,
|
@{PROC}/meminfo r,
|
||||||
@{PROC}/stat r,
|
@{PROC}/stat r,
|
||||||
@{PROC}/cpuinfo r,
|
@{PROC}/cpuinfo r,
|
||||||
@{sys}/devices/system/cpu/ r,
|
@{sys}/devices/system/cpu/ r,
|
||||||
@{sys}/devices/system/cpu/online r,
|
@{sys}/devices/system/cpu/online r,
|
||||||
|
@{sys}/devices/system/cpu/possible r,
|
||||||
|
|
||||||
|
# transparent hugepage support
|
||||||
|
@{sys}/kernel/mm/transparent_hugepage/hpage_pmd_size r,
|
||||||
|
|
||||||
# glibc's *printf protections read the maps file
|
# glibc's *printf protections read the maps file
|
||||||
@{PROC}/@{pid}/{maps,auxv,status} r,
|
@{PROC}/@{pid}/{maps,auxv,status} r,
|
||||||
|
|
||||||
# libgcrypt reads some flags from /proc
|
|
||||||
@{PROC}/sys/crypto/* r,
|
|
||||||
|
|
||||||
# some applications will display license information
|
# some applications will display license information
|
||||||
/usr/share/common-licenses/** r,
|
/usr/share/common-licenses/** r,
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user