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 39ad19607aSChristian Braunerthe set of all possible ids useable 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 50ad19607aSChristian Braunerdealing with subsets we can embedd 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 63ad19607aSChristian Braunerstraightfoward 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, the id ``u1000`` is an id in the upper idmapset or "userspace 150ad19607aSChristian Brauneridmapset" starting with ``u1000``. And it is mapped to ``k11000`` which is a 151ad19607aSChristian Braunerkernel id in the lower idmapset or "kernel idmapset" starting with ``k10000``. 152ad19607aSChristian Brauner 153ad19607aSChristian BraunerA kernel id is always created by an idmapping. Such idmappings are associated 154ad19607aSChristian Braunerwith user namespaces. Since we mainly care about how idmappings work we're not 155ad19607aSChristian Braunergoing to be concerned with how idmappings are created nor how they are used 156ad19607aSChristian Brauneroutside of the filesystem context. This is best left to an explanation of user 157ad19607aSChristian Braunernamespaces. 158ad19607aSChristian Brauner 159ad19607aSChristian BraunerThe initial user namespace is special. It always has an idmapping of the 160ad19607aSChristian Braunerfollowing form:: 161ad19607aSChristian Brauner 162ad19607aSChristian Brauner u0:k0:r4294967295 163ad19607aSChristian Brauner 164ad19607aSChristian Braunerwhich is an identity idmapping over the full range of ids available on this 165ad19607aSChristian Braunersystem. 166ad19607aSChristian Brauner 167ad19607aSChristian BraunerOther user namespaces usually have non-identity idmappings such as:: 168ad19607aSChristian Brauner 169ad19607aSChristian Brauner u0:k10000:r10000 170ad19607aSChristian Brauner 171ad19607aSChristian BraunerWhen a process creates or wants to change ownership of a file, or when the 172ad19607aSChristian Braunerownership of a file is read from disk by a filesystem, the userspace id is 173ad19607aSChristian Braunerimmediately translated into a kernel id according to the idmapping associated 174ad19607aSChristian Braunerwith the relevant user namespace. 175ad19607aSChristian Brauner 176ad19607aSChristian BraunerFor instance, consider a file that is stored on disk by a filesystem as being 177ad19607aSChristian Braunerowned by ``u1000``: 178ad19607aSChristian Brauner 179ad19607aSChristian Brauner- If a filesystem were to be mounted in the initial user namespaces (as most 180ad19607aSChristian Brauner filesystems are) then the initial idmapping will be used. As we saw this is 181ad19607aSChristian Brauner simply the identity idmapping. This would mean id ``u1000`` read from disk 182ad19607aSChristian Brauner would be mapped to id ``k1000``. So an inode's ``i_uid`` and ``i_gid`` field 183ad19607aSChristian Brauner would contain ``k1000``. 184ad19607aSChristian Brauner 185ad19607aSChristian Brauner- If a filesystem were to be mounted with an idmapping of ``u0:k10000:r10000`` 186ad19607aSChristian Brauner then ``u1000`` read from disk would be mapped to ``k11000``. So an inode's 187ad19607aSChristian Brauner ``i_uid`` and ``i_gid`` would contain ``k11000``. 188ad19607aSChristian Brauner 189ad19607aSChristian BraunerTranslation algorithms 190ad19607aSChristian Brauner---------------------- 191ad19607aSChristian Brauner 192ad19607aSChristian BraunerWe've already seen briefly that it is possible to translate between different 193ad19607aSChristian Brauneridmappings. We'll now take a closer look how that works. 194ad19607aSChristian Brauner 195ad19607aSChristian BraunerCrossmapping 196ad19607aSChristian Brauner~~~~~~~~~~~~ 197ad19607aSChristian Brauner 198ad19607aSChristian BraunerThis translation algorithm is used by the kernel in quite a few places. For 199ad19607aSChristian Braunerexample, it is used when reporting back the ownership of a file to userspace 200ad19607aSChristian Braunervia the ``stat()`` system call family. 201ad19607aSChristian Brauner 202ad19607aSChristian BraunerIf we've been given ``k11000`` from one idmapping we can map that id up in 203ad19607aSChristian Brauneranother idmapping. In order for this to work both idmappings need to contain 204ad19607aSChristian Braunerthe same kernel id in their kernel idmapsets. For example, consider the 205ad19607aSChristian Braunerfollowing idmappings:: 206ad19607aSChristian Brauner 207ad19607aSChristian Brauner 1. u0:k10000:r10000 208ad19607aSChristian Brauner 2. u20000:k10000:r10000 209ad19607aSChristian Brauner 210ad19607aSChristian Braunerand we are mapping ``u1000`` down to ``k11000`` in the first idmapping . We can 211ad19607aSChristian Braunerthen translate ``k11000`` into a userspace id in the second idmapping using the 212ad19607aSChristian Braunerkernel idmapset of the second idmapping:: 213ad19607aSChristian Brauner 214ad19607aSChristian Brauner /* Map the kernel id up into a userspace id in the second idmapping. */ 215ad19607aSChristian Brauner from_kuid(u20000:k10000:r10000, k11000) = u21000 216ad19607aSChristian Brauner 217ad19607aSChristian BraunerNote, how we can get back to the kernel id in the first idmapping by inverting 218ad19607aSChristian Braunerthe algorithm:: 219ad19607aSChristian Brauner 220ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the second idmapping. */ 221ad19607aSChristian Brauner make_kuid(u20000:k10000:r10000, u21000) = k11000 222ad19607aSChristian Brauner 223ad19607aSChristian Brauner /* Map the kernel id up into a userspace id in the first idmapping. */ 224ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 225ad19607aSChristian Brauner 226ad19607aSChristian BraunerThis algorithm allows us to answer the question what userspace id a given 227ad19607aSChristian Braunerkernel id corresponds to in a given idmapping. In order to be able to answer 228ad19607aSChristian Braunerthis question both idmappings need to contain the same kernel id in their 229ad19607aSChristian Braunerrespective kernel idmapsets. 230ad19607aSChristian Brauner 231ad19607aSChristian BraunerFor example, when the kernel reads a raw userspace id from disk it maps it down 232ad19607aSChristian Braunerinto a kernel id according to the idmapping associated with the filesystem. 233ad19607aSChristian BraunerLet's assume the filesystem was mounted with an idmapping of 234ad19607aSChristian Brauner``u0:k20000:r10000`` and it reads a file owned by ``u1000`` from disk. This 235ad19607aSChristian Braunermeans ``u1000`` will be mapped to ``k21000`` which is what will be stored in 236ad19607aSChristian Braunerthe inode's ``i_uid`` and ``i_gid`` field. 237ad19607aSChristian Brauner 238ad19607aSChristian BraunerWhen someone in userspace calls ``stat()`` or a related function to get 239ad19607aSChristian Braunerownership information about the file the kernel can't simply map the id back up 240ad19607aSChristian Brauneraccording to the filesystem's idmapping as this would give the wrong owner if 241ad19607aSChristian Braunerthe caller is using an idmapping. 242ad19607aSChristian Brauner 243ad19607aSChristian BraunerSo the kernel will map the id back up in the idmapping of the caller. Let's 244*5d3ca596SChristian Braunerassume the caller has the somewhat unconventional idmapping 245ad19607aSChristian Brauner``u3000:k20000:r10000`` then ``k21000`` would map back up to ``u4000``. 246ad19607aSChristian BraunerConsequently the user would see that this file is owned by ``u4000``. 247ad19607aSChristian Brauner 248ad19607aSChristian BraunerRemapping 249ad19607aSChristian Brauner~~~~~~~~~ 250ad19607aSChristian Brauner 251ad19607aSChristian BraunerIt is possible to translate a kernel id from one idmapping to another one via 252ad19607aSChristian Braunerthe userspace idmapset of the two idmappings. This is equivalent to remapping 253ad19607aSChristian Braunera kernel id. 254ad19607aSChristian Brauner 255ad19607aSChristian BraunerLet's look at an example. We are given the following two idmappings:: 256ad19607aSChristian Brauner 257ad19607aSChristian Brauner 1. u0:k10000:r10000 258ad19607aSChristian Brauner 2. u0:k20000:r10000 259ad19607aSChristian Brauner 260ad19607aSChristian Braunerand we are given ``k11000`` in the first idmapping. In order to translate this 261ad19607aSChristian Braunerkernel id in the first idmapping into a kernel id in the second idmapping we 262ad19607aSChristian Braunerneed to perform two steps: 263ad19607aSChristian Brauner 264ad19607aSChristian Brauner1. Map the kernel id up into a userspace id in the first idmapping:: 265ad19607aSChristian Brauner 266ad19607aSChristian Brauner /* Map the kernel id up into a userspace id in the first idmapping. */ 267ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 268ad19607aSChristian Brauner 269ad19607aSChristian Brauner2. Map the userspace id down into a kernel id in the second idmapping:: 270ad19607aSChristian Brauner 271ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the second idmapping. */ 272ad19607aSChristian Brauner make_kuid(u0:k20000:r10000, u1000) = k21000 273ad19607aSChristian Brauner 274ad19607aSChristian BraunerAs you can see we used the userspace idmapset in both idmappings to translate 275ad19607aSChristian Braunerthe kernel id in one idmapping to a kernel id in another idmapping. 276ad19607aSChristian Brauner 277ad19607aSChristian BraunerThis allows us to answer the question what kernel id we would need to use to 278ad19607aSChristian Braunerget the same userspace id in another idmapping. In order to be able to answer 279ad19607aSChristian Braunerthis question both idmappings need to contain the same userspace id in their 280ad19607aSChristian Braunerrespective userspace idmapsets. 281ad19607aSChristian Brauner 282ad19607aSChristian BraunerNote, how we can easily get back to the kernel id in the first idmapping by 283ad19607aSChristian Braunerinverting the algorithm: 284ad19607aSChristian Brauner 285ad19607aSChristian Brauner1. Map the kernel id up into a userspace id in the second idmapping:: 286ad19607aSChristian Brauner 287ad19607aSChristian Brauner /* Map the kernel id up into a userspace id in the second idmapping. */ 288ad19607aSChristian Brauner from_kuid(u0:k20000:r10000, k21000) = u1000 289ad19607aSChristian Brauner 290ad19607aSChristian Brauner2. Map the userspace id down into a kernel id in the first idmapping:: 291ad19607aSChristian Brauner 292ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the first idmapping. */ 293ad19607aSChristian Brauner make_kuid(u0:k10000:r10000, u1000) = k11000 294ad19607aSChristian Brauner 295ad19607aSChristian BraunerAnother way to look at this translation is to treat it as inverting one 296ad19607aSChristian Brauneridmapping and applying another idmapping if both idmappings have the relevant 297ad19607aSChristian Brauneruserspace id mapped. This will come in handy when working with idmapped mounts. 298ad19607aSChristian Brauner 299ad19607aSChristian BraunerInvalid translations 300ad19607aSChristian Brauner~~~~~~~~~~~~~~~~~~~~ 301ad19607aSChristian Brauner 302ad19607aSChristian BraunerIt is never valid to use an id in the kernel idmapset of one idmapping as the 303ad19607aSChristian Braunerid in the userspace idmapset of another or the same idmapping. While the kernel 304ad19607aSChristian Brauneridmapset always indicates an idmapset in the kernel id space the userspace 305ad19607aSChristian Brauneridmapset indicates a userspace id. So the following translations are forbidden:: 306ad19607aSChristian Brauner 307ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the first idmapping. */ 308ad19607aSChristian Brauner make_kuid(u0:k10000:r10000, u1000) = k11000 309ad19607aSChristian Brauner 310ad19607aSChristian Brauner /* INVALID: Map the kernel id down into a kernel id in the second idmapping. */ 311ad19607aSChristian Brauner make_kuid(u10000:k20000:r10000, k110000) = k21000 312ad19607aSChristian Brauner ~~~~~~~ 313ad19607aSChristian Brauner 314ad19607aSChristian Braunerand equally wrong:: 315ad19607aSChristian Brauner 316ad19607aSChristian Brauner /* Map the kernel id up into a userspace id in the first idmapping. */ 317ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 318ad19607aSChristian Brauner 319ad19607aSChristian Brauner /* INVALID: Map the userspace id up into a userspace id in the second idmapping. */ 320ad19607aSChristian Brauner from_kuid(u20000:k0:r10000, u1000) = k21000 321ad19607aSChristian Brauner ~~~~~ 322ad19607aSChristian Brauner 323*5d3ca596SChristian BraunerSince userspace ids have type ``uid_t`` and ``gid_t`` and kernel ids have type 324*5d3ca596SChristian Brauner``kuid_t`` and ``kgid_t`` the compiler will throw an error when they are 325*5d3ca596SChristian Braunerconflated. So the two examples above would cause a compilation failure. 326*5d3ca596SChristian Brauner 327ad19607aSChristian BraunerIdmappings when creating filesystem objects 328ad19607aSChristian Brauner------------------------------------------- 329ad19607aSChristian Brauner 330ad19607aSChristian BraunerThe concepts of mapping an id down or mapping an id up are expressed in the two 331ad19607aSChristian Braunerkernel functions filesystem developers are rather familiar with and which we've 332ad19607aSChristian Brauneralready used in this document:: 333ad19607aSChristian Brauner 334ad19607aSChristian Brauner /* Map the userspace id down into a kernel id. */ 335ad19607aSChristian Brauner make_kuid(idmapping, uid) 336ad19607aSChristian Brauner 337ad19607aSChristian Brauner /* Map the kernel id up into a userspace id. */ 338ad19607aSChristian Brauner from_kuid(idmapping, kuid) 339ad19607aSChristian Brauner 340ad19607aSChristian BraunerWe will take an abbreviated look into how idmappings figure into creating 341ad19607aSChristian Braunerfilesystem objects. For simplicity we will only look at what happens when the 342ad19607aSChristian BraunerVFS has already completed path lookup right before it calls into the filesystem 343ad19607aSChristian Brauneritself. So we're concerned with what happens when e.g. ``vfs_mkdir()`` is 344ad19607aSChristian Braunercalled. We will also assume that the directory we're creating filesystem 345ad19607aSChristian Braunerobjects in is readable and writable for everyone. 346ad19607aSChristian Brauner 347ad19607aSChristian BraunerWhen creating a filesystem object the caller will look at the caller's 348ad19607aSChristian Braunerfilesystem ids. These are just regular ``uid_t`` and ``gid_t`` userspace ids 349ad19607aSChristian Braunerbut they are exclusively used when determining file ownership which is why they 350ad19607aSChristian Braunerare called "filesystem ids". They are usually identical to the uid and gid of 351ad19607aSChristian Braunerthe caller but can differ. We will just assume they are always identical to not 352ad19607aSChristian Braunerget lost in too many details. 353ad19607aSChristian Brauner 354ad19607aSChristian BraunerWhen the caller enters the kernel two things happen: 355ad19607aSChristian Brauner 356ad19607aSChristian Brauner1. Map the caller's userspace ids down into kernel ids in the caller's 357ad19607aSChristian Brauner idmapping. 358ad19607aSChristian Brauner (To be precise, the kernel will simply look at the kernel ids stashed in the 359ad19607aSChristian Brauner credentials of the current task but for our education we'll pretend this 360ad19607aSChristian Brauner translation happens just in time.) 361ad19607aSChristian Brauner2. Verify that the caller's kernel ids can be mapped up to userspace ids in the 362ad19607aSChristian Brauner filesystem's idmapping. 363ad19607aSChristian Brauner 364ad19607aSChristian BraunerThe second step is important as regular filesystem will ultimately need to map 365ad19607aSChristian Braunerthe kernel id back up into a userspace id when writing to disk. 366ad19607aSChristian BraunerSo with the second step the kernel guarantees that a valid userspace id can be 367ad19607aSChristian Braunerwritten to disk. If it can't the kernel will refuse the creation request to not 368ad19607aSChristian Braunereven remotely risk filesystem corruption. 369ad19607aSChristian Brauner 370ad19607aSChristian BraunerThe astute reader will have realized that this is simply a varation of the 371ad19607aSChristian Braunercrossmapping algorithm we mentioned above in a previous section. First, the 372ad19607aSChristian Braunerkernel maps the caller's userspace id down into a kernel id according to the 373ad19607aSChristian Braunercaller's idmapping and then maps that kernel id up according to the 374ad19607aSChristian Braunerfilesystem's idmapping. 375ad19607aSChristian Brauner 376ccbd0c99SRodrigo CamposLet's see some examples with caller/filesystem idmapping but without mount 377ccbd0c99SRodrigo Camposidmappings. This will exhibit some problems we can hit. After that we will 378ccbd0c99SRodrigo Camposrevisit/reconsider these examples, this time using mount idmappings, to see how 379ccbd0c99SRodrigo Camposthey can solve the problems we observed before. 380ccbd0c99SRodrigo Campos 381ad19607aSChristian BraunerExample 1 382ad19607aSChristian Brauner~~~~~~~~~ 383ad19607aSChristian Brauner 384ad19607aSChristian Brauner:: 385ad19607aSChristian Brauner 386ad19607aSChristian Brauner caller id: u1000 387ad19607aSChristian Brauner caller idmapping: u0:k0:r4294967295 388ad19607aSChristian Brauner filesystem idmapping: u0:k0:r4294967295 389ad19607aSChristian Brauner 390ad19607aSChristian BraunerBoth the caller and the filesystem use the identity idmapping: 391ad19607aSChristian Brauner 392ad19607aSChristian Brauner1. Map the caller's userspace ids into kernel ids in the caller's idmapping:: 393ad19607aSChristian Brauner 394ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 395ad19607aSChristian Brauner 396ad19607aSChristian Brauner2. Verify that the caller's kernel ids can be mapped to userspace ids in the 397ad19607aSChristian Brauner filesystem's idmapping. 398ad19607aSChristian Brauner 399ad19607aSChristian Brauner For this second step the kernel will call the function 400ad19607aSChristian Brauner ``fsuidgid_has_mapping()`` which ultimately boils down to calling 401ad19607aSChristian Brauner ``from_kuid()``:: 402ad19607aSChristian Brauner 403ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k1000) = u1000 404ad19607aSChristian Brauner 405ad19607aSChristian BraunerIn this example both idmappings are the same so there's nothing exciting going 406ad19607aSChristian Brauneron. Ultimately the userspace id that lands on disk will be ``u1000``. 407ad19607aSChristian Brauner 408ad19607aSChristian BraunerExample 2 409ad19607aSChristian Brauner~~~~~~~~~ 410ad19607aSChristian Brauner 411ad19607aSChristian Brauner:: 412ad19607aSChristian Brauner 413ad19607aSChristian Brauner caller id: u1000 414ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 415ad19607aSChristian Brauner filesystem idmapping: u0:k20000:r10000 416ad19607aSChristian Brauner 417ad19607aSChristian Brauner1. Map the caller's userspace ids down into kernel ids in the caller's 418ad19607aSChristian Brauner idmapping:: 419ad19607aSChristian Brauner 420ad19607aSChristian Brauner make_kuid(u0:k10000:r10000, u1000) = k11000 421ad19607aSChristian Brauner 422ad19607aSChristian Brauner2. Verify that the caller's kernel ids can be mapped up to userspace ids in the 423ad19607aSChristian Brauner filesystem's idmapping:: 424ad19607aSChristian Brauner 425ad19607aSChristian Brauner from_kuid(u0:k20000:r10000, k11000) = u-1 426ad19607aSChristian Brauner 427ad19607aSChristian BraunerIt's immediately clear that while the caller's userspace id could be 428ad19607aSChristian Braunersuccessfully mapped down into kernel ids in the caller's idmapping the kernel 429ad19607aSChristian Braunerids could not be mapped up according to the filesystem's idmapping. So the 430ad19607aSChristian Braunerkernel will deny this creation request. 431ad19607aSChristian Brauner 432ad19607aSChristian BraunerNote that while this example is less common, because most filesystem can't be 433ad19607aSChristian Braunermounted with non-initial idmappings this is a general problem as we can see in 434ad19607aSChristian Braunerthe next examples. 435ad19607aSChristian Brauner 436ad19607aSChristian BraunerExample 3 437ad19607aSChristian Brauner~~~~~~~~~ 438ad19607aSChristian Brauner 439ad19607aSChristian Brauner:: 440ad19607aSChristian Brauner 441ad19607aSChristian Brauner caller id: u1000 442ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 443ad19607aSChristian Brauner filesystem idmapping: u0:k0:r4294967295 444ad19607aSChristian Brauner 445ad19607aSChristian Brauner1. Map the caller's userspace ids down into kernel ids in the caller's 446ad19607aSChristian Brauner idmapping:: 447ad19607aSChristian Brauner 448ad19607aSChristian Brauner make_kuid(u0:k10000:r10000, u1000) = k11000 449ad19607aSChristian Brauner 450ad19607aSChristian Brauner2. Verify that the caller's kernel ids can be mapped up to userspace ids in the 451ad19607aSChristian Brauner filesystem's idmapping:: 452ad19607aSChristian Brauner 453ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k11000) = u11000 454ad19607aSChristian Brauner 455ad19607aSChristian BraunerWe can see that the translation always succeeds. The userspace id that the 456ad19607aSChristian Braunerfilesystem will ultimately put to disk will always be identical to the value of 457ad19607aSChristian Braunerthe kernel id that was created in the caller's idmapping. This has mainly two 458ad19607aSChristian Braunerconsequences. 459ad19607aSChristian Brauner 460ad19607aSChristian BraunerFirst, that we can't allow a caller to ultimately write to disk with another 461ad19607aSChristian Brauneruserspace id. We could only do this if we were to mount the whole fileystem 462ad19607aSChristian Braunerwith the caller's or another idmapping. But that solution is limited to a few 463ad19607aSChristian Braunerfilesystems and not very flexible. But this is a use-case that is pretty 464ad19607aSChristian Braunerimportant in containerized workloads. 465ad19607aSChristian Brauner 466ad19607aSChristian BraunerSecond, the caller will usually not be able to create any files or access 467ad19607aSChristian Braunerdirectories that have stricter permissions because none of the filesystem's 468ad19607aSChristian Braunerkernel ids map up into valid userspace ids in the caller's idmapping 469ad19607aSChristian Brauner 470ad19607aSChristian Brauner1. Map raw userspace ids down to kernel ids in the filesystem's idmapping:: 471ad19607aSChristian Brauner 472ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 473ad19607aSChristian Brauner 474ad19607aSChristian Brauner2. Map kernel ids up to userspace ids in the caller's idmapping:: 475ad19607aSChristian Brauner 476ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k1000) = u-1 477ad19607aSChristian Brauner 478ad19607aSChristian BraunerExample 4 479ad19607aSChristian Brauner~~~~~~~~~ 480ad19607aSChristian Brauner 481ad19607aSChristian Brauner:: 482ad19607aSChristian Brauner 483ad19607aSChristian Brauner file id: u1000 484ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 485ad19607aSChristian Brauner filesystem idmapping: u0:k0:r4294967295 486ad19607aSChristian Brauner 487ad19607aSChristian BraunerIn order to report ownership to userspace the kernel uses the crossmapping 488ad19607aSChristian Brauneralgorithm introduced in a previous section: 489ad19607aSChristian Brauner 490ad19607aSChristian Brauner1. Map the userspace id on disk down into a kernel id in the filesystem's 491ad19607aSChristian Brauner idmapping:: 492ad19607aSChristian Brauner 493ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 494ad19607aSChristian Brauner 495ad19607aSChristian Brauner2. Map the kernel id up into a userspace id in the caller's idmapping:: 496ad19607aSChristian Brauner 497ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k1000) = u-1 498ad19607aSChristian Brauner 499ad19607aSChristian BraunerThe crossmapping algorithm fails in this case because the kernel id in the 500ad19607aSChristian Braunerfilesystem idmapping cannot be mapped up to a userspace id in the caller's 501ad19607aSChristian Brauneridmapping. Thus, the kernel will report the ownership of this file as the 502ad19607aSChristian Brauneroverflowid. 503ad19607aSChristian Brauner 504ad19607aSChristian BraunerExample 5 505ad19607aSChristian Brauner~~~~~~~~~ 506ad19607aSChristian Brauner 507ad19607aSChristian Brauner:: 508ad19607aSChristian Brauner 509ad19607aSChristian Brauner file id: u1000 510ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 511ad19607aSChristian Brauner filesystem idmapping: u0:k20000:r10000 512ad19607aSChristian Brauner 513ad19607aSChristian BraunerIn order to report ownership to userspace the kernel uses the crossmapping 514ad19607aSChristian Brauneralgorithm introduced in a previous section: 515ad19607aSChristian Brauner 516ad19607aSChristian Brauner1. Map the userspace id on disk down into a kernel id in the filesystem's 517ad19607aSChristian Brauner idmapping:: 518ad19607aSChristian Brauner 519ad19607aSChristian Brauner make_kuid(u0:k20000:r10000, u1000) = k21000 520ad19607aSChristian Brauner 521ad19607aSChristian Brauner2. Map the kernel id up into a userspace id in the caller's idmapping:: 522ad19607aSChristian Brauner 523ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k21000) = u-1 524ad19607aSChristian Brauner 525ad19607aSChristian BraunerAgain, the crossmapping algorithm fails in this case because the kernel id in 526ad19607aSChristian Braunerthe filesystem idmapping cannot be mapped to a userspace id in the caller's 527ad19607aSChristian Brauneridmapping. Thus, the kernel will report the ownership of this file as the 528ad19607aSChristian Brauneroverflowid. 529ad19607aSChristian Brauner 530ad19607aSChristian BraunerNote how in the last two examples things would be simple if the caller would be 531ad19607aSChristian Braunerusing the initial idmapping. For a filesystem mounted with the initial 532ad19607aSChristian Brauneridmapping it would be trivial. So we only consider a filesystem with an 533ad19607aSChristian Brauneridmapping of ``u0:k20000:r10000``: 534ad19607aSChristian Brauner 535ad19607aSChristian Brauner1. Map the userspace id on disk down into a kernel id in the filesystem's 536ad19607aSChristian Brauner idmapping:: 537ad19607aSChristian Brauner 538ad19607aSChristian Brauner make_kuid(u0:k20000:r10000, u1000) = k21000 539ad19607aSChristian Brauner 540ad19607aSChristian Brauner2. Map the kernel id up into a userspace id in the caller's idmapping:: 541ad19607aSChristian Brauner 542ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k21000) = u21000 543ad19607aSChristian Brauner 544ad19607aSChristian BraunerIdmappings on idmapped mounts 545ad19607aSChristian Brauner----------------------------- 546ad19607aSChristian Brauner 547ad19607aSChristian BraunerThe examples we've seen in the previous section where the caller's idmapping 548ad19607aSChristian Braunerand the filesystem's idmapping are incompatible causes various issues for 549ad19607aSChristian Braunerworkloads. For a more complex but common example, consider two containers 550ad19607aSChristian Braunerstarted on the host. To completely prevent the two containers from affecting 551ad19607aSChristian Braunereach other, an administrator may often use different non-overlapping idmappings 552ad19607aSChristian Braunerfor the two containers:: 553ad19607aSChristian Brauner 554ad19607aSChristian Brauner container1 idmapping: u0:k10000:r10000 555ad19607aSChristian Brauner container2 idmapping: u0:k20000:r10000 556ad19607aSChristian Brauner filesystem idmapping: u0:k30000:r10000 557ad19607aSChristian Brauner 558ad19607aSChristian BraunerAn administrator wanting to provide easy read-write access to the following set 559ad19607aSChristian Braunerof files:: 560ad19607aSChristian Brauner 561ad19607aSChristian Brauner dir id: u0 562ad19607aSChristian Brauner dir/file1 id: u1000 563ad19607aSChristian Brauner dir/file2 id: u2000 564ad19607aSChristian Brauner 565ad19607aSChristian Braunerto both containers currently can't. 566ad19607aSChristian Brauner 567ad19607aSChristian BraunerOf course the administrator has the option to recursively change ownership via 568ad19607aSChristian Brauner``chown()``. For example, they could change ownership so that ``dir`` and all 569ad19607aSChristian Braunerfiles below it can be crossmapped from the filesystem's into the container's 570ad19607aSChristian Brauneridmapping. Let's assume they change ownership so it is compatible with the 571ad19607aSChristian Braunerfirst container's idmapping:: 572ad19607aSChristian Brauner 573ad19607aSChristian Brauner dir id: u10000 574ad19607aSChristian Brauner dir/file1 id: u11000 575ad19607aSChristian Brauner dir/file2 id: u12000 576ad19607aSChristian Brauner 577ad19607aSChristian BraunerThis would still leave ``dir`` rather useless to the second container. In fact, 578ad19607aSChristian Brauner``dir`` and all files below it would continue to appear owned by the overflowid 579ad19607aSChristian Braunerfor the second container. 580ad19607aSChristian Brauner 581ad19607aSChristian BraunerOr consider another increasingly popular example. Some service managers such as 582ad19607aSChristian Braunersystemd implement a concept called "portable home directories". A user may want 583ad19607aSChristian Braunerto use their home directories on different machines where they are assigned 584ad19607aSChristian Braunerdifferent login userspace ids. Most users will have ``u1000`` as the login id 585ad19607aSChristian Brauneron their machine at home and all files in their home directory will usually be 586ad19607aSChristian Braunerowned by ``u1000``. At uni or at work they may have another login id such as 587ad19607aSChristian Brauner``u1125``. This makes it rather difficult to interact with their home directory 588ad19607aSChristian Brauneron their work machine. 589ad19607aSChristian Brauner 590ad19607aSChristian BraunerIn both cases changing ownership recursively has grave implications. The most 591ad19607aSChristian Braunerobvious one is that ownership is changed globally and permanently. In the home 592ad19607aSChristian Braunerdirectory case this change in ownership would even need to happen everytime the 593ad19607aSChristian Brauneruser switches from their home to their work machine. For really large sets of 594ad19607aSChristian Braunerfiles this becomes increasingly costly. 595ad19607aSChristian Brauner 596ad19607aSChristian BraunerIf the user is lucky, they are dealing with a filesystem that is mountable 597ad19607aSChristian Braunerinside user namespaces. But this would also change ownership globally and the 598ad19607aSChristian Braunerchange in ownership is tied to the lifetime of the filesystem mount, i.e. the 599ad19607aSChristian Braunersuperblock. The only way to change ownership is to completely unmount the 600ad19607aSChristian Braunerfilesystem and mount it again in another user namespace. This is usually 601ad19607aSChristian Braunerimpossible because it would mean that all users currently accessing the 602ad19607aSChristian Braunerfilesystem can't anymore. And it means that ``dir`` still can't be shared 603ad19607aSChristian Braunerbetween two containers with different idmappings. 604ad19607aSChristian BraunerBut usually the user doesn't even have this option since most filesystems 605ad19607aSChristian Brauneraren't mountable inside containers. And not having them mountable might be 606ad19607aSChristian Braunerdesirable as it doesn't require the filesystem to deal with malicious 607ad19607aSChristian Braunerfilesystem images. 608ad19607aSChristian Brauner 609ad19607aSChristian BraunerBut the usecases mentioned above and more can be handled by idmapped mounts. 610ad19607aSChristian BraunerThey allow to expose the same set of dentries with different ownership at 611ad19607aSChristian Braunerdifferent mounts. This is achieved by marking the mounts with a user namespace 612ad19607aSChristian Braunerthrough the ``mount_setattr()`` system call. The idmapping associated with it 613ad19607aSChristian Brauneris then used to translate from the caller's idmapping to the filesystem's 614ad19607aSChristian Brauneridmapping and vica versa using the remapping algorithm we introduced above. 615ad19607aSChristian Brauner 616ad19607aSChristian BraunerIdmapped mounts make it possible to change ownership in a temporary and 617ad19607aSChristian Braunerlocalized way. The ownership changes are restricted to a specific mount and the 618ad19607aSChristian Braunerownership changes are tied to the lifetime of the mount. All other users and 619ad19607aSChristian Braunerlocations where the filesystem is exposed are unaffected. 620ad19607aSChristian Brauner 621ad19607aSChristian BraunerFilesystems that support idmapped mounts don't have any real reason to support 622ad19607aSChristian Braunerbeing mountable inside user namespaces. A filesystem could be exposed 623ad19607aSChristian Braunercompletely under an idmapped mount to get the same effect. This has the 624ad19607aSChristian Brauneradvantage that filesystems can leave the creation of the superblock to 625ad19607aSChristian Braunerprivileged users in the initial user namespace. 626ad19607aSChristian Brauner 627ad19607aSChristian BraunerHowever, it is perfectly possible to combine idmapped mounts with filesystems 628ad19607aSChristian Braunermountable inside user namespaces. We will touch on this further below. 629ad19607aSChristian Brauner 630*5d3ca596SChristian BraunerFilesystem types vs idmapped mount types 631*5d3ca596SChristian Brauner~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 632*5d3ca596SChristian Brauner 633*5d3ca596SChristian BraunerWith the introduction of idmapped mounts we need to distinguish between 634*5d3ca596SChristian Braunerfilesystem ownership and mount ownership of a VFS object such as an inode. The 635*5d3ca596SChristian Braunerowner of a inode might be different when looked at from a filesystem 636*5d3ca596SChristian Braunerperspective than when looked at from an idmapped mount. Such fundamental 637*5d3ca596SChristian Braunerconceptual distinctions should almost always be clearly expressed in the code. 638*5d3ca596SChristian BraunerSo, to distinguish idmapped mount ownership from filesystem ownership separate 639*5d3ca596SChristian Braunertypes have been introduced. 640*5d3ca596SChristian Brauner 641*5d3ca596SChristian BraunerIf a uid or gid has been generated using the filesystem or caller's idmapping 642*5d3ca596SChristian Braunerthen we will use the ``kuid_t`` and ``kgid_t`` types. However, if a uid or gid 643*5d3ca596SChristian Braunerhas been generated using a mount idmapping then we will be using the dedicated 644*5d3ca596SChristian Brauner``vfsuid_t`` and ``vfsgid_t`` types. 645*5d3ca596SChristian Brauner 646*5d3ca596SChristian BraunerAll VFS helpers that generate or take uids and gids as arguments use the 647*5d3ca596SChristian Brauner``vfsuid_t`` and ``vfsgid_t`` types and we will be able to rely on the compiler 648*5d3ca596SChristian Braunerto catch errors that originate from conflating filesystem and VFS uids and gids. 649*5d3ca596SChristian Brauner 650*5d3ca596SChristian BraunerThe ``vfsuid_t`` and ``vfsgid_t`` types are often mapped from and to ``kuid_t`` 651*5d3ca596SChristian Braunerand ``kgid_t`` types similar how ``kuid_t`` and ``kgid_t`` types are mapped 652*5d3ca596SChristian Braunerfrom and to ``uid_t`` and ``gid_t`` types:: 653*5d3ca596SChristian Brauner 654*5d3ca596SChristian Brauner uid_t <--> kuid_t <--> vfsuid_t 655*5d3ca596SChristian Brauner gid_t <--> kgid_t <--> vfsgid_t 656*5d3ca596SChristian Brauner 657*5d3ca596SChristian BraunerWhenever we report ownership based on a ``vfsuid_t`` or ``vfsgid_t`` type, 658*5d3ca596SChristian Braunere.g., during ``stat()``, or store ownership information in a shared VFS object 659*5d3ca596SChristian Braunerbased on a ``vfsuid_t`` or ``vfsgid_t`` type, e.g., during ``chown()`` we can 660*5d3ca596SChristian Brauneruse the ``vfsuid_into_kuid()`` and ``vfsgid_into_kgid()`` helpers. 661*5d3ca596SChristian Brauner 662*5d3ca596SChristian BraunerTo illustrate why this helper currently exists, consider what happens when we 663*5d3ca596SChristian Braunerchange ownership of an inode from an idmapped mount. After we generated 664*5d3ca596SChristian Braunera ``vfsuid_t`` or ``vfsgid_t`` based on the mount idmapping we later commit to 665*5d3ca596SChristian Braunerthis ``vfsuid_t`` or ``vfsgid_t`` to become the new filesytem wide ownership. 666*5d3ca596SChristian BraunerThus, we are turning the ``vfsuid_t`` or ``vfsgid_t`` into a global ``kuid_t`` 667*5d3ca596SChristian Brauneror ``kgid_t``. And this can be done by using ``vfsuid_into_kuid()`` and 668*5d3ca596SChristian Brauner``vfsgid_into_kgid()``. 669*5d3ca596SChristian Brauner 670*5d3ca596SChristian BraunerNote, whenever a shared VFS object, e.g., a cached ``struct inode`` or a cached 671*5d3ca596SChristian Brauner``struct posix_acl``, stores ownership information a filesystem or "global" 672*5d3ca596SChristian Brauner``kuid_t`` and ``kgid_t`` must be used. Ownership expressed via ``vfsuid_t`` 673*5d3ca596SChristian Braunerand ``vfsgid_t`` is specific to an idmapped mount. 674*5d3ca596SChristian Brauner 675*5d3ca596SChristian BraunerWe already noted that ``vfsuid_t`` and ``vfsgid_t`` types are generated based 676*5d3ca596SChristian Brauneron mount idmappings whereas ``kuid_t`` and ``kgid_t`` types are generated based 677*5d3ca596SChristian Brauneron filesystem idmappings. To prevent abusing filesystem idmappings to generate 678*5d3ca596SChristian Brauner``vfsuid_t`` or ``vfsgid_t`` types or mount idmappings to generate ``kuid_t`` 679*5d3ca596SChristian Brauneror ``kgid_t`` types filesystem idmappings and mount idmappings are different 680*5d3ca596SChristian Braunertypes as well. 681*5d3ca596SChristian Brauner 682*5d3ca596SChristian BraunerAll helpers that map to or from ``vfsuid_t`` and ``vfsgid_t`` types require 683*5d3ca596SChristian Braunera mount idmapping to be passed which is of type ``struct mnt_idmap``. Passing 684*5d3ca596SChristian Braunera filesystem or caller idmapping will cause a compilation error. 685*5d3ca596SChristian Brauner 686*5d3ca596SChristian BraunerSimilar to how we prefix all userspace ids in this document with ``u`` and all 687*5d3ca596SChristian Braunerkernel ids with ``k`` we will prefix all VFS ids with ``v``. So a mount 688*5d3ca596SChristian Brauneridmapping will be written as: ``u0:v10000:r10000``. 689*5d3ca596SChristian Brauner 690ad19607aSChristian BraunerRemapping helpers 691ad19607aSChristian Brauner~~~~~~~~~~~~~~~~~ 692ad19607aSChristian Brauner 693ad19607aSChristian BraunerIdmapping functions were added that translate between idmappings. They make use 694*5d3ca596SChristian Braunerof the remapping algorithm we've introduced earlier. We're going to look at: 695ad19607aSChristian Brauner 696*5d3ca596SChristian Brauner- ``i_uid_into_vfsuid()`` and ``i_gid_into_vfsgid()`` 697ad19607aSChristian Brauner 698*5d3ca596SChristian Brauner The ``i_*id_into_vfs*id()`` functions translate filesystem's kernel ids into 699*5d3ca596SChristian Brauner VFS ids in the mount's idmapping:: 700ad19607aSChristian Brauner 701ad19607aSChristian Brauner /* Map the filesystem's kernel id up into a userspace id in the filesystem's idmapping. */ 702ad19607aSChristian Brauner from_kuid(filesystem, kid) = uid 703ad19607aSChristian Brauner 704*5d3ca596SChristian Brauner /* Map the filesystem's userspace id down ito a VFS id in the mount's idmapping. */ 705ad19607aSChristian Brauner make_kuid(mount, uid) = kuid 706ad19607aSChristian Brauner 707ad19607aSChristian Brauner- ``mapped_fsuid()`` and ``mapped_fsgid()`` 708ad19607aSChristian Brauner 709ad19607aSChristian Brauner The ``mapped_fs*id()`` functions translate the caller's kernel ids into 710ad19607aSChristian Brauner kernel ids in the filesystem's idmapping. This translation is achieved by 711*5d3ca596SChristian Brauner remapping the caller's VFS ids using the mount's idmapping:: 712ad19607aSChristian Brauner 713*5d3ca596SChristian Brauner /* Map the caller's VFS id up into a userspace id in the mount's idmapping. */ 714ad19607aSChristian Brauner from_kuid(mount, kid) = uid 715ad19607aSChristian Brauner 716ad19607aSChristian Brauner /* Map the mount's userspace id down into a kernel id in the filesystem's idmapping. */ 717ad19607aSChristian Brauner make_kuid(filesystem, uid) = kuid 718ad19607aSChristian Brauner 719*5d3ca596SChristian Brauner- ``vfsuid_into_kuid()`` and ``vfsgid_into_kgid()`` 720*5d3ca596SChristian Brauner 721*5d3ca596SChristian Brauner Whenever 722*5d3ca596SChristian Brauner 723ad19607aSChristian BraunerNote that these two functions invert each other. Consider the following 724ad19607aSChristian Brauneridmappings:: 725ad19607aSChristian Brauner 726ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 727ad19607aSChristian Brauner filesystem idmapping: u0:k20000:r10000 728*5d3ca596SChristian Brauner mount idmapping: u0:v10000:r10000 729ad19607aSChristian Brauner 730ad19607aSChristian BraunerAssume a file owned by ``u1000`` is read from disk. The filesystem maps this id 731622d6f19SRandy Dunlapto ``k21000`` according to its idmapping. This is what is stored in the 732ad19607aSChristian Braunerinode's ``i_uid`` and ``i_gid`` fields. 733ad19607aSChristian Brauner 734ad19607aSChristian BraunerWhen the caller queries the ownership of this file via ``stat()`` the kernel 735ad19607aSChristian Braunerwould usually simply use the crossmapping algorithm and map the filesystem's 736ad19607aSChristian Braunerkernel id up to a userspace id in the caller's idmapping. 737ad19607aSChristian Brauner 738ad19607aSChristian BraunerBut when the caller is accessing the file on an idmapped mount the kernel will 739*5d3ca596SChristian Braunerfirst call ``i_uid_into_vfsuid()`` thereby translating the filesystem's kernel 740*5d3ca596SChristian Braunerid into a VFS id in the mount's idmapping:: 741ad19607aSChristian Brauner 742*5d3ca596SChristian Brauner i_uid_into_vfsuid(k21000): 743ad19607aSChristian Brauner /* Map the filesystem's kernel id up into a userspace id. */ 744ad19607aSChristian Brauner from_kuid(u0:k20000:r10000, k21000) = u1000 745ad19607aSChristian Brauner 746*5d3ca596SChristian Brauner /* Map the filesystem's userspace id down into a VFS id in the mount's idmapping. */ 747*5d3ca596SChristian Brauner make_kuid(u0:v10000:r10000, u1000) = v11000 748ad19607aSChristian Brauner 749ad19607aSChristian BraunerFinally, when the kernel reports the owner to the caller it will turn the 750*5d3ca596SChristian BraunerVFS id in the mount's idmapping into a userspace id in the caller's 751ad19607aSChristian Brauneridmapping:: 752ad19607aSChristian Brauner 753*5d3ca596SChristian Brauner k11000 = vfsuid_into_kuid(v11000) 754ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 755ad19607aSChristian Brauner 756ad19607aSChristian BraunerWe can test whether this algorithm really works by verifying what happens when 757ad19607aSChristian Braunerwe create a new file. Let's say the user is creating a file with ``u1000``. 758ad19607aSChristian Brauner 759ad19607aSChristian BraunerThe kernel maps this to ``k11000`` in the caller's idmapping. Usually the 760ad19607aSChristian Braunerkernel would now apply the crossmapping, verifying that ``k11000`` can be 761ad19607aSChristian Braunermapped to a userspace id in the filesystem's idmapping. Since ``k11000`` can't 762ad19607aSChristian Braunerbe mapped up in the filesystem's idmapping directly this creation request 763ad19607aSChristian Braunerfails. 764ad19607aSChristian Brauner 765ad19607aSChristian BraunerBut when the caller is accessing the file on an idmapped mount the kernel will 766ad19607aSChristian Braunerfirst call ``mapped_fs*id()`` thereby translating the caller's kernel id into 767*5d3ca596SChristian Braunera VFS id according to the mount's idmapping:: 768ad19607aSChristian Brauner 769ad19607aSChristian Brauner mapped_fsuid(k11000): 770ad19607aSChristian Brauner /* Map the caller's kernel id up into a userspace id in the mount's idmapping. */ 771ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 772ad19607aSChristian Brauner 773ad19607aSChristian Brauner /* Map the mount's userspace id down into a kernel id in the filesystem's idmapping. */ 774*5d3ca596SChristian Brauner make_kuid(u0:v20000:r10000, u1000) = v21000 775ad19607aSChristian Brauner 776*5d3ca596SChristian BraunerWhen finally writing to disk the kernel will then map ``v21000`` up into a 777ad19607aSChristian Brauneruserspace id in the filesystem's idmapping:: 778ad19607aSChristian Brauner 779*5d3ca596SChristian Brauner k21000 = vfsuid_into_kuid(v21000) 780ad19607aSChristian Brauner from_kuid(u0:k20000:r10000, k21000) = u1000 781ad19607aSChristian Brauner 782ad19607aSChristian BraunerAs we can see, we end up with an invertible and therefore information 783ad19607aSChristian Braunerpreserving algorithm. A file created from ``u1000`` on an idmapped mount will 784ad19607aSChristian Brauneralso be reported as being owned by ``u1000`` and vica versa. 785ad19607aSChristian Brauner 786ad19607aSChristian BraunerLet's now briefly reconsider the failing examples from earlier in the context 787ad19607aSChristian Braunerof idmapped mounts. 788ad19607aSChristian Brauner 789ad19607aSChristian BraunerExample 2 reconsidered 790ad19607aSChristian Brauner~~~~~~~~~~~~~~~~~~~~~~ 791ad19607aSChristian Brauner 792ad19607aSChristian Brauner:: 793ad19607aSChristian Brauner 794ad19607aSChristian Brauner caller id: u1000 795ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 796ad19607aSChristian Brauner filesystem idmapping: u0:k20000:r10000 797*5d3ca596SChristian Brauner mount idmapping: u0:v10000:r10000 798ad19607aSChristian Brauner 799ad19607aSChristian BraunerWhen the caller is using a non-initial idmapping the common case is to attach 800ad19607aSChristian Braunerthe same idmapping to the mount. We now perform three steps: 801ad19607aSChristian Brauner 802ad19607aSChristian Brauner1. Map the caller's userspace ids into kernel ids in the caller's idmapping:: 803ad19607aSChristian Brauner 804ad19607aSChristian Brauner make_kuid(u0:k10000:r10000, u1000) = k11000 805ad19607aSChristian Brauner 806*5d3ca596SChristian Brauner2. Translate the caller's VFS id into a kernel id in the filesystem's 807ad19607aSChristian Brauner idmapping:: 808ad19607aSChristian Brauner 809*5d3ca596SChristian Brauner mapped_fsuid(v11000): 810*5d3ca596SChristian Brauner /* Map the VFS id up into a userspace id in the mount's idmapping. */ 811*5d3ca596SChristian Brauner from_kuid(u0:v10000:r10000, v11000) = u1000 812ad19607aSChristian Brauner 813ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the filesystem's idmapping. */ 814ad19607aSChristian Brauner make_kuid(u0:k20000:r10000, u1000) = k21000 815ad19607aSChristian Brauner 816ad19607aSChristian Brauner2. Verify that the caller's kernel ids can be mapped to userspace ids in the 817ad19607aSChristian Brauner filesystem's idmapping:: 818ad19607aSChristian Brauner 819ad19607aSChristian Brauner from_kuid(u0:k20000:r10000, k21000) = u1000 820ad19607aSChristian Brauner 821ad19607aSChristian BraunerSo the ownership that lands on disk will be ``u1000``. 822ad19607aSChristian Brauner 823ad19607aSChristian BraunerExample 3 reconsidered 824ad19607aSChristian Brauner~~~~~~~~~~~~~~~~~~~~~~ 825ad19607aSChristian Brauner 826ad19607aSChristian Brauner:: 827ad19607aSChristian Brauner 828ad19607aSChristian Brauner caller id: u1000 829ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 830ad19607aSChristian Brauner filesystem idmapping: u0:k0:r4294967295 831*5d3ca596SChristian Brauner mount idmapping: u0:v10000:r10000 832ad19607aSChristian Brauner 833ad19607aSChristian BraunerThe same translation algorithm works with the third example. 834ad19607aSChristian Brauner 835ad19607aSChristian Brauner1. Map the caller's userspace ids into kernel ids in the caller's idmapping:: 836ad19607aSChristian Brauner 837ad19607aSChristian Brauner make_kuid(u0:k10000:r10000, u1000) = k11000 838ad19607aSChristian Brauner 839*5d3ca596SChristian Brauner2. Translate the caller's VFS id into a kernel id in the filesystem's 840ad19607aSChristian Brauner idmapping:: 841ad19607aSChristian Brauner 842*5d3ca596SChristian Brauner mapped_fsuid(v11000): 843*5d3ca596SChristian Brauner /* Map the VFS id up into a userspace id in the mount's idmapping. */ 844*5d3ca596SChristian Brauner from_kuid(u0:v10000:r10000, v11000) = u1000 845ad19607aSChristian Brauner 846ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the filesystem's idmapping. */ 847ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 848ad19607aSChristian Brauner 849ad19607aSChristian Brauner2. Verify that the caller's kernel ids can be mapped to userspace ids in the 850ad19607aSChristian Brauner filesystem's idmapping:: 851ad19607aSChristian Brauner 852ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k21000) = u1000 853ad19607aSChristian Brauner 854ad19607aSChristian BraunerSo the ownership that lands on disk will be ``u1000``. 855ad19607aSChristian Brauner 856ad19607aSChristian BraunerExample 4 reconsidered 857ad19607aSChristian Brauner~~~~~~~~~~~~~~~~~~~~~~ 858ad19607aSChristian Brauner 859ad19607aSChristian Brauner:: 860ad19607aSChristian Brauner 861ad19607aSChristian Brauner file id: u1000 862ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 863ad19607aSChristian Brauner filesystem idmapping: u0:k0:r4294967295 864*5d3ca596SChristian Brauner mount idmapping: u0:v10000:r10000 865ad19607aSChristian Brauner 866ad19607aSChristian BraunerIn order to report ownership to userspace the kernel now does three steps using 867ad19607aSChristian Braunerthe translation algorithm we introduced earlier: 868ad19607aSChristian Brauner 869ad19607aSChristian Brauner1. Map the userspace id on disk down into a kernel id in the filesystem's 870ad19607aSChristian Brauner idmapping:: 871ad19607aSChristian Brauner 872ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 873ad19607aSChristian Brauner 874*5d3ca596SChristian Brauner2. Translate the kernel id into a VFS id in the mount's idmapping:: 875ad19607aSChristian Brauner 876*5d3ca596SChristian Brauner i_uid_into_vfsuid(k1000): 877ad19607aSChristian Brauner /* Map the kernel id up into a userspace id in the filesystem's idmapping. */ 878ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k1000) = u1000 879ad19607aSChristian Brauner 880*5d3ca596SChristian Brauner /* Map the userspace id down into a VFS id in the mounts's idmapping. */ 881*5d3ca596SChristian Brauner make_kuid(u0:v10000:r10000, u1000) = v11000 882ad19607aSChristian Brauner 883*5d3ca596SChristian Brauner3. Map the VFS id up into a userspace id in the caller's idmapping:: 884ad19607aSChristian Brauner 885*5d3ca596SChristian Brauner k11000 = vfsuid_into_kuid(v11000) 886ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 887ad19607aSChristian Brauner 888ad19607aSChristian BraunerEarlier, the caller's kernel id couldn't be crossmapped in the filesystems's 889ad19607aSChristian Brauneridmapping. With the idmapped mount in place it now can be crossmapped into the 890ad19607aSChristian Braunerfilesystem's idmapping via the mount's idmapping. The file will now be created 891ad19607aSChristian Braunerwith ``u1000`` according to the mount's idmapping. 892ad19607aSChristian Brauner 893ad19607aSChristian BraunerExample 5 reconsidered 894ad19607aSChristian Brauner~~~~~~~~~~~~~~~~~~~~~~ 895ad19607aSChristian Brauner 896ad19607aSChristian Brauner:: 897ad19607aSChristian Brauner 898ad19607aSChristian Brauner file id: u1000 899ad19607aSChristian Brauner caller idmapping: u0:k10000:r10000 900ad19607aSChristian Brauner filesystem idmapping: u0:k20000:r10000 901*5d3ca596SChristian Brauner mount idmapping: u0:v10000:r10000 902ad19607aSChristian Brauner 903ad19607aSChristian BraunerAgain, in order to report ownership to userspace the kernel now does three 904ad19607aSChristian Braunersteps using the translation algorithm we introduced earlier: 905ad19607aSChristian Brauner 906ad19607aSChristian Brauner1. Map the userspace id on disk down into a kernel id in the filesystem's 907ad19607aSChristian Brauner idmapping:: 908ad19607aSChristian Brauner 909ad19607aSChristian Brauner make_kuid(u0:k20000:r10000, u1000) = k21000 910ad19607aSChristian Brauner 911*5d3ca596SChristian Brauner2. Translate the kernel id into a VFS id in the mount's idmapping:: 912ad19607aSChristian Brauner 913*5d3ca596SChristian Brauner i_uid_into_vfsuid(k21000): 914ad19607aSChristian Brauner /* Map the kernel id up into a userspace id in the filesystem's idmapping. */ 915ad19607aSChristian Brauner from_kuid(u0:k20000:r10000, k21000) = u1000 916ad19607aSChristian Brauner 917*5d3ca596SChristian Brauner /* Map the userspace id down into a VFS id in the mounts's idmapping. */ 918*5d3ca596SChristian Brauner make_kuid(u0:v10000:r10000, u1000) = v11000 919ad19607aSChristian Brauner 920*5d3ca596SChristian Brauner3. Map the VFS id up into a userspace id in the caller's idmapping:: 921ad19607aSChristian Brauner 922*5d3ca596SChristian Brauner k11000 = vfsuid_into_kuid(v11000) 923ad19607aSChristian Brauner from_kuid(u0:k10000:r10000, k11000) = u1000 924ad19607aSChristian Brauner 925ad19607aSChristian BraunerEarlier, the file's kernel id couldn't be crossmapped in the filesystems's 926ad19607aSChristian Brauneridmapping. With the idmapped mount in place it now can be crossmapped into the 927ad19607aSChristian Braunerfilesystem's idmapping via the mount's idmapping. The file is now owned by 928ad19607aSChristian Brauner``u1000`` according to the mount's idmapping. 929ad19607aSChristian Brauner 930ad19607aSChristian BraunerChanging ownership on a home directory 931ad19607aSChristian Brauner~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 932ad19607aSChristian Brauner 933ad19607aSChristian BraunerWe've seen above how idmapped mounts can be used to translate between 934ad19607aSChristian Brauneridmappings when either the caller, the filesystem or both uses a non-initial 935ad19607aSChristian Brauneridmapping. A wide range of usecases exist when the caller is using 936ad19607aSChristian Braunera non-initial idmapping. This mostly happens in the context of containerized 937ad19607aSChristian Braunerworkloads. The consequence is as we have seen that for both, filesystem's 938ad19607aSChristian Braunermounted with the initial idmapping and filesystems mounted with non-initial 939ad19607aSChristian Brauneridmappings, access to the filesystem isn't working because the kernel ids can't 940ad19607aSChristian Braunerbe crossmapped between the caller's and the filesystem's idmapping. 941ad19607aSChristian Brauner 942ad19607aSChristian BraunerAs we've seen above idmapped mounts provide a solution to this by remapping the 943ad19607aSChristian Braunercaller's or filesystem's idmapping according to the mount's idmapping. 944ad19607aSChristian Brauner 945ad19607aSChristian BraunerAside from containerized workloads, idmapped mounts have the advantage that 946ad19607aSChristian Braunerthey also work when both the caller and the filesystem use the initial 947ad19607aSChristian Brauneridmapping which means users on the host can change the ownership of directories 948ad19607aSChristian Braunerand files on a per-mount basis. 949ad19607aSChristian Brauner 950ad19607aSChristian BraunerConsider our previous example where a user has their home directory on portable 951ad19607aSChristian Braunerstorage. At home they have id ``u1000`` and all files in their home directory 952ad19607aSChristian Braunerare owned by ``u1000`` whereas at uni or work they have login id ``u1125``. 953ad19607aSChristian Brauner 954ad19607aSChristian BraunerTaking their home directory with them becomes problematic. They can't easily 955ad19607aSChristian Brauneraccess their files, they might not be able to write to disk without applying 956ad19607aSChristian Braunerlax permissions or ACLs and even if they can, they will end up with an annoying 957ad19607aSChristian Braunermix of files and directories owned by ``u1000`` and ``u1125``. 958ad19607aSChristian Brauner 959ad19607aSChristian BraunerIdmapped mounts allow to solve this problem. A user can create an idmapped 960ad19607aSChristian Braunermount for their home directory on their work computer or their computer at home 961ad19607aSChristian Braunerdepending on what ownership they would prefer to end up on the portable storage 962ad19607aSChristian Brauneritself. 963ad19607aSChristian Brauner 964ad19607aSChristian BraunerLet's assume they want all files on disk to belong to ``u1000``. When the user 965ad19607aSChristian Braunerplugs in their portable storage at their work station they can setup a job that 966ad19607aSChristian Braunercreates an idmapped mount with the minimal idmapping ``u1000:k1125:r1``. So now 967ad19607aSChristian Braunerwhen they create a file the kernel performs the following steps we already know 968ad19607aSChristian Braunerfrom above::: 969ad19607aSChristian Brauner 970ad19607aSChristian Brauner caller id: u1125 971ad19607aSChristian Brauner caller idmapping: u0:k0:r4294967295 972ad19607aSChristian Brauner filesystem idmapping: u0:k0:r4294967295 973*5d3ca596SChristian Brauner mount idmapping: u1000:v1125:r1 974ad19607aSChristian Brauner 975ad19607aSChristian Brauner1. Map the caller's userspace ids into kernel ids in the caller's idmapping:: 976ad19607aSChristian Brauner 977ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1125) = k1125 978ad19607aSChristian Brauner 979*5d3ca596SChristian Brauner2. Translate the caller's VFS id into a kernel id in the filesystem's 980ad19607aSChristian Brauner idmapping:: 981ad19607aSChristian Brauner 982*5d3ca596SChristian Brauner mapped_fsuid(v1125): 983*5d3ca596SChristian Brauner /* Map the VFS id up into a userspace id in the mount's idmapping. */ 984*5d3ca596SChristian Brauner from_kuid(u1000:v1125:r1, v1125) = u1000 985ad19607aSChristian Brauner 986ad19607aSChristian Brauner /* Map the userspace id down into a kernel id in the filesystem's idmapping. */ 987ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 988ad19607aSChristian Brauner 989*5d3ca596SChristian Brauner2. Verify that the caller's filesystem ids can be mapped to userspace ids in the 990ad19607aSChristian Brauner filesystem's idmapping:: 991ad19607aSChristian Brauner 992ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k1000) = u1000 993ad19607aSChristian Brauner 994ad19607aSChristian BraunerSo ultimately the file will be created with ``u1000`` on disk. 995ad19607aSChristian Brauner 996ad19607aSChristian BraunerNow let's briefly look at what ownership the caller with id ``u1125`` will see 997ad19607aSChristian Brauneron their work computer: 998ad19607aSChristian Brauner 999ad19607aSChristian Brauner:: 1000ad19607aSChristian Brauner 1001ad19607aSChristian Brauner file id: u1000 1002ad19607aSChristian Brauner caller idmapping: u0:k0:r4294967295 1003ad19607aSChristian Brauner filesystem idmapping: u0:k0:r4294967295 1004*5d3ca596SChristian Brauner mount idmapping: u1000:v1125:r1 1005ad19607aSChristian Brauner 1006ad19607aSChristian Brauner1. Map the userspace id on disk down into a kernel id in the filesystem's 1007ad19607aSChristian Brauner idmapping:: 1008ad19607aSChristian Brauner 1009ad19607aSChristian Brauner make_kuid(u0:k0:r4294967295, u1000) = k1000 1010ad19607aSChristian Brauner 1011*5d3ca596SChristian Brauner2. Translate the kernel id into a VFS id in the mount's idmapping:: 1012ad19607aSChristian Brauner 1013*5d3ca596SChristian Brauner i_uid_into_vfsuid(k1000): 1014ad19607aSChristian Brauner /* Map the kernel id up into a userspace id in the filesystem's idmapping. */ 1015ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k1000) = u1000 1016ad19607aSChristian Brauner 1017*5d3ca596SChristian Brauner /* Map the userspace id down into a VFS id in the mounts's idmapping. */ 1018*5d3ca596SChristian Brauner make_kuid(u1000:v1125:r1, u1000) = v1125 1019ad19607aSChristian Brauner 1020*5d3ca596SChristian Brauner3. Map the VFS id up into a userspace id in the caller's idmapping:: 1021ad19607aSChristian Brauner 1022*5d3ca596SChristian Brauner k1125 = vfsuid_into_kuid(v1125) 1023ad19607aSChristian Brauner from_kuid(u0:k0:r4294967295, k1125) = u1125 1024ad19607aSChristian Brauner 1025ad19607aSChristian BraunerSo ultimately the caller will be reported that the file belongs to ``u1125`` 1026ad19607aSChristian Braunerwhich is the caller's userspace id on their workstation in our example. 1027ad19607aSChristian Brauner 1028ad19607aSChristian BraunerThe raw userspace id that is put on disk is ``u1000`` so when the user takes 1029ad19607aSChristian Braunertheir home directory back to their home computer where they are assigned 1030ad19607aSChristian Brauner``u1000`` using the initial idmapping and mount the filesystem with the initial 1031ad19607aSChristian Brauneridmapping they will see all those files owned by ``u1000``. 1032