Capabilities patch for v6.19

There is only a single commit,
 
    Clarify the rootid_owns_currentns
 
 which introduces no functional change.  Ryan Foster had sent a patch
 to add testing of the security/commoncap.c:rootid_owns_currentns()
 function.  The patch pointed out that this function was not as clear
 as it should be.
 
 This commit has two purposes:
 
 1. Clarify the intent of the function in the name
 2. Split the function so that the base functionality is easier
    to test from a kunit test.
 
 This commit has been in linux-next since November 18 with no reported
 issues.  Ryan has posted an updated test patch based on this commit.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEqb0/8XByttt4D8+UNXDaFycKziQFAmkyJQsACgkQNXDaFycK
 ziTuVAgAuNKlx3SH2G9JAk75pyg3LB5DOHZo9SUXeyPJ0E5Mr2zsYEBDfrL0Ai7N
 ERIMdGHu07xeVeO/zRCpHqV0ghiKX8PNKk41Ck0+SIBDw4CQ/OVEql2WJB229YRI
 0MljanjV9Zi3WPREpXQd7Hj0cYKIff+ZgzQ/CBKN4co5HH9VXkggnm13zXoejQiR
 GZOsV/uVkLeXy9wXBsnySZ4p5PkCiqsDn8dp7RgNSHLDoh4s+Aj0zvxlCyeNr2IY
 tKS8iXsxMWgZyVsP6VOZkSRvXRTzgL8My+zCnCV10j8aHvw/LKrKW+iGePHDu6Pa
 CTw2S4I+AhIy0KtYKZSqqvllnX/low==
 =MaY2
 -----END PGP SIGNATURE-----

Merge tag 'caps-pr-20251204' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux

Pull capabilities update from Serge Hallyn:
 "Ryan Foster had sent a patch to add testing of the
  rootid_owns_currentns() function. That patch pointed out
  that this function was not as clear as it should be. Fix it:

   - Clarify the intent of the function in the name

   - Split the function so that the base functionality is easier to test
     from a kunit test"

* tag 'caps-pr-20251204' of git://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux:
  Clarify the rootid_owns_currentns
This commit is contained in:
Linus Torvalds 2025-12-04 20:10:28 -08:00
commit 2061f18ad7
1 changed files with 22 additions and 12 deletions

View File

@ -358,17 +358,17 @@ int cap_inode_killpriv(struct mnt_idmap *idmap, struct dentry *dentry)
return error; return error;
} }
static bool rootid_owns_currentns(vfsuid_t rootvfsuid) /**
* kuid_root_in_ns - check whether the given kuid is root in the given ns
* @kuid: the kuid to be tested
* @ns: the user namespace to test against
*
* Returns true if @kuid represents the root user in @ns, false otherwise.
*/
static bool kuid_root_in_ns(kuid_t kuid, struct user_namespace *ns)
{ {
struct user_namespace *ns; for (;; ns = ns->parent) {
kuid_t kroot; if (from_kuid(ns, kuid) == 0)
if (!vfsuid_valid(rootvfsuid))
return false;
kroot = vfsuid_into_kuid(rootvfsuid);
for (ns = current_user_ns();; ns = ns->parent) {
if (from_kuid(ns, kroot) == 0)
return true; return true;
if (ns == &init_user_ns) if (ns == &init_user_ns)
break; break;
@ -377,6 +377,16 @@ static bool rootid_owns_currentns(vfsuid_t rootvfsuid)
return false; return false;
} }
static bool vfsuid_root_in_currentns(vfsuid_t vfsuid)
{
kuid_t kuid;
if (!vfsuid_valid(vfsuid))
return false;
kuid = vfsuid_into_kuid(vfsuid);
return kuid_root_in_ns(kuid, current_user_ns());
}
static __u32 sansflags(__u32 m) static __u32 sansflags(__u32 m)
{ {
return m & ~VFS_CAP_FLAGS_EFFECTIVE; return m & ~VFS_CAP_FLAGS_EFFECTIVE;
@ -481,7 +491,7 @@ int cap_inode_getsecurity(struct mnt_idmap *idmap,
goto out_free; goto out_free;
} }
if (!rootid_owns_currentns(vfsroot)) { if (!vfsuid_root_in_currentns(vfsroot)) {
size = -EOVERFLOW; size = -EOVERFLOW;
goto out_free; goto out_free;
} }
@ -722,7 +732,7 @@ int get_vfs_caps_from_disk(struct mnt_idmap *idmap,
/* Limit the caps to the mounter of the filesystem /* Limit the caps to the mounter of the filesystem
* or the more limited uid specified in the xattr. * or the more limited uid specified in the xattr.
*/ */
if (!rootid_owns_currentns(rootvfsuid)) if (!vfsuid_root_in_currentns(rootvfsuid))
return -ENODATA; return -ENODATA;
cpu_caps->permitted.val = le32_to_cpu(caps->data[0].permitted); cpu_caps->permitted.val = le32_to_cpu(caps->data[0].permitted);