Avoid unshifted ouids for socket file operations as observed when using AppArmor profiles in unprivileged containers with LXD or Incus.
For example, root inside container and uid 1000000 outside, with `owner /root/sock rw,` profile entry for nc: /root$ nc -lkU sock & nc -U sock ==> dmesg apparmor="DENIED" operation="connect" class="file" namespace="root//lxd-podia_<var-snap-lxd-common-lxd>" profile="sockit" name="/root/sock" pid=3924 comm="nc" requested_mask="wr" denied_mask="wr" fsuid=1000000 ouid=0 [<== should be 1000000] Fix by performing uid mapping as per common_perm_cond() in lsm.c Signed-off-by: Gabriel Totev <[email protected]> --- The example above was taken from an Ubuntu Noble 6.8.0 kernel, which has a different af_unix.c file, which nevertheless contains an identical section that I patched identically and verified the connect operation saw the correctly shifted ouid. I was not able to verify this fix on the mainline kernel as it does not appear to mediate af_unix (due to dcd7a559411e "gate... behind v9 abi"?) and I don't know how to make it do so. I am also not sure how this change should be propagated to the Ubuntu kernel and its differing af_unix.c First time patch mailer so please excuse my ignorance or blunders. security/apparmor/af_unix.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/security/apparmor/af_unix.c b/security/apparmor/af_unix.c index ed4b34b88e38..a1c2b8516681 100644 --- a/security/apparmor/af_unix.c +++ b/security/apparmor/af_unix.c @@ -12,6 +12,7 @@ * License. */ +#include <linux/fs.h> #include <net/tcp_states.h> #include "include/audit.h" @@ -45,8 +46,11 @@ static int unix_fs_perm(const char *op, u32 mask, const struct cred *subj_cred, */ if (u->path.dentry) { /* the sunpath may not be valid for this ns so use the path */ - struct path_cond cond = { u->path.dentry->d_inode->i_uid, - u->path.dentry->d_inode->i_mode + struct inode *inode = u->path.dentry->d_inode; + vfsuid_t vfsuid = i_uid_into_vfsuid(mnt_idmap(u->path.mnt), inode); + struct path_cond cond = { + .uid = vfsuid_into_kuid(vfsuid), + .mode = inode->i_mode, }; return aa_path_perm(op, subj_cred, label, &u->path, -- 2.34.1
