Skip to content

Commit

Permalink
apparmor: stack apparmor profiles if nnp and confined
Browse files Browse the repository at this point in the history
In case crun is running under apparmor profile and
no_new_privileges flag set for containers
the only way apparmor allows a change of profile
is when a profile is stacked on top of current profile
to ensure no new permissions are gained

Closes: containers#1385
Signed-off-by: 😎Mostafa Emami <mustafaemami@gmail.com>
  • Loading branch information
idleroamer committed Jan 15, 2024
1 parent 3b3061a commit e276960
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/libcrun/linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -2812,7 +2812,7 @@ int
libcrun_set_apparmor_profile (runtime_spec_schema_config_schema_process *proc, libcrun_error_t *err)
{
if (proc->apparmor_profile)
return set_apparmor_profile (proc->apparmor_profile, err);
return set_apparmor_profile (proc->apparmor_profile, proc->no_new_privileges, err);
return 0;
}

Expand Down
25 changes: 22 additions & 3 deletions src/libcrun/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -830,8 +830,24 @@ libcrun_is_apparmor_enabled (libcrun_error_t *err)
return apparmor_enabled;
}

static int
is_current_process_confined(libcrun_error_t *err)
{
int fd = open("/proc/thread-self/attr/current", O_RDONLY|O_CLOEXEC);

if (fd != -1) {
char buf[256];
ssize_t bytesRead = read(fd, buf, sizeof(buf) - 1);
close(fd);
if (bytesRead != -1)
return (strcmp(buf, "unconfined") != 0 && buf != '\0');
}
crun_make_error (err, errno, "error reading file /proc/thread-self/attr/current");
return -1;
}

int
set_apparmor_profile (const char *profile, libcrun_error_t *err)
set_apparmor_profile (const char *profile, bool no_new_privileges, libcrun_error_t *err)
{
int ret;

Expand All @@ -841,8 +857,11 @@ set_apparmor_profile (const char *profile, libcrun_error_t *err)
if (ret)
{
cleanup_free char *buf = NULL;

xasprintf (&buf, "exec %s", profile);
ret = is_current_process_confined(err);
if (UNLIKELY (ret < 0))
return ret;
// if confined only way for apparmor to allow change of profile with NNP is with stacking
xasprintf (&buf, "%s %s", no_new_privileges && ret ? "stack": "exec", profile);

ret = write_file_and_check_fs_type ("/proc/thread-self/attr/exec", buf, strlen (buf), PROC_SUPER_MAGIC, "procfs",
err);
Expand Down
2 changes: 1 addition & 1 deletion src/libcrun/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ int set_selinux_exec_label (const char *label, libcrun_error_t *err);

int add_selinux_mount_label (char **ret, const char *data, const char *label, libcrun_error_t *err);

int set_apparmor_profile (const char *profile, libcrun_error_t *err);
int set_apparmor_profile (const char *profile, bool no_new_privileges, libcrun_error_t *err);

int read_all_fd (int fd, const char *description, char **out, size_t *len, libcrun_error_t *err);

Expand Down

0 comments on commit e276960

Please sign in to comment.