diff options
Diffstat (limited to 'Documentation/filesystems/idmappings.rst')
-rw-r--r-- | Documentation/filesystems/idmappings.rst | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/Documentation/filesystems/idmappings.rst b/Documentation/filesystems/idmappings.rst index ad6d21640576..ac0af679e61e 100644 --- a/Documentation/filesystems/idmappings.rst +++ b/Documentation/filesystems/idmappings.rst @@ -36,7 +36,7 @@ and write down the mappings it will generate:: From a mathematical viewpoint ``U`` and ``K`` are well-ordered sets and an idmapping is an order isomorphism from ``U`` into ``K``. So ``U`` and ``K`` are order isomorphic. In fact, ``U`` and ``K`` are always well-ordered subsets of -the set of all possible ids useable on a given system. +the set of all possible ids usable on a given system. Looking at this mathematically briefly will help us highlight some properties that make it easier to understand how we can translate between idmappings. For @@ -47,7 +47,7 @@ example, we know that the inverse idmapping is an order isomorphism as well:: k10002 -> u24 Given that we are dealing with order isomorphisms plus the fact that we're -dealing with subsets we can embedd idmappings into each other, i.e. we can +dealing with subsets we can embed idmappings into each other, i.e. we can sensibly translate between different idmappings. For example, assume we've been given the three idmappings:: @@ -60,7 +60,7 @@ and id ``k11000`` which has been generated by the first idmapping by mapping Because we're dealing with order isomorphic subsets it is meaningful to ask what id ``k11000`` corresponds to in the second or third idmapping. The -straightfoward algorithm to use is to apply the inverse of the first idmapping, +straightforward algorithm to use is to apply the inverse of the first idmapping, mapping ``k11000`` up to ``u1000``. Afterwards, we can map ``u1000`` down using either the second idmapping mapping or third idmapping mapping. The second idmapping would map ``u1000`` down to ``21000``. The third idmapping would map @@ -146,9 +146,10 @@ For the rest of this document we will prefix all userspace ids with ``u`` and all kernel ids with ``k``. Ranges of idmappings will be prefixed with ``r``. So an idmapping will be written as ``u0:k10000:r10000``. -For example, the id ``u1000`` is an id in the upper idmapset or "userspace -idmapset" starting with ``u1000``. And it is mapped to ``k11000`` which is a -kernel id in the lower idmapset or "kernel idmapset" starting with ``k10000``. +For example, within this idmapping, the id ``u1000`` is an id in the upper +idmapset or "userspace idmapset" starting with ``u0``. And it is mapped to +``k11000`` which is a kernel id in the lower idmapset or "kernel idmapset" +starting with ``k10000``. A kernel id is always created by an idmapping. Such idmappings are associated with user namespaces. Since we mainly care about how idmappings work we're not @@ -367,12 +368,19 @@ So with the second step the kernel guarantees that a valid userspace id can be written to disk. If it can't the kernel will refuse the creation request to not even remotely risk filesystem corruption. -The astute reader will have realized that this is simply a varation of the +The astute reader will have realized that this is simply a variation of the crossmapping algorithm we mentioned above in a previous section. First, the kernel maps the caller's userspace id down into a kernel id according to the caller's idmapping and then maps that kernel id up according to the filesystem's idmapping. +From the implementation point it's worth mentioning how idmappings are represented. +All idmappings are taken from the corresponding user namespace. + + - caller's idmapping (usually taken from ``current_user_ns()``) + - filesystem's idmapping (``sb->s_user_ns``) + - mount's idmapping (``mnt_idmap(vfsmnt)``) + Let's see some examples with caller/filesystem idmapping but without mount idmappings. This will exhibit some problems we can hit. After that we will revisit/reconsider these examples, this time using mount idmappings, to see how @@ -458,7 +466,7 @@ the kernel id that was created in the caller's idmapping. This has mainly two consequences. First, that we can't allow a caller to ultimately write to disk with another -userspace id. We could only do this if we were to mount the whole fileystem +userspace id. We could only do this if we were to mount the whole filesystem with the caller's or another idmapping. But that solution is limited to a few filesystems and not very flexible. But this is a use-case that is pretty important in containerized workloads. @@ -589,7 +597,7 @@ on their work machine. In both cases changing ownership recursively has grave implications. The most obvious one is that ownership is changed globally and permanently. In the home -directory case this change in ownership would even need to happen everytime the +directory case this change in ownership would even need to happen every time the user switches from their home to their work machine. For really large sets of files this becomes increasingly costly. @@ -662,7 +670,7 @@ use the ``vfsuid_into_kuid()`` and ``vfsgid_into_kgid()`` helpers. To illustrate why this helper currently exists, consider what happens when we change ownership of an inode from an idmapped mount. After we generated a ``vfsuid_t`` or ``vfsgid_t`` based on the mount idmapping we later commit to -this ``vfsuid_t`` or ``vfsgid_t`` to become the new filesytem wide ownership. +this ``vfsuid_t`` or ``vfsgid_t`` to become the new filesystem wide ownership. Thus, we are turning the ``vfsuid_t`` or ``vfsgid_t`` into a global ``kuid_t`` or ``kgid_t``. And this can be done by using ``vfsuid_into_kuid()`` and ``vfsgid_into_kgid()``. |