2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-29 13:28:19 +00:00

parser: add support for attach_disconnected.path

Add support for specifying the path prefix used when attach disconnected
is specified. The kernel supports prepending a different value than
/ when a path is disconnected. Expose through a profile flag.

Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2020-10-20 03:53:06 -07:00
parent 65de34f462
commit b46b2662ff
20 changed files with 232 additions and 4 deletions

View File

@ -113,7 +113,9 @@ B<XATTR VALUE FILEGLOB> = I<FILEGLOB>
B<PROFILE FLAG CONDS> = [ 'flags=' ] '(' comma or white space separated list of I<PROFILE FLAGS> ')'
B<PROFILE FLAGS> = I<PROFILE MODE> | I<AUDIT_MODE> | 'mediate_deleted' | 'attach_disconnected' | 'chroot_relative' | 'debug'
B<PROFILE FLAGS> = I<PROFILE MODE> | I<AUDIT_MODE> | 'mediate_deleted'
| 'attach_disconnected' | 'attach_disconneced.path' |'chroot_relative'
| 'debug'
B<PROFILE MODE> = 'enforce' | 'complain' | 'kill' | 'unconfined' | 'prompt'
@ -491,6 +493,10 @@ though they are part of the namespace. WARNING this mode is unsafe and
can result in aliasing and access to objects that should not be
allowed. Its intent is a debug and policy development tool.
=item B<attach_disconnected.path> If attach_disconnected is in use
attach disconnected object to the supplied path instead of the root of
the namespace.
=item B<chroot_relative> This forces file names to be relative to a
chroot and behave as if the chroot is a mount namespace.

View File

@ -420,6 +420,12 @@ void sd_serialize_profile(std::ostringstream &buf, Profile *profile,
}
}
/* added in 4.13, unfortunately there is no features flag */
if (profile->flags.disconnected_path) {
sd_write_string(buf, profile->flags.disconnected_path,
"disconnected");
}
sd_write_struct(buf, "flags");
/* used to be flags.debug, but that's no longer supported */
sd_write_uint32(buf, profile->flags.flags);

View File

@ -285,7 +285,20 @@ static int process_variables_in_name(Profile &prof)
int error = expand_entry_variables(&prof.name);
if (!error && prof.attachment)
error = expand_entry_variables(&prof.attachment);
if (!error && prof.flags.disconnected_path) {
error = expand_entry_variables(&prof.flags.disconnected_path);
if (error)
return error;
filter_slashes(prof.flags.disconnected_path);
// TODO: semantic check should go somewhere else
if (prof.flags.disconnected_path[0] != '/')
yyerror(_("attach_disconnected_path value must begin with a /"));
int n = strlen(prof.flags.disconnected_path);
// removing trailing / */
while (n && prof.flags.disconnected_path[n-1] == '/')
prof.flags.disconnected_path[--n] = 0;
}
return error;
}

View File

