[SRU][J/N/P][PATCH 2/2] apparmor: shift uid when mediating af_unix in userns

John Johansen john.johansen at canonical.com
Tue Aug 26 19:16:58 UTC 2025


On 8/26/25 11:05, Wesley Hershberger wrote:
> From: Gabriel Totev <gabriel.totev at zetier.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/2121257
> 
> 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 <gabriel.totev at zetier.com>
> Fixes: c05e705812d1 ("apparmor: add fine grained af_unix mediation")
> Signed-off-by: John Johansen <john.johansen at canonical.com>
> (backported from commit 3fa0af4cc8a31d4139ee85a7b0e3d9b4f37b3093)
> [whershberger: u->path to path from missing bc6e5f693]
> Signed-off-by: Wesley Hershberger <wesley.hershberger at canonical.com>

Backport looks good, from the AppArmor side

Acked-by: John Johansen <john.johansen at canonical.com>

> ---
>   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 c036bbba814f..9a6ae7b2cf2e 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,




More information about the kernel-team mailing list