mnt_idmapping.h (03ab8e6297acd1bc0eedaa050e2a1635c576fd11) mnt_idmapping.h (1e5267cd0895183e09c5bb76da85c674014285d0)
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
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
16typedef struct {
17 uid_t val;
18} vfsuid_t;
19
20typedef struct {
21 gid_t val;
22} vfsgid_t;
23
24#ifdef CONFIG_MULTIUSER
25static inline uid_t __vfsuid_val(vfsuid_t uid)
26{
27 return uid.val;
28}
29
30static inline gid_t __vfsgid_val(vfsgid_t gid)
31{
32 return gid.val;
33}
34#else
35static inline uid_t __vfsuid_val(vfsuid_t uid)
36{
37 return 0;
38}
39
40static inline gid_t __vfsgid_val(vfsgid_t gid)
41{
42 return 0;
43}
44#endif
45
46static inline bool vfsuid_valid(vfsuid_t uid)
47{
48 return __vfsuid_val(uid) != (uid_t)-1;
49}
50
51static inline bool vfsgid_valid(vfsgid_t gid)
52{
53 return __vfsgid_val(gid) != (gid_t)-1;
54}
55
56static inline bool vfsuid_eq(vfsuid_t left, vfsuid_t right)
57{
58 return __vfsuid_val(left) == __vfsuid_val(right);
59}
60
61static inline bool vfsgid_eq(vfsgid_t left, vfsgid_t right)
62{
63 return __vfsgid_val(left) == __vfsgid_val(right);
64}
65
16/**
66/**
67 * vfsuid_eq_kuid - check whether kuid and vfsuid have the same value
68 * @kuid: the kuid to compare
69 * @vfsuid: the vfsuid to compare
70 *
71 * Check whether @kuid and @vfsuid have the same values.
72 *
73 * Return: true if @kuid and @vfsuid have the same value, false if not.
74 */
75static inline bool vfsuid_eq_kuid(vfsuid_t vfsuid, kuid_t kuid)
76{
77 return __vfsuid_val(vfsuid) == __kuid_val(kuid);
78}
79
80/**
81 * vfsgid_eq_kgid - check whether kgid and vfsgid have the same value
82 * @kgid: the kgid to compare
83 * @vfsgid: the vfsgid to compare
84 *
85 * Check whether @kgid and @vfsgid have the same values.
86 *
87 * Return: true if @kgid and @vfsgid have the same value, false if not.
88 */
89static inline bool vfsgid_eq_kgid(kgid_t kgid, vfsgid_t vfsgid)
90{
91 return __vfsgid_val(vfsgid) == __kgid_val(kgid);
92}
93
94/*
95 * vfs{g,u}ids are created from k{g,u}ids.
96 * We don't allow them to be created from regular {u,g}id.
97 */
98#define VFSUIDT_INIT(val) (vfsuid_t){ __kuid_val(val) }
99#define VFSGIDT_INIT(val) (vfsgid_t){ __kgid_val(val) }
100
101#define INVALID_VFSUID VFSUIDT_INIT(INVALID_UID)
102#define INVALID_VFSGID VFSGIDT_INIT(INVALID_GID)
103
104/*
105 * Allow a vfs{g,u}id to be used as a k{g,u}id where we want to compare
106 * whether the mapped value is identical to value of a k{g,u}id.
107 */
108#define AS_KUIDT(val) (kuid_t){ __vfsuid_val(val) }
109#define AS_KGIDT(val) (kgid_t){ __vfsgid_val(val) }
110
111#ifdef CONFIG_MULTIUSER
112/**
113 * vfsgid_in_group_p() - check whether a vfsuid matches the caller's groups
114 * @vfsgid: the mnt gid to match
115 *
116 * This function can be used to determine whether @vfsuid matches any of the
117 * caller's groups.
118 *
119 * Return: 1 if vfsuid matches caller's groups, 0 if not.
120 */
121static inline int vfsgid_in_group_p(vfsgid_t vfsgid)
122{
123 return in_group_p(AS_KGIDT(vfsgid));
124}
125#else
126static inline int vfsgid_in_group_p(vfsgid_t vfsgid)
127{
128 return 1;
129}
130#endif
131
132/**
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 */

--- 37 unchanged lines hidden (view full) ---

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 */
133 * initial_idmapping - check whether this is the initial mapping
134 * @ns: idmapping to check
135 *
136 * Check whether this is the initial mapping, mapping 0 to 0, 1 to 1,
137 * [...], 1000 to 1000 [...].
138 *
139 * Return: true if this is the initial mapping, false if not.
140 */

--- 37 unchanged lines hidden (view full) ---

