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