mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-03 15:55:46 +00:00
parser: add support for attach_disconnected.ipc flag
The attach_disconnected.ipc flag allows the use of disconnected paths on posix mqueues. This flag is a subset of attach_disconnected, and it does not allow disconnected paths for all files. Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
This commit is contained in:
@@ -115,6 +115,7 @@ B<PROFILE FLAG CONDS> = [ 'flags=' ] '(' comma or white space separated list of
|
|||||||
|
|
||||||
B<PROFILE FLAGS> = I<PROFILE MODE> | I<AUDIT_MODE> | 'mediate_deleted'
|
B<PROFILE FLAGS> = I<PROFILE MODE> | I<AUDIT_MODE> | 'mediate_deleted'
|
||||||
| 'attach_disconnected' | 'attach_disconneced.path='I<ABS PATH> | 'chroot_relative'
|
| 'attach_disconnected' | 'attach_disconneced.path='I<ABS PATH> | 'chroot_relative'
|
||||||
|
| 'attach_disconnected.ipc' | 'attach_disconnected.ipc='I<ABS PATH>
|
||||||
| 'debug' | 'interruptible' | 'kill.signal='I<SIGNAL> | 'error='I<ERROR CODE>
|
| 'debug' | 'interruptible' | 'kill.signal='I<SIGNAL> | 'error='I<ERROR CODE>
|
||||||
|
|
||||||
B<ERROR CODE> = (case insensitive error code name starting with 'E'; see errno(3))
|
B<ERROR CODE> = (case insensitive error code name starting with 'E'; see errno(3))
|
||||||
@@ -560,6 +561,14 @@ allowed. Its intent is a debug and policy development tool.
|
|||||||
attach disconnected objects to the supplied path instead of the root of
|
attach disconnected objects to the supplied path instead of the root of
|
||||||
the namespace.
|
the namespace.
|
||||||
|
|
||||||
|
=item B<attach_disconnected.ipc> A subset of attach_disconnected, but specific
|
||||||
|
for IPC namespaces. It allows attaching disconnected IPC paths without having
|
||||||
|
to allow attaching all types of files.
|
||||||
|
|
||||||
|
=item B<attach_disconnected.ipc>=I<ABS PATH> Like attach_disconnected.ipc, but
|
||||||
|
attach disconnected posix mqueue to the supplied path instead of the root of
|
||||||
|
the namespace.
|
||||||
|
|
||||||
=item B<chroot_relative> This forces file names to be relative to a
|
=item B<chroot_relative> This forces file names to be relative to a
|
||||||
chroot and behave as if the chroot is a mount namespace.
|
chroot and behave as if the chroot is a mount namespace.
|
||||||
|
|
||||||
|
@@ -189,7 +189,7 @@ extern int preprocess_only;
|
|||||||
#define PATH_DELEGATE_DELETED 0x20
|
#define PATH_DELEGATE_DELETED 0x20
|
||||||
#define PATH_ATTACH 0x40
|
#define PATH_ATTACH 0x40
|
||||||
#define PATH_NO_ATTACH 0x80
|
#define PATH_NO_ATTACH 0x80
|
||||||
|
#define PATH_IPC_ATTACH 0x100
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@@ -334,6 +334,7 @@ extern int features_supports_io_uring;
|
|||||||
extern int features_supports_flag_interruptible;
|
extern int features_supports_flag_interruptible;
|
||||||
extern int features_supports_flag_signal;
|
extern int features_supports_flag_signal;
|
||||||
extern int features_supports_flag_error;
|
extern int features_supports_flag_error;
|
||||||
|
extern int features_supports_flag_disconnected_ipc;
|
||||||
extern int kernel_supports_oob;
|
extern int kernel_supports_oob;
|
||||||
extern int kernel_supports_promptdev;
|
extern int kernel_supports_promptdev;
|
||||||
extern int kernel_supports_permstable32;
|
extern int kernel_supports_permstable32;
|
||||||
|
@@ -86,6 +86,7 @@ int features_supports_io_uring = 0; /* kernel supports io_uring rules */
|
|||||||
int features_supports_flag_interruptible = 0;
|
int features_supports_flag_interruptible = 0;
|
||||||
int features_supports_flag_signal = 0;
|
int features_supports_flag_signal = 0;
|
||||||
int features_supports_flag_error = 0;
|
int features_supports_flag_error = 0;
|
||||||
|
int features_supports_flag_disconnected_ipc = 0; /* kernel supports disconnected paths for ipc ns */
|
||||||
int kernel_supports_oob = 0; /* out of band transitions */
|
int kernel_supports_oob = 0; /* out of band transitions */
|
||||||
int kernel_supports_promptdev = 0; /* prompt via audit perms */
|
int kernel_supports_promptdev = 0; /* prompt via audit perms */
|
||||||
int kernel_supports_permstable32 = 0; /* extended permissions */
|
int kernel_supports_permstable32 = 0; /* extended permissions */
|
||||||
|
@@ -474,6 +474,11 @@ void sd_serialize_profile(std::ostringstream &buf, Profile *profile,
|
|||||||
"disconnected");
|
"disconnected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (profile->flags.disconnected_ipc && features_supports_flag_disconnected_ipc) {
|
||||||
|
sd_write_string(buf, profile->flags.disconnected_ipc,
|
||||||
|
"disconnected_ipc");
|
||||||
|
}
|
||||||
|
|
||||||
if (profile->flags.signal && features_supports_flag_signal) {
|
if (profile->flags.signal && features_supports_flag_signal) {
|
||||||
sd_write_name(buf, "kill");
|
sd_write_name(buf, "kill");
|
||||||
sd_write_uint32(buf, profile->flags.signal);
|
sd_write_uint32(buf, profile->flags.signal);
|
||||||
@@ -500,6 +505,8 @@ void sd_serialize_profile(std::ostringstream &buf, Profile *profile,
|
|||||||
flags |= 0x4;
|
flags |= 0x4;
|
||||||
if (profile->flags.path & PATH_CHROOT_NSATTACH)
|
if (profile->flags.path & PATH_CHROOT_NSATTACH)
|
||||||
flags |= 0x10;
|
flags |= 0x10;
|
||||||
|
if (profile->flags.path & PATH_IPC_ATTACH)
|
||||||
|
flags |= 0x20;
|
||||||
|
|
||||||
sd_write_name(buf, "path_flags");
|
sd_write_name(buf, "path_flags");
|
||||||
sd_write_uint32(buf, flags);
|
sd_write_uint32(buf, flags);
|
||||||
|
@@ -991,6 +991,9 @@ void set_supported_features()
|
|||||||
features_supports_flag_error = features_intersect(kernel_features,
|
features_supports_flag_error = features_intersect(kernel_features,
|
||||||
policy_features,
|
policy_features,
|
||||||
"policy/profile/error");
|
"policy/profile/error");
|
||||||
|
features_supports_flag_disconnected_ipc = features_intersect(kernel_features,
|
||||||
|
policy_features,
|
||||||
|
"domain/disconnected.ipc");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool do_print_cache_dir(aa_features *features, int dirfd, const char *path)
|
static bool do_print_cache_dir(aa_features *features, int dirfd, const char *path)
|
||||||
|
@@ -272,6 +272,23 @@ static int process_variables_in_rules(Profile &prof)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int process_variable_in_attach_disconnected(char **disconnected)
|
||||||
|
{
|
||||||
|
int error = expand_entry_variables(disconnected);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
filter_slashes(*disconnected);
|
||||||
|
// TODO: semantic check should go somewhere else
|
||||||
|
if ((*disconnected)[0] != '/')
|
||||||
|
yyerror(_("attach_disconnected path must begin with a /"));
|
||||||
|
int n = strlen(*disconnected);
|
||||||
|
// removing trailing / */
|
||||||
|
while (n && (*disconnected)[n-1] == '/')
|
||||||
|
(*disconnected)[--n] = 0;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
static int process_variables_in_name(Profile &prof)
|
static int process_variables_in_name(Profile &prof)
|
||||||
{
|
{
|
||||||
/* this needs to be done before alias expansion, ie. altnames are
|
/* this needs to be done before alias expansion, ie. altnames are
|
||||||
@@ -280,20 +297,10 @@ static int process_variables_in_name(Profile &prof)
|
|||||||
int error = expand_entry_variables(&prof.name);
|
int error = expand_entry_variables(&prof.name);
|
||||||
if (!error && prof.attachment)
|
if (!error && prof.attachment)
|
||||||
error = expand_entry_variables(&prof.attachment);
|
error = expand_entry_variables(&prof.attachment);
|
||||||
if (!error && prof.flags.disconnected_path) {
|
if (!error && prof.flags.disconnected_path)
|
||||||
error = expand_entry_variables(&prof.flags.disconnected_path);
|
error = process_variable_in_attach_disconnected(&prof.flags.disconnected_path);
|
||||||
if (error)
|
if (!error && prof.flags.disconnected_ipc)
|
||||||
return error;
|
error = process_variable_in_attach_disconnected(&prof.flags.disconnected_ipc);
|
||||||
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;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -97,6 +97,8 @@ Profile::~Profile()
|
|||||||
free(attachment);
|
free(attachment);
|
||||||
if (flags.disconnected_path)
|
if (flags.disconnected_path)
|
||||||
free(flags.disconnected_path);
|
free(flags.disconnected_path);
|
||||||
|
if (flags.disconnected_ipc)
|
||||||
|
free(flags.disconnected_ipc);
|
||||||
if (ns)
|
if (ns)
|
||||||
free(ns);
|
free(ns);
|
||||||
for (int i = (AA_EXEC_LOCAL >> 10) + 1; i < AA_EXEC_COUNT; i++)
|
for (int i = (AA_EXEC_LOCAL >> 10) + 1; i < AA_EXEC_COUNT; i++)
|
||||||
|
@@ -159,6 +159,7 @@ public:
|
|||||||
int audit;
|
int audit;
|
||||||
int path;
|
int path;
|
||||||
char *disconnected_path;
|
char *disconnected_path;
|
||||||
|
char *disconnected_ipc;
|
||||||
int signal;
|
int signal;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@@ -170,6 +171,7 @@ public:
|
|||||||
audit = 0;
|
audit = 0;
|
||||||
path = 0;
|
path = 0;
|
||||||
disconnected_path = NULL;
|
disconnected_path = NULL;
|
||||||
|
disconnected_ipc = NULL;
|
||||||
signal = 0;
|
signal = 0;
|
||||||
error = 0;
|
error = 0;
|
||||||
}
|
}
|
||||||
@@ -216,6 +218,12 @@ public:
|
|||||||
yyerror("unknown error code specified for error=\'%s\'\n", str + 6);
|
yyerror("unknown error code specified for error=\'%s\'\n", str + 6);
|
||||||
} else if (strcmp(str, "interruptible") == 0) {
|
} else if (strcmp(str, "interruptible") == 0) {
|
||||||
flags |= FLAG_INTERRUPTIBLE;
|
flags |= FLAG_INTERRUPTIBLE;
|
||||||
|
} else if (strcmp(str, "attach_disconnected.ipc") == 0) {
|
||||||
|
path |= PATH_IPC_ATTACH;
|
||||||
|
} else if (strncmp(str, "attach_disconnected.ipc=", 24) == 0) {
|
||||||
|
/* TODO: make this a proper parse */
|
||||||
|
path |= PATH_IPC_ATTACH;
|
||||||
|
disconnected_ipc = strdup(str + 24);
|
||||||
} else {
|
} else {
|
||||||
yyerror(_("Invalid profile flag: %s."), str);
|
yyerror(_("Invalid profile flag: %s."), str);
|
||||||
}
|
}
|
||||||
@@ -237,6 +245,8 @@ public:
|
|||||||
os << ", kill.signal=" << signal;
|
os << ", kill.signal=" << signal;
|
||||||
if (error)
|
if (error)
|
||||||
os << ", error=" << find_error_name_mapping(error);
|
os << ", error=" << find_error_name_mapping(error);
|
||||||
|
if (disconnected_ipc)
|
||||||
|
os << ", attach_disconnected.ipc=" << disconnected_ipc;
|
||||||
|
|
||||||
if (flags & FLAG_PROMPT_COMPAT)
|
if (flags & FLAG_PROMPT_COMPAT)
|
||||||
os << ", prompt_dev";
|
os << ", prompt_dev";
|
||||||
@@ -277,6 +287,9 @@ public:
|
|||||||
if ((path & (PATH_ATTACH | PATH_NO_ATTACH)) ==
|
if ((path & (PATH_ATTACH | PATH_NO_ATTACH)) ==
|
||||||
(PATH_ATTACH | PATH_NO_ATTACH))
|
(PATH_ATTACH | PATH_NO_ATTACH))
|
||||||
yyerror(_("Profile flag attach_disconnected conflicts with no_attach_disconnected"));
|
yyerror(_("Profile flag attach_disconnected conflicts with no_attach_disconnected"));
|
||||||
|
if ((path & (PATH_IPC_ATTACH | PATH_NO_ATTACH)) ==
|
||||||
|
(PATH_IPC_ATTACH | PATH_NO_ATTACH))
|
||||||
|
yyerror(_("Profile flag attach_disconnected.ipc conflicts with no_attach_disconnected"));
|
||||||
if ((path & (PATH_CHROOT_NSATTACH | PATH_CHROOT_NO_ATTACH)) ==
|
if ((path & (PATH_CHROOT_NSATTACH | PATH_CHROOT_NO_ATTACH)) ==
|
||||||
(PATH_CHROOT_NSATTACH | PATH_CHROOT_NO_ATTACH))
|
(PATH_CHROOT_NSATTACH | PATH_CHROOT_NO_ATTACH))
|
||||||
yyerror(_("Profile flag chroot_attach conflicts with chroot_no_attach"));
|
yyerror(_("Profile flag chroot_attach conflicts with chroot_no_attach"));
|
||||||
@@ -291,6 +304,16 @@ public:
|
|||||||
disconnected_path = rhs.disconnected_path;
|
disconnected_path = rhs.disconnected_path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rhs.disconnected_ipc) {
|
||||||
|
if (disconnected_ipc) {
|
||||||
|
if (strcmp(disconnected_ipc, rhs.disconnected_ipc) != 0) {
|
||||||
|
yyerror(_("Profile flag attach_disconnected set to conflicting values: '%s' and '%s'"), disconnected_ipc, rhs.disconnected_ipc);
|
||||||
|
}
|
||||||
|
// same so do nothing
|
||||||
|
} else {
|
||||||
|
disconnected_ipc = rhs.disconnected_ipc;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (rhs.signal) {
|
if (rhs.signal) {
|
||||||
if (signal) {
|
if (signal) {
|
||||||
if (signal != rhs.signal) {
|
if (signal != rhs.signal) {
|
||||||
|
Reference in New Issue
Block a user