178 * idmapping we know the value of @kuid won't change when calling
179 * from_kuid() so we can simply retrieve the value via __kuid_val()
180 * directly.
181 *
182 * Return: @kuid mapped according to @mnt_userns.
183 * If @kuid has no mapping in either @mnt_userns or @fs_userns INVALID_UID is
184 * returned.
185 */
70static inline kuid_t mapped_kuid_fs(struct user_namespace *mnt_userns,
71 struct user_namespace *fs_userns,
72 kuid_t kuid)
186
187static inline vfsuid_t make_vfsuid(struct user_namespace *mnt_userns,
188 struct user_namespace *fs_userns,
189 kuid_t kuid)
73{
74 uid_t uid;
75
76 if (no_idmapping(mnt_userns, fs_userns))
190{
191 uid_t uid;
192
193 if (no_idmapping(mnt_userns, fs_userns))
77 return kuid;
194 return VFSUIDT_INIT(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)
195 if (initial_idmapping(fs_userns))
196 uid = __kuid_val(kuid);
197 else
198 uid = from_kuid(fs_userns, kuid);
199 if (uid == (uid_t)-1)
83 return INVALID_UID;
84 return make_kuid(mnt_userns, uid);
200 return INVALID_VFSUID;
201 return VFSUIDT_INIT(make_kuid(mnt_userns, uid));
85}
86
202}
203
204static inline kuid_t mapped_kuid_fs(struct user_namespace *mnt_userns,
205 struct user_namespace *fs_userns,
206 kuid_t kuid)
207{
208 return AS_KUIDT(make_vfsuid(mnt_userns, fs_userns, kuid));
209}
210
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.

