1ad19607aSChristian Brauner.. SPDX-License-Identifier: GPL-2.0 2ad19607aSChristian Brauner 3ad19607aSChristian BraunerIdmappings 4ad19607aSChristian Brauner========== 5ad19607aSChristian Brauner 6ad19607aSChristian BraunerMost filesystem developers will have encountered idmappings. They are used when 7ad19607aSChristian Braunerreading from or writing ownership to disk, reporting ownership to userspace, or 8ad19607aSChristian Braunerfor permission checking. This document is aimed at filesystem developers that 9ad19607aSChristian Braunerwant to know how idmappings work. 10ad19607aSChristian Brauner 11ad19607aSChristian BraunerFormal notes 12ad19607aSChristian Brauner------------ 13ad19607aSChristian Brauner 14ad19607aSChristian BraunerAn idmapping is essentially a translation of a range of ids into another or the 15ad19607aSChristian Braunersame range of ids. The notational convention for idmappings that is widely used 16ad19607aSChristian Braunerin userspace is:: 17ad19607aSChristian Brauner 18ad19607aSChristian Brauner u:k:r 19ad19607aSChristian Brauner 20ad19607aSChristian Brauner``u`` indicates the first element in the upper idmapset ``U`` and ``k`` 21ad19607aSChristian Braunerindicates the first element in the lower idmapset ``K``. The ``r`` parameter 22ad19607aSChristian Braunerindicates the range of the idmapping, i.e. how many ids are mapped. From now 23ad19607aSChristian Brauneron, we will always prefix ids with ``u`` or ``k`` to make it clear whether 24ad19607aSChristian Braunerwe're talking about an id in the upper or lower idmapset. 25ad19607aSChristian Brauner 26ad19607aSChristian BraunerTo see what this looks like in practice, let's take the following idmapping:: 27ad19607aSChristian Brauner 28ad19607aSChristian Brauner u22:k10000:r3 29ad19607aSChristian Brauner 30ad19607aSChristian Braunerand write down the mappings it will generate:: 31ad19607aSChristian Brauner 32ad19607aSChristian Brauner u22 -> k10000 33ad19607aSChristian Brauner u23 -> k10001 34ad19607aSChristian Brauner u24 -> k10002 35ad19607aSChristian Brauner 36ad19607aSChristian BraunerFrom a mathematical viewpoint ``U`` and ``K`` are well-ordered sets and an 37ad19607aSChristian Brauneridmapping is an order isomorphism from ``U`` into ``K``. So ``U`` and ``K`` are 38ad19607aSChristian Braunerorder isomorphic. In fact, ``U`` and ``K`` are always well-ordered subsets of 39*d56b699dSBjorn Helgaasthe set of all possible ids usable on a given system. 40ad19607aSChristian Brauner 41ad19607aSChristian BraunerLooking at this mathematically briefly will help us highlight some properties 42ad19607aSChristian Braunerthat make it easier to understand how we can translate between idmappings. For 43ad19607aSChristian Braunerexample, we know that the inverse idmapping is an order isomorphism as well:: 44ad19607aSChristian Brauner 45ad19607aSChristian Brauner k10000 -> u22 46ad19607aSChristian Brauner k10001 -> u23 47ad19607aSChristian Brauner k10002 -> u24 48ad19607aSChristian Brauner 49ad19607aSChristian BraunerGiven that we are dealing with order isomorphisms plus the fact that we're 50*d56b699dSBjorn Helgaasdealing with subsets we can embed idmappings into each other, i.e. we can 51ad19607aSChristian Braunersensibly translate between different idmappings. For example, assume we've been 52ad19607aSChristian Braunergiven the three idmappings:: 53ad19607aSChristian Brauner 54ad19607aSChristian Brauner 1. u0:k10000:r10000 55ad19607aSChristian Brauner 2. u0:k20000:r10000 56ad19607aSChristian Brauner 3. u0:k30000:r10000 57ad19607aSChristian Brauner 58ad19607aSChristian Braunerand id ``k11000`` which has been generated by the first idmapping by mapping 59ad19607aSChristian Brauner``u1000`` from the upper idmapset down to ``k11000`` in the lower idmapset. 60ad19607aSChristian Brauner 61ad19607aSChristian BraunerBecause we're dealing with order isomorphic subsets it is meaningful to ask 62ad19607aSChristian Braunerwhat id ``k11000`` corresponds to in the second or third idmapping. The 63*d56b699dSBjorn Helgaasstraightforward algorithm to use is to apply the inverse of the first idmapping, 64ad19607aSChristian Braunermapping ``k11000`` up to ``u1000``. Afterwards, we can map ``u1000`` down using 65ad19607aSChristian Braunereither the second idmapping mapping or third idmapping mapping. The second 66ad19607aSChristian Brauneridmapping would map ``u1000`` down to ``21000``. The third idmapping would map 67ad19607aSChristian Brauner``u1000`` down to ``u31000``. 68ad19607aSChristian Brauner 69ad19607aSChristian BraunerIf we were given the same task for the following three idmappings:: 70ad19607aSChristian Brauner 71ad19607aSChristian Brauner 1. u0:k10000:r10000 72ad19607aSChristian Brauner 2. u0:k20000:r200 73ad19607aSChristian Brauner 3. u0:k30000:r300 74ad19607aSChristian Brauner 75ad19607aSChristian Braunerwe would fail to translate as the sets aren't order isomorphic over the full 76ad19607aSChristian Braunerrange of the first idmapping anymore (However they are order isomorphic over 77ad19607aSChristian Braunerthe full range of the second idmapping.). Neither the second or third idmapping 78ad19607aSChristian Braunercontain ``u1000`` in the upper idmapset ``U``. This is equivalent to not having 79ad19607aSChristian Brauneran id mapped. We can simply say that ``u1000`` is unmapped in the second and 80ad19607aSChristian Braunerthird idmapping. The kernel will report unmapped ids as the overflowuid 81ad19607aSChristian Brauner``(uid_t)-1`` or overflowgid ``(gid_t)-1`` to userspace. 82ad19607aSChristian Brauner 83ad19607aSChristian BraunerThe algorithm to calculate what a given id maps to is pretty simple. First, we 84ad19607aSChristian Braunerneed to verify that the range can contain our target id. We will skip this step 85ad19607aSChristian Braunerfor simplicity. After that if we want to know what ``id`` maps to we can do 86ad19607aSChristian Braunersimple calculations: 87ad19607aSChristian Brauner 88ad19607aSChristian Brauner- If we want to map from left to right:: 89ad19607aSChristian Brauner 90ad19607aSChristian Brauner u:k:r 91ad19607aSChristian Brauner id - u + k = n 92ad19607aSChristian Brauner 93ad19607aSChristian Brauner- If we want to map from right to left:: 94ad19607aSChristian Brauner 95ad19607aSChristian Brauner u:k:r 96ad19607aSChristian Brauner id - k + u = n 97ad19607aSChristian Brauner 98ad19607aSChristian BraunerInstead of "left to right" we can also say "down" and instead of "right to 99ad19607aSChristian Braunerleft" we can also say "up". Obviously mapping down and up invert each other. 100ad19607aSChristian Brauner 101ad19607aSChristian BraunerTo see whether the simple formulas above work, consider the following two 102ad19607aSChristian Brauneridmappings:: 103ad19607aSChristian Brauner 104ad19607aSChristian Brauner 1. u0:k20000:r10000 105ad19607aSChristian Brauner 2. u500:k30000:r10000 106ad19607aSChristian Brauner 107ad19607aSChristian BraunerAssume we are given ``k21000`` in the lower idmapset of the first idmapping. We 108ad19607aSChristian Braunerwant to know what id this was mapped from in the upper idmapset of the first 109ad19607aSChristian Brauneridmapping. So we're mapping up in the first idmapping:: 110ad19607aSChristian Brauner 111ad19607aSChristian Brauner id - k + u = n 112ad19607aSChristian Brauner k21000 - k20000 + u0 = u1000 113ad19607aSChristian Brauner 114ad19607aSChristian BraunerNow assume we are given the id ``u1100`` in the upper idmapset of the second 115ad19607aSChristian Brauneridmapping and we want to know what this id maps down to in the lower idmapset 116ad19607aSChristian Braunerof the second idmapping. This means we're mapping down in the second 117ad19607aSChristian Brauneridmapping:: 118ad19607aSChristian Brauner 119ad19607aSChristian Brauner id - u + k = n 120ad19607aSChristian Brauner u1100 - u500 + k30000 = k30600 121ad19607aSChristian Brauner 122ad19607aSChristian BraunerGeneral notes 123ad19607aSChristian Brauner------------- 124ad19607aSChristian Brauner 125ad19607aSChristian BraunerIn the context of the kernel an idmapping can be interpreted as mapping a range 126ad19607aSChristian Braunerof userspace ids into a range of kernel ids:: 127ad19607aSChristian Brauner 128ad19607aSChristian Brauner userspace-id:kernel-id:range 129ad19607aSChristian Brauner 130ad19607aSChristian BraunerA userspace id is always an element in the upper idmapset of an idmapping of 131ad19607aSChristian Braunertype ``uid_t`` or ``gid_t`` and a kernel id is always an element in the lower 132ad19607aSChristian Brauneridmapset of an idmapping of type ``kuid_t`` or ``kgid_t``. From now on 133ad19607aSChristian Brauner"userspace id" will be used to refer to the well known ``uid_t`` and ``gid_t`` 134ad19607aSChristian Braunertypes and "kernel id" will be used to refer to ``kuid_t`` and ``kgid_t``. 135ad19607aSChristian Brauner 136ad19607aSChristian BraunerThe kernel is mostly concerned with kernel ids. They are used when performing 137ad19607aSChristian Braunerpermission checks and are stored in an inode's ``i_uid`` and ``i_gid`` field. 138ad19607aSChristian BraunerA userspace id on the other hand is an id that is reported to userspace by the 139ad19607aSChristian Braunerkernel, or is passed by userspace to the kernel, or a raw device id that is 140ad19607aSChristian Braunerwritten or read from disk. 141ad19607aSChristian Brauner 142ad19607aSChristian BraunerNote that we are only concerned with idmappings as the kernel stores them not 143ad19607aSChristian Braunerhow userspace would specify them. 144ad19607aSChristian Brauner 145ad19607aSChristian BraunerFor the rest of this document we will prefix all userspace ids with ``u`` and 146ad19607aSChristian Braunerall kernel ids with ``k``. Ranges of idmappings will be prefixed with ``r``. So 147ad19607aSChristian Brauneran idmapping will be written as ``u0:k10000:r10000``. 148ad19607aSChristian Brauner 149ad19607aSChristian BraunerFor example, within this idmapping, the id ``u1000`` is an id in the upper 150ad19607aSChristian Brauneridmapset or "userspace idmapset" starting with ``u0``. And it is mapped to 151ad19607aSChristian Brauner``k11000`` which is a kernel id in the lower idmapset or "kernel idmapset" 152ad19607aSChristian Braunerstarting with ``k10000``. 153ad19607aSChristian Brauner 154ad19607aSChristian BraunerA kernel id is always created by an idmapping. Such idmappings are associated 155ad19607aSChristian Braunerwith user namespaces. Since we mainly care about how idmappings work we're not 156ad19607aSChristian Braunergoing to be concerned with how idmappings are created nor how they are used 157ad19607aSChristian Brauneroutside of the filesystem context. This is best left to an explanation of user 158ad19607aSChristian Braunernamespaces. 159ad19607aSChristian Brauner 160ad19607aSChristian BraunerThe initial user namespace is special. It always has an idmapping of the 161ad19607aSChristian Braunerfollowing form:: 162ad19607aSChristian Brauner 163ad19607aSChristian Brauner u0:k0:r4294967295 164ad19607aSChristian Brauner 165ad19607aSChristian Braunerwhich is an identity idmapping over the full range of ids available on this 166ad19607aSChristian Braunersystem. 167ad19607aSChristian Brauner 168ad19607aSChristian BraunerOther user namespaces usually have non-identity idmappings such as:: 169ad19607aSChristian Brauner 170ad19607aSChristian Brauner u0:k10000:r10000 171ad19607aSChristian Brauner 172ad19607aSChristian BraunerWhen a process creates or wants to change ownership of a file, or when the 173ad19607aSChristian Braunerownership of a file is read from disk by a filesystem, the userspace id is 174ad19607aSChristian Braunerimmediately translated into a kernel id according to the idmapping associated 175ad19607aSChristian Braunerwith the relevant user namespace. 176ad19607aSChristian Brauner 177ad19607aSChristian BraunerFor instance, consider a file that is stored on disk by a filesystem as being 178ad19607aSChristian Braunerowned by ``u1000``: 179ad19607aSChristian Brauner 180ad19607aSChristian Brauner- If a filesystem were to be mounted in the initial user namespaces (as most 181ad19607aSChristian Brauner filesystems are) then the initial idmapping will be used. As we saw this is 182ad19607aSChristian Brauner simply the identity idmapping. This would mean id ``u1000`` read from disk 183ad19607aSChristian Brauner would be mapped to id ``k1000``. So an inode's ``i_uid`` and ``i_gid`` field 184ad19607aSChristian Brauner would contain ``k1000``. 185ad19607aSChristian Brauner 186ad19607aSChristian Brauner- If a filesystem were to be mounted with an idmapping of ``u0:k10000:r10000`` 187ad19607aSChristian Brauner then ``u1000`` read from disk would be mapped to ``k11000``. So an inode's 188ad19607aSChristian Brauner ``i_uid`` and ``i_gid`` would contain ``k11000``. 189ad19607aSChristian Brauner 190ad19607aSChristian BraunerTranslation algorithms 191ad19607aSChristian Brauner---------------------- 192ad19607aSChristian Brauner 193ad19607aSChristian BraunerWe've already seen briefly that it is possible to translate between different 194ad19607aSChristian Brauneridmappings. We'll now take a closer look how that works. 195ad19607aSChristian Brauner 196ad19607aSChristian BraunerCrossmapping 197ad19607aSChristian Brauner~~~~~~~~~~~~ 198ad19607aSChristian Brauner 199ad19607aSChristian BraunerThis translation algorithm is used by the kernel in quite a few places. For 200ad19607aSChristian Braunerexample, it is used when reporting back the ownership of a file to userspace 201ad19607aSChristian Braunervia the ``stat()`` system call family. 202ad19607aSChristian Brauner 203ad19607aSChristian BraunerIf we've been given ``k11000`` from one idmapping we can map that id up in 204ad19607aSChristian Brauneranother idmapping. In order for this to work both idmappings need to contain 205ad19607aSChristian Braunerthe same kernel id in their kernel idmapsets. For example, consider the 206ad19607aSChristian Braunerfollowing idmappings:: 207ad19607aSChristian Brauner 208ad19607aSChristian Brauner 1. u0:k10000:r10000 209ad19607aSChristian Brauner 2. u20000:k10000:r10000 210ad19607aSChristian Brauner 211ad19607aSChristian Braunerand we are mapping ``u1000`` down to ``k11000`` in the first idmapping . We can 212ad19607aSChristian Braunerthen translate ``k11000`` into a userspace id in the second idmapping using the 213ad19607aSChristian Braunerkernel idmapset of the second idmapping:: 214ad19607aSChristian Brauner 215ad19607aSChristian Brauner /* Map the kernel id up into a userspace id in the second idmapping. */ 216ad19607aSChristian Brauner from_kuid(u20000:k10000:r10000, k11000) = u21000 217ad19607aSChristian Brauner 218ad19607aSChristian BraunerNote, how we can get back to the kernel id in the first idmapping by inverting 219ad19607aSChristian Braunerthe algorithm:: 220ad19607aSChristian Brauner 221ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the second idmapping. */ 222ad19607aSChristian Brauner make_kuid(u20000:k10000:r10000, u21000) = k11000 223ad19607aSChristian Brauner 224ad19607aSChristian Brauner /* Map the kernel id up into a userspace id in the first idmapping. */ 225ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 226ad19607aSChristian Brauner 227ad19607aSChristian BraunerThis algorithm allows us to answer the question what userspace id a given 228ad19607aSChristian Braunerkernel id corresponds to in a given idmapping. In order to be able to answer 229ad19607aSChristian Braunerthis question both idmappings need to contain the same kernel id in their 230ad19607aSChristian Braunerrespective kernel idmapsets. 231ad19607aSChristian Brauner 232ad19607aSChristian BraunerFor example, when the kernel reads a raw userspace id from disk it maps it down 233ad19607aSChristian Braunerinto a kernel id according to the idmapping associated with the filesystem. 234ad19607aSChristian BraunerLet's assume the filesystem was mounted with an idmapping of 235ad19607aSChristian Brauner``u0:k20000:r10000`` and it reads a file owned by ``u1000`` from disk. This 236ad19607aSChristian Braunermeans ``u1000`` will be mapped to ``k21000`` which is what will be stored in 237ad19607aSChristian Braunerthe inode's ``i_uid`` and ``i_gid`` field. 238ad19607aSChristian Brauner 239ad19607aSChristian BraunerWhen someone in userspace calls ``stat()`` or a related function to get 240ad19607aSChristian Braunerownership information about the file the kernel can't simply map the id back up 241ad19607aSChristian Brauneraccording to the filesystem's idmapping as this would give the wrong owner if 242ad19607aSChristian Braunerthe caller is using an idmapping. 243ad19607aSChristian Brauner 2445d3ca596SChristian BraunerSo the kernel will map the id back up in the idmapping of the caller. Let's 245ad19607aSChristian Braunerassume the caller has the somewhat unconventional idmapping 246ad19607aSChristian Brauner``u3000:k20000:r10000`` then ``k21000`` would map back up to ``u4000``. 247ad19607aSChristian BraunerConsequently the user would see that this file is owned by ``u4000``. 248ad19607aSChristian Brauner 249ad19607aSChristian BraunerRemapping 250ad19607aSChristian Brauner~~~~~~~~~ 251ad19607aSChristian Brauner 252ad19607aSChristian BraunerIt is possible to translate a kernel id from one idmapping to another one via 253ad19607aSChristian Braunerthe userspace idmapset of the two idmappings. This is equivalent to remapping 254ad19607aSChristian Braunera kernel id. 255ad19607aSChristian Brauner 256ad19607aSChristian BraunerLet's look at an example. We are given the following two idmappings:: 257ad19607aSChristian Brauner 258ad19607aSChristian Brauner 1. u0:k10000:r10000 259ad19607aSChristian Brauner 2. u0:k20000:r10000 260ad19607aSChristian Brauner 261ad19607aSChristian Braunerand we are given ``k11000`` in the first idmapping. In order to translate this 262ad19607aSChristian Braunerkernel id in the first idmapping into a kernel id in the second idmapping we 263ad19607aSChristian Braunerneed to perform two steps: 264ad19607aSChristian Brauner 265ad19607aSChristian Brauner1. Map the kernel id up into a userspace id in the first idmapping:: 266ad19607aSChristian Brauner 267ad19607aSChristian Brauner /* Map the kernel id up into a userspace id in the first idmapping. */ 268ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 269ad19607aSChristian Brauner 270ad19607aSChristian Brauner2. Map the userspace id down into a kernel id in the second idmapping:: 271ad19607aSChristian Brauner 272ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the second idmapping. */ 273ad19607aSChristian Brauner make_kuid(u0:k20000:r10000, u1000) = k21000 274ad19607aSChristian Brauner 275ad19607aSChristian BraunerAs you can see we used the userspace idmapset in both idmappings to translate 276ad19607aSChristian Braunerthe kernel id in one idmapping to a kernel id in another idmapping. 277ad19607aSChristian Brauner 278ad19607aSChristian BraunerThis allows us to answer the question what kernel id we would need to use to 279ad19607aSChristian Braunerget the same userspace id in another idmapping. In order to be able to answer 280ad19607aSChristian Braunerthis question both idmappings need to contain the same userspace id in their 281ad19607aSChristian Braunerrespective userspace idmapsets. 282ad19607aSChristian Brauner 283ad19607aSChristian BraunerNote, how we can easily get back to the kernel id in the first idmapping by 284ad19607aSChristian Braunerinverting the algorithm: 285ad19607aSChristian Brauner 286ad19607aSChristian Brauner1. Map the kernel id up into a userspace id in the second idmapping:: 287ad19607aSChristian Brauner 288ad19607aSChristian Brauner /* Map the kernel id up into a userspace id in the second idmapping. */ 289ad19607aSChristian Brauner from_kuid(u0:k20000:r10000, k21000) = u1000 290ad19607aSChristian Brauner 291ad19607aSChristian Brauner2. Map the userspace id down into a kernel id in the first idmapping:: 292ad19607aSChristian Brauner 293ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the first idmapping. */ 294ad19607aSChristian Brauner make_kuid(u0:k10000:r10000, u1000) = k11000 295ad19607aSChristian Brauner 296ad19607aSChristian BraunerAnother way to look at this translation is to treat it as inverting one 297ad19607aSChristian Brauneridmapping and applying another idmapping if both idmappings have the relevant 298ad19607aSChristian Brauneruserspace id mapped. This will come in handy when working with idmapped mounts. 299ad19607aSChristian Brauner 300ad19607aSChristian BraunerInvalid translations 301ad19607aSChristian Brauner~~~~~~~~~~~~~~~~~~~~ 302ad19607aSChristian Brauner 303ad19607aSChristian BraunerIt is never valid to use an id in the kernel idmapset of one idmapping as the 304ad19607aSChristian Braunerid in the userspace idmapset of another or the same idmapping. While the kernel 305ad19607aSChristian Brauneridmapset always indicates an idmapset in the kernel id space the userspace 306ad19607aSChristian Brauneridmapset indicates a userspace id. So the following translations are forbidden:: 307ad19607aSChristian Brauner 308ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the first idmapping. */ 309ad19607aSChristian Brauner make_kuid(u0:k10000:r10000, u1000) = k11000 310ad19607aSChristian Brauner 311ad19607aSChristian Brauner /* INVALID: Map the kernel id down into a kernel id in the second idmapping. */ 312ad19607aSChristian Brauner make_kuid(u10000:k20000:r10000, k110000) = k21000 313ad19607aSChristian Brauner ~~~~~~~ 314ad19607aSChristian Brauner 315ad19607aSChristian Braunerand equally wrong:: 316ad19607aSChristian Brauner 317ad19607aSChristian Brauner /* Map the kernel id up into a userspace id in the first idmapping. */ 318ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 319ad19607aSChristian Brauner 320ad19607aSChristian Brauner /* INVALID: Map the userspace id up into a userspace id in the second idmapping. */ 321ad19607aSChristian Brauner from_kuid(u20000:k0:r10000, u1000) = k21000 322ad19607aSChristian Brauner ~~~~~ 3235d3ca596SChristian Brauner 3245d3ca596SChristian BraunerSince userspace ids have type ``uid_t`` and ``gid_t`` and kernel ids have type 3255d3ca596SChristian Brauner``kuid_t`` and ``kgid_t`` the compiler will throw an error when they are 3265d3ca596SChristian Braunerconflated. So the two examples above would cause a compilation failure. 327ad19607aSChristian Brauner 328ad19607aSChristian BraunerIdmappings when creating filesystem objects 329ad19607aSChristian Brauner------------------------------------------- 330ad19607aSChristian Brauner 331ad19607aSChristian BraunerThe concepts of mapping an id down or mapping an id up are expressed in the two 332ad19607aSChristian Braunerkernel functions filesystem developers are rather familiar with and which we've 333ad19607aSChristian Brauneralready used in this document:: 334ad19607aSChristian Brauner 335ad19607aSChristian Brauner /* Map the userspace id down into a kernel id. */ 336ad19607aSChristian Brauner make_kuid(idmapping, uid) 337ad19607aSChristian Brauner 338ad19607aSChristian Brauner /* Map the kernel id up into a userspace id. */ 339ad19607aSChristian Brauner from_kuid(idmapping, kuid) 340ad19607aSChristian Brauner 341ad19607aSChristian BraunerWe will take an abbreviated look into how idmappings figure into creating 342ad19607aSChristian Braunerfilesystem objects. For simplicity we will only look at what happens when the 343ad19607aSChristian BraunerVFS has already completed path lookup right before it calls into the filesystem 344ad19607aSChristian Brauneritself. So we're concerned with what happens when e.g. ``vfs_mkdir()`` is 345ad19607aSChristian Braunercalled. We will also assume that the directory we're creating filesystem 346ad19607aSChristian Braunerobjects in is readable and writable for everyone. 347ad19607aSChristian Brauner 348ad19607aSChristian BraunerWhen creating a filesystem object the caller will look at the caller's 349ad19607aSChristian Braunerfilesystem ids. These are just regular ``uid_t`` and ``gid_t`` userspace ids 350ad19607aSChristian Braunerbut they are exclusively used when determining file ownership which is why they 351ad19607aSChristian Braunerare called "filesystem ids". They are usually identical to the uid and gid of 352ad19607aSChristian Braunerthe caller but can differ. We will just assume they are always identical to not 353ad19607aSChristian Braunerget lost in too many details. 354ad19607aSChristian Brauner 355ad19607aSChristian BraunerWhen the caller enters the kernel two things happen: 356ad19607aSChristian Brauner 357ad19607aSChristian Brauner1. Map the caller's userspace ids down into kernel ids in the caller's 358ad19607aSChristian Brauner idmapping. 359ad19607aSChristian Brauner (To be precise, the kernel will simply look at the kernel ids stashed in the 360ad19607aSChristian Brauner credentials of the current task but for our education we'll pretend this 361ad19607aSChristian Brauner translation happens just in time.) 362ad19607aSChristian Brauner2. Verify that the caller's kernel ids can be mapped up to userspace ids in the 363ad19607aSChristian Brauner filesystem's idmapping. 364ad19607aSChristian Brauner 365ad19607aSChristian BraunerThe second step is important as regular filesystem will ultimately need to map 366ad19607aSChristian Braunerthe kernel id back up into a userspace id when writing to disk. 367ad19607aSChristian BraunerSo with the second step the kernel guarantees that a valid userspace id can be 368ad19607aSChristian Braunerwritten to disk. If it can't the kernel will refuse the creation request to not 369ad19607aSChristian Braunereven remotely risk filesystem corruption. 370*d56b699dSBjorn Helgaas 371ad19607aSChristian BraunerThe astute reader will have realized that this is simply a variation of the 372ad19607aSChristian Braunercrossmapping algorithm we mentioned above in a previous section. First, the 373ad19607aSChristian Braunerkernel maps the caller's userspace id down into a kernel id according to the 374ad19607aSChristian Braunercaller's idmapping and then maps that kernel id up according to the 375ad19607aSChristian Braunerfilesystem's idmapping. 376ccbd0c99SRodrigo Campos 377ccbd0c99SRodrigo CamposFrom the implementation point it's worth mentioning how idmappings are represented. 378ccbd0c99SRodrigo CamposAll idmappings are taken from the corresponding user namespace. 379ccbd0c99SRodrigo Campos 380ccbd0c99SRodrigo Campos - caller's idmapping (usually taken from ``current_user_ns()``) 381ad19607aSChristian Brauner - filesystem's idmapping (``sb->s_user_ns``) 382ad19607aSChristian Brauner - mount's idmapping (``mnt_idmap(vfsmnt)``) 383ad19607aSChristian Brauner 384ad19607aSChristian BraunerLet's see some examples with caller/filesystem idmapping but without mount 385ad19607aSChristian Brauneridmappings. This will exhibit some problems we can hit. After that we will 386ad19607aSChristian Braunerrevisit/reconsider these examples, this time using mount idmappings, to see how 387ad19607aSChristian Braunerthey can solve the problems we observed before. 388ad19607aSChristian Brauner 389ad19607aSChristian BraunerExample 1 390ad19607aSChristian Brauner~~~~~~~~~ 391ad19607aSChristian Brauner 392ad19607aSChristian Brauner:: 393ad19607aSChristian Brauner 394ad19607aSChristian Brauner caller id: u1000 395ad19607aSChristian Brauner caller idmapping: u0:k0:r4294967295 396ad19607aSChristian Brauner filesystem idmapping: u0:k0:r4294967295 397ad19607aSChristian Brauner 398ad19607aSChristian BraunerBoth the caller and the filesystem use the identity idmapping: 399ad19607aSChristian Brauner 400ad19607aSChristian Brauner1. Map the caller's userspace ids into kernel ids in the caller's idmapping:: 401ad19607aSChristian Brauner 402ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 403ad19607aSChristian Brauner 404ad19607aSChristian Brauner2. Verify that the caller's kernel ids can be mapped to userspace ids in the 405ad19607aSChristian Brauner filesystem's idmapping. 406ad19607aSChristian Brauner 407ad19607aSChristian Brauner For this second step the kernel will call the function 408ad19607aSChristian Brauner ``fsuidgid_has_mapping()`` which ultimately boils down to calling 409ad19607aSChristian Brauner ``from_kuid()``:: 410ad19607aSChristian Brauner 411ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k1000) = u1000 412ad19607aSChristian Brauner 413ad19607aSChristian BraunerIn this example both idmappings are the same so there's nothing exciting going 414ad19607aSChristian Brauneron. Ultimately the userspace id that lands on disk will be ``u1000``. 415ad19607aSChristian Brauner 416ad19607aSChristian BraunerExample 2 417ad19607aSChristian Brauner~~~~~~~~~ 418ad19607aSChristian Brauner 419ad19607aSChristian Brauner:: 420ad19607aSChristian Brauner 421ad19607aSChristian Brauner caller id: u1000 422ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 423ad19607aSChristian Brauner filesystem idmapping: u0:k20000:r10000 424ad19607aSChristian Brauner 425ad19607aSChristian Brauner1. Map the caller's userspace ids down into kernel ids in the caller's 426ad19607aSChristian Brauner idmapping:: 427ad19607aSChristian Brauner 428ad19607aSChristian Brauner make_kuid(u0:k10000:r10000, u1000) = k11000 429ad19607aSChristian Brauner 430ad19607aSChristian Brauner2. Verify that the caller's kernel ids can be mapped up to userspace ids in the 431ad19607aSChristian Brauner filesystem's idmapping:: 432ad19607aSChristian Brauner 433ad19607aSChristian Brauner from_kuid(u0:k20000:r10000, k11000) = u-1 434ad19607aSChristian Brauner 435ad19607aSChristian BraunerIt's immediately clear that while the caller's userspace id could be 436ad19607aSChristian Braunersuccessfully mapped down into kernel ids in the caller's idmapping the kernel 437ad19607aSChristian Braunerids could not be mapped up according to the filesystem's idmapping. So the 438ad19607aSChristian Braunerkernel will deny this creation request. 439ad19607aSChristian Brauner 440ad19607aSChristian BraunerNote that while this example is less common, because most filesystem can't be 441ad19607aSChristian Braunermounted with non-initial idmappings this is a general problem as we can see in 442ad19607aSChristian Braunerthe next examples. 443ad19607aSChristian Brauner 444ad19607aSChristian BraunerExample 3 445ad19607aSChristian Brauner~~~~~~~~~ 446ad19607aSChristian Brauner 447ad19607aSChristian Brauner:: 448ad19607aSChristian Brauner 449ad19607aSChristian Brauner caller id: u1000 450ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 451ad19607aSChristian Brauner filesystem idmapping: u0:k0:r4294967295 452ad19607aSChristian Brauner 453ad19607aSChristian Brauner1. Map the caller's userspace ids down into kernel ids in the caller's 454ad19607aSChristian Brauner idmapping:: 455ad19607aSChristian Brauner 456ad19607aSChristian Brauner make_kuid(u0:k10000:r10000, u1000) = k11000 457ad19607aSChristian Brauner 458ad19607aSChristian Brauner2. Verify that the caller's kernel ids can be mapped up to userspace ids in the 459ad19607aSChristian Brauner filesystem's idmapping:: 460ad19607aSChristian Brauner 461*d56b699dSBjorn Helgaas from_kuid(u0:k0:r4294967295, k11000) = u11000 462ad19607aSChristian Brauner 463ad19607aSChristian BraunerWe can see that the translation always succeeds. The userspace id that the 464ad19607aSChristian Braunerfilesystem will ultimately put to disk will always be identical to the value of 465ad19607aSChristian Braunerthe kernel id that was created in the caller's idmapping. This has mainly two 466ad19607aSChristian Braunerconsequences. 467ad19607aSChristian Brauner 468ad19607aSChristian BraunerFirst, that we can't allow a caller to ultimately write to disk with another 469ad19607aSChristian Brauneruserspace id. We could only do this if we were to mount the whole filesystem 470ad19607aSChristian Braunerwith the caller's or another idmapping. But that solution is limited to a few 471ad19607aSChristian Braunerfilesystems and not very flexible. But this is a use-case that is pretty 472ad19607aSChristian Braunerimportant in containerized workloads. 473ad19607aSChristian Brauner 474ad19607aSChristian BraunerSecond, the caller will usually not be able to create any files or access 475ad19607aSChristian Braunerdirectories that have stricter permissions because none of the filesystem's 476ad19607aSChristian Braunerkernel ids map up into valid userspace ids in the caller's idmapping 477ad19607aSChristian Brauner 478ad19607aSChristian Brauner1. Map raw userspace ids down to kernel ids in the filesystem's idmapping:: 479ad19607aSChristian Brauner 480ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 481ad19607aSChristian Brauner 482ad19607aSChristian Brauner2. Map kernel ids up to userspace ids in the caller's idmapping:: 483ad19607aSChristian Brauner 484ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k1000) = u-1 485ad19607aSChristian Brauner 486ad19607aSChristian BraunerExample 4 487ad19607aSChristian Brauner~~~~~~~~~ 488ad19607aSChristian Brauner 489ad19607aSChristian Brauner:: 490ad19607aSChristian Brauner 491ad19607aSChristian Brauner file id: u1000 492ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 493ad19607aSChristian Brauner filesystem idmapping: u0:k0:r4294967295 494ad19607aSChristian Brauner 495ad19607aSChristian BraunerIn order to report ownership to userspace the kernel uses the crossmapping 496ad19607aSChristian Brauneralgorithm introduced in a previous section: 497ad19607aSChristian Brauner 498ad19607aSChristian Brauner1. Map the userspace id on disk down into a kernel id in the filesystem's 499ad19607aSChristian Brauner idmapping:: 500ad19607aSChristian Brauner 501ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 502ad19607aSChristian Brauner 503ad19607aSChristian Brauner2. Map the kernel id up into a userspace id in the caller's idmapping:: 504ad19607aSChristian Brauner 505ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k1000) = u-1 506ad19607aSChristian Brauner 507ad19607aSChristian BraunerThe crossmapping algorithm fails in this case because the kernel id in the 508ad19607aSChristian Braunerfilesystem idmapping cannot be mapped up to a userspace id in the caller's 509ad19607aSChristian Brauneridmapping. Thus, the kernel will report the ownership of this file as the 510ad19607aSChristian Brauneroverflowid. 511ad19607aSChristian Brauner 512ad19607aSChristian BraunerExample 5 513ad19607aSChristian Brauner~~~~~~~~~ 514ad19607aSChristian Brauner 515ad19607aSChristian Brauner:: 516ad19607aSChristian Brauner 517ad19607aSChristian Brauner file id: u1000 518ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 519ad19607aSChristian Brauner filesystem idmapping: u0:k20000:r10000 520ad19607aSChristian Brauner 521ad19607aSChristian BraunerIn order to report ownership to userspace the kernel uses the crossmapping 522ad19607aSChristian Brauneralgorithm introduced in a previous section: 523ad19607aSChristian Brauner 524ad19607aSChristian Brauner1. Map the userspace id on disk down into a kernel id in the filesystem's 525ad19607aSChristian Brauner idmapping:: 526ad19607aSChristian Brauner 527ad19607aSChristian Brauner make_kuid(u0:k20000:r10000, u1000) = k21000 528ad19607aSChristian Brauner 529ad19607aSChristian Brauner2. Map the kernel id up into a userspace id in the caller's idmapping:: 530ad19607aSChristian Brauner 531ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k21000) = u-1 532ad19607aSChristian Brauner 533ad19607aSChristian BraunerAgain, the crossmapping algorithm fails in this case because the kernel id in 534ad19607aSChristian Braunerthe filesystem idmapping cannot be mapped to a userspace id in the caller's 535ad19607aSChristian Brauneridmapping. Thus, the kernel will report the ownership of this file as the 536ad19607aSChristian Brauneroverflowid. 537ad19607aSChristian Brauner 538ad19607aSChristian BraunerNote how in the last two examples things would be simple if the caller would be 539ad19607aSChristian Braunerusing the initial idmapping. For a filesystem mounted with the initial 540ad19607aSChristian Brauneridmapping it would be trivial. So we only consider a filesystem with an 541ad19607aSChristian Brauneridmapping of ``u0:k20000:r10000``: 542ad19607aSChristian Brauner 543ad19607aSChristian Brauner1. Map the userspace id on disk down into a kernel id in the filesystem's 544ad19607aSChristian Brauner idmapping:: 545ad19607aSChristian Brauner 546ad19607aSChristian Brauner make_kuid(u0:k20000:r10000, u1000) = k21000 547ad19607aSChristian Brauner 548ad19607aSChristian Brauner2. Map the kernel id up into a userspace id in the caller's idmapping:: 549ad19607aSChristian Brauner 550ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k21000) = u21000 551ad19607aSChristian Brauner 552ad19607aSChristian BraunerIdmappings on idmapped mounts 553ad19607aSChristian Brauner----------------------------- 554ad19607aSChristian Brauner 555ad19607aSChristian BraunerThe examples we've seen in the previous section where the caller's idmapping 556ad19607aSChristian Braunerand the filesystem's idmapping are incompatible causes various issues for 557ad19607aSChristian Braunerworkloads. For a more complex but common example, consider two containers 558ad19607aSChristian Braunerstarted on the host. To completely prevent the two containers from affecting 559ad19607aSChristian Braunereach other, an administrator may often use different non-overlapping idmappings 560ad19607aSChristian Braunerfor the two containers:: 561ad19607aSChristian Brauner 562ad19607aSChristian Brauner container1 idmapping: u0:k10000:r10000 563ad19607aSChristian Brauner container2 idmapping: u0:k20000:r10000 564ad19607aSChristian Brauner filesystem idmapping: u0:k30000:r10000 565ad19607aSChristian Brauner 566ad19607aSChristian BraunerAn administrator wanting to provide easy read-write access to the following set 567ad19607aSChristian Braunerof files:: 568ad19607aSChristian Brauner 569ad19607aSChristian Brauner dir id: u0 570ad19607aSChristian Brauner dir/file1 id: u1000 571ad19607aSChristian Brauner dir/file2 id: u2000 572ad19607aSChristian Brauner 573ad19607aSChristian Braunerto both containers currently can't. 574ad19607aSChristian Brauner 575ad19607aSChristian BraunerOf course the administrator has the option to recursively change ownership via 576ad19607aSChristian Brauner``chown()``. For example, they could change ownership so that ``dir`` and all 577ad19607aSChristian Braunerfiles below it can be crossmapped from the filesystem's into the container's 578ad19607aSChristian Brauneridmapping. Let's assume they change ownership so it is compatible with the 579ad19607aSChristian Braunerfirst container's idmapping:: 580ad19607aSChristian Brauner 581ad19607aSChristian Brauner dir id: u10000 582ad19607aSChristian Brauner dir/file1 id: u11000 583ad19607aSChristian Brauner dir/file2 id: u12000 584ad19607aSChristian Brauner 585ad19607aSChristian BraunerThis would still leave ``dir`` rather useless to the second container. In fact, 586ad19607aSChristian Brauner``dir`` and all files below it would continue to appear owned by the overflowid 587ad19607aSChristian Braunerfor the second container. 588ad19607aSChristian Brauner 589ad19607aSChristian BraunerOr consider another increasingly popular example. Some service managers such as 590ad19607aSChristian Braunersystemd implement a concept called "portable home directories". A user may want 591ad19607aSChristian Braunerto use their home directories on different machines where they are assigned 592ad19607aSChristian Braunerdifferent login userspace ids. Most users will have ``u1000`` as the login id 593ad19607aSChristian Brauneron their machine at home and all files in their home directory will usually be 594ad19607aSChristian Braunerowned by ``u1000``. At uni or at work they may have another login id such as 595ad19607aSChristian Brauner``u1125``. This makes it rather difficult to interact with their home directory 596ad19607aSChristian Brauneron their work machine. 597ad19607aSChristian Brauner 598ad19607aSChristian BraunerIn both cases changing ownership recursively has grave implications. The most 599ad19607aSChristian Braunerobvious one is that ownership is changed globally and permanently. In the home 600ad19607aSChristian Braunerdirectory case this change in ownership would even need to happen every time the 601ad19607aSChristian Brauneruser switches from their home to their work machine. For really large sets of 602ad19607aSChristian Braunerfiles this becomes increasingly costly. 603ad19607aSChristian Brauner 604ad19607aSChristian BraunerIf the user is lucky, they are dealing with a filesystem that is mountable 605ad19607aSChristian Braunerinside user namespaces. But this would also change ownership globally and the 606ad19607aSChristian Braunerchange in ownership is tied to the lifetime of the filesystem mount, i.e. the 607ad19607aSChristian Braunersuperblock. The only way to change ownership is to completely unmount the 608ad19607aSChristian Braunerfilesystem and mount it again in another user namespace. This is usually 609ad19607aSChristian Braunerimpossible because it would mean that all users currently accessing the 610ad19607aSChristian Braunerfilesystem can't anymore. And it means that ``dir`` still can't be shared 611ad19607aSChristian Braunerbetween two containers with different idmappings. 612ad19607aSChristian BraunerBut usually the user doesn't even have this option since most filesystems 613ad19607aSChristian Brauneraren't mountable inside containers. And not having them mountable might be 614ad19607aSChristian Braunerdesirable as it doesn't require the filesystem to deal with malicious 615ad19607aSChristian Braunerfilesystem images. 616ad19607aSChristian Brauner 617ad19607aSChristian BraunerBut the usecases mentioned above and more can be handled by idmapped mounts. 618ad19607aSChristian BraunerThey allow to expose the same set of dentries with different ownership at 619ad19607aSChristian Braunerdifferent mounts. This is achieved by marking the mounts with a user namespace 620ad19607aSChristian Braunerthrough the ``mount_setattr()`` system call. The idmapping associated with it 621ad19607aSChristian Brauneris then used to translate from the caller's idmapping to the filesystem's 622ad19607aSChristian Brauneridmapping and vica versa using the remapping algorithm we introduced above. 623ad19607aSChristian Brauner 624ad19607aSChristian BraunerIdmapped mounts make it possible to change ownership in a temporary and 625ad19607aSChristian Braunerlocalized way. The ownership changes are restricted to a specific mount and the 626ad19607aSChristian Braunerownership changes are tied to the lifetime of the mount. All other users and 627ad19607aSChristian Braunerlocations where the filesystem is exposed are unaffected. 628ad19607aSChristian Brauner 629ad19607aSChristian BraunerFilesystems that support idmapped mounts don't have any real reason to support 6305d3ca596SChristian Braunerbeing mountable inside user namespaces. A filesystem could be exposed 6315d3ca596SChristian Braunercompletely under an idmapped mount to get the same effect. This has the 6325d3ca596SChristian Brauneradvantage that filesystems can leave the creation of the superblock to 6335d3ca596SChristian Braunerprivileged users in the initial user namespace. 6345d3ca596SChristian Brauner 6355d3ca596SChristian BraunerHowever, it is perfectly possible to combine idmapped mounts with filesystems 6365d3ca596SChristian Braunermountable inside user namespaces. We will touch on this further below. 6375d3ca596SChristian Brauner 6385d3ca596SChristian BraunerFilesystem types vs idmapped mount types 6395d3ca596SChristian Brauner~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6405d3ca596SChristian Brauner 6415d3ca596SChristian BraunerWith the introduction of idmapped mounts we need to distinguish between 6425d3ca596SChristian Braunerfilesystem ownership and mount ownership of a VFS object such as an inode. The 6435d3ca596SChristian Braunerowner of a inode might be different when looked at from a filesystem 6445d3ca596SChristian Braunerperspective than when looked at from an idmapped mount. Such fundamental 6455d3ca596SChristian Braunerconceptual distinctions should almost always be clearly expressed in the code. 6465d3ca596SChristian BraunerSo, to distinguish idmapped mount ownership from filesystem ownership separate 6475d3ca596SChristian Braunertypes have been introduced. 6485d3ca596SChristian Brauner 6495d3ca596SChristian BraunerIf a uid or gid has been generated using the filesystem or caller's idmapping 6505d3ca596SChristian Braunerthen we will use the ``kuid_t`` and ``kgid_t`` types. However, if a uid or gid 6515d3ca596SChristian Braunerhas been generated using a mount idmapping then we will be using the dedicated 6525d3ca596SChristian Brauner``vfsuid_t`` and ``vfsgid_t`` types. 6535d3ca596SChristian Brauner 6545d3ca596SChristian BraunerAll VFS helpers that generate or take uids and gids as arguments use the 6555d3ca596SChristian Brauner``vfsuid_t`` and ``vfsgid_t`` types and we will be able to rely on the compiler 6565d3ca596SChristian Braunerto catch errors that originate from conflating filesystem and VFS uids and gids. 6575d3ca596SChristian Brauner 6585d3ca596SChristian BraunerThe ``vfsuid_t`` and ``vfsgid_t`` types are often mapped from and to ``kuid_t`` 6595d3ca596SChristian Braunerand ``kgid_t`` types similar how ``kuid_t`` and ``kgid_t`` types are mapped 6605d3ca596SChristian Braunerfrom and to ``uid_t`` and ``gid_t`` types:: 6615d3ca596SChristian Brauner 6625d3ca596SChristian Brauner uid_t <--> kuid_t <--> vfsuid_t 6635d3ca596SChristian Brauner gid_t <--> kgid_t <--> vfsgid_t 6645d3ca596SChristian Brauner 665*d56b699dSBjorn HelgaasWhenever we report ownership based on a ``vfsuid_t`` or ``vfsgid_t`` type, 6665d3ca596SChristian Braunere.g., during ``stat()``, or store ownership information in a shared VFS object 6675d3ca596SChristian Braunerbased on a ``vfsuid_t`` or ``vfsgid_t`` type, e.g., during ``chown()`` we can 6685d3ca596SChristian Brauneruse the ``vfsuid_into_kuid()`` and ``vfsgid_into_kgid()`` helpers. 6695d3ca596SChristian Brauner 6705d3ca596SChristian BraunerTo illustrate why this helper currently exists, consider what happens when we 6715d3ca596SChristian Braunerchange ownership of an inode from an idmapped mount. After we generated 6725d3ca596SChristian Braunera ``vfsuid_t`` or ``vfsgid_t`` based on the mount idmapping we later commit to 6735d3ca596SChristian Braunerthis ``vfsuid_t`` or ``vfsgid_t`` to become the new filesystem wide ownership. 6745d3ca596SChristian BraunerThus, we are turning the ``vfsuid_t`` or ``vfsgid_t`` into a global ``kuid_t`` 6755d3ca596SChristian Brauneror ``kgid_t``. And this can be done by using ``vfsuid_into_kuid()`` and 6765d3ca596SChristian Brauner``vfsgid_into_kgid()``. 6775d3ca596SChristian Brauner 6785d3ca596SChristian BraunerNote, whenever a shared VFS object, e.g., a cached ``struct inode`` or a cached 6795d3ca596SChristian Brauner``struct posix_acl``, stores ownership information a filesystem or "global" 6805d3ca596SChristian Brauner``kuid_t`` and ``kgid_t`` must be used. Ownership expressed via ``vfsuid_t`` 6815d3ca596SChristian Braunerand ``vfsgid_t`` is specific to an idmapped mount. 6825d3ca596SChristian Brauner 6835d3ca596SChristian BraunerWe already noted that ``vfsuid_t`` and ``vfsgid_t`` types are generated based 6845d3ca596SChristian Brauneron mount idmappings whereas ``kuid_t`` and ``kgid_t`` types are generated based 6855d3ca596SChristian Brauneron filesystem idmappings. To prevent abusing filesystem idmappings to generate 6865d3ca596SChristian Brauner``vfsuid_t`` or ``vfsgid_t`` types or mount idmappings to generate ``kuid_t`` 6875d3ca596SChristian Brauneror ``kgid_t`` types filesystem idmappings and mount idmappings are different 6885d3ca596SChristian Braunertypes as well. 6895d3ca596SChristian Brauner 690ad19607aSChristian BraunerAll helpers that map to or from ``vfsuid_t`` and ``vfsgid_t`` types require 691ad19607aSChristian Braunera mount idmapping to be passed which is of type ``struct mnt_idmap``. Passing 692ad19607aSChristian Braunera filesystem or caller idmapping will cause a compilation error. 693ad19607aSChristian Brauner 6945d3ca596SChristian BraunerSimilar to how we prefix all userspace ids in this document with ``u`` and all 695ad19607aSChristian Braunerkernel ids with ``k`` we will prefix all VFS ids with ``v``. So a mount 6965d3ca596SChristian Brauneridmapping will be written as: ``u0:v10000:r10000``. 697ad19607aSChristian Brauner 6985d3ca596SChristian BraunerRemapping helpers 6995d3ca596SChristian Brauner~~~~~~~~~~~~~~~~~ 700ad19607aSChristian Brauner 701ad19607aSChristian BraunerIdmapping functions were added that translate between idmappings. They make use 702ad19607aSChristian Braunerof the remapping algorithm we've introduced earlier. We're going to look at: 703ad19607aSChristian Brauner 7045d3ca596SChristian Brauner- ``i_uid_into_vfsuid()`` and ``i_gid_into_vfsgid()`` 705ad19607aSChristian Brauner 706ad19607aSChristian Brauner The ``i_*id_into_vfs*id()`` functions translate filesystem's kernel ids into 707ad19607aSChristian Brauner VFS ids in the mount's idmapping:: 708ad19607aSChristian Brauner 709ad19607aSChristian Brauner /* Map the filesystem's kernel id up into a userspace id in the filesystem's idmapping. */ 710ad19607aSChristian Brauner from_kuid(filesystem, kid) = uid 7115d3ca596SChristian Brauner 712ad19607aSChristian Brauner /* Map the filesystem's userspace id down ito a VFS id in the mount's idmapping. */ 7135d3ca596SChristian Brauner make_kuid(mount, uid) = kuid 714ad19607aSChristian Brauner 715ad19607aSChristian Brauner- ``mapped_fsuid()`` and ``mapped_fsgid()`` 716ad19607aSChristian Brauner 717ad19607aSChristian Brauner The ``mapped_fs*id()`` functions translate the caller's kernel ids into 718ad19607aSChristian Brauner kernel ids in the filesystem's idmapping. This translation is achieved by 7195d3ca596SChristian Brauner remapping the caller's VFS ids using the mount's idmapping:: 7205d3ca596SChristian Brauner 7215d3ca596SChristian Brauner /* Map the caller's VFS id up into a userspace id in the mount's idmapping. */ 7225d3ca596SChristian Brauner from_kuid(mount, kid) = uid 723ad19607aSChristian Brauner 724ad19607aSChristian Brauner /* Map the mount's userspace id down into a kernel id in the filesystem's idmapping. */ 725ad19607aSChristian Brauner make_kuid(filesystem, uid) = kuid 726ad19607aSChristian Brauner 727ad19607aSChristian Brauner- ``vfsuid_into_kuid()`` and ``vfsgid_into_kgid()`` 7285d3ca596SChristian Brauner 729ad19607aSChristian Brauner Whenever 730ad19607aSChristian Brauner 731622d6f19SRandy DunlapNote that these two functions invert each other. Consider the following 732ad19607aSChristian Brauneridmappings:: 733ad19607aSChristian Brauner 734ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 735ad19607aSChristian Brauner filesystem idmapping: u0:k20000:r10000 736ad19607aSChristian Brauner mount idmapping: u0:v10000:r10000 737ad19607aSChristian Brauner 738ad19607aSChristian BraunerAssume a file owned by ``u1000`` is read from disk. The filesystem maps this id 7395d3ca596SChristian Braunerto ``k21000`` according to its idmapping. This is what is stored in the 7405d3ca596SChristian Braunerinode's ``i_uid`` and ``i_gid`` fields. 741ad19607aSChristian Brauner 7425d3ca596SChristian BraunerWhen the caller queries the ownership of this file via ``stat()`` the kernel 743ad19607aSChristian Braunerwould usually simply use the crossmapping algorithm and map the filesystem's 744ad19607aSChristian Braunerkernel id up to a userspace id in the caller's idmapping. 745ad19607aSChristian Brauner 7465d3ca596SChristian BraunerBut when the caller is accessing the file on an idmapped mount the kernel will 7475d3ca596SChristian Braunerfirst call ``i_uid_into_vfsuid()`` thereby translating the filesystem's kernel 748ad19607aSChristian Braunerid into a VFS id in the mount's idmapping:: 749ad19607aSChristian Brauner 7505d3ca596SChristian Brauner i_uid_into_vfsuid(k21000): 751ad19607aSChristian Brauner /* Map the filesystem's kernel id up into a userspace id. */ 752ad19607aSChristian Brauner from_kuid(u0:k20000:r10000, k21000) = u1000 7535d3ca596SChristian Brauner 754ad19607aSChristian Brauner /* Map the filesystem's userspace id down into a VFS id in the mount's idmapping. */ 755ad19607aSChristian Brauner make_kuid(u0:v10000:r10000, u1000) = v11000 756ad19607aSChristian Brauner 757ad19607aSChristian BraunerFinally, when the kernel reports the owner to the caller it will turn the 758ad19607aSChristian BraunerVFS id in the mount's idmapping into a userspace id in the caller's 759ad19607aSChristian Brauneridmapping:: 760ad19607aSChristian Brauner 761ad19607aSChristian Brauner k11000 = vfsuid_into_kuid(v11000) 762ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 763ad19607aSChristian Brauner 764ad19607aSChristian BraunerWe can test whether this algorithm really works by verifying what happens when 765ad19607aSChristian Braunerwe create a new file. Let's say the user is creating a file with ``u1000``. 766ad19607aSChristian Brauner 7675d3ca596SChristian BraunerThe kernel maps this to ``k11000`` in the caller's idmapping. Usually the 768ad19607aSChristian Braunerkernel would now apply the crossmapping, verifying that ``k11000`` can be 769ad19607aSChristian Braunermapped to a userspace id in the filesystem's idmapping. Since ``k11000`` can't 770ad19607aSChristian Braunerbe mapped up in the filesystem's idmapping directly this creation request 771ad19607aSChristian Braunerfails. 772ad19607aSChristian Brauner 773ad19607aSChristian BraunerBut when the caller is accessing the file on an idmapped mount the kernel will 7745d3ca596SChristian Braunerfirst call ``mapped_fs*id()`` thereby translating the caller's kernel id into 775ad19607aSChristian Braunera VFS id according to the mount's idmapping:: 7765d3ca596SChristian Brauner 777ad19607aSChristian Brauner mapped_fsuid(k11000): 778ad19607aSChristian Brauner /* Map the caller's kernel id up into a userspace id in the mount's idmapping. */ 7795d3ca596SChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 780ad19607aSChristian Brauner 781ad19607aSChristian Brauner /* Map the mount's userspace id down into a kernel id in the filesystem's idmapping. */ 782ad19607aSChristian Brauner make_kuid(u0:v20000:r10000, u1000) = v21000 783ad19607aSChristian Brauner 784ad19607aSChristian BraunerWhen finally writing to disk the kernel will then map ``v21000`` up into a 785ad19607aSChristian Brauneruserspace id in the filesystem's idmapping:: 786ad19607aSChristian Brauner 787ad19607aSChristian Brauner k21000 = vfsuid_into_kuid(v21000) 788ad19607aSChristian Brauner from_kuid(u0:k20000:r10000, k21000) = u1000 789ad19607aSChristian Brauner 790ad19607aSChristian BraunerAs we can see, we end up with an invertible and therefore information 791ad19607aSChristian Braunerpreserving algorithm. A file created from ``u1000`` on an idmapped mount will 792ad19607aSChristian Brauneralso be reported as being owned by ``u1000`` and vica versa. 793ad19607aSChristian Brauner 794ad19607aSChristian BraunerLet's now briefly reconsider the failing examples from earlier in the context 795ad19607aSChristian Braunerof idmapped mounts. 796ad19607aSChristian Brauner 7975d3ca596SChristian BraunerExample 2 reconsidered 798ad19607aSChristian Brauner~~~~~~~~~~~~~~~~~~~~~~ 799ad19607aSChristian Brauner 800ad19607aSChristian Brauner:: 801ad19607aSChristian Brauner 802ad19607aSChristian Brauner caller id: u1000 803ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 804ad19607aSChristian Brauner filesystem idmapping: u0:k20000:r10000 805ad19607aSChristian Brauner mount idmapping: u0:v10000:r10000 8065d3ca596SChristian Brauner 807ad19607aSChristian BraunerWhen the caller is using a non-initial idmapping the common case is to attach 808ad19607aSChristian Braunerthe same idmapping to the mount. We now perform three steps: 8095d3ca596SChristian Brauner 8105d3ca596SChristian Brauner1. Map the caller's userspace ids into kernel ids in the caller's idmapping:: 8115d3ca596SChristian Brauner 812ad19607aSChristian Brauner make_kuid(u0:k10000:r10000, u1000) = k11000 813ad19607aSChristian Brauner 814ad19607aSChristian Brauner2. Translate the caller's VFS id into a kernel id in the filesystem's 815ad19607aSChristian Brauner idmapping:: 816ad19607aSChristian Brauner 817ad19607aSChristian Brauner mapped_fsuid(v11000): 818ad19607aSChristian Brauner /* Map the VFS id up into a userspace id in the mount's idmapping. */ 819ad19607aSChristian Brauner from_kuid(u0:v10000:r10000, v11000) = u1000 820ad19607aSChristian Brauner 821ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the filesystem's idmapping. */ 822ad19607aSChristian Brauner make_kuid(u0:k20000:r10000, u1000) = k21000 823ad19607aSChristian Brauner 824ad19607aSChristian Brauner2. Verify that the caller's kernel ids can be mapped to userspace ids in the 825ad19607aSChristian Brauner filesystem's idmapping:: 826ad19607aSChristian Brauner 827ad19607aSChristian Brauner from_kuid(u0:k20000:r10000, k21000) = u1000 828ad19607aSChristian Brauner 829ad19607aSChristian BraunerSo the ownership that lands on disk will be ``u1000``. 830ad19607aSChristian Brauner 8315d3ca596SChristian BraunerExample 3 reconsidered 832ad19607aSChristian Brauner~~~~~~~~~~~~~~~~~~~~~~ 833ad19607aSChristian Brauner 834ad19607aSChristian Brauner:: 835ad19607aSChristian Brauner 836ad19607aSChristian Brauner caller id: u1000 837ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 838ad19607aSChristian Brauner filesystem idmapping: u0:k0:r4294967295 8395d3ca596SChristian Brauner mount idmapping: u0:v10000:r10000 840ad19607aSChristian Brauner 841ad19607aSChristian BraunerThe same translation algorithm works with the third example. 8425d3ca596SChristian Brauner 8435d3ca596SChristian Brauner1. Map the caller's userspace ids into kernel ids in the caller's idmapping:: 8445d3ca596SChristian Brauner 845ad19607aSChristian Brauner make_kuid(u0:k10000:r10000, u1000) = k11000 846ad19607aSChristian Brauner 847ad19607aSChristian Brauner2. Translate the caller's VFS id into a kernel id in the filesystem's 848ad19607aSChristian Brauner idmapping:: 849ad19607aSChristian Brauner 850ad19607aSChristian Brauner mapped_fsuid(v11000): 851ad19607aSChristian Brauner /* Map the VFS id up into a userspace id in the mount's idmapping. */ 852ad19607aSChristian Brauner from_kuid(u0:v10000:r10000, v11000) = u1000 853ad19607aSChristian Brauner 854ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the filesystem's idmapping. */ 855ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 856ad19607aSChristian Brauner 857ad19607aSChristian Brauner2. Verify that the caller's kernel ids can be mapped to userspace ids in the 858ad19607aSChristian Brauner filesystem's idmapping:: 859ad19607aSChristian Brauner 860ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k21000) = u1000 861ad19607aSChristian Brauner 862ad19607aSChristian BraunerSo the ownership that lands on disk will be ``u1000``. 863ad19607aSChristian Brauner 8645d3ca596SChristian BraunerExample 4 reconsidered 865ad19607aSChristian Brauner~~~~~~~~~~~~~~~~~~~~~~ 866ad19607aSChristian Brauner 867ad19607aSChristian Brauner:: 868ad19607aSChristian Brauner 869ad19607aSChristian Brauner file id: u1000 870ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 871ad19607aSChristian Brauner filesystem idmapping: u0:k0:r4294967295 872ad19607aSChristian Brauner mount idmapping: u0:v10000:r10000 873ad19607aSChristian Brauner 8745d3ca596SChristian BraunerIn order to report ownership to userspace the kernel now does three steps using 875ad19607aSChristian Braunerthe translation algorithm we introduced earlier: 8765d3ca596SChristian Brauner 877ad19607aSChristian Brauner1. Map the userspace id on disk down into a kernel id in the filesystem's 878ad19607aSChristian Brauner idmapping:: 879ad19607aSChristian Brauner 8805d3ca596SChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 8815d3ca596SChristian Brauner 882ad19607aSChristian Brauner2. Translate the kernel id into a VFS id in the mount's idmapping:: 8835d3ca596SChristian Brauner 884ad19607aSChristian Brauner i_uid_into_vfsuid(k1000): 8855d3ca596SChristian Brauner /* Map the kernel id up into a userspace id in the filesystem's idmapping. */ 886ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k1000) = u1000 887ad19607aSChristian Brauner 888ad19607aSChristian Brauner /* Map the userspace id down into a VFS id in the mounts's idmapping. */ 889ad19607aSChristian Brauner make_kuid(u0:v10000:r10000, u1000) = v11000 890ad19607aSChristian Brauner 891ad19607aSChristian Brauner3. Map the VFS id up into a userspace id in the caller's idmapping:: 892ad19607aSChristian Brauner 893ad19607aSChristian Brauner k11000 = vfsuid_into_kuid(v11000) 894ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 895ad19607aSChristian Brauner 896ad19607aSChristian BraunerEarlier, the caller's kernel id couldn't be crossmapped in the filesystems's 897ad19607aSChristian Brauneridmapping. With the idmapped mount in place it now can be crossmapped into the 898ad19607aSChristian Braunerfilesystem's idmapping via the mount's idmapping. The file will now be created 899ad19607aSChristian Braunerwith ``u1000`` according to the mount's idmapping. 900ad19607aSChristian Brauner 9015d3ca596SChristian BraunerExample 5 reconsidered 902ad19607aSChristian Brauner~~~~~~~~~~~~~~~~~~~~~~ 903ad19607aSChristian Brauner 904ad19607aSChristian Brauner:: 905ad19607aSChristian Brauner 906ad19607aSChristian Brauner file id: u1000 907ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 908ad19607aSChristian Brauner filesystem idmapping: u0:k20000:r10000 909ad19607aSChristian Brauner mount idmapping: u0:v10000:r10000 910ad19607aSChristian Brauner 9115d3ca596SChristian BraunerAgain, in order to report ownership to userspace the kernel now does three 912ad19607aSChristian Braunersteps using the translation algorithm we introduced earlier: 9135d3ca596SChristian Brauner 914ad19607aSChristian Brauner1. Map the userspace id on disk down into a kernel id in the filesystem's 915ad19607aSChristian Brauner idmapping:: 916ad19607aSChristian Brauner 9175d3ca596SChristian Brauner make_kuid(u0:k20000:r10000, u1000) = k21000 9185d3ca596SChristian Brauner 919ad19607aSChristian Brauner2. Translate the kernel id into a VFS id in the mount's idmapping:: 9205d3ca596SChristian Brauner 921ad19607aSChristian Brauner i_uid_into_vfsuid(k21000): 9225d3ca596SChristian Brauner /* Map the kernel id up into a userspace id in the filesystem's idmapping. */ 923ad19607aSChristian Brauner from_kuid(u0:k20000:r10000, k21000) = u1000 924ad19607aSChristian Brauner 925ad19607aSChristian Brauner /* Map the userspace id down into a VFS id in the mounts's idmapping. */ 926ad19607aSChristian Brauner make_kuid(u0:v10000:r10000, u1000) = v11000 927ad19607aSChristian Brauner 928ad19607aSChristian Brauner3. Map the VFS id up into a userspace id in the caller's idmapping:: 929ad19607aSChristian Brauner 930ad19607aSChristian Brauner k11000 = vfsuid_into_kuid(v11000) 931ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 932ad19607aSChristian Brauner 933ad19607aSChristian BraunerEarlier, the file's kernel id couldn't be crossmapped in the filesystems's 934ad19607aSChristian Brauneridmapping. With the idmapped mount in place it now can be crossmapped into the 935ad19607aSChristian Braunerfilesystem's idmapping via the mount's idmapping. The file is now owned by 936ad19607aSChristian Brauner``u1000`` according to the mount's idmapping. 937ad19607aSChristian Brauner 938ad19607aSChristian BraunerChanging ownership on a home directory 939ad19607aSChristian Brauner~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 940ad19607aSChristian Brauner 941ad19607aSChristian BraunerWe've seen above how idmapped mounts can be used to translate between 942ad19607aSChristian Brauneridmappings when either the caller, the filesystem or both uses a non-initial 943ad19607aSChristian Brauneridmapping. A wide range of usecases exist when the caller is using 944ad19607aSChristian Braunera non-initial idmapping. This mostly happens in the context of containerized 945ad19607aSChristian Braunerworkloads. The consequence is as we have seen that for both, filesystem's 946ad19607aSChristian Braunermounted with the initial idmapping and filesystems mounted with non-initial 947ad19607aSChristian Brauneridmappings, access to the filesystem isn't working because the kernel ids can't 948ad19607aSChristian Braunerbe crossmapped between the caller's and the filesystem's idmapping. 949ad19607aSChristian Brauner 950ad19607aSChristian BraunerAs we've seen above idmapped mounts provide a solution to this by remapping the 951ad19607aSChristian Braunercaller's or filesystem's idmapping according to the mount's idmapping. 952ad19607aSChristian Brauner 953ad19607aSChristian BraunerAside from containerized workloads, idmapped mounts have the advantage that 954ad19607aSChristian Braunerthey also work when both the caller and the filesystem use the initial 955ad19607aSChristian Brauneridmapping which means users on the host can change the ownership of directories 956ad19607aSChristian Braunerand files on a per-mount basis. 957ad19607aSChristian Brauner 958ad19607aSChristian BraunerConsider our previous example where a user has their home directory on portable 959ad19607aSChristian Braunerstorage. At home they have id ``u1000`` and all files in their home directory 960ad19607aSChristian Braunerare owned by ``u1000`` whereas at uni or work they have login id ``u1125``. 961ad19607aSChristian Brauner 962ad19607aSChristian BraunerTaking their home directory with them becomes problematic. They can't easily 963ad19607aSChristian Brauneraccess their files, they might not be able to write to disk without applying 964ad19607aSChristian Braunerlax permissions or ACLs and even if they can, they will end up with an annoying 965ad19607aSChristian Braunermix of files and directories owned by ``u1000`` and ``u1125``. 966ad19607aSChristian Brauner 967ad19607aSChristian BraunerIdmapped mounts allow to solve this problem. A user can create an idmapped 968ad19607aSChristian Braunermount for their home directory on their work computer or their computer at home 969ad19607aSChristian Braunerdepending on what ownership they would prefer to end up on the portable storage 970ad19607aSChristian Brauneritself. 971ad19607aSChristian Brauner 972ad19607aSChristian BraunerLet's assume they want all files on disk to belong to ``u1000``. When the user 9735d3ca596SChristian Braunerplugs in their portable storage at their work station they can setup a job that 974ad19607aSChristian Braunercreates an idmapped mount with the minimal idmapping ``u1000:k1125:r1``. So now 975ad19607aSChristian Braunerwhen they create a file the kernel performs the following steps we already know 976ad19607aSChristian Braunerfrom above::: 977ad19607aSChristian Brauner 978ad19607aSChristian Brauner caller id: u1125 9795d3ca596SChristian Brauner caller idmapping: u0:k0:r4294967295 980ad19607aSChristian Brauner filesystem idmapping: u0:k0:r4294967295 981ad19607aSChristian Brauner mount idmapping: u1000:v1125:r1 9825d3ca596SChristian Brauner 9835d3ca596SChristian Brauner1. Map the caller's userspace ids into kernel ids in the caller's idmapping:: 9845d3ca596SChristian Brauner 985ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1125) = k1125 986ad19607aSChristian Brauner 987ad19607aSChristian Brauner2. Translate the caller's VFS id into a kernel id in the filesystem's 988ad19607aSChristian Brauner idmapping:: 9895d3ca596SChristian Brauner 990ad19607aSChristian Brauner mapped_fsuid(v1125): 991ad19607aSChristian Brauner /* Map the VFS id up into a userspace id in the mount's idmapping. */ 992ad19607aSChristian Brauner from_kuid(u1000:v1125:r1, v1125) = u1000 993ad19607aSChristian Brauner 994ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the filesystem's idmapping. */ 995ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 996ad19607aSChristian Brauner 997ad19607aSChristian Brauner2. Verify that the caller's filesystem ids can be mapped to userspace ids in the 998ad19607aSChristian Brauner filesystem's idmapping:: 999ad19607aSChristian Brauner 1000ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k1000) = u1000 1001ad19607aSChristian Brauner 1002ad19607aSChristian BraunerSo ultimately the file will be created with ``u1000`` on disk. 1003ad19607aSChristian Brauner 10045d3ca596SChristian BraunerNow let's briefly look at what ownership the caller with id ``u1125`` will see 1005ad19607aSChristian Brauneron their work computer: 1006ad19607aSChristian Brauner 1007ad19607aSChristian Brauner:: 1008ad19607aSChristian Brauner 1009ad19607aSChristian Brauner file id: u1000 1010ad19607aSChristian Brauner caller idmapping: u0:k0:r4294967295 10115d3ca596SChristian Brauner filesystem idmapping: u0:k0:r4294967295 1012ad19607aSChristian Brauner mount idmapping: u1000:v1125:r1 10135d3ca596SChristian Brauner 1014ad19607aSChristian Brauner1. Map the userspace id on disk down into a kernel id in the filesystem's 1015ad19607aSChristian Brauner idmapping:: 1016ad19607aSChristian Brauner 10175d3ca596SChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 10185d3ca596SChristian Brauner 1019ad19607aSChristian Brauner2. Translate the kernel id into a VFS id in the mount's idmapping:: 10205d3ca596SChristian Brauner 1021ad19607aSChristian Brauner i_uid_into_vfsuid(k1000): 10225d3ca596SChristian Brauner /* Map the kernel id up into a userspace id in the filesystem's idmapping. */ 1023ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k1000) = u1000 1024ad19607aSChristian Brauner 1025ad19607aSChristian Brauner /* Map the userspace id down into a VFS id in the mounts's idmapping. */ 1026ad19607aSChristian Brauner make_kuid(u1000:v1125:r1, u1000) = v1125 1027ad19607aSChristian Brauner 1028ad19607aSChristian Brauner3. Map the VFS id up into a userspace id in the caller's idmapping:: 1029ad19607aSChristian Brauner 1030ad19607aSChristian Brauner k1125 = vfsuid_into_kuid(v1125) 1031ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k1125) = u1125 1032 1033So ultimately the caller will be reported that the file belongs to ``u1125`` 1034which is the caller's userspace id on their workstation in our example. 1035 1036The raw userspace id that is put on disk is ``u1000`` so when the user takes 1037their home directory back to their home computer where they are assigned 1038``u1000`` using the initial idmapping and mount the filesystem with the initial 1039idmapping they will see all those files owned by ``u1000``. 1040