LCOV - code coverage report
Current view: top level - include/linux - mnt_idmapping.h (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 17 17 100.0 %
Date: 2023-07-31 20:08:12 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0 */
       2             : #ifndef _LINUX_MNT_IDMAPPING_H
       3             : #define _LINUX_MNT_IDMAPPING_H
       4             : 
       5             : #include <linux/types.h>
       6             : #include <linux/uidgid.h>
       7             : 
       8             : struct mnt_idmap;
       9             : struct user_namespace;
      10             : 
      11             : extern struct mnt_idmap nop_mnt_idmap;
      12             : extern struct user_namespace init_user_ns;
      13             : 
      14             : typedef struct {
      15             :         uid_t val;
      16             : } vfsuid_t;
      17             : 
      18             : typedef struct {
      19             :         gid_t val;
      20             : } vfsgid_t;
      21             : 
      22             : static_assert(sizeof(vfsuid_t) == sizeof(kuid_t));
      23             : static_assert(sizeof(vfsgid_t) == sizeof(kgid_t));
      24             : static_assert(offsetof(vfsuid_t, val) == offsetof(kuid_t, val));
      25             : static_assert(offsetof(vfsgid_t, val) == offsetof(kgid_t, val));
      26             : 
      27             : #ifdef CONFIG_MULTIUSER
      28             : static inline uid_t __vfsuid_val(vfsuid_t uid)
      29             : {
      30  1497131100 :         return uid.val;
      31             : }
      32             : 
      33             : static inline gid_t __vfsgid_val(vfsgid_t gid)
      34             : {
      35  1535169708 :         return gid.val;
      36             : }
      37             : #else
      38             : static inline uid_t __vfsuid_val(vfsuid_t uid)
      39             : {
      40             :         return 0;
      41             : }
      42             : 
      43             : static inline gid_t __vfsgid_val(vfsgid_t gid)
      44             : {
      45             :         return 0;
      46             : }
      47             : #endif
      48             : 
      49             : static inline bool vfsuid_valid(vfsuid_t uid)
      50             : {
      51    26481751 :         return __vfsuid_val(uid) != (uid_t)-1;
      52             : }
      53             : 
      54             : static inline bool vfsgid_valid(vfsgid_t gid)
      55             : {
      56    24337603 :         return __vfsgid_val(gid) != (gid_t)-1;
      57             : }
      58             : 
      59             : static inline bool vfsuid_eq(vfsuid_t left, vfsuid_t right)
      60             : {
      61    52148197 :         return vfsuid_valid(left) && __vfsuid_val(left) == __vfsuid_val(right);
      62             : }
      63             : 
      64             : static inline bool vfsgid_eq(vfsgid_t left, vfsgid_t right)
      65             : {
      66    47368208 :         return vfsgid_valid(left) && __vfsgid_val(left) == __vfsgid_val(right);
      67             : }
      68             : 
      69             : /**
      70             :  * vfsuid_eq_kuid - check whether kuid and vfsuid have the same value
      71             :  * @vfsuid: the vfsuid to compare
      72             :  * @kuid: the kuid to compare
      73             :  *
      74             :  * Check whether @vfsuid and @kuid have the same values.
      75             :  *
      76             :  * Return: true if @vfsuid and @kuid have the same value, false if not.
      77             :  * Comparison between two invalid uids returns false.
      78             :  */
      79             : static inline bool vfsuid_eq_kuid(vfsuid_t vfsuid, kuid_t kuid)
      80             : {
      81 63138202619 :         return vfsuid_valid(vfsuid) && __vfsuid_val(vfsuid) == __kuid_val(kuid);
      82             : }
      83             : 
      84             : /**
      85             :  * vfsgid_eq_kgid - check whether kgid and vfsgid have the same value
      86             :  * @vfsgid: the vfsgid to compare
      87             :  * @kgid: the kgid to compare
      88             :  *
      89             :  * Check whether @vfsgid and @kgid have the same values.
      90             :  *
      91             :  * Return: true if @vfsgid and @kgid have the same value, false if not.
      92             :  * Comparison between two invalid gids returns false.
      93             :  */
      94             : static inline bool vfsgid_eq_kgid(vfsgid_t vfsgid, kgid_t kgid)
      95             : {
      96             :         return vfsgid_valid(vfsgid) && __vfsgid_val(vfsgid) == __kgid_val(kgid);
      97             : }
      98             : 
      99             : /*
     100             :  * vfs{g,u}ids are created from k{g,u}ids.
     101             :  * We don't allow them to be created from regular {u,g}id.
     102             :  */
     103             : #define VFSUIDT_INIT(val) (vfsuid_t){ __kuid_val(val) }
     104             : #define VFSGIDT_INIT(val) (vfsgid_t){ __kgid_val(val) }
     105             : 
     106             : #define INVALID_VFSUID VFSUIDT_INIT(INVALID_UID)
     107             : #define INVALID_VFSGID VFSGIDT_INIT(INVALID_GID)
     108             : 
     109             : /*
     110             :  * Allow a vfs{g,u}id to be used as a k{g,u}id where we want to compare
     111             :  * whether the mapped value is identical to value of a k{g,u}id.
     112             :  */
     113             : #define AS_KUIDT(val) (kuid_t){ __vfsuid_val(val) }
     114             : #define AS_KGIDT(val) (kgid_t){ __vfsgid_val(val) }
     115             : 
     116             : int vfsgid_in_group_p(vfsgid_t vfsgid);
     117             : 
     118             : vfsuid_t make_vfsuid(struct mnt_idmap *idmap,
     119             :                      struct user_namespace *fs_userns, kuid_t kuid);
     120             : 
     121             : vfsgid_t make_vfsgid(struct mnt_idmap *idmap,
     122             :                      struct user_namespace *fs_userns, kgid_t kgid);
     123             : 
     124             : kuid_t from_vfsuid(struct mnt_idmap *idmap,
     125             :                    struct user_namespace *fs_userns, vfsuid_t vfsuid);
     126             : 
     127             : kgid_t from_vfsgid(struct mnt_idmap *idmap,
     128             :                    struct user_namespace *fs_userns, vfsgid_t vfsgid);
     129             : 
     130             : /**
     131             :  * vfsuid_has_fsmapping - check whether a vfsuid maps into the filesystem
     132             :  * @idmap: the mount's idmapping
     133             :  * @fs_userns: the filesystem's idmapping
     134             :  * @vfsuid: vfsuid to be mapped
     135             :  *
     136             :  * Check whether @vfsuid has a mapping in the filesystem idmapping. Use this
     137             :  * function to check whether the filesystem idmapping has a mapping for
     138             :  * @vfsuid.
     139             :  *
     140             :  * Return: true if @vfsuid has a mapping in the filesystem, false if not.
     141             :  */
     142             : static inline bool vfsuid_has_fsmapping(struct mnt_idmap *idmap,
     143             :                                         struct user_namespace *fs_userns,
     144             :                                         vfsuid_t vfsuid)
     145             : {
     146    18317725 :         return uid_valid(from_vfsuid(idmap, fs_userns, vfsuid));
     147             : }
     148             : 
     149             : static inline bool vfsuid_has_mapping(struct user_namespace *userns,
     150             :                                       vfsuid_t vfsuid)
     151             : {
     152    12537202 :         return from_kuid(userns, AS_KUIDT(vfsuid)) != (uid_t)-1;
     153             : }
     154             : 
     155             : /**
     156             :  * vfsuid_into_kuid - convert vfsuid into kuid
     157             :  * @vfsuid: the vfsuid to convert
     158             :  *
     159             :  * This can be used when a vfsuid is committed as a kuid.
     160             :  *
     161             :  * Return: a kuid with the value of @vfsuid
     162             :  */
     163             : static inline kuid_t vfsuid_into_kuid(vfsuid_t vfsuid)
     164             : {
     165 72650844538 :         return AS_KUIDT(vfsuid);
     166             : }
     167             : 
     168             : /**
     169             :  * vfsgid_has_fsmapping - check whether a vfsgid maps into the filesystem
     170             :  * @idmap: the mount's idmapping
     171             :  * @fs_userns: the filesystem's idmapping
     172             :  * @vfsgid: vfsgid to be mapped
     173             :  *
     174             :  * Check whether @vfsgid has a mapping in the filesystem idmapping. Use this
     175             :  * function to check whether the filesystem idmapping has a mapping for
     176             :  * @vfsgid.
     177             :  *
     178             :  * Return: true if @vfsgid has a mapping in the filesystem, false if not.
     179             :  */
     180             : static inline bool vfsgid_has_fsmapping(struct mnt_idmap *idmap,
     181             :                                         struct user_namespace *fs_userns,
     182             :                                         vfsgid_t vfsgid)
     183             : {
     184    18275508 :         return gid_valid(from_vfsgid(idmap, fs_userns, vfsgid));
     185             : }
     186             : 
     187             : static inline bool vfsgid_has_mapping(struct user_namespace *userns,
     188             :                                       vfsgid_t vfsgid)
     189             : {
     190      309086 :         return from_kgid(userns, AS_KGIDT(vfsgid)) != (gid_t)-1;
     191             : }
     192             : 
     193             : /**
     194             :  * vfsgid_into_kgid - convert vfsgid into kgid
     195             :  * @vfsgid: the vfsgid to convert
     196             :  *
     197             :  * This can be used when a vfsgid is committed as a kgid.
     198             :  *
     199             :  * Return: a kgid with the value of @vfsgid
     200             :  */
     201             : static inline kgid_t vfsgid_into_kgid(vfsgid_t vfsgid)
     202             : {
     203 72709226979 :         return AS_KGIDT(vfsgid);
     204             : }
     205             : 
     206             : /**
     207             :  * mapped_fsuid - return caller's fsuid mapped according to an idmapping
     208             :  * @idmap: the mount's idmapping
     209             :  * @fs_userns: the filesystem's idmapping
     210             :  *
     211             :  * Use this helper to initialize a new vfs or filesystem object based on
     212             :  * the caller's fsuid. A common example is initializing the i_uid field of
     213             :  * a newly allocated inode triggered by a creation event such as mkdir or
     214             :  * O_CREAT. Other examples include the allocation of quotas for a specific
     215             :  * user.
     216             :  *
     217             :  * Return: the caller's current fsuid mapped up according to @idmap.
     218             :  */
     219  1406326890 : static inline kuid_t mapped_fsuid(struct mnt_idmap *idmap,
     220             :                                   struct user_namespace *fs_userns)
     221             : {
     222  1406326890 :         return from_vfsuid(idmap, fs_userns, VFSUIDT_INIT(current_fsuid()));
     223             : }
     224             : 
     225             : /**
     226             :  * mapped_fsgid - return caller's fsgid mapped according to an idmapping
     227             :  * @idmap: the mount's idmapping
     228             :  * @fs_userns: the filesystem's idmapping
     229             :  *
     230             :  * Use this helper to initialize a new vfs or filesystem object based on
     231             :  * the caller's fsgid. A common example is initializing the i_gid field of
     232             :  * a newly allocated inode triggered by a creation event such as mkdir or
     233             :  * O_CREAT. Other examples include the allocation of quotas for a specific
     234             :  * user.
     235             :  *
     236             :  * Return: the caller's current fsgid mapped up according to @idmap.
     237             :  */
     238  1406254604 : static inline kgid_t mapped_fsgid(struct mnt_idmap *idmap,
     239             :                                   struct user_namespace *fs_userns)
     240             : {
     241  1406254604 :         return from_vfsgid(idmap, fs_userns, VFSGIDT_INIT(current_fsgid()));
     242             : }
     243             : 
     244             : bool check_fsmapping(const struct mnt_idmap *idmap,
     245             :                      const struct super_block *sb);
     246             : 
     247             : #endif /* _LINUX_MNT_IDMAPPING_H */

Generated by: LCOV version 1.14