--- 4 unchanged lines hidden (view full) ---

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 */
211/**
212 * mapped_kgid_fs - map a filesystem kgid into a mnt_userns
213 * @mnt_userns: the mount's idmapping
214 * @fs_userns: the filesystem's idmapping
215 * @kgid : kgid to be mapped
216 *
217 * Take a @kgid and remap it from @fs_userns into @mnt_userns. Use this
218 * function when preparing a @kgid to be reported to userspace.

--- 4 unchanged lines hidden (view full) ---

223 * idmapping we know the value of @kgid won't change when calling
224 * from_kgid() so we can simply retrieve the value via __kgid_val()
225 * directly.
226 *
227 * Return: @kgid mapped according to @mnt_userns.
228 * If @kgid has no mapping in either @mnt_userns or @fs_userns INVALID_GID is
229 * returned.
230 */
107static inline kgid_t mapped_kgid_fs(struct user_namespace *mnt_userns,
108 struct user_namespace *fs_userns,
109 kgid_t kgid)
231
232static inline vfsgid_t make_vfsgid(struct user_namespace *mnt_userns,
233 struct user_namespace *fs_userns,
234 kgid_t kgid)
110{
111 gid_t gid;
112
113 if (no_idmapping(mnt_userns, fs_userns))
235{
236 gid_t gid;
237
238 if (no_idmapping(mnt_userns, fs_userns))
114 return kgid;
239 return VFSGIDT_INIT(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)
240 if (initial_idmapping(fs_userns))
241 gid = __kgid_val(kgid);
242 else
243 gid = from_kgid(fs_userns, kgid);
244 if (gid == (gid_t)-1)
120 return INVALID_GID;
121 return make_kgid(mnt_userns, gid);
245 return INVALID_VFSGID;
246 return VFSGIDT_INIT(make_kgid(mnt_userns, gid));
122}
123
247}
248
249static inline kgid_t mapped_kgid_fs(struct user_namespace *mnt_userns,
250 struct user_namespace *fs_userns,
251 kgid_t kgid)
252{
253 return AS_KGIDT(make_vfsgid(mnt_userns, fs_userns, kgid));
254}
255
124/**
256/**
257 * from_vfsuid - map a vfsuid into the filesystem idmapping
258 * @mnt_userns: the mount's idmapping
259 * @fs_userns: the filesystem's idmapping
260 * @vfsuid : vfsuid to be mapped
261 *
262 * Map @vfsuid into the filesystem idmapping. This function has to be used in
263 * order to e.g. write @vfsuid to inode->i_uid.
264 *
265 * Return: @vfsuid mapped into the filesystem idmapping
266 */
267static inline kuid_t from_vfsuid(struct user_namespace *mnt_userns,
268 struct user_namespace *fs_userns,
269 vfsuid_t vfsuid)
270{
271 uid_t uid;
272
273 if (no_idmapping(mnt_userns, fs_userns))
274 return AS_KUIDT(vfsuid);
275 uid = from_kuid(mnt_userns, AS_KUIDT(vfsuid));
276 if (uid == (uid_t)-1)
277 return INVALID_UID;
278 if (initial_idmapping(fs_userns))
279 return KUIDT_INIT(uid);
280 return make_kuid(fs_userns, uid);
281}
282
283/**
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 *

--- 7 unchanged lines hidden (view full) ---

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{
284 * mapped_kuid_user - map a user kuid into a mnt_userns
285 * @mnt_userns: the mount's idmapping
286 * @fs_userns: the filesystem's idmapping
287 * @kuid : kuid to be mapped
288 *
289 * Use the idmapping of @mnt_userns to remap a @kuid into @fs_userns. Use this
290 * function when preparing a @kuid to be written to disk or inode.
291 *

--- 7 unchanged lines hidden (view full) ---

299 * Return: @kuid mapped according to @mnt_userns.
300 * If @kuid has no mapping in either @mnt_userns or @fs_userns INVALID_UID is
301 * returned.
302 */
303static inline kuid_t mapped_kuid_user(struct user_namespace *mnt_userns,
304 struct user_namespace *fs_userns,
305 kuid_t kuid)
306{
148 uid_t uid;
307 return from_vfsuid(mnt_userns, fs_userns, VFSUIDT_INIT(kuid));
308}
149
309
310/**
311 * vfsuid_has_fsmapping - check whether a vfsuid maps into the filesystem
312 * @mnt_userns: the mount's idmapping
313 * @fs_userns: the filesystem's idmapping
314 * @vfsuid: vfsuid to be mapped
315 *
316 * Check whether @vfsuid has a mapping in the filesystem idmapping. Use this
317 * function to check whether the filesystem idmapping has a mapping for
318 * @vfsuid.
319 *
320 * Return: true if @vfsuid has a mapping in the filesystem, false if not.
321 */
322static inline bool vfsuid_has_fsmapping(struct user_namespace *mnt_userns,
323 struct user_namespace *fs_userns,
324 vfsuid_t vfsuid)
325{
326 return uid_valid(from_vfsuid(mnt_userns, fs_userns, vfsuid));
327}
328
329/**
330 * from_vfsgid - map a vfsgid into the filesystem idmapping
331 * @mnt_userns: the mount's idmapping
332 * @fs_userns: the filesystem's idmapping
333 * @vfsgid : vfsgid to be mapped
334 *
335 * Map @vfsgid into the filesystem idmapping. This function has to be used in
336 * order to e.g. write @vfsgid to inode->i_gid.
337 *
338 * Return: @vfsgid mapped into the filesystem idmapping
339 */
340static inline kgid_t from_vfsgid(struct user_namespace *mnt_userns,
341 struct user_namespace *fs_userns,
342 vfsgid_t vfsgid)
343{
344 gid_t gid;
345
150 if (no_idmapping(mnt_userns, fs_userns))
346 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;
347 return AS_KGIDT(vfsgid);
348 gid = from_kgid(mnt_userns, AS_KGIDT(vfsgid));
349 if (gid == (gid_t)-1)
350 return INVALID_GID;
155 if (initial_idmapping(fs_userns))
351 if (initial_idmapping(fs_userns))
156 return KUIDT_INIT(uid);
157 return make_kuid(fs_userns, uid);
352 return KGIDT_INIT(gid);
353 return make_kgid(fs_userns, gid);
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 *

--- 10 unchanged lines hidden (view full) ---

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{
354}
355
356/**
357 * mapped_kgid_user - map a user kgid into a mnt_userns
358 * @mnt_userns: the mount's idmapping
359 * @fs_userns: the filesystem's idmapping
360 * @kgid : kgid to be mapped
361 *

--- 10 unchanged lines hidden (view full) ---

372 * Return: @kgid mapped according to @mnt_userns.
373 * If @kgid has no mapping in either @mnt_userns or @fs_userns INVALID_GID is
374 * returned.
375 */
376static inline kgid_t mapped_kgid_user(struct user_namespace *mnt_userns,
377 struct user_namespace *fs_userns,
378 kgid_t kgid)
379{
184 gid_t gid;
380 return from_vfsgid(mnt_userns, fs_userns, VFSGIDT_INIT(kgid));
381}
185
382
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);
383/**
384 * vfsgid_has_fsmapping - check whether a vfsgid maps into the filesystem
385 * @mnt_userns: the mount's idmapping
386 * @fs_userns: the filesystem's idmapping
387 * @vfsgid: vfsgid to be mapped
388 *
389 * Check whether @vfsgid has a mapping in the filesystem idmapping. Use this
390 * function to check whether the filesystem idmapping has a mapping for
391 * @vfsgid.
392 *
393 * Return: true if @vfsgid has a mapping in the filesystem, false if not.
394 */
395static inline bool vfsgid_has_fsmapping(struct user_namespace *mnt_userns,
396 struct user_namespace *fs_userns,
397 vfsgid_t vfsgid)
398{
399 return gid_valid(from_vfsgid(mnt_userns, fs_userns, vfsgid));
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

--- 33 unchanged lines hidden ---
400}
401
402/**
403 * mapped_fsuid - return caller's fsuid mapped up into a mnt_userns
404 * @mnt_userns: the mount's idmapping
405 * @fs_userns: the filesystem's idmapping
406 *
407 * Use this helper to initialize a new vfs or filesystem object based on

--- 33 unchanged lines hidden ---