cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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 */