@ -575,7 +575,7 @@ valuelist: valuelist TOK_VALUE
}
flags: { /* nothing */
flagvals fv = { 0, MODE_UNSPECIFIED, 0, 0 };
flagvals fv = { 0, MODE_UNSPECIFIED, 0, 0, NULL };
$$ = fv;
};
@ -627,7 +627,7 @@ flagvals: flagval
flagval: TOK_VALUE
{
flagvals fv = { 0, MODE_UNSPECIFIED, 0, 0 };
flagvals fv = { 0, MODE_UNSPECIFIED, 0, 0, NULL };
enum profile_mode mode;
if (strcmp($1, "debug") == 0) {
@ -653,6 +653,9 @@ flagval: TOK_VALUE
fv.path |= PATH_CHROOT_NSATTACH;
} else if (strcmp($1, "chroot_no_attach") == 0) {
fv.path |= PATH_CHROOT_NO_ATTACH;
} else if (strncmp($1, "attach_disconnected.path=", 25) == 0) {
/* TODO: make this a proper parse */
fv.disconnected_path = strdup($1 + 25);
} else {
yyerror(_("Invalid profile flag: %s."), $1);
}

View File

@ -107,6 +107,8 @@ Profile::~Profile()
free(name);
if (attachment)
free(attachment);
if (flags.disconnected_path)
free(flags.disconnected_path);
if (ns)
free(ns);
for (int i = (AA_EXEC_LOCAL >> 10) + 1; i < AA_EXEC_COUNT; i++)

View File

@ -121,6 +121,7 @@ public:
enum profile_mode mode;
int audit;
int path;
char *disconnected_path;
ostream &dump(ostream &os)
{
@ -132,6 +133,8 @@ public:
if (flags & FLAG_HAT)
os << ", Hat";
if (disconnected_path)
os << ", attach_disconnected.path=" << disconnected_path;
os << "\n";
return os;
@ -222,7 +225,7 @@ public:
parent = NULL;
flags = { 0, MODE_UNSPECIFIED, 0, 0 };
flags = { 0, MODE_UNSPECIFIED, 0, 0, NULL };
rlimits = {0, {}};
std::fill(exec_table, exec_table + AA_EXEC_COUNT, (char *)NULL);

View File

@ -0,0 +1,13 @@
#
#=DESCRIPTION validate some uses of the profile flags.
#=EXRESULT FAIL
# vim:syntax=subdomain
# Last Modified: Sun Apr 17 19:44:44 2005
#
/does/not/exist flags=(attach_disconnected.path=foo) {
#include <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View File

@ -0,0 +1,13 @@
#
#=DESCRIPTION validate some uses of the profile flags.
#=EXRESULT FAIL
# vim:syntax=subdomain
# Last Modified: Sun Apr 17 19:44:44 2005
#
/does/not/exist flags=(attach_disconnected.path=foo/) {
#include <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View File

@ -0,0 +1,16 @@
#
#=DESCRIPTION validate some uses of the profile flags.
#=EXRESULT FAIL
# vim:syntax=subdomain
# Last Modified: Sun Apr 17 19:44:44 2005
#
@{var}=bar
/does/not/exist flags=(attach_disconnected.path=@{var}) {
#include <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View File

@ -0,0 +1,16 @@
#
#=DESCRIPTION validate some uses of the profile flags.
#=EXRESULT FAIL
# vim:syntax=subdomain
# Last Modified: Sun Apr 17 19:44:44 2005
#
@{var}=bar/
/does/not/exist flags=(attach_disconnected.path=@{var}) {
#include <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View File

@ -0,0 +1,16 @@
#
#=DESCRIPTION validate some uses of the profile flags.
#=EXRESULT FAIL
# vim:syntax=subdomain
# Last Modified: Sun Apr 17 19:44:44 2005
#
@{var}=bar/
/does/not/exist flags=(attach_disconnected.path=@{var}/) {
#include <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View File

@ -0,0 +1,13 @@
#
#=DESCRIPTION validate some uses of the profile flags.
#=EXRESULT PASS
# vim:syntax=subdomain
# Last Modified: Sun Apr 17 19:44:44 2005
#
/does/not/exist flags=(attach_disconnected.path=/foo) {
#include <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View File

@ -0,0 +1,13 @@
#
#=DESCRIPTION validate some uses of the profile flags.
#=EXRESULT PASS
# vim:syntax=subdomain
# Last Modified: Sun Apr 17 19:44:44 2005
#
/does/not/exist flags=(attach_disconnected.path=/foo/) {
#include <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View File

@ -0,0 +1,13 @@
#
#=DESCRIPTION validate some uses of the profile flags.
#=EXRESULT PASS
# vim:syntax=subdomain
# Last Modified: Sun Apr 17 19:44:44 2005
#
/does/not/exist flags=(attach_disconnected.path=/foo//) {
#include <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View File

@ -0,0 +1,13 @@
#
#=DESCRIPTION validate some uses of the profile flags.
#=EXRESULT PASS
# vim:syntax=subdomain
# Last Modified: Sun Apr 17 19:44:44 2005
#
/does/not/exist flags=(attach_disconnected.path=/foo/bar) {
#include <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View File

@ -0,0 +1,16 @@
#
#=DESCRIPTION validate some uses of the profile flags.
#=EXRESULT PASS
# vim:syntax=subdomain
# Last Modified: Sun Apr 17 19:44:44 2005
#
@{var}=/bar
/does/not/exist flags=(attach_disconnected.path=/foo/@{var}) {
#include <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View File

@ -0,0 +1,16 @@
#
#=DESCRIPTION validate some uses of the profile flags.
#=EXRESULT PASS
# vim:syntax=subdomain
# Last Modified: Sun Apr 17 19:44:44 2005
#
@{var}=/bar
/does/not/exist flags=(attach_disconnected.path=/foo/@{var}/) {
#include <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View File

@ -0,0 +1,16 @@
#
#=DESCRIPTION validate some uses of the profile flags.
#=EXRESULT PASS
# vim:syntax=subdomain
# Last Modified: Sun Apr 17 19:44:44 2005
#
@{var}=/bar
/does/not/exist flags=(attach_disconnected.path=@{var}/foo) {
#include <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View File

@ -0,0 +1,16 @@
#
#=DESCRIPTION validate some uses of the profile flags.
#=EXRESULT PASS
# vim:syntax=subdomain
# Last Modified: Sun Apr 17 19:44:44 2005
#
@{var}=/bar
/does/not/exist flags=(attach_disconnected.path=@{var}) {
#include <includes/base>
/usr/X11R6/lib/lib*so* r,
/does/not/exist r,
}

View File

@ -164,6 +164,11 @@ exception_not_raised = (
'profile/flags/flags_bad54.sd',
'profile/flags/flags_bad55.sd',
'profile/flags/flags_bad56.sd',
'profile/flags/flags_bad_disconnected_path1.sd',
'profile/flags/flags_bad_disconnected_path2.sd',
'profile/flags/flags_bad_disconnected_path3.sd',
'profile/flags/flags_bad_disconnected_path4.sd',
'profile/flags/flags_bad_disconnected_path5.sd',
'profile/profile_ns_bad8.sd', # 'profile :ns/t' without terminating ':'
'ptrace/bad_05.sd', # actually contains a capability rule with invalid (ptrace-related) keyword
'ptrace/bad_06.sd', # actually contains a capability rule with invalid (ptrace-related) keyword