mnt_idmapping.h (7838B)
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 8struct 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 */ 14extern 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 */ 25static 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 */ 44static inline bool no_idmapping(const struct user_namespace *mnt_userns, 45 const struct user_namespace *fs_userns) 46{ 47 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 */ 70static 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 if (no_idmapping(mnt_userns, fs_userns)) 77 return kuid; 78 if (initial_idmapping(fs_userns)) 79 uid = __kuid_val(kuid); 80 else 81 uid = from_kuid(fs_userns, kuid); 82 if (uid == (uid_t)-1) 83 return INVALID_UID; 84 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 */ 107static 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 if (no_idmapping(mnt_userns, fs_userns)) 114 return kgid; 115 if (initial_idmapping(fs_userns)) 116 gid = __kgid_val(kgid); 117 else 118 gid = from_kgid(fs_userns, kgid); 119 if (gid == (gid_t)-1) 120 return INVALID_GID; 121 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 */ 144static 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 if (no_idmapping(mnt_userns, fs_userns)) 151 return kuid; 152 uid = from_kuid(mnt_userns, kuid); 153 if (uid == (uid_t)-1) 154 return INVALID_UID; 155 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 */ 180static 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 if (no_idmapping(mnt_userns, fs_userns)) 187 return kgid; 188 gid = from_kgid(mnt_userns, kgid); 189 if (gid == (gid_t)-1) 190 return INVALID_GID; 191 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 */ 209static inline kuid_t mapped_fsuid(struct user_namespace *mnt_userns, 210 struct user_namespace *fs_userns) 211{ 212 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 */ 228static inline kgid_t mapped_fsgid(struct user_namespace *mnt_userns, 229 struct user_namespace *fs_userns) 230{ 231 return mapped_kgid_user(mnt_userns, fs_userns, current_fsgid()); 232} 233 234#endif /* _LINUX_MNT_IDMAPPING_H */