Commit 7cf7eed1 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'fs.idmapped.v5.16-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux

Pull setattr idmapping fix from Christian Brauner:
 "This contains a simple fix for setattr. When determining the validity
  of the attributes the ia_{g,u}id fields contain the value that will be
  written to inode->i_{g,u}id. When the {g,u}id attribute of the file
  isn't altered and the caller's fs{g,u}id matches the current {g,u}id
  attribute the attribute change is allowed.

  The value in ia_{g,u}id does already account for idmapped mounts and
  will have taken the relevant idmapping into account. So in order to
  verify that the {g,u}id attribute isn't changed we simple need to
  compare the ia_{g,u}id value against the inode's i_{g,u}id value.

  This only has any meaning for idmapped mounts as idmapping helpers are
  idempotent without them. And for idmapped mounts this really only has
  a meaning when circular idmappings are used, i.e. mappings where e.g.
  id 1000 is mapped to id 1001 and id 1001 is mapped to id 1000. Such
  ciruclar mappings can e.g. be useful when sharing the same home
  directory between multiple users at the same time.

  Before this patch we could end up denying legitimate attribute changes
  and allowing invalid attribute changes when circular mappings are
  used. To even get into this situation the caller must've been
  privileged both to create that mapping and to create that idmapped
  mount.

  This hasn't been seen in the wild anywhere but came up when expanding
  the fstest suite during work on a series of hardening patches. All
  idmapped fstests pass without any regressions and we're adding new
  tests to verify the behavior of circular mappings.

  The new tests can be found at [1]"

Link: https://lore.kernel.org/linux-fsdevel/20211109145713.1868404-2-brauner@kernel.org [1]

* tag 'fs.idmapped.v5.16-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux:
  fs: handle circular mappings correctly
parents a6a6d227 96821970
...@@ -35,7 +35,7 @@ static bool chown_ok(struct user_namespace *mnt_userns, ...@@ -35,7 +35,7 @@ static bool chown_ok(struct user_namespace *mnt_userns,
kuid_t uid) kuid_t uid)
{ {
kuid_t kuid = i_uid_into_mnt(mnt_userns, inode); kuid_t kuid = i_uid_into_mnt(mnt_userns, inode);
if (uid_eq(current_fsuid(), kuid) && uid_eq(uid, kuid)) if (uid_eq(current_fsuid(), kuid) && uid_eq(uid, inode->i_uid))
return true; return true;
if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN)) if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN))
return true; return true;
...@@ -62,7 +62,7 @@ static bool chgrp_ok(struct user_namespace *mnt_userns, ...@@ -62,7 +62,7 @@ static bool chgrp_ok(struct user_namespace *mnt_userns,
{ {
kgid_t kgid = i_gid_into_mnt(mnt_userns, inode); kgid_t kgid = i_gid_into_mnt(mnt_userns, inode);
if (uid_eq(current_fsuid(), i_uid_into_mnt(mnt_userns, inode)) && if (uid_eq(current_fsuid(), i_uid_into_mnt(mnt_userns, inode)) &&
(in_group_p(gid) || gid_eq(gid, kgid))) (in_group_p(gid) || gid_eq(gid, inode->i_gid)))
return true; return true;
if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN)) if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN))
return true; return true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment