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 user_namespace; 9 : /* 10 : * Carries the initial idmapping of 0:0:4294967295 which is an identity 11 : * mapping. This means that {g,u}id 0 is mapped to {g,u}id 0, {g,u}id 1 is 12 : * mapped to {g,u}id 1, [...], {g,u}id 1000 to {g,u}id 1000, [...]. 13 : */ 14 : extern struct user_namespace init_user_ns; 15 : 16 : /** 17 : * initial_idmapping - check whether this is the initial mapping 18 : * @ns: idmapping to check 19 : * 20 : * Check whether this is the initial mapping, mapping 0 to 0, 1 to 1, 21 : * [...], 1000 to 1000 [...]. 22 : * 23 : * Return: true if this is the initial mapping, false if not. 24 : */ 25 : static inline bool initial_idmapping(const struct user_namespace *ns) 26 : { 27 : return ns == &init_user_ns; 28 : } 29 : 30 : /** 31 : * no_idmapping - check whether we can skip remapping a kuid/gid 32 : * @mnt_userns: the mount's idmapping 33 : * @fs_userns: the filesystem's idmapping 34 : * 35 : * This function can be used to check whether a remapping between two 36 : * idmappings is required. 37 : * An idmapped mount is a mount that has an idmapping attached to it that 38 : * is different from the filsystem's idmapping and the initial idmapping. 39 : * If the initial mapping is used or the idmapping of the mount and the 40 : * filesystem are identical no remapping is required. 41 : * 42 : * Return: true if remapping can be skipped, false if not. 43 : */ 44 : static inline bool no_idmapping(const struct user_namespace *mnt_userns, 45 : const struct user_namespace *fs_userns) 46 : { 47 32 : return initial_idmapping(mnt_userns) || mnt_userns == fs_userns; 48 : } 49 : 50 : /** 51 : * mapped_kuid_fs - map a filesystem kuid into a mnt_userns 52 : * @mnt_userns: the mount's idmapping 53 : * @fs_userns: the filesystem's idmapping 54 : * @kuid : kuid to be mapped 55 : * 56 : * Take a @kuid and remap it from @fs_userns into @mnt_userns. Use this 57 : * function when preparing a @kuid to be reported to userspace. 58 : * 59 : * If no_idmapping() determines that this is not an idmapped mount we can 60 : * simply return @kuid unchanged. 61 : * If initial_idmapping() tells us that the filesystem is not mounted with an 62 : * idmapping we know the value of @kuid won't change when calling 63 : * from_kuid() so we can simply retrieve the value via __kuid_val() 64 : * directly. 65 : * 66 : * Return: @kuid mapped according to @mnt_userns. 67 : * If @kuid has no mapping in either @mnt_userns or @fs_userns INVALID_UID is 68 : * returned. 69 : */ 70 : static inline kuid_t mapped_kuid_fs(struct user_namespace *mnt_userns, 71 : struct user_namespace *fs_userns, 72 : kuid_t kuid) 73 : { 74 : uid_t uid; 75 : 76 13 : if (no_idmapping(mnt_userns, fs_userns)) 77 : return kuid; 78 0 : if (initial_idmapping(fs_userns)) 79 : uid = __kuid_val(kuid); 80 : else 81 : uid = from_kuid(fs_userns, kuid); 82 0 : if (uid == (uid_t)-1) 83 : return INVALID_UID; 84 0 : return make_kuid(mnt_userns, uid); 85 : } 86 : 87 : /** 88 : * mapped_kgid_fs - map a filesystem kgid into a mnt_userns 89 : * @mnt_userns: the mount's idmapping 90 : * @fs_userns: the filesystem's idmapping 91 : * @kgid : kgid to be mapped 92 : * 93 : * Take a @kgid and remap it from @fs_userns into @mnt_userns. Use this 94 : * function when preparing a @kgid to be reported to userspace. 95 : * 96 : * If no_idmapping() determines that this is not an idmapped mount we can 97 : * simply return @kgid unchanged. 98 : * If initial_idmapping() tells us that the filesystem is not mounted with an 99 : * idmapping we know the value of @kgid won't change when calling 100 : * from_kgid() so we can simply retrieve the value via __kgid_val() 101 : * directly. 102 : * 103 : * Return: @kgid mapped according to @mnt_userns. 104 : * If @kgid has no mapping in either @mnt_userns or @fs_userns INVALID_GID is 105 : * returned. 106 : */ 107 : static inline kgid_t mapped_kgid_fs(struct user_namespace *mnt_userns, 108 : struct user_namespace *fs_userns, 109 : kgid_t kgid) 110 : { 111 : gid_t gid; 112 : 113 3 : if (no_idmapping(mnt_userns, fs_userns)) 114 : return kgid; 115 0 : if (initial_idmapping(fs_userns)) 116 : gid = __kgid_val(kgid); 117 : else 118 : gid = from_kgid(fs_userns, kgid); 119 0 : if (gid == (gid_t)-1) 120 : return INVALID_GID; 121 0 : return make_kgid(mnt_userns, gid); 122 : } 123 : 124 : /** 125 : * mapped_kuid_user - map a user kuid into a mnt_userns 126 : * @mnt_userns: the mount's idmapping 127 : * @fs_userns: the filesystem's idmapping 128 : * @kuid : kuid to be mapped 129 : * 130 : * Use the idmapping of @mnt_userns to remap a @kuid into @fs_userns. Use this 131 : * function when preparing a @kuid to be written to disk or inode. 132 : * 133 : * If no_idmapping() determines that this is not an idmapped mount we can 134 : * simply return @kuid unchanged. 135 : * If initial_idmapping() tells us that the filesystem is not mounted with an 136 : * idmapping we know the value of @kuid won't change when calling 137 : * make_kuid() so we can simply retrieve the value via KUIDT_INIT() 138 : * directly. 139 : * 140 : * Return: @kuid mapped according to @mnt_userns. 141 : * If @kuid has no mapping in either @mnt_userns or @fs_userns INVALID_UID is 142 : * returned. 143 : */ 144 : static inline kuid_t mapped_kuid_user(struct user_namespace *mnt_userns, 145 : struct user_namespace *fs_userns, 146 : kuid_t kuid) 147 : { 148 : uid_t uid; 149 : 150 8 : if (no_idmapping(mnt_userns, fs_userns)) 151 : return kuid; 152 0 : uid = from_kuid(mnt_userns, kuid); 153 0 : if (uid == (uid_t)-1) 154 : return INVALID_UID; 155 0 : if (initial_idmapping(fs_userns)) 156 : return KUIDT_INIT(uid); 157 : return make_kuid(fs_userns, uid); 158 : } 159 : 160 : /** 161 : * mapped_kgid_user - map a user kgid into a mnt_userns 162 : * @mnt_userns: the mount's idmapping 163 : * @fs_userns: the filesystem's idmapping 164 : * @kgid : kgid to be mapped 165 : * 166 : * Use the idmapping of @mnt_userns to remap a @kgid into @fs_userns. Use this 167 : * function when preparing a @kgid to be written to disk or inode. 168 : * 169 : * If no_idmapping() determines that this is not an idmapped mount we can 170 : * simply return @kgid unchanged. 171 : * If initial_idmapping() tells us that the filesystem is not mounted with an 172 : * idmapping we know the value of @kgid won't change when calling 173 : * make_kgid() so we can simply retrieve the value via KGIDT_INIT() 174 : * directly. 175 : * 176 : * Return: @kgid mapped according to @mnt_userns. 177 : * If @kgid has no mapping in either @mnt_userns or @fs_userns INVALID_GID is 178 : * returned. 179 : */ 180 : static inline kgid_t mapped_kgid_user(struct user_namespace *mnt_userns, 181 : struct user_namespace *fs_userns, 182 : kgid_t kgid) 183 : { 184 : gid_t gid; 185 : 186 8 : if (no_idmapping(mnt_userns, fs_userns)) 187 : return kgid; 188 0 : gid = from_kgid(mnt_userns, kgid); 189 0 : if (gid == (gid_t)-1) 190 : return INVALID_GID; 191 0 : if (initial_idmapping(fs_userns)) 192 : return KGIDT_INIT(gid); 193 : return make_kgid(fs_userns, gid); 194 : } 195 : 196 : /** 197 : * mapped_fsuid - return caller's fsuid mapped up into a mnt_userns 198 : * @mnt_userns: the mount's idmapping 199 : * @fs_userns: the filesystem's idmapping 200 : * 201 : * Use this helper to initialize a new vfs or filesystem object based on 202 : * the caller's fsuid. A common example is initializing the i_uid field of 203 : * a newly allocated inode triggered by a creation event such as mkdir or 204 : * O_CREAT. Other examples include the allocation of quotas for a specific 205 : * user. 206 : * 207 : * Return: the caller's current fsuid mapped up according to @mnt_userns. 208 : */ 209 : static inline kuid_t mapped_fsuid(struct user_namespace *mnt_userns, 210 : struct user_namespace *fs_userns) 211 : { 212 16 : return mapped_kuid_user(mnt_userns, fs_userns, current_fsuid()); 213 : } 214 : 215 : /** 216 : * mapped_fsgid - return caller's fsgid mapped up into a mnt_userns 217 : * @mnt_userns: the mount's idmapping 218 : * @fs_userns: the filesystem's idmapping 219 : * 220 : * Use this helper to initialize a new vfs or filesystem object based on 221 : * the caller's fsgid. A common example is initializing the i_gid field of 222 : * a newly allocated inode triggered by a creation event such as mkdir or 223 : * O_CREAT. Other examples include the allocation of quotas for a specific 224 : * user. 225 : * 226 : * Return: the caller's current fsgid mapped up according to @mnt_userns. 227 : */ 228 : static inline kgid_t mapped_fsgid(struct user_namespace *mnt_userns, 229 : struct user_namespace *fs_userns) 230 : { 231 16 : return mapped_kgid_user(mnt_userns, fs_userns, current_fsgid()); 232 : } 233 : 234 : #endif /* _LINUX_MNT_IDMAPPING_H */