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