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 d1a8dc0 commit ac27cb1
Show file tree
Hide file tree
Showing 3 changed files with 23 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 @@ -3232,7 +3232,7 @@ int
libcrun_set_apparmor_profile (runtime_spec_schema_config_schema_process *proc, bool now, libcrun_error_t *err)
{
if (proc->apparmor_profile)
return set_apparmor_profile (proc->apparmor_profile, now, err);
return set_apparmor_profile (proc->apparmor_profile, proc->no_new_privileges, now, err);
return 0;
}

Expand Down
24 changes: 21 additions & 3 deletions src/libcrun/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -897,8 +897,23 @@ 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 bytes_read = read(fd, buf, sizeof(buf) - 1);
close(fd);
if (bytes_read != -1)
return (strncmp(buf, "unconfined", bytes_read) != 0 && buf != '\0');
}
return crun_make_error (err, errno, "error reading file /proc/thread-self/attr/current");
}

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

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

xasprintf (&buf, "%s %s", now ? "changeprofile" : "exec", 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": now ? "changeprofile" : "exec", profile);

return set_security_attr ("apparmor", now ? "current" : "exec", buf, 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 @@ -293,7 +293,7 @@ int set_selinux_label (const char *label, bool now, libcrun_error_t *err);

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

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

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

Expand Down

0 comments on commit ac27cb1

Please sign in to comment.