]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
apparmor: userns: Add support for execpath in userns
authorMaxime Bélair <maxime.belair@canonical.com>
Mon, 21 Jul 2025 14:46:44 +0000 (16:46 +0200)
committerJohn Johansen <john.johansen@canonical.com>
Thu, 29 Jan 2026 09:27:53 +0000 (01:27 -0800)
This new field allows reliable identification of the binary that
triggered a denial since the existing field (comm) only gives the name of
the binary, not its path. Thus comm doesn't work for binaries outside of
$PATH or works unreliably when two binaries have the same name.
Additionally comm can be modified by a program, for example, comm="(tor)"
or comm=4143504920506F6C6C6572 (= ACPI Poller).

Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
security/apparmor/task.c

index c9bc9cc694750b231eb7572f74c6d94c16b5e774..0db0e81b460017de8e623df75366181a45fc1ed0 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/gfp.h>
 #include <linux/ptrace.h>
 
+#include "include/path.h"
 #include "include/audit.h"
 #include "include/cred.h"
 #include "include/policy.h"
@@ -300,16 +301,47 @@ int aa_may_ptrace(const struct cred *tracer_cred, struct aa_label *tracer,
                                            xrequest, &sa));
 }
 
+static const char *get_current_exe_path(char *buffer, int buffer_size)
+{
+       struct file *exe_file;
+       struct path p;
+       const char *path_str;
+
+       exe_file = get_task_exe_file(current);
+       if (!exe_file)
+               return ERR_PTR(-ENOENT);
+       p = exe_file->f_path;
+       path_get(&p);
+
+       if (aa_path_name(&p, FLAG_VIEW_SUBNS, buffer, &path_str, NULL, NULL))
+               return ERR_PTR(-ENOMEM);
+
+       fput(exe_file);
+       path_put(&p);
+
+       return path_str;
+}
+
 /* call back to audit ptrace fields */
 static void audit_ns_cb(struct audit_buffer *ab, void *va)
 {
        struct apparmor_audit_data *ad = aad_of_va(va);
+       char *buffer;
+       const char *path;
 
        if (ad->request & AA_USERNS_CREATE)
                audit_log_format(ab, " requested=\"userns_create\"");
 
        if (ad->denied & AA_USERNS_CREATE)
                audit_log_format(ab, " denied=\"userns_create\"");
+
+       buffer = aa_get_buffer(false);
+       if (!buffer)
+               return; // OOM
+       path = get_current_exe_path(buffer, aa_g_path_max);
+       if (!IS_ERR(path))
+               audit_log_format(ab, " execpath=\"%s\"", path);
+       aa_put_buffer(buffer);
 }
 
 int aa_profile_ns_perm(struct aa_profile *profile,