mnt_idmapping.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _LINUX_MNT_IDMAPPING_H
  3. #define _LINUX_MNT_IDMAPPING_H
  4. #include <linux/types.h>
  5. #include <linux/uidgid.h>
  6. struct user_namespace;
  7. /*
  8. * Carries the initial idmapping of 0:0:4294967295 which is an identity
  9. * mapping. This means that {g,u}id 0 is mapped to {g,u}id 0, {g,u}id 1 is
  10. * mapped to {g,u}id 1, [...], {g,u}id 1000 to {g,u}id 1000, [...].
  11. */
  12. extern struct user_namespace init_user_ns;
  13. typedef struct {
  14. uid_t val;
  15. } vfsuid_t;
  16. typedef struct {
  17. gid_t val;
  18. } vfsgid_t;
  19. static_assert(sizeof(vfsuid_t) == sizeof(kuid_t));
  20. static_assert(sizeof(vfsgid_t) == sizeof(kgid_t));
  21. static_assert(offsetof(vfsuid_t, val) == offsetof(kuid_t, val));
  22. static_assert(offsetof(vfsgid_t, val) == offsetof(kgid_t, val));
  23. #ifdef CONFIG_MULTIUSER
  24. static inline uid_t __vfsuid_val(vfsuid_t uid)
  25. {
  26. return uid.val;
  27. }
  28. static inline gid_t __vfsgid_val(vfsgid_t gid)
  29. {
  30. return gid.val;
  31. }
  32. #else
  33. static inline uid_t __vfsuid_val(vfsuid_t uid)
  34. {
  35. return 0;
  36. }
  37. static inline gid_t __vfsgid_val(vfsgid_t gid)
  38. {
  39. return 0;
  40. }
  41. #endif
  42. static inline bool vfsuid_valid(vfsuid_t uid)
  43. {
  44. return __vfsuid_val(uid) != (uid_t)-1;
  45. }
  46. static inline bool vfsgid_valid(vfsgid_t gid)
  47. {
  48. return __vfsgid_val(gid) != (gid_t)-1;
  49. }
  50. static inline bool vfsuid_eq(vfsuid_t left, vfsuid_t right)
  51. {
  52. return vfsuid_valid(left) && __vfsuid_val(left) == __vfsuid_val(right);
  53. }
  54. static inline bool vfsgid_eq(vfsgid_t left, vfsgid_t right)
  55. {
  56. return vfsgid_valid(left) && __vfsgid_val(left) == __vfsgid_val(right);
  57. }
  58. /**
  59. * vfsuid_eq_kuid - check whether kuid and vfsuid have the same value
  60. * @vfsuid: the vfsuid to compare
  61. * @kuid: the kuid to compare
  62. *
  63. * Check whether @vfsuid and @kuid have the same values.
  64. *
  65. * Return: true if @vfsuid and @kuid have the same value, false if not.
  66. * Comparison between two invalid uids returns false.
  67. */
  68. static inline bool vfsuid_eq_kuid(vfsuid_t vfsuid, kuid_t kuid)
  69. {
  70. return vfsuid_valid(vfsuid) && __vfsuid_val(vfsuid) == __kuid_val(kuid);
  71. }
  72. /**
  73. * vfsgid_eq_kgid - check whether kgid and vfsgid have the same value
  74. * @vfsgid: the vfsgid to compare
  75. * @kgid: the kgid to compare
  76. *
  77. * Check whether @vfsgid and @kgid have the same values.
  78. *
  79. * Return: true if @vfsgid and @kgid have the same value, false if not.
  80. * Comparison between two invalid gids returns false.
  81. */
  82. static inline bool vfsgid_eq_kgid(vfsgid_t vfsgid, kgid_t kgid)
  83. {
  84. return vfsgid_valid(vfsgid) && __vfsgid_val(vfsgid) == __kgid_val(kgid);
  85. }
  86. /*
  87. * vfs{g,u}ids are created from k{g,u}ids.
  88. * We don't allow them to be created from regular {u,g}id.
  89. */
  90. #define VFSUIDT_INIT(val) (vfsuid_t){ __kuid_val(val) }
  91. #define VFSGIDT_INIT(val) (vfsgid_t){ __kgid_val(val) }
  92. #define INVALID_VFSUID VFSUIDT_INIT(INVALID_UID)
  93. #define INVALID_VFSGID VFSGIDT_INIT(INVALID_GID)
  94. /*
  95. * Allow a vfs{g,u}id to be used as a k{g,u}id where we want to compare
  96. * whether the mapped value is identical to value of a k{g,u}id.
  97. */
  98. #define AS_KUIDT(val) (kuid_t){ __vfsuid_val(val) }
  99. #define AS_KGIDT(val) (kgid_t){ __vfsgid_val(val) }
  100. #ifdef CONFIG_MULTIUSER
  101. /**
  102. * vfsgid_in_group_p() - check whether a vfsuid matches the caller's groups
  103. * @vfsgid: the mnt gid to match
  104. *
  105. * This function can be used to determine whether @vfsuid matches any of the
  106. * caller's groups.
  107. *
  108. * Return: 1 if vfsuid matches caller's groups, 0 if not.
  109. */
  110. static inline int vfsgid_in_group_p(vfsgid_t vfsgid)
  111. {
  112. return in_group_p(AS_KGIDT(vfsgid));
  113. }
  114. #else
  115. static inline int vfsgid_in_group_p(vfsgid_t vfsgid)
  116. {
  117. return 1;
  118. }
  119. #endif
  120. /**
  121. * initial_idmapping - check whether this is the initial mapping
  122. * @ns: idmapping to check
  123. *
  124. * Check whether this is the initial mapping, mapping 0 to 0, 1 to 1,
  125. * [...], 1000 to 1000 [...].
  126. *
  127. * Return: true if this is the initial mapping, false if not.
  128. */
  129. static inline bool initial_idmapping(const struct user_namespace *ns)
  130. {
  131. return ns == &init_user_ns;
  132. }
  133. /**
  134. * no_idmapping - check whether we can skip remapping a kuid/gid
  135. * @mnt_userns: the mount's idmapping
  136. * @fs_userns: the filesystem's idmapping
  137. *
  138. * This function can be used to check whether a remapping between two
  139. * idmappings is required.
  140. * An idmapped mount is a mount that has an idmapping attached to it that
  141. * is different from the filsystem's idmapping and the initial idmapping.
  142. * If the initial mapping is used or the idmapping of the mount and the
  143. * filesystem are identical no remapping is required.
  144. *
  145. * Return: true if remapping can be skipped, false if not.
  146. */
  147. static inline bool no_idmapping(const struct user_namespace *mnt_userns,
  148. const struct user_namespace *fs_userns)
  149. {
  150. return initial_idmapping(mnt_userns) || mnt_userns == fs_userns;
  151. }
  152. /**
  153. * make_vfsuid - map a filesystem kuid into a mnt_userns
  154. * @mnt_userns: the mount's idmapping
  155. * @fs_userns: the filesystem's idmapping
  156. * @kuid : kuid to be mapped
  157. *
  158. * Take a @kuid and remap it from @fs_userns into @mnt_userns. Use this
  159. * function when preparing a @kuid to be reported to userspace.
  160. *
  161. * If no_idmapping() determines that this is not an idmapped mount we can
  162. * simply return @kuid unchanged.
  163. * If initial_idmapping() tells us that the filesystem is not mounted with an
  164. * idmapping we know the value of @kuid won't change when calling
  165. * from_kuid() so we can simply retrieve the value via __kuid_val()
  166. * directly.
  167. *
  168. * Return: @kuid mapped according to @mnt_userns.
  169. * If @kuid has no mapping in either @mnt_userns or @fs_userns INVALID_UID is
  170. * returned.
  171. */
  172. static inline vfsuid_t make_vfsuid(struct user_namespace *mnt_userns,
  173. struct user_namespace *fs_userns,
  174. kuid_t kuid)
  175. {
  176. uid_t uid;
  177. if (no_idmapping(mnt_userns, fs_userns))
  178. return VFSUIDT_INIT(kuid);
  179. if (initial_idmapping(fs_userns))
  180. uid = __kuid_val(kuid);
  181. else
  182. uid = from_kuid(fs_userns, kuid);
  183. if (uid == (uid_t)-1)
  184. return INVALID_VFSUID;
  185. return VFSUIDT_INIT(make_kuid(mnt_userns, uid));
  186. }
  187. static inline kuid_t mapped_kuid_fs(struct user_namespace *mnt_userns,
  188. struct user_namespace *fs_userns,
  189. kuid_t kuid)
  190. {
  191. return AS_KUIDT(make_vfsuid(mnt_userns, fs_userns, kuid));
  192. }
  193. /**
  194. * make_vfsgid - map a filesystem kgid into a mnt_userns
  195. * @mnt_userns: the mount's idmapping
  196. * @fs_userns: the filesystem's idmapping
  197. * @kgid : kgid to be mapped
  198. *
  199. * Take a @kgid and remap it from @fs_userns into @mnt_userns. Use this
  200. * function when preparing a @kgid to be reported to userspace.
  201. *
  202. * If no_idmapping() determines that this is not an idmapped mount we can
  203. * simply return @kgid unchanged.
  204. * If initial_idmapping() tells us that the filesystem is not mounted with an
  205. * idmapping we know the value of @kgid won't change when calling
  206. * from_kgid() so we can simply retrieve the value via __kgid_val()
  207. * directly.
  208. *
  209. * Return: @kgid mapped according to @mnt_userns.
  210. * If @kgid has no mapping in either @mnt_userns or @fs_userns INVALID_GID is
  211. * returned.
  212. */
  213. static inline vfsgid_t make_vfsgid(struct user_namespace *mnt_userns,
  214. struct user_namespace *fs_userns,
  215. kgid_t kgid)
  216. {
  217. gid_t gid;
  218. if (no_idmapping(mnt_userns, fs_userns))
  219. return VFSGIDT_INIT(kgid);
  220. if (initial_idmapping(fs_userns))
  221. gid = __kgid_val(kgid);
  222. else
  223. gid = from_kgid(fs_userns, kgid);
  224. if (gid == (gid_t)-1)
  225. return INVALID_VFSGID;
  226. return VFSGIDT_INIT(make_kgid(mnt_userns, gid));
  227. }
  228. static inline kgid_t mapped_kgid_fs(struct user_namespace *mnt_userns,
  229. struct user_namespace *fs_userns,
  230. kgid_t kgid)
  231. {
  232. return AS_KGIDT(make_vfsgid(mnt_userns, fs_userns, kgid));
  233. }
  234. /**
  235. * from_vfsuid - map a vfsuid into the filesystem idmapping
  236. * @mnt_userns: the mount's idmapping
  237. * @fs_userns: the filesystem's idmapping
  238. * @vfsuid : vfsuid to be mapped
  239. *
  240. * Map @vfsuid into the filesystem idmapping. This function has to be used in
  241. * order to e.g. write @vfsuid to inode->i_uid.
  242. *
  243. * Return: @vfsuid mapped into the filesystem idmapping
  244. */
  245. static inline kuid_t from_vfsuid(struct user_namespace *mnt_userns,
  246. struct user_namespace *fs_userns,
  247. vfsuid_t vfsuid)
  248. {
  249. uid_t uid;
  250. if (no_idmapping(mnt_userns, fs_userns))
  251. return AS_KUIDT(vfsuid);
  252. uid = from_kuid(mnt_userns, AS_KUIDT(vfsuid));
  253. if (uid == (uid_t)-1)
  254. return INVALID_UID;
  255. if (initial_idmapping(fs_userns))
  256. return KUIDT_INIT(uid);
  257. return make_kuid(fs_userns, uid);
  258. }
  259. /**
  260. * mapped_kuid_user - map a user kuid into a mnt_userns
  261. * @mnt_userns: the mount's idmapping
  262. * @fs_userns: the filesystem's idmapping
  263. * @kuid : kuid to be mapped
  264. *
  265. * Use the idmapping of @mnt_userns to remap a @kuid into @fs_userns. Use this
  266. * function when preparing a @kuid to be written to disk or inode.
  267. *
  268. * If no_idmapping() determines that this is not an idmapped mount we can
  269. * simply return @kuid unchanged.
  270. * If initial_idmapping() tells us that the filesystem is not mounted with an
  271. * idmapping we know the value of @kuid won't change when calling
  272. * make_kuid() so we can simply retrieve the value via KUIDT_INIT()
  273. * directly.
  274. *
  275. * Return: @kuid mapped according to @mnt_userns.
  276. * If @kuid has no mapping in either @mnt_userns or @fs_userns INVALID_UID is
  277. * returned.
  278. */
  279. static inline kuid_t mapped_kuid_user(struct user_namespace *mnt_userns,
  280. struct user_namespace *fs_userns,
  281. kuid_t kuid)
  282. {
  283. return from_vfsuid(mnt_userns, fs_userns, VFSUIDT_INIT(kuid));
  284. }
  285. /**
  286. * vfsuid_has_fsmapping - check whether a vfsuid maps into the filesystem
  287. * @mnt_userns: the mount's idmapping
  288. * @fs_userns: the filesystem's idmapping
  289. * @vfsuid: vfsuid to be mapped
  290. *
  291. * Check whether @vfsuid has a mapping in the filesystem idmapping. Use this
  292. * function to check whether the filesystem idmapping has a mapping for
  293. * @vfsuid.
  294. *
  295. * Return: true if @vfsuid has a mapping in the filesystem, false if not.
  296. */
  297. static inline bool vfsuid_has_fsmapping(struct user_namespace *mnt_userns,
  298. struct user_namespace *fs_userns,
  299. vfsuid_t vfsuid)
  300. {
  301. return uid_valid(from_vfsuid(mnt_userns, fs_userns, vfsuid));
  302. }
  303. /**
  304. * vfsuid_into_kuid - convert vfsuid into kuid
  305. * @vfsuid: the vfsuid to convert
  306. *
  307. * This can be used when a vfsuid is committed as a kuid.
  308. *
  309. * Return: a kuid with the value of @vfsuid
  310. */
  311. static inline kuid_t vfsuid_into_kuid(vfsuid_t vfsuid)
  312. {
  313. return AS_KUIDT(vfsuid);
  314. }
  315. /**
  316. * from_vfsgid - map a vfsgid into the filesystem idmapping
  317. * @mnt_userns: the mount's idmapping
  318. * @fs_userns: the filesystem's idmapping
  319. * @vfsgid : vfsgid to be mapped
  320. *
  321. * Map @vfsgid into the filesystem idmapping. This function has to be used in
  322. * order to e.g. write @vfsgid to inode->i_gid.
  323. *
  324. * Return: @vfsgid mapped into the filesystem idmapping
  325. */
  326. static inline kgid_t from_vfsgid(struct user_namespace *mnt_userns,
  327. struct user_namespace *fs_userns,
  328. vfsgid_t vfsgid)
  329. {
  330. gid_t gid;
  331. if (no_idmapping(mnt_userns, fs_userns))
  332. return AS_KGIDT(vfsgid);
  333. gid = from_kgid(mnt_userns, AS_KGIDT(vfsgid));
  334. if (gid == (gid_t)-1)
  335. return INVALID_GID;
  336. if (initial_idmapping(fs_userns))
  337. return KGIDT_INIT(gid);
  338. return make_kgid(fs_userns, gid);
  339. }
  340. /**
  341. * mapped_kgid_user - map a user kgid into a mnt_userns
  342. * @mnt_userns: the mount's idmapping
  343. * @fs_userns: the filesystem's idmapping
  344. * @kgid : kgid to be mapped
  345. *
  346. * Use the idmapping of @mnt_userns to remap a @kgid into @fs_userns. Use this
  347. * function when preparing a @kgid to be written to disk or inode.
  348. *
  349. * If no_idmapping() determines that this is not an idmapped mount we can
  350. * simply return @kgid unchanged.
  351. * If initial_idmapping() tells us that the filesystem is not mounted with an
  352. * idmapping we know the value of @kgid won't change when calling
  353. * make_kgid() so we can simply retrieve the value via KGIDT_INIT()
  354. * directly.
  355. *
  356. * Return: @kgid mapped according to @mnt_userns.
  357. * If @kgid has no mapping in either @mnt_userns or @fs_userns INVALID_GID is
  358. * returned.
  359. */
  360. static inline kgid_t mapped_kgid_user(struct user_namespace *mnt_userns,
  361. struct user_namespace *fs_userns,
  362. kgid_t kgid)
  363. {
  364. return from_vfsgid(mnt_userns, fs_userns, VFSGIDT_INIT(kgid));
  365. }
  366. /**
  367. * vfsgid_has_fsmapping - check whether a vfsgid maps into the filesystem
  368. * @mnt_userns: the mount's idmapping
  369. * @fs_userns: the filesystem's idmapping
  370. * @vfsgid: vfsgid to be mapped
  371. *
  372. * Check whether @vfsgid has a mapping in the filesystem idmapping. Use this
  373. * function to check whether the filesystem idmapping has a mapping for
  374. * @vfsgid.
  375. *
  376. * Return: true if @vfsgid has a mapping in the filesystem, false if not.
  377. */
  378. static inline bool vfsgid_has_fsmapping(struct user_namespace *mnt_userns,
  379. struct user_namespace *fs_userns,
  380. vfsgid_t vfsgid)
  381. {
  382. return gid_valid(from_vfsgid(mnt_userns, fs_userns, vfsgid));
  383. }
  384. /**
  385. * vfsgid_into_kgid - convert vfsgid into kgid
  386. * @vfsgid: the vfsgid to convert
  387. *
  388. * This can be used when a vfsgid is committed as a kgid.
  389. *
  390. * Return: a kgid with the value of @vfsgid
  391. */
  392. static inline kgid_t vfsgid_into_kgid(vfsgid_t vfsgid)
  393. {
  394. return AS_KGIDT(vfsgid);
  395. }
  396. /**
  397. * mapped_fsuid - return caller's fsuid mapped up into a mnt_userns
  398. * @mnt_userns: the mount's idmapping
  399. * @fs_userns: the filesystem's idmapping
  400. *
  401. * Use this helper to initialize a new vfs or filesystem object based on
  402. * the caller's fsuid. A common example is initializing the i_uid field of
  403. * a newly allocated inode triggered by a creation event such as mkdir or
  404. * O_CREAT. Other examples include the allocation of quotas for a specific
  405. * user.
  406. *
  407. * Return: the caller's current fsuid mapped up according to @mnt_userns.
  408. */
  409. static inline kuid_t mapped_fsuid(struct user_namespace *mnt_userns,
  410. struct user_namespace *fs_userns)
  411. {
  412. return from_vfsuid(mnt_userns, fs_userns,
  413. VFSUIDT_INIT(current_fsuid()));
  414. }
  415. /**
  416. * mapped_fsgid - return caller's fsgid mapped up into a mnt_userns
  417. * @mnt_userns: the mount's idmapping
  418. * @fs_userns: the filesystem's idmapping
  419. *
  420. * Use this helper to initialize a new vfs or filesystem object based on
  421. * the caller's fsgid. A common example is initializing the i_gid field of
  422. * a newly allocated inode triggered by a creation event such as mkdir or
  423. * O_CREAT. Other examples include the allocation of quotas for a specific
  424. * user.
  425. *
  426. * Return: the caller's current fsgid mapped up according to @mnt_userns.
  427. */
  428. static inline kgid_t mapped_fsgid(struct user_namespace *mnt_userns,
  429. struct user_namespace *fs_userns)
  430. {
  431. return from_vfsgid(mnt_userns, fs_userns,
  432. VFSGIDT_INIT(current_fsgid()));
  433. }
  434. #endif /* _LINUX_MNT_IDMAPPING_H */