src/idmapped-mounts: Remove useless header file
[xfstests-dev.git] / src / idmapped-mounts / idmapped-mounts.c
1 // SPDX-License-Identifier: GPL-2.0
2 #ifndef _GNU_SOURCE
3 #define _GNU_SOURCE
4 #endif
5
6 #include "../global.h"
7
8 #include <dirent.h>
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <getopt.h>
12 #include <grp.h>
13 #include <limits.h>
14 #include <linux/limits.h>
15 #include <linux/types.h>
16 #include <pthread.h>
17 #include <sched.h>
18 #include <stdbool.h>
19 #include <sys/fsuid.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <sys/xattr.h>
23 #include <unistd.h>
24
25 #ifdef HAVE_SYS_CAPABILITY_H
26 #include <sys/capability.h>
27 #endif
28
29 #ifdef HAVE_LIBURING_H
30 #include <liburing.h>
31 #endif
32
33 #include "missing.h"
34 #include "utils.h"
35
36 #define T_DIR1 "idmapped_mounts_1"
37 #define FILE1 "file1"
38 #define FILE1_RENAME "file1_rename"
39 #define FILE2 "file2"
40 #define FILE2_RENAME "file2_rename"
41 #define DIR1 "dir1"
42 #define DIR2 "dir2"
43 #define DIR3 "dir3"
44 #define DIR1_RENAME "dir1_rename"
45 #define HARDLINK1 "hardlink1"
46 #define SYMLINK1 "symlink1"
47 #define SYMLINK_USER1 "symlink_user1"
48 #define SYMLINK_USER2 "symlink_user2"
49 #define SYMLINK_USER3 "symlink_user3"
50 #define CHRDEV1 "chrdev1"
51
52 #define log_stderr(format, ...)                                                         \
53         fprintf(stderr, "%s: %d: %s - %m - " format "\n", __FILE__, __LINE__, __func__, \
54                 ##__VA_ARGS__)
55
56 #ifdef DEBUG_TRACE
57 #define log_debug(format, ...)                                           \
58         fprintf(stderr, "%s: %d: %s - " format "\n", __FILE__, __LINE__, \
59                 __func__, ##__VA_ARGS__)
60 #else
61 #define log_debug(format, ...)
62 #endif
63
64 #define log_error_errno(__ret__, __errno__, format, ...)      \
65         ({                                                    \
66                 typeof(__ret__) __internal_ret__ = (__ret__); \
67                 errno = (__errno__);                          \
68                 log_stderr(format, ##__VA_ARGS__);            \
69                 __internal_ret__;                             \
70         })
71
72 #define log_errno(__ret__, format, ...) log_error_errno(__ret__, errno, format, ##__VA_ARGS__)
73
74 #define die_errno(__errno__, format, ...)          \
75         ({                                         \
76                 errno = (__errno__);               \
77                 log_stderr(format, ##__VA_ARGS__); \
78                 exit(EXIT_FAILURE);                \
79         })
80
81 #define die(format, ...) die_errno(errno, format, ##__VA_ARGS__)
82
83 uid_t t_overflowuid = 65534;
84 gid_t t_overflowgid = 65534;
85
86 /* path of the test device */
87 const char *t_fstype;
88
89 /* path of the test device */
90 const char *t_device;
91
92 /* mountpoint of the test device */
93 const char *t_mountpoint;
94
95 /* fd for @t_mountpoint */
96 int t_mnt_fd;
97
98 /* fd for @T_DIR1 */
99 int t_dir1_fd;
100
101 /* temporary buffer */
102 char t_buf[PATH_MAX];
103
104 static void stash_overflowuid(void)
105 {
106         int fd;
107         ssize_t ret;
108         char buf[256];
109
110         fd = open("/proc/sys/fs/overflowuid", O_RDONLY | O_CLOEXEC);
111         if (fd < 0)
112                 return;
113
114         ret = read(fd, buf, sizeof(buf));
115         close(fd);
116         if (ret < 0)
117                 return;
118
119         t_overflowuid = atoi(buf);
120 }
121
122 static void stash_overflowgid(void)
123 {
124         int fd;
125         ssize_t ret;
126         char buf[256];
127
128         fd = open("/proc/sys/fs/overflowgid", O_RDONLY | O_CLOEXEC);
129         if (fd < 0)
130                 return;
131
132         ret = read(fd, buf, sizeof(buf));
133         close(fd);
134         if (ret < 0)
135                 return;
136
137         t_overflowgid = atoi(buf);
138 }
139
140 static bool is_xfs(void)
141 {
142         static int enabled = -1;
143
144         if (enabled == -1)
145                 enabled = !strcmp(t_fstype, "xfs");
146
147         return enabled;
148 }
149
150 static bool protected_symlinks_enabled(void)
151 {
152         static int enabled = -1;
153
154         if (enabled == -1) {
155                 int fd;
156                 ssize_t ret;
157                 char buf[256];
158
159                 enabled = 0;
160
161                 fd = open("/proc/sys/fs/protected_symlinks", O_RDONLY | O_CLOEXEC);
162                 if (fd < 0)
163                         return false;
164
165                 ret = read(fd, buf, sizeof(buf));
166                 close(fd);
167                 if (ret < 0)
168                         return false;
169
170                 if (atoi(buf) >= 1)
171                         enabled = 1;
172         }
173
174         return enabled == 1;
175 }
176
177 static bool xfs_irix_sgid_inherit_enabled(void)
178 {
179         static int enabled = -1;
180
181         if (enabled == -1) {
182                 int fd;
183                 ssize_t ret;
184                 char buf[256];
185
186                 enabled = 0;
187
188                 if (is_xfs()) {
189                         fd = open("/proc/sys/fs/xfs/irix_sgid_inherit", O_RDONLY | O_CLOEXEC);
190                         if (fd < 0)
191                                 return false;
192
193                         ret = read(fd, buf, sizeof(buf));
194                         close(fd);
195                         if (ret < 0)
196                                 return false;
197
198                         if (atoi(buf) >= 1)
199                                 enabled = 1;
200                 }
201         }
202
203         return enabled == 1;
204 }
205
206 static inline bool caps_supported(void)
207 {
208         bool ret = false;
209
210 #ifdef HAVE_SYS_CAPABILITY_H
211         ret = true;
212 #endif
213
214         return ret;
215 }
216
217 /* caps_down - lower all effective caps */
218 static int caps_down(void)
219 {
220         bool fret = false;
221 #ifdef HAVE_SYS_CAPABILITY_H
222         cap_t caps = NULL;
223         int ret = -1;
224
225         caps = cap_get_proc();
226         if (!caps)
227                 goto out;
228
229         ret = cap_clear_flag(caps, CAP_EFFECTIVE);
230         if (ret)
231                 goto out;
232
233         ret = cap_set_proc(caps);
234         if (ret)
235                 goto out;
236
237         fret = true;
238
239 out:
240         cap_free(caps);
241 #endif
242         return fret;
243 }
244
245 /* caps_up - raise all permitted caps */
246 static int caps_up(void)
247 {
248         bool fret = false;
249 #ifdef HAVE_SYS_CAPABILITY_H
250         cap_t caps = NULL;
251         cap_value_t cap;
252         int ret = -1;
253
254         caps = cap_get_proc();
255         if (!caps)
256                 goto out;
257
258         for (cap = 0; cap <= CAP_LAST_CAP; cap++) {
259                 cap_flag_value_t flag;
260
261                 ret = cap_get_flag(caps, cap, CAP_PERMITTED, &flag);
262                 if (ret) {
263                         if (errno == EINVAL)
264                                 break;
265                         else
266                                 goto out;
267                 }
268
269                 ret = cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap, flag);
270                 if (ret)
271                         goto out;
272         }
273
274         ret = cap_set_proc(caps);
275         if (ret)
276                 goto out;
277
278         fret = true;
279 out:
280         cap_free(caps);
281 #endif
282         return fret;
283 }
284
285 /* __expected_uid_gid - check whether file is owned by the provided uid and gid */
286 static bool __expected_uid_gid(int dfd, const char *path, int flags,
287                                uid_t expected_uid, gid_t expected_gid, bool log)
288 {
289         int ret;
290         struct stat st;
291
292         ret = fstatat(dfd, path, &st, flags);
293         if (ret < 0)
294                 return log_errno(false, "failure: fstatat");
295
296         if (log && st.st_uid != expected_uid)
297                 log_stderr("failure: uid(%d) != expected_uid(%d)", st.st_uid, expected_uid);
298
299         if (log && st.st_gid != expected_gid)
300                 log_stderr("failure: gid(%d) != expected_gid(%d)", st.st_gid, expected_gid);
301
302         errno = 0; /* Don't report misleading errno. */
303         return st.st_uid == expected_uid && st.st_gid == expected_gid;
304 }
305
306 static bool expected_uid_gid(int dfd, const char *path, int flags,
307                              uid_t expected_uid, gid_t expected_gid)
308 {
309         return __expected_uid_gid(dfd, path, flags,
310                                   expected_uid, expected_gid, true);
311 }
312
313 static bool expected_file_size(int dfd, const char *path,
314                                int flags, off_t expected_size)
315 {
316         int ret;
317         struct stat st;
318
319         ret = fstatat(dfd, path, &st, flags);
320         if (ret < 0)
321                 return log_errno(false, "failure: fstatat");
322
323         if (st.st_size != expected_size)
324                 return log_errno(false, "failure: st_size(%zu) != expected_size(%zu)",
325                                  (size_t)st.st_size, (size_t)expected_size);
326
327         return true;
328 }
329
330 /* is_setid - check whether file is S_ISUID and S_ISGID */
331 static bool is_setid(int dfd, const char *path, int flags)
332 {
333         int ret;
334         struct stat st;
335
336         ret = fstatat(dfd, path, &st, flags);
337         if (ret < 0)
338                 return false;
339
340         errno = 0; /* Don't report misleading errno. */
341         return (st.st_mode & S_ISUID) || (st.st_mode & S_ISGID);
342 }
343
344 /* is_setgid - check whether file or directory is S_ISGID */
345 static bool is_setgid(int dfd, const char *path, int flags)
346 {
347         int ret;
348         struct stat st;
349
350         ret = fstatat(dfd, path, &st, flags);
351         if (ret < 0)
352                 return false;
353
354         errno = 0; /* Don't report misleading errno. */
355         return (st.st_mode & S_ISGID);
356 }
357
358 /* is_sticky - check whether file is S_ISVTX */
359 static bool is_sticky(int dfd, const char *path, int flags)
360 {
361         int ret;
362         struct stat st;
363
364         ret = fstatat(dfd, path, &st, flags);
365         if (ret < 0)
366                 return false;
367
368         errno = 0; /* Don't report misleading errno. */
369         return (st.st_mode & S_ISVTX) > 0;
370 }
371
372 static inline int set_cloexec(int fd)
373 {
374         return fcntl(fd, F_SETFD, FD_CLOEXEC);
375 }
376
377 static inline bool switch_fsids(uid_t fsuid, gid_t fsgid)
378 {
379         if (setfsgid(fsgid))
380                 return log_errno(false, "failure: setfsgid");
381
382         if (setfsgid(-1) != fsgid)
383                 return log_errno(false, "failure: setfsgid(-1)");
384
385         if (setfsuid(fsuid))
386                 return log_errno(false, "failure: setfsuid");
387
388         if (setfsuid(-1) != fsuid)
389                 return log_errno(false, "failure: setfsuid(-1)");
390
391         return true;
392 }
393
394 static inline bool switch_ids(uid_t uid, gid_t gid)
395 {
396         if (setgroups(0, NULL))
397                 return log_errno(false, "failure: setgroups");
398
399         if (setresgid(gid, gid, gid))
400                 return log_errno(false, "failure: setresgid");
401
402         if (setresuid(uid, uid, uid))
403                 return log_errno(false, "failure: setresuid");
404
405         return true;
406 }
407
408 static inline bool switch_userns(int fd, uid_t uid, gid_t gid, bool drop_caps)
409 {
410         if (setns(fd, CLONE_NEWUSER))
411                 return log_errno(false, "failure: setns");
412
413         if (!switch_ids(uid, gid))
414                 return log_errno(false, "failure: switch_ids");
415
416         if (drop_caps && !caps_down())
417                 return log_errno(false, "failure: caps_down");
418
419         return true;
420 }
421
422 /* rm_r - recursively remove all files */
423 static int rm_r(int fd, const char *path)
424 {
425         int dfd, ret;
426         DIR *dir;
427         struct dirent *direntp;
428
429         if (!path || strcmp(path, "") == 0)
430                 return -1;
431
432         dfd = openat(fd, path, O_CLOEXEC | O_DIRECTORY);
433         if (dfd < 0)
434                 return -1;
435
436         dir = fdopendir(dfd);
437         if (!dir) {
438                 close(dfd);
439                 return -1;
440         }
441
442         while ((direntp = readdir(dir))) {
443                 struct stat st;
444
445                 if (!strcmp(direntp->d_name, ".") ||
446                     !strcmp(direntp->d_name, ".."))
447                         continue;
448
449                 ret = fstatat(dfd, direntp->d_name, &st, AT_SYMLINK_NOFOLLOW);
450                 if (ret < 0 && errno != ENOENT)
451                         break;
452
453                 if (S_ISDIR(st.st_mode))
454                         ret = rm_r(dfd, direntp->d_name);
455                 else
456                         ret = unlinkat(dfd, direntp->d_name, 0);
457                 if (ret < 0 && errno != ENOENT)
458                         break;
459         }
460
461         ret = unlinkat(fd, path, AT_REMOVEDIR);
462         closedir(dir);
463         return ret;
464 }
465
466 /* chown_r - recursively change ownership of all files */
467 static int chown_r(int fd, const char *path, uid_t uid, gid_t gid)
468 {
469         int dfd, ret;
470         DIR *dir;
471         struct dirent *direntp;
472
473         dfd = openat(fd, path, O_CLOEXEC | O_DIRECTORY);
474         if (dfd < 0)
475                 return -1;
476
477         dir = fdopendir(dfd);
478         if (!dir) {
479                 close(dfd);
480                 return -1;
481         }
482
483         while ((direntp = readdir(dir))) {
484                 struct stat st;
485
486                 if (!strcmp(direntp->d_name, ".") ||
487                     !strcmp(direntp->d_name, ".."))
488                         continue;
489
490                 ret = fstatat(dfd, direntp->d_name, &st, AT_SYMLINK_NOFOLLOW);
491                 if (ret < 0 && errno != ENOENT)
492                         break;
493
494                 if (S_ISDIR(st.st_mode))
495                         ret = chown_r(dfd, direntp->d_name, uid, gid);
496                 else
497                         ret = fchownat(dfd, direntp->d_name, uid, gid, AT_SYMLINK_NOFOLLOW);
498                 if (ret < 0 && errno != ENOENT)
499                         break;
500         }
501
502         ret = fchownat(fd, path, uid, gid, AT_SYMLINK_NOFOLLOW);
503         closedir(dir);
504         return ret;
505 }
506
507 /*
508  * There'll be scenarios where you'll want to see the attributes associated with
509  * a directory tree during debugging or just to make sure things look correct.
510  * Simply uncomment and place the print_r() helper where you need it.
511  */
512 #ifdef DEBUG_TRACE
513 static int fd_cloexec(int fd, bool cloexec)
514 {
515         int oflags, nflags;
516
517         oflags = fcntl(fd, F_GETFD, 0);
518         if (oflags < 0)
519                 return -errno;
520
521         if (cloexec)
522                 nflags = oflags | FD_CLOEXEC;
523         else
524                 nflags = oflags & ~FD_CLOEXEC;
525
526         if (nflags == oflags)
527                 return 0;
528
529         if (fcntl(fd, F_SETFD, nflags) < 0)
530                 return -errno;
531
532         return 0;
533 }
534
535 static inline int dup_cloexec(int fd)
536 {
537         int fd_dup;
538
539         fd_dup = dup(fd);
540         if (fd_dup < 0)
541                 return -errno;
542
543         if (fd_cloexec(fd_dup, true)) {
544                 close(fd_dup);
545                 return -errno;
546         }
547
548         return fd_dup;
549 }
550
551 __attribute__((unused)) static int print_r(int fd, const char *path)
552 {
553         int ret = 0;
554         int dfd, dfd_dup;
555         DIR *dir;
556         struct dirent *direntp;
557         struct stat st;
558
559         if (!path || *path == '\0') {
560                 char buf[sizeof("/proc/self/fd/") + 30];
561
562                 ret = snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
563                 if (ret < 0 || (size_t)ret >= sizeof(buf))
564                         return -1;
565
566                 /*
567                  * O_PATH file descriptors can't be used so we need to re-open
568                  * just in case.
569                  */
570                 dfd = openat(-EBADF, buf, O_CLOEXEC | O_DIRECTORY, 0);
571         } else {
572                 dfd = openat(fd, path, O_CLOEXEC | O_DIRECTORY, 0);
573         }
574         if (dfd < 0)
575                 return -1;
576
577         /*
578          * When fdopendir() below succeeds it assumes ownership of the fd so we
579          * to make sure we always have an fd that fdopendir() can own which is
580          * why we dup() in the case where the caller wants us to operate on the
581          * fd directly.
582          */
583         dfd_dup = dup_cloexec(dfd);
584         if (dfd_dup < 0) {
585                 close(dfd);
586                 return -1;
587         }
588
589         dir = fdopendir(dfd);
590         if (!dir) {
591                 close(dfd);
592                 close(dfd_dup);
593                 return -1;
594         }
595         /* Transfer ownership to fdopendir(). */
596         dfd = -EBADF;
597
598         while ((direntp = readdir(dir))) {
599                 if (!strcmp(direntp->d_name, ".") ||
600                     !strcmp(direntp->d_name, ".."))
601                         continue;
602
603                 ret = fstatat(dfd_dup, direntp->d_name, &st, AT_SYMLINK_NOFOLLOW);
604                 if (ret < 0 && errno != ENOENT)
605                         break;
606
607                 ret = 0;
608                 if (S_ISDIR(st.st_mode))
609                         ret = print_r(dfd_dup, direntp->d_name);
610                 else
611                         fprintf(stderr, "mode(%o):uid(%d):gid(%d) -> %d/%s\n",
612                                 (st.st_mode & ~S_IFMT), st.st_uid, st.st_gid,
613                                 dfd_dup, direntp->d_name);
614                 if (ret < 0 && errno != ENOENT)
615                         break;
616         }
617
618         if (!path || *path == '\0')
619                 ret = fstatat(fd, "", &st,
620                               AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW |
621                               AT_EMPTY_PATH);
622         else
623                 ret = fstatat(fd, path, &st,
624                               AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW);
625         if (!ret)
626                 fprintf(stderr, "mode(%o):uid(%d):gid(%d) -> %s",
627                         (st.st_mode & ~S_IFMT), st.st_uid, st.st_gid,
628                         (path && *path) ? path : "(null)");
629
630         close(dfd_dup);
631         closedir(dir);
632
633         return ret;
634 }
635 #endif
636
637 /* fd_to_fd - transfer data from one fd to another */
638 static int fd_to_fd(int from, int to)
639 {
640         for (;;) {
641                 uint8_t buf[PATH_MAX];
642                 uint8_t *p = buf;
643                 ssize_t bytes_to_write;
644                 ssize_t bytes_read;
645
646                 bytes_read = read_nointr(from, buf, sizeof buf);
647                 if (bytes_read < 0)
648                         return -1;
649                 if (bytes_read == 0)
650                         break;
651
652                 bytes_to_write = (size_t)bytes_read;
653                 do {
654                         ssize_t bytes_written;
655
656                         bytes_written = write_nointr(to, p, bytes_to_write);
657                         if (bytes_written < 0)
658                                 return -1;
659
660                         bytes_to_write -= bytes_written;
661                         p += bytes_written;
662                 } while (bytes_to_write > 0);
663         }
664
665         return 0;
666 }
667
668 static int sys_execveat(int fd, const char *path, char **argv, char **envp,
669                         int flags)
670 {
671 #ifdef __NR_execveat
672         return syscall(__NR_execveat, fd, path, argv, envp, flags);
673 #else
674         errno = ENOSYS;
675         return -1;
676 #endif
677 }
678
679 #ifndef CAP_NET_RAW
680 #define CAP_NET_RAW 13
681 #endif
682
683 #ifndef VFS_CAP_FLAGS_EFFECTIVE
684 #define VFS_CAP_FLAGS_EFFECTIVE 0x000001
685 #endif
686
687 #ifndef VFS_CAP_U32_3
688 #define VFS_CAP_U32_3 2
689 #endif
690
691 #ifndef VFS_CAP_U32
692 #define VFS_CAP_U32 VFS_CAP_U32_3
693 #endif
694
695 #ifndef VFS_CAP_REVISION_1
696 #define VFS_CAP_REVISION_1 0x01000000
697 #endif
698
699 #ifndef VFS_CAP_REVISION_2
700 #define VFS_CAP_REVISION_2 0x02000000
701 #endif
702
703 #ifndef VFS_CAP_REVISION_3
704 #define VFS_CAP_REVISION_3 0x03000000
705 struct vfs_ns_cap_data {
706         __le32 magic_etc;
707         struct {
708                 __le32 permitted;
709                 __le32 inheritable;
710         } data[VFS_CAP_U32];
711         __le32 rootid;
712 };
713 #endif
714
715 #if __BYTE_ORDER == __BIG_ENDIAN
716 #define cpu_to_le16(w16) le16_to_cpu(w16)
717 #define le16_to_cpu(w16) ((u_int16_t)((u_int16_t)(w16) >> 8) | (u_int16_t)((u_int16_t)(w16) << 8))
718 #define cpu_to_le32(w32) le32_to_cpu(w32)
719 #define le32_to_cpu(w32)                                                                       \
720         ((u_int32_t)((u_int32_t)(w32) >> 24) | (u_int32_t)(((u_int32_t)(w32) >> 8) & 0xFF00) | \
721          (u_int32_t)(((u_int32_t)(w32) << 8) & 0xFF0000) | (u_int32_t)((u_int32_t)(w32) << 24))
722 #elif __BYTE_ORDER == __LITTLE_ENDIAN
723 #define cpu_to_le16(w16) ((u_int16_t)(w16))
724 #define le16_to_cpu(w16) ((u_int16_t)(w16))
725 #define cpu_to_le32(w32) ((u_int32_t)(w32))
726 #define le32_to_cpu(w32) ((u_int32_t)(w32))
727 #else
728 #error Expected endianess macro to be set
729 #endif
730
731 /* expected_dummy_vfs_caps_uid - check vfs caps are stored with the provided uid */
732 static bool expected_dummy_vfs_caps_uid(int fd, uid_t expected_uid)
733 {
734 #define __cap_raised_permitted(x, ns_cap_data)                                 \
735         ((ns_cap_data.data[(x) >> 5].permitted) & (1 << ((x)&31)))
736         struct vfs_ns_cap_data ns_xattr = {};
737         ssize_t ret;
738
739         ret = fgetxattr(fd, "security.capability", &ns_xattr, sizeof(ns_xattr));
740         if (ret < 0 || ret == 0)
741                 return false;
742
743         if (ns_xattr.magic_etc & VFS_CAP_REVISION_3) {
744
745                 if (le32_to_cpu(ns_xattr.rootid) != expected_uid) {
746                         errno = EINVAL;
747                         log_stderr("failure: rootid(%d) != expected_rootid(%d)", le32_to_cpu(ns_xattr.rootid), expected_uid);
748                 }
749
750                 return (le32_to_cpu(ns_xattr.rootid) == expected_uid) &&
751                        (__cap_raised_permitted(CAP_NET_RAW, ns_xattr) > 0);
752         } else {
753                 log_stderr("failure: fscaps version");
754         }
755
756         return false;
757 }
758
759 /* set_dummy_vfs_caps - set dummy vfs caps for the provided uid */
760 static int set_dummy_vfs_caps(int fd, int flags, int rootuid)
761 {
762 #define __raise_cap_permitted(x, ns_cap_data)                                  \
763         ns_cap_data.data[(x) >> 5].permitted |= (1 << ((x)&31))
764
765         struct vfs_ns_cap_data ns_xattr;
766
767         memset(&ns_xattr, 0, sizeof(ns_xattr));
768         __raise_cap_permitted(CAP_NET_RAW, ns_xattr);
769         ns_xattr.magic_etc |= VFS_CAP_REVISION_3 | VFS_CAP_FLAGS_EFFECTIVE;
770         ns_xattr.rootid = cpu_to_le32(rootuid);
771
772         return fsetxattr(fd, "security.capability",
773                          &ns_xattr, sizeof(ns_xattr), flags);
774 }
775
776 #define safe_close(fd)      \
777         if (fd >= 0) {           \
778                 int _e_ = errno; \
779                 close(fd);       \
780                 errno = _e_;     \
781                 fd = -EBADF;     \
782         }
783
784 static void test_setup(void)
785 {
786         if (mkdirat(t_mnt_fd, T_DIR1, 0777))
787                 die("failure: mkdirat");
788
789         t_dir1_fd = openat(t_mnt_fd, T_DIR1, O_CLOEXEC | O_DIRECTORY);
790         if (t_dir1_fd < 0)
791                 die("failure: openat");
792
793         if (fchmod(t_dir1_fd, 0777))
794                 die("failure: fchmod");
795 }
796
797 static void test_cleanup(void)
798 {
799         safe_close(t_dir1_fd);
800         if (rm_r(t_mnt_fd, T_DIR1))
801                 die("failure: rm_r");
802 }
803
804 /* Validate that basic file operations on idmapped mounts. */
805 static int fsids_unmapped(void)
806 {
807         int fret = -1;
808         int file1_fd = -EBADF, hardlink_target_fd = -EBADF, open_tree_fd = -EBADF;
809         struct mount_attr attr = {
810                 .attr_set = MOUNT_ATTR_IDMAP,
811         };
812
813         /* create hardlink target */
814         hardlink_target_fd = openat(t_dir1_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
815         if (hardlink_target_fd < 0) {
816                 log_stderr("failure: openat");
817                 goto out;
818         }
819
820         /* create directory for rename test */
821         if (mkdirat(t_dir1_fd, DIR1, 0700)) {
822                 log_stderr("failure: mkdirat");
823                 goto out;
824         }
825
826         /* change ownership of all files to uid 0 */
827         if (chown_r(t_mnt_fd, T_DIR1, 0, 0)) {
828                 log_stderr("failure: chown_r");
829                 goto out;
830         }
831
832         /* Changing mount properties on a detached mount. */
833         attr.userns_fd  = get_userns_fd(0, 10000, 10000);
834         if (attr.userns_fd < 0) {
835                 log_stderr("failure: get_userns_fd");
836                 goto out;
837         }
838
839         open_tree_fd = sys_open_tree(t_dir1_fd, "",
840                                      AT_EMPTY_PATH |
841                                      AT_NO_AUTOMOUNT |
842                                      AT_SYMLINK_NOFOLLOW |
843                                      OPEN_TREE_CLOEXEC |
844                                      OPEN_TREE_CLONE);
845         if (open_tree_fd < 0) {
846                 log_stderr("failure: sys_open_tree");
847                 goto out;
848         }
849
850         if (sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
851                 log_stderr("failure: sys_mount_setattr");
852                 goto out;
853         }
854
855         if (!switch_fsids(0, 0)) {
856                 log_stderr("failure: switch_fsids");
857                 goto out;
858         }
859
860         /* The caller's fsids don't have a mappings in the idmapped mount so any
861          * file creation must fail.
862          */
863
864         /* create hardlink */
865         if (!linkat(open_tree_fd, FILE1, open_tree_fd, HARDLINK1, 0)) {
866                 log_stderr("failure: linkat");
867                 goto out;
868         }
869         if (errno != EOVERFLOW) {
870                 log_stderr("failure: errno");
871                 goto out;
872         }
873
874         /* try to rename a file */
875         if (!renameat(open_tree_fd, FILE1, open_tree_fd, FILE1_RENAME)) {
876                 log_stderr("failure: renameat");
877                 goto out;
878         }
879         if (errno != EOVERFLOW) {
880                 log_stderr("failure: errno");
881                 goto out;
882         }
883
884         /* try to rename a directory */
885         if (!renameat(open_tree_fd, DIR1, open_tree_fd, DIR1_RENAME)) {
886                 log_stderr("failure: renameat");
887                 goto out;
888         }
889         if (errno != EOVERFLOW) {
890                 log_stderr("failure: errno");
891                 goto out;
892         }
893
894         /* The caller is privileged over the inode so file deletion must work. */
895
896         /* remove file */
897         if (unlinkat(open_tree_fd, FILE1, 0)) {
898                 log_stderr("failure: unlinkat");
899                 goto out;
900         }
901
902         /* remove directory */
903         if (unlinkat(open_tree_fd, DIR1, AT_REMOVEDIR)) {
904                 log_stderr("failure: unlinkat");
905                 goto out;
906         }
907
908         /* The caller's fsids don't have a mappings in the idmapped mount so
909          * any file creation must fail.
910          */
911
912         /* create regular file via open() */
913         file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
914         if (file1_fd >= 0) {
915                 log_stderr("failure: create");
916                 goto out;
917         }
918         if (errno != EOVERFLOW) {
919                 log_stderr("failure: errno");
920                 goto out;
921         }
922
923         /* create regular file via mknod */
924         if (!mknodat(open_tree_fd, FILE2, S_IFREG | 0000, 0)) {
925                 log_stderr("failure: mknodat");
926                 goto out;
927         }
928         if (errno != EOVERFLOW) {
929                 log_stderr("failure: errno");
930                 goto out;
931         }
932
933         /* create character device */
934         if (!mknodat(open_tree_fd, CHRDEV1, S_IFCHR | 0644, makedev(5, 1))) {
935                 log_stderr("failure: mknodat");
936                 goto out;
937         }
938         if (errno != EOVERFLOW) {
939                 log_stderr("failure: errno");
940                 goto out;
941         }
942
943         /* create symlink */
944         if (!symlinkat(FILE2, open_tree_fd, SYMLINK1)) {
945                 log_stderr("failure: symlinkat");
946                 goto out;
947         }
948         if (errno != EOVERFLOW) {
949                 log_stderr("failure: errno");
950                 goto out;
951         }
952
953         /* create directory */
954         if (!mkdirat(open_tree_fd, DIR1, 0700)) {
955                 log_stderr("failure: mkdirat");
956                 goto out;
957         }
958         if (errno != EOVERFLOW) {
959                 log_stderr("failure: errno");
960                 goto out;
961         }
962
963         fret = 0;
964         log_debug("Ran test");
965 out:
966         safe_close(attr.userns_fd);
967         safe_close(hardlink_target_fd);
968         safe_close(file1_fd);
969         safe_close(open_tree_fd);
970
971         return fret;
972 }
973
974 static int fsids_mapped(void)
975 {
976         int fret = -1;
977         int file1_fd = -EBADF, hardlink_target_fd = -EBADF, open_tree_fd = -EBADF;
978         struct mount_attr attr = {
979                 .attr_set = MOUNT_ATTR_IDMAP,
980         };
981         pid_t pid;
982
983         if (!caps_supported())
984                 return 0;
985
986         /* create hardlink target */
987         hardlink_target_fd = openat(t_dir1_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
988         if (hardlink_target_fd < 0) {
989                 log_stderr("failure: openat");
990                 goto out;
991         }
992
993         /* create directory for rename test */
994         if (mkdirat(t_dir1_fd, DIR1, 0700)) {
995                 log_stderr("failure: mkdirat");
996                 goto out;
997         }
998
999         /* change ownership of all files to uid 0 */
1000         if (chown_r(t_mnt_fd, T_DIR1, 0, 0)) {
1001                 log_stderr("failure: chown_r");
1002                 goto out;
1003         }
1004
1005         /* Changing mount properties on a detached mount. */
1006         attr.userns_fd  = get_userns_fd(0, 10000, 10000);
1007         if (attr.userns_fd < 0) {
1008                 log_stderr("failure: get_userns_fd");
1009                 goto out;
1010         }
1011
1012         open_tree_fd = sys_open_tree(t_dir1_fd, "",
1013                                      AT_EMPTY_PATH |
1014                                      AT_NO_AUTOMOUNT |
1015                                      AT_SYMLINK_NOFOLLOW |
1016                                      OPEN_TREE_CLOEXEC |
1017                                      OPEN_TREE_CLONE);
1018         if (open_tree_fd < 0) {
1019                 log_stderr("failure: sys_open_tree");
1020                 goto out;
1021         }
1022
1023         if (sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
1024                 log_stderr("failure: sys_mount_setattr");
1025                 goto out;
1026         }
1027
1028         pid = fork();
1029         if (pid < 0) {
1030                 log_stderr("failure: fork");
1031                 goto out;
1032         }
1033         if (pid == 0) {
1034                 if (!switch_fsids(10000, 10000))
1035                         die("failure: switch fsids");
1036
1037                 if (!caps_up())
1038                         die("failure: raise caps");
1039
1040                 /* The caller's fsids now have mappings in the idmapped mount so
1041                  * any file creation must fail.
1042                  */
1043
1044                 /* create hardlink */
1045                 if (linkat(open_tree_fd, FILE1, open_tree_fd, HARDLINK1, 0))
1046                         die("failure: create hardlink");
1047
1048                 /* try to rename a file */
1049                 if (renameat(open_tree_fd, FILE1, open_tree_fd, FILE1_RENAME))
1050                         die("failure: rename");
1051
1052                 /* try to rename a directory */
1053                 if (renameat(open_tree_fd, DIR1, open_tree_fd, DIR1_RENAME))
1054                         die("failure: rename");
1055
1056                 /* remove file */
1057                 if (unlinkat(open_tree_fd, FILE1_RENAME, 0))
1058                         die("failure: delete");
1059
1060                 /* remove directory */
1061                 if (unlinkat(open_tree_fd, DIR1_RENAME, AT_REMOVEDIR))
1062                         die("failure: delete");
1063
1064                 /* The caller's fsids have mappings in the idmapped mount so any
1065                  * file creation must fail.
1066                  */
1067
1068                 /* create regular file via open() */
1069                 file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
1070                 if (file1_fd < 0)
1071                         die("failure: create");
1072
1073                 /* create regular file via mknod */
1074                 if (mknodat(open_tree_fd, FILE2, S_IFREG | 0000, 0))
1075                         die("failure: create");
1076
1077                 /* create character device */
1078                 if (mknodat(open_tree_fd, CHRDEV1, S_IFCHR | 0644, makedev(5, 1)))
1079                         die("failure: create");
1080
1081                 /* create symlink */
1082                 if (symlinkat(FILE2, open_tree_fd, SYMLINK1))
1083                         die("failure: create");
1084
1085                 /* create directory */
1086                 if (mkdirat(open_tree_fd, DIR1, 0700))
1087                         die("failure: create");
1088
1089                 exit(EXIT_SUCCESS);
1090         }
1091         if (wait_for_pid(pid))
1092                 goto out;
1093
1094         fret = 0;
1095         log_debug("Ran test");
1096 out:
1097         safe_close(attr.userns_fd);
1098         safe_close(file1_fd);
1099         safe_close(hardlink_target_fd);
1100         safe_close(open_tree_fd);
1101
1102         return fret;
1103 }
1104
1105 /* Validate that basic file operations on idmapped mounts from a user namespace. */
1106 static int create_in_userns(void)
1107 {
1108         int fret = -1;
1109         int file1_fd = -EBADF, open_tree_fd = -EBADF;
1110         struct mount_attr attr = {
1111                 .attr_set = MOUNT_ATTR_IDMAP,
1112         };
1113         pid_t pid;
1114
1115         /* change ownership of all files to uid 0 */
1116         if (chown_r(t_mnt_fd, T_DIR1, 0, 0)) {
1117                 log_stderr("failure: chown_r");
1118                 goto out;
1119         }
1120
1121         /* Changing mount properties on a detached mount. */
1122         attr.userns_fd  = get_userns_fd(0, 10000, 10000);
1123         if (attr.userns_fd < 0) {
1124                 log_stderr("failure: get_userns_fd");
1125                 goto out;
1126         }
1127
1128         open_tree_fd = sys_open_tree(t_dir1_fd, "",
1129                                      AT_EMPTY_PATH |
1130                                      AT_NO_AUTOMOUNT |
1131                                      AT_SYMLINK_NOFOLLOW |
1132                                      OPEN_TREE_CLOEXEC |
1133                                      OPEN_TREE_CLONE);
1134         if (open_tree_fd < 0) {
1135                 log_stderr("failure: sys_open_tree");
1136                 goto out;
1137         }
1138
1139         if (sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
1140                 log_stderr("failure: sys_mount_setattr");
1141                 goto out;
1142         }
1143
1144         pid = fork();
1145         if (pid < 0) {
1146                 log_stderr("failure: fork");
1147                 goto out;
1148         }
1149         if (pid == 0) {
1150                 if (!switch_userns(attr.userns_fd, 0, 0, false))
1151                         die("failure: switch_userns");
1152
1153                 /* create regular file via open() */
1154                 file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
1155                 if (file1_fd < 0)
1156                         die("failure: open file");
1157                 safe_close(file1_fd);
1158
1159                 if (!expected_uid_gid(open_tree_fd, FILE1, 0, 0, 0))
1160                         die("failure: check ownership");
1161
1162                 /* create regular file via mknod */
1163                 if (mknodat(open_tree_fd, FILE2, S_IFREG | 0000, 0))
1164                         die("failure: create");
1165
1166                 if (!expected_uid_gid(open_tree_fd, FILE2, 0, 0, 0))
1167                         die("failure: check ownership");
1168
1169                 /* create symlink */
1170                 if (symlinkat(FILE2, open_tree_fd, SYMLINK1))
1171                         die("failure: create");
1172
1173                 if (!expected_uid_gid(open_tree_fd, SYMLINK1, AT_SYMLINK_NOFOLLOW, 0, 0))
1174                         die("failure: check ownership");
1175
1176                 /* create directory */
1177                 if (mkdirat(open_tree_fd, DIR1, 0700))
1178                         die("failure: create");
1179
1180                 if (!expected_uid_gid(open_tree_fd, DIR1, 0, 0, 0))
1181                         die("failure: check ownership");
1182
1183                 /* try to rename a file */
1184                 if (renameat(open_tree_fd, FILE1, open_tree_fd, FILE1_RENAME))
1185                         die("failure: create");
1186
1187                 if (!expected_uid_gid(open_tree_fd, FILE1_RENAME, 0, 0, 0))
1188                         die("failure: check ownership");
1189
1190                 /* try to rename a file */
1191                 if (renameat(open_tree_fd, DIR1, open_tree_fd, DIR1_RENAME))
1192                         die("failure: create");
1193
1194                 if (!expected_uid_gid(open_tree_fd, DIR1_RENAME, 0, 0, 0))
1195                         die("failure: check ownership");
1196
1197                 /* remove file */
1198                 if (unlinkat(open_tree_fd, FILE1_RENAME, 0))
1199                         die("failure: remove");
1200
1201                 /* remove directory */
1202                 if (unlinkat(open_tree_fd, DIR1_RENAME, AT_REMOVEDIR))
1203                         die("failure: remove");
1204
1205                 exit(EXIT_SUCCESS);
1206         }
1207
1208         if (wait_for_pid(pid))
1209                 goto out;
1210
1211         fret = 0;
1212         log_debug("Ran test");
1213 out:
1214         safe_close(attr.userns_fd);
1215         safe_close(file1_fd);
1216         safe_close(open_tree_fd);
1217
1218         return fret;
1219 }
1220
1221 static int hardlink_crossing_mounts(void)
1222 {
1223         int fret = -1;
1224         int file1_fd = -EBADF, open_tree_fd = -EBADF;
1225
1226         if (chown_r(t_mnt_fd, T_DIR1, 10000, 10000)) {
1227                 log_stderr("failure: chown_r");
1228                 goto out;
1229         }
1230
1231         open_tree_fd = sys_open_tree(t_dir1_fd, "",
1232                                      AT_EMPTY_PATH |
1233                                      AT_NO_AUTOMOUNT |
1234                                      AT_SYMLINK_NOFOLLOW |
1235                                      OPEN_TREE_CLOEXEC |
1236                                      OPEN_TREE_CLONE);
1237         if (open_tree_fd < 0) {
1238                 log_stderr("failure: sys_open_tree");
1239                 goto out;
1240         }
1241
1242         file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
1243         if (file1_fd < 0) {
1244                 log_stderr("failure: openat");
1245                 goto out;
1246         }
1247
1248         if (mkdirat(open_tree_fd, DIR1, 0777)) {
1249                 log_stderr("failure: mkdirat");
1250                 goto out;
1251         }
1252
1253         /* We're crossing a mountpoint so this must fail.
1254          *
1255          * Note that this must also fail for non-idmapped mounts but here we're
1256          * interested in making sure we're not introducing an accidental way to
1257          * violate that restriction or that suddenly this becomes possible.
1258          */
1259         if (!linkat(open_tree_fd, FILE1, t_dir1_fd, HARDLINK1, 0)) {
1260                 log_stderr("failure: linkat");
1261                 goto out;
1262         }
1263         if (errno != EXDEV) {
1264                 log_stderr("failure: errno");
1265                 goto out;
1266         }
1267
1268         fret = 0;
1269         log_debug("Ran test");
1270 out:
1271         safe_close(file1_fd);
1272         safe_close(open_tree_fd);
1273
1274         return fret;
1275 }
1276
1277 static int hardlink_crossing_idmapped_mounts(void)
1278 {
1279         int fret = -1;
1280         int file1_fd = -EBADF, open_tree_fd1 = -EBADF, open_tree_fd2 = -EBADF;
1281         struct mount_attr attr = {
1282                 .attr_set = MOUNT_ATTR_IDMAP,
1283         };
1284
1285         if (chown_r(t_mnt_fd, T_DIR1, 10000, 10000)) {
1286                 log_stderr("failure: chown_r");
1287                 goto out;
1288         }
1289
1290         attr.userns_fd  = get_userns_fd(10000, 0, 10000);
1291         if (attr.userns_fd < 0) {
1292                 log_stderr("failure: get_userns_fd");
1293                 goto out;
1294         }
1295
1296         open_tree_fd1 = sys_open_tree(t_dir1_fd, "",
1297                                      AT_EMPTY_PATH |
1298                                      AT_NO_AUTOMOUNT |
1299                                      AT_SYMLINK_NOFOLLOW |
1300                                      OPEN_TREE_CLOEXEC |
1301                                      OPEN_TREE_CLONE);
1302         if (open_tree_fd1 < 0) {
1303                 log_stderr("failure: sys_open_tree");
1304                 goto out;
1305         }
1306
1307         if (sys_mount_setattr(open_tree_fd1, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
1308                 log_stderr("failure: sys_mount_setattr");
1309                 goto out;
1310         }
1311
1312         file1_fd = openat(open_tree_fd1, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
1313         if (file1_fd < 0) {
1314                 log_stderr("failure: openat");
1315                 goto out;
1316         }
1317
1318         if (!expected_uid_gid(open_tree_fd1, FILE1, 0, 0, 0)) {
1319                 log_stderr("failure: expected_uid_gid");
1320                 goto out;
1321         }
1322
1323         if (!expected_uid_gid(t_dir1_fd, FILE1, 0, 10000, 10000)) {
1324                 log_stderr("failure: expected_uid_gid");
1325                 goto out;
1326         }
1327
1328         safe_close(file1_fd);
1329
1330         if (mkdirat(open_tree_fd1, DIR1, 0777)) {
1331                 log_stderr("failure: mkdirat");
1332                 goto out;
1333         }
1334
1335         open_tree_fd2 = sys_open_tree(t_dir1_fd, DIR1,
1336                                       AT_NO_AUTOMOUNT |
1337                                       AT_SYMLINK_NOFOLLOW |
1338                                       OPEN_TREE_CLOEXEC |
1339                                       OPEN_TREE_CLONE |
1340                                       AT_RECURSIVE);
1341         if (open_tree_fd2 < 0) {
1342                 log_stderr("failure: sys_open_tree");
1343                 goto out;
1344         }
1345
1346         if (sys_mount_setattr(open_tree_fd2, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
1347                 log_stderr("failure: sys_mount_setattr");
1348                 goto out;
1349         }
1350
1351         /* We're crossing a mountpoint so this must fail.
1352          *
1353          * Note that this must also fail for non-idmapped mounts but here we're
1354          * interested in making sure we're not introducing an accidental way to
1355          * violate that restriction or that suddenly this becomes possible.
1356          */
1357         if (!linkat(open_tree_fd1, FILE1, open_tree_fd2, HARDLINK1, 0)) {
1358                 log_stderr("failure: linkat");
1359                 goto out;
1360         }
1361         if (errno != EXDEV) {
1362                 log_stderr("failure: errno");
1363                 goto out;
1364         }
1365
1366         fret = 0;
1367         log_debug("Ran test");
1368 out:
1369         safe_close(attr.userns_fd);
1370         safe_close(file1_fd);
1371         safe_close(open_tree_fd1);
1372         safe_close(open_tree_fd2);
1373
1374         return fret;
1375 }
1376
1377 static int hardlink_from_idmapped_mount(void)
1378 {
1379         int fret = -1;
1380         int file1_fd = -EBADF, open_tree_fd = -EBADF;
1381         struct mount_attr attr = {
1382                 .attr_set = MOUNT_ATTR_IDMAP,
1383         };
1384
1385         if (chown_r(t_mnt_fd, T_DIR1, 10000, 10000)) {
1386                 log_stderr("failure: chown_r");
1387                 goto out;
1388         }
1389
1390         attr.userns_fd  = get_userns_fd(10000, 0, 10000);
1391         if (attr.userns_fd < 0) {
1392                 log_stderr("failure: get_userns_fd");
1393                 goto out;
1394         }
1395
1396         open_tree_fd = sys_open_tree(t_dir1_fd, "",
1397                                      AT_EMPTY_PATH |
1398                                      AT_NO_AUTOMOUNT |
1399                                      AT_SYMLINK_NOFOLLOW |
1400                                      OPEN_TREE_CLOEXEC |
1401                                      OPEN_TREE_CLONE);
1402         if (open_tree_fd < 0) {
1403                 log_stderr("failure: sys_open_tree");
1404                 goto out;
1405         }
1406
1407         if (sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
1408                 log_stderr("failure: sys_mount_setattr");
1409                 goto out;
1410         }
1411
1412         file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
1413         if (file1_fd < 0) {
1414                 log_stderr("failure: openat");
1415                 goto out;
1416         }
1417         safe_close(file1_fd);
1418
1419         if (!expected_uid_gid(open_tree_fd, FILE1, 0, 0, 0)) {
1420                 log_stderr("failure: expected_uid_gid");
1421                 goto out;
1422         }
1423
1424         if (!expected_uid_gid(t_dir1_fd, FILE1, 0, 10000, 10000)) {
1425                 log_stderr("failure: expected_uid_gid");
1426                 goto out;
1427         }
1428
1429         /* We're not crossing a mountpoint so this must succeed. */
1430         if (linkat(open_tree_fd, FILE1, open_tree_fd, HARDLINK1, 0)) {
1431                 log_stderr("failure: linkat");
1432                 goto out;
1433         }
1434
1435
1436         fret = 0;
1437         log_debug("Ran test");
1438 out:
1439         safe_close(attr.userns_fd);
1440         safe_close(file1_fd);
1441         safe_close(open_tree_fd);
1442
1443         return fret;
1444 }
1445
1446 static int hardlink_from_idmapped_mount_in_userns(void)
1447 {
1448         int fret = -1;
1449         int file1_fd = -EBADF, open_tree_fd = -EBADF;
1450         struct mount_attr attr = {
1451                 .attr_set = MOUNT_ATTR_IDMAP,
1452         };
1453         pid_t pid;
1454
1455         if (chown_r(t_mnt_fd, T_DIR1, 0, 0)) {
1456                 log_stderr("failure: chown_r");
1457                 goto out;
1458         }
1459
1460         attr.userns_fd  = get_userns_fd(0, 10000, 10000);
1461         if (attr.userns_fd < 0) {
1462                 log_stderr("failure: get_userns_fd");
1463                 goto out;
1464         }
1465
1466         open_tree_fd = sys_open_tree(t_dir1_fd, "",
1467                                      AT_EMPTY_PATH |
1468                                      AT_NO_AUTOMOUNT |
1469                                      AT_SYMLINK_NOFOLLOW |
1470                                      OPEN_TREE_CLOEXEC |
1471                                      OPEN_TREE_CLONE);
1472         if (open_tree_fd < 0) {
1473                 log_stderr("failure: sys_open_tree");
1474                 goto out;
1475         }
1476
1477         if (sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
1478                 log_stderr("failure: sys_mount_setattr");
1479                 goto out;
1480         }
1481
1482         pid = fork();
1483         if (pid < 0) {
1484                 log_stderr("failure: fork");
1485                 goto out;
1486         }
1487         if (pid == 0) {
1488                 if (!switch_userns(attr.userns_fd, 0, 0, false))
1489                         die("failure: switch_userns");
1490
1491                 file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
1492                 if (file1_fd < 0)
1493                         die("failure: create");
1494
1495                 if (!expected_uid_gid(open_tree_fd, FILE1, 0, 0, 0))
1496                         die("failure: check ownership");
1497
1498                 /* We're not crossing a mountpoint so this must succeed. */
1499                 if (linkat(open_tree_fd, FILE1, open_tree_fd, HARDLINK1, 0))
1500                         die("failure: create");
1501
1502                 if (!expected_uid_gid(open_tree_fd, HARDLINK1, 0, 0, 0))
1503                         die("failure: check ownership");
1504
1505                 exit(EXIT_SUCCESS);
1506         }
1507
1508         if (wait_for_pid(pid))
1509                 goto out;
1510
1511         fret = 0;
1512         log_debug("Ran test");
1513 out:
1514         safe_close(attr.userns_fd);
1515         safe_close(file1_fd);
1516         safe_close(open_tree_fd);
1517
1518         return fret;
1519 }
1520
1521 static int rename_crossing_mounts(void)
1522 {
1523         int fret = -1;
1524         int file1_fd = -EBADF, open_tree_fd = -EBADF;
1525
1526         if (chown_r(t_mnt_fd, T_DIR1, 10000, 10000)) {
1527                 log_stderr("failure: chown_r");
1528                 goto out;
1529         }
1530
1531         open_tree_fd = sys_open_tree(t_dir1_fd, "",
1532                                      AT_EMPTY_PATH |
1533                                      AT_NO_AUTOMOUNT |
1534                                      AT_SYMLINK_NOFOLLOW |
1535                                      OPEN_TREE_CLOEXEC |
1536                                      OPEN_TREE_CLONE);
1537         if (open_tree_fd < 0) {
1538                 log_stderr("failure: sys_open_tree");
1539                 goto out;
1540         }
1541
1542         file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
1543         if (file1_fd < 0) {
1544                 log_stderr("failure: openat");
1545                 goto out;
1546         }
1547
1548         if (mkdirat(open_tree_fd, DIR1, 0777)) {
1549                 log_stderr("failure: mkdirat");
1550                 goto out;
1551         }
1552
1553         /* We're crossing a mountpoint so this must fail.
1554          *
1555          * Note that this must also fail for non-idmapped mounts but here we're
1556          * interested in making sure we're not introducing an accidental way to
1557          * violate that restriction or that suddenly this becomes possible.
1558          */
1559         if (!renameat(open_tree_fd, FILE1, t_dir1_fd, FILE1_RENAME)) {
1560                 log_stderr("failure: renameat");
1561                 goto out;
1562         }
1563         if (errno != EXDEV) {
1564                 log_stderr("failure: errno");
1565                 goto out;
1566         }
1567
1568         fret = 0;
1569         log_debug("Ran test");
1570 out:
1571         safe_close(file1_fd);
1572         safe_close(open_tree_fd);
1573
1574         return fret;
1575 }
1576
1577 static int rename_crossing_idmapped_mounts(void)
1578 {
1579         int fret = -1;
1580         int file1_fd = -EBADF, open_tree_fd1 = -EBADF, open_tree_fd2 = -EBADF;
1581         struct mount_attr attr = {
1582                 .attr_set = MOUNT_ATTR_IDMAP,
1583         };
1584
1585         if (chown_r(t_mnt_fd, T_DIR1, 10000, 10000)) {
1586                 log_stderr("failure: chown_r");
1587                 goto out;
1588         }
1589
1590         attr.userns_fd  = get_userns_fd(10000, 0, 10000);
1591         if (attr.userns_fd < 0) {
1592                 log_stderr("failure: get_userns_fd");
1593                 goto out;
1594         }
1595
1596         open_tree_fd1 = sys_open_tree(t_dir1_fd, "",
1597                                      AT_EMPTY_PATH |
1598                                      AT_NO_AUTOMOUNT |
1599                                      AT_SYMLINK_NOFOLLOW |
1600                                      OPEN_TREE_CLOEXEC |
1601                                      OPEN_TREE_CLONE);
1602         if (open_tree_fd1 < 0) {
1603                 log_stderr("failure: sys_open_tree");
1604                 goto out;
1605         }
1606
1607         if (sys_mount_setattr(open_tree_fd1, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
1608                 log_stderr("failure: sys_mount_setattr");
1609                 goto out;
1610         }
1611
1612         file1_fd = openat(open_tree_fd1, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
1613         if (file1_fd < 0) {
1614                 log_stderr("failure: openat");
1615                 goto out;
1616         }
1617
1618         if (!expected_uid_gid(open_tree_fd1, FILE1, 0, 0, 0)) {
1619                 log_stderr("failure: expected_uid_gid");
1620                 goto out;
1621         }
1622
1623         if (!expected_uid_gid(t_dir1_fd, FILE1, 0, 10000, 10000)) {
1624                 log_stderr("failure: expected_uid_gid");
1625                 goto out;
1626         }
1627
1628         if (mkdirat(open_tree_fd1, DIR1, 0777)) {
1629                 log_stderr("failure: mkdirat");
1630                 goto out;
1631         }
1632
1633         open_tree_fd2 = sys_open_tree(t_dir1_fd, DIR1,
1634                                       AT_NO_AUTOMOUNT |
1635                                       AT_SYMLINK_NOFOLLOW |
1636                                       OPEN_TREE_CLOEXEC |
1637                                       OPEN_TREE_CLONE |
1638                                       AT_RECURSIVE);
1639         if (open_tree_fd2 < 0) {
1640                 log_stderr("failure: sys_open_tree");
1641                 goto out;
1642         }
1643
1644         if (sys_mount_setattr(open_tree_fd2, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
1645                 log_stderr("failure: sys_mount_setattr");
1646                 goto out;
1647         }
1648
1649         /* We're crossing a mountpoint so this must fail.
1650          *
1651          * Note that this must also fail for non-idmapped mounts but here we're
1652          * interested in making sure we're not introducing an accidental way to
1653          * violate that restriction or that suddenly this becomes possible.
1654          */
1655         if (!renameat(open_tree_fd1, FILE1, open_tree_fd2, FILE1_RENAME)) {
1656                 log_stderr("failure: renameat");
1657                 goto out;
1658         }
1659         if (errno != EXDEV) {
1660                 log_stderr("failure: errno");
1661                 goto out;
1662         }
1663
1664         fret = 0;
1665         log_debug("Ran test");
1666 out:
1667         safe_close(attr.userns_fd);
1668         safe_close(file1_fd);
1669         safe_close(open_tree_fd1);
1670         safe_close(open_tree_fd2);
1671
1672         return fret;
1673 }
1674
1675 static int rename_from_idmapped_mount(void)
1676 {
1677         int fret = -1;
1678         int file1_fd = -EBADF, open_tree_fd = -EBADF;
1679         struct mount_attr attr = {
1680                 .attr_set = MOUNT_ATTR_IDMAP,
1681         };
1682
1683         if (chown_r(t_mnt_fd, T_DIR1, 10000, 10000)) {
1684                 log_stderr("failure: chown_r");
1685                 goto out;
1686         }
1687
1688         attr.userns_fd  = get_userns_fd(10000, 0, 10000);
1689         if (attr.userns_fd < 0) {
1690                 log_stderr("failure: get_userns_fd");
1691                 goto out;
1692         }
1693
1694         open_tree_fd = sys_open_tree(t_dir1_fd, "",
1695                                      AT_EMPTY_PATH |
1696                                      AT_NO_AUTOMOUNT |
1697                                      AT_SYMLINK_NOFOLLOW |
1698                                      OPEN_TREE_CLOEXEC |
1699                                      OPEN_TREE_CLONE);
1700         if (open_tree_fd < 0) {
1701                 log_stderr("failure: sys_open_tree");
1702                 goto out;
1703         }
1704
1705         if (sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
1706                 log_stderr("failure: sys_mount_setattr");
1707                 goto out;
1708         }
1709
1710         file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
1711         if (file1_fd < 0) {
1712                 log_stderr("failure: openat");
1713                 goto out;
1714         }
1715
1716         if (!expected_uid_gid(open_tree_fd, FILE1, 0, 0, 0)) {
1717                 log_stderr("failure: expected_uid_gid");
1718                 goto out;
1719         }
1720
1721         if (!expected_uid_gid(t_dir1_fd, FILE1, 0, 10000, 10000)) {
1722                 log_stderr("failure: expected_uid_gid");
1723                 goto out;
1724         }
1725
1726         /* We're not crossing a mountpoint so this must succeed. */
1727         if (renameat(open_tree_fd, FILE1, open_tree_fd, FILE1_RENAME)) {
1728                 log_stderr("failure: renameat");
1729                 goto out;
1730         }
1731
1732         fret = 0;
1733         log_debug("Ran test");
1734 out:
1735         safe_close(attr.userns_fd);
1736         safe_close(file1_fd);
1737         safe_close(open_tree_fd);
1738
1739         return fret;
1740 }
1741
1742 static int rename_from_idmapped_mount_in_userns(void)
1743 {
1744         int fret = -1;
1745         int file1_fd = -EBADF, open_tree_fd = -EBADF;
1746         pid_t pid;
1747         struct mount_attr attr = {
1748                 .attr_set = MOUNT_ATTR_IDMAP,
1749         };
1750
1751         if (chown_r(t_mnt_fd, T_DIR1, 0, 0)) {
1752                 log_stderr("failure: chown_r");
1753                 goto out;
1754         }
1755
1756         attr.userns_fd  = get_userns_fd(0, 10000, 10000);
1757         if (attr.userns_fd < 0) {
1758                 log_stderr("failure: get_userns_fd");
1759                 goto out;
1760         }
1761
1762         open_tree_fd = sys_open_tree(t_dir1_fd, "",
1763                                      AT_EMPTY_PATH |
1764                                      AT_NO_AUTOMOUNT |
1765                                      AT_SYMLINK_NOFOLLOW |
1766                                      OPEN_TREE_CLOEXEC |
1767                                      OPEN_TREE_CLONE);
1768         if (open_tree_fd < 0) {
1769                 log_stderr("failure: sys_open_tree");
1770                 goto out;
1771         }
1772
1773         if (sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
1774                 log_stderr("failure: sys_mount_setattr");
1775                 goto out;
1776         }
1777
1778         pid = fork();
1779         if (pid < 0) {
1780                 log_stderr("failure: fork");
1781                 goto out;
1782         }
1783         if (pid == 0) {
1784                 if (!switch_userns(attr.userns_fd, 0, 0, false))
1785                         die("failure: switch_userns");
1786
1787                 file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
1788                 if (file1_fd < 0)
1789                         die("failure: create");
1790
1791                 if (!expected_uid_gid(open_tree_fd, FILE1, 0, 0, 0))
1792                         die("failure: check ownership");
1793
1794                 /* We're not crossing a mountpoint so this must succeed. */
1795                 if (renameat(open_tree_fd, FILE1, open_tree_fd, FILE1_RENAME))
1796                         die("failure: create");
1797
1798                 if (!expected_uid_gid(open_tree_fd, FILE1_RENAME, 0, 0, 0))
1799                         die("failure: check ownership");
1800
1801                 exit(EXIT_SUCCESS);
1802         }
1803
1804         if (wait_for_pid(pid))
1805                 goto out;
1806
1807         fret = 0;
1808         log_debug("Ran test");
1809 out:
1810         safe_close(attr.userns_fd);
1811         safe_close(file1_fd);
1812         safe_close(open_tree_fd);
1813
1814         return fret;
1815 }
1816
1817 static int symlink_regular_mounts(void)
1818 {
1819         int fret = -1;
1820         int file1_fd = -EBADF, open_tree_fd = -EBADF;
1821         struct stat st;
1822
1823         file1_fd = openat(t_dir1_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
1824         if (file1_fd < 0) {
1825                 log_stderr("failure: openat");
1826                 goto out;
1827         }
1828
1829         if (chown_r(t_mnt_fd, T_DIR1, 10000, 10000)) {
1830                 log_stderr("failure: chown_r");
1831                 goto out;
1832         }
1833
1834         open_tree_fd = sys_open_tree(t_dir1_fd, "",
1835                                      AT_EMPTY_PATH |
1836                                      AT_NO_AUTOMOUNT |
1837                                      AT_SYMLINK_NOFOLLOW |
1838                                      OPEN_TREE_CLOEXEC |
1839                                      OPEN_TREE_CLONE);
1840         if (open_tree_fd < 0) {
1841                 log_stderr("failure: sys_open_tree");
1842                 goto out;
1843         }
1844
1845         if (symlinkat(FILE1, open_tree_fd, FILE2)) {
1846                 log_stderr("failure: symlinkat");
1847                 goto out;
1848         }
1849
1850         if (fchownat(open_tree_fd, FILE2, 15000, 15000, AT_SYMLINK_NOFOLLOW)) {
1851                 log_stderr("failure: fchownat");
1852                 goto out;
1853         }
1854
1855         if (fstatat(open_tree_fd, FILE2, &st, AT_SYMLINK_NOFOLLOW)) {
1856                 log_stderr("failure: fstatat");
1857                 goto out;
1858         }
1859
1860         if (st.st_uid != 15000 || st.st_gid != 15000) {
1861                 log_stderr("failure: compare ids");
1862                 goto out;
1863         }
1864
1865         if (fstatat(open_tree_fd, FILE1, &st, 0)) {
1866                 log_stderr("failure: fstatat");
1867                 goto out;
1868         }
1869
1870         if (st.st_uid != 10000 || st.st_gid != 10000) {
1871                 log_stderr("failure: compare ids");
1872                 goto out;
1873         }
1874
1875         fret = 0;
1876         log_debug("Ran test");
1877 out:
1878         safe_close(file1_fd);
1879         safe_close(open_tree_fd);
1880
1881         return fret;
1882 }
1883
1884 static int symlink_idmapped_mounts(void)
1885 {
1886         int fret = -1;
1887         int file1_fd = -EBADF, open_tree_fd = -EBADF;
1888         struct mount_attr attr = {
1889                 .attr_set = MOUNT_ATTR_IDMAP,
1890         };
1891         pid_t pid;
1892
1893         if (!caps_supported())
1894                 return 0;
1895
1896         file1_fd = openat(t_dir1_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
1897         if (file1_fd < 0) {
1898                 log_stderr("failure: openat");
1899                 goto out;
1900         }
1901
1902         if (chown_r(t_mnt_fd, T_DIR1, 0, 0)) {
1903                 log_stderr("failure: chown_r");
1904                 goto out;
1905         }
1906
1907         /* Changing mount properties on a detached mount. */
1908         attr.userns_fd  = get_userns_fd(0, 10000, 10000);
1909         if (attr.userns_fd < 0) {
1910                 log_stderr("failure: get_userns_fd");
1911                 goto out;
1912         }
1913
1914         open_tree_fd = sys_open_tree(t_dir1_fd, "",
1915                                      AT_EMPTY_PATH |
1916                                      AT_NO_AUTOMOUNT |
1917                                      AT_SYMLINK_NOFOLLOW |
1918                                      OPEN_TREE_CLOEXEC |
1919                                      OPEN_TREE_CLONE);
1920         if (open_tree_fd < 0) {
1921                 log_stderr("failure: sys_open_tree");
1922                 goto out;
1923         }
1924
1925         if (sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
1926                 log_stderr("failure: sys_mount_setattr");
1927                 goto out;
1928         }
1929
1930         pid = fork();
1931         if (pid < 0) {
1932                 log_stderr("failure: fork");
1933                 goto out;
1934         }
1935         if (pid == 0) {
1936                 if (!switch_fsids(10000, 10000))
1937                         die("failure: switch fsids");
1938
1939                 if (!caps_up())
1940                         die("failure: raise caps");
1941
1942                 if (symlinkat(FILE1, open_tree_fd, FILE2))
1943                         die("failure: create");
1944
1945                 if (fchownat(open_tree_fd, FILE2, 15000, 15000, AT_SYMLINK_NOFOLLOW))
1946                         die("failure: change ownership");
1947
1948                 if (!expected_uid_gid(open_tree_fd, FILE2, AT_SYMLINK_NOFOLLOW, 15000, 15000))
1949                         die("failure: check ownership");
1950
1951                 if (!expected_uid_gid(open_tree_fd, FILE1, 0, 10000, 10000))
1952                         die("failure: check ownership");
1953
1954                 exit(EXIT_SUCCESS);
1955         }
1956         if (wait_for_pid(pid))
1957                 goto out;
1958
1959         fret = 0;
1960         log_debug("Ran test");
1961 out:
1962         safe_close(attr.userns_fd);
1963         safe_close(file1_fd);
1964         safe_close(open_tree_fd);
1965
1966         return fret;
1967 }
1968
1969 static int symlink_idmapped_mounts_in_userns(void)
1970 {
1971         int fret = -1;
1972         int file1_fd = -EBADF, open_tree_fd = -EBADF;
1973         struct mount_attr attr = {
1974                 .attr_set = MOUNT_ATTR_IDMAP,
1975         };
1976         pid_t pid;
1977
1978         if (chown_r(t_mnt_fd, T_DIR1, 0, 0)) {
1979                 log_stderr("failure: chown_r");
1980                 goto out;
1981         }
1982
1983         /* Changing mount properties on a detached mount. */
1984         attr.userns_fd  = get_userns_fd(0, 10000, 10000);
1985         if (attr.userns_fd < 0) {
1986                 log_stderr("failure: get_userns_fd");
1987                 goto out;
1988         }
1989
1990         open_tree_fd = sys_open_tree(t_dir1_fd, "",
1991                                      AT_EMPTY_PATH |
1992                                      AT_NO_AUTOMOUNT |
1993                                      AT_SYMLINK_NOFOLLOW |
1994                                      OPEN_TREE_CLOEXEC |
1995                                      OPEN_TREE_CLONE);
1996         if (open_tree_fd < 0) {
1997                 log_stderr("failure: sys_open_tree");
1998                 goto out;
1999         }
2000
2001         if (sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
2002                 log_stderr("failure: sys_mount_setattr");
2003                 goto out;
2004         }
2005
2006         pid = fork();
2007         if (pid < 0) {
2008                 log_stderr("failure: fork");
2009                 goto out;
2010         }
2011         if (pid == 0) {
2012                 if (!switch_userns(attr.userns_fd, 0, 0, false))
2013                         die("failure: switch_userns");
2014
2015                 file1_fd = openat(open_tree_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
2016                 if (file1_fd < 0)
2017                         die("failure: create");
2018                 safe_close(file1_fd);
2019
2020                 if (symlinkat(FILE1, open_tree_fd, FILE2))
2021                         die("failure: create");
2022
2023                 if (fchownat(open_tree_fd, FILE2, 5000, 5000, AT_SYMLINK_NOFOLLOW))
2024                         die("failure: change ownership");
2025
2026                 if (!expected_uid_gid(open_tree_fd, FILE2, AT_SYMLINK_NOFOLLOW, 5000, 5000))
2027                         die("failure: check ownership");
2028
2029                 if (!expected_uid_gid(open_tree_fd, FILE1, 0, 0, 0))
2030                         die("failure: check ownership");
2031
2032                 exit(EXIT_SUCCESS);
2033         }
2034
2035         if (wait_for_pid(pid))
2036                 goto out;
2037
2038         if (!expected_uid_gid(t_dir1_fd, FILE2, AT_SYMLINK_NOFOLLOW, 5000, 5000)) {
2039                 log_stderr("failure: expected_uid_gid");
2040                 goto out;
2041         }
2042
2043         if (!expected_uid_gid(t_dir1_fd, FILE1, 0, 0, 0)) {
2044                 log_stderr("failure: expected_uid_gid");
2045                 goto out;
2046         }
2047
2048         fret = 0;
2049         log_debug("Ran test");
2050 out:
2051         safe_close(attr.userns_fd);
2052         safe_close(file1_fd);
2053         safe_close(open_tree_fd);
2054
2055         return fret;
2056 }
2057
2058 /* Validate that a caller whose fsids map into the idmapped mount within it's
2059  * user namespace cannot create any device nodes.
2060  */
2061 static int device_node_in_userns(void)
2062 {
2063         int fret = -1;
2064         int open_tree_fd = -EBADF;
2065         struct mount_attr attr = {
2066                 .attr_set = MOUNT_ATTR_IDMAP,
2067         };
2068         pid_t pid;
2069
2070         attr.userns_fd  = get_userns_fd(0, 10000, 10000);
2071         if (attr.userns_fd < 0) {
2072                 log_stderr("failure: get_userns_fd");
2073                 goto out;
2074         }
2075
2076         open_tree_fd = sys_open_tree(t_dir1_fd, "",
2077                                      AT_EMPTY_PATH |
2078                                      AT_NO_AUTOMOUNT |
2079                                      AT_SYMLINK_NOFOLLOW |
2080                                      OPEN_TREE_CLOEXEC |
2081                                      OPEN_TREE_CLONE);
2082         if (open_tree_fd < 0) {
2083                 log_stderr("failure: sys_open_tree");
2084                 goto out;
2085         }
2086
2087         if (sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
2088                 log_stderr("failure: sys_mount_setattr");
2089                 goto out;
2090         }
2091
2092         pid = fork();
2093         if (pid < 0) {
2094                 log_stderr("failure: fork");
2095                 goto out;
2096         }
2097         if (pid == 0) {
2098                 if (!switch_userns(attr.userns_fd, 0, 0, false))
2099                         die("failure: switch_userns");
2100
2101                 /* create character device */
2102                 if (!mknodat(open_tree_fd, CHRDEV1, S_IFCHR | 0644, makedev(5, 1)))
2103                         die("failure: create");
2104
2105                 exit(EXIT_SUCCESS);
2106         }
2107
2108         if (wait_for_pid(pid))
2109                 goto out;
2110
2111         fret = 0;
2112         log_debug("Ran test");
2113 out:
2114         safe_close(attr.userns_fd);
2115         safe_close(open_tree_fd);
2116
2117         return fret;
2118 }
2119
2120
2121 /* Validate that changing file ownership works correctly on idmapped mounts. */
2122 static int expected_uid_gid_idmapped_mounts(void)
2123 {
2124         int fret = -1;
2125         int file1_fd = -EBADF, open_tree_fd1 = -EBADF, open_tree_fd2 = -EBADF;
2126         struct mount_attr attr1 = {
2127                 .attr_set = MOUNT_ATTR_IDMAP,
2128         };
2129         struct mount_attr attr2 = {
2130                 .attr_set = MOUNT_ATTR_IDMAP,
2131         };
2132         pid_t pid;
2133
2134         if (!switch_fsids(0, 0)) {
2135                 log_stderr("failure: switch_fsids");
2136                 goto out;
2137         }
2138
2139         /* create regular file via open() */
2140         file1_fd = openat(t_dir1_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
2141         if (file1_fd < 0) {
2142                 log_stderr("failure: openat");
2143                 goto out;
2144         }
2145
2146         /* create regular file via mknod */
2147         if (mknodat(t_dir1_fd, FILE2, S_IFREG | 0000, 0)) {
2148                 log_stderr("failure: mknodat");
2149                 goto out;
2150         }
2151
2152         /* create character device */
2153         if (mknodat(t_dir1_fd, CHRDEV1, S_IFCHR | 0644, makedev(5, 1))) {
2154                 log_stderr("failure: mknodat");
2155                 goto out;
2156         }
2157
2158         /* create hardlink */
2159         if (linkat(t_dir1_fd, FILE1, t_dir1_fd, HARDLINK1, 0)) {
2160                 log_stderr("failure: linkat");
2161                 goto out;
2162         }
2163
2164         /* create symlink */
2165         if (symlinkat(FILE2, t_dir1_fd, SYMLINK1)) {
2166                 log_stderr("failure: symlinkat");
2167                 goto out;
2168         }
2169
2170         /* create directory */
2171         if (mkdirat(t_dir1_fd, DIR1, 0700)) {
2172                 log_stderr("failure: mkdirat");
2173                 goto out;
2174         }
2175
2176         /* Changing mount properties on a detached mount. */
2177         attr1.userns_fd = get_userns_fd(0, 10000, 10000);
2178         if (attr1.userns_fd < 0) {
2179                 log_stderr("failure: get_userns_fd");
2180                 goto out;
2181         }
2182
2183         open_tree_fd1 = sys_open_tree(t_dir1_fd, "",
2184                                      AT_EMPTY_PATH |
2185                                      AT_NO_AUTOMOUNT |
2186                                      AT_SYMLINK_NOFOLLOW |
2187                                      OPEN_TREE_CLOEXEC |
2188                                      OPEN_TREE_CLONE);
2189         if (open_tree_fd1 < 0) {
2190                 log_stderr("failure: sys_open_tree");
2191                 goto out;
2192         }
2193
2194         if (sys_mount_setattr(open_tree_fd1, "", AT_EMPTY_PATH, &attr1, sizeof(attr1))) {
2195                 log_stderr("failure: sys_mount_setattr");
2196                 goto out;
2197         }
2198
2199         /* Validate that all files created through the image mountpoint are
2200          * owned by the callers fsuid and fsgid.
2201          */
2202         if (!expected_uid_gid(t_dir1_fd, FILE1, 0, 0, 0)) {
2203                 log_stderr("failure: expected_uid_gid");
2204                 goto out;
2205         }
2206         if (!expected_uid_gid(t_dir1_fd, FILE2, 0, 0, 0)) {
2207                 log_stderr("failure: expected_uid_gid");
2208                 goto out;
2209         }
2210         if (!expected_uid_gid(t_dir1_fd, HARDLINK1, 0, 0, 0)) {
2211                 log_stderr("failure: expected_uid_gid");
2212                 goto out;
2213         }
2214         if (!expected_uid_gid(t_dir1_fd, CHRDEV1, 0, 0, 0)) {
2215                 log_stderr("failure: expected_uid_gid");
2216                 goto out;
2217         }
2218         if (!expected_uid_gid(t_dir1_fd, SYMLINK1, AT_SYMLINK_NOFOLLOW, 0, 0)) {
2219                 log_stderr("failure: expected_uid_gid");
2220                 goto out;
2221         }
2222         if (!expected_uid_gid(t_dir1_fd, SYMLINK1, 0, 0, 0)) {
2223                 log_stderr("failure: expected_uid_gid");
2224                 goto out;
2225         }
2226         if (!expected_uid_gid(t_dir1_fd, DIR1, 0, 0, 0)) {
2227                 log_stderr("failure: expected_uid_gid");
2228                 goto out;
2229         }
2230
2231         /* Validate that all files are owned by the uid and gid specified in
2232          * the idmapping of the mount they are accessed from.
2233          */
2234         if (!expected_uid_gid(open_tree_fd1, FILE1, 0, 10000, 10000)) {
2235                 log_stderr("failure: expected_uid_gid");
2236                 goto out;
2237         }
2238         if (!expected_uid_gid(open_tree_fd1, FILE2, 0, 10000, 10000)) {
2239                 log_stderr("failure: expected_uid_gid");
2240                 goto out;
2241         }
2242         if (!expected_uid_gid(open_tree_fd1, HARDLINK1, 0, 10000, 10000)) {
2243                 log_stderr("failure: expected_uid_gid");
2244                 goto out;
2245         }
2246         if (!expected_uid_gid(open_tree_fd1, CHRDEV1, 0, 10000, 10000)) {
2247                 log_stderr("failure: expected_uid_gid");
2248                 goto out;
2249         }
2250         if (!expected_uid_gid(open_tree_fd1, SYMLINK1, AT_SYMLINK_NOFOLLOW, 10000, 10000)) {
2251                 log_stderr("failure: expected_uid_gid");
2252                 goto out;
2253         }
2254         if (!expected_uid_gid(open_tree_fd1, SYMLINK1, 0, 10000, 10000)) {
2255                 log_stderr("failure: expected_uid_gid");
2256                 goto out;
2257         }
2258         if (!expected_uid_gid(open_tree_fd1, DIR1, 0, 10000, 10000)) {
2259                 log_stderr("failure: expected_uid_gid");
2260                 goto out;
2261         }
2262
2263         /* Changing mount properties on a detached mount. */
2264         attr2.userns_fd = get_userns_fd(0, 30000, 2001);
2265         if (attr2.userns_fd < 0) {
2266                 log_stderr("failure: get_userns_fd");
2267                 goto out;
2268         }
2269
2270         open_tree_fd2 = sys_open_tree(t_dir1_fd, "",
2271                                      AT_EMPTY_PATH |
2272                                      AT_NO_AUTOMOUNT |
2273                                      AT_SYMLINK_NOFOLLOW |
2274                                      OPEN_TREE_CLOEXEC |
2275                                      OPEN_TREE_CLONE);
2276         if (open_tree_fd2 < 0) {
2277                 log_stderr("failure: sys_open_tree");
2278                 goto out;
2279         }
2280
2281         if (sys_mount_setattr(open_tree_fd2, "", AT_EMPTY_PATH, &attr2, sizeof(attr2))) {
2282                 log_stderr("failure: sys_mount_setattr");
2283                 goto out;
2284         }
2285
2286         /* Validate that all files are owned by the uid and gid specified in
2287          * the idmapping of the mount they are accessed from.
2288          */
2289         if (!expected_uid_gid(open_tree_fd2, FILE1, 0, 30000, 30000)) {
2290                 log_stderr("failure: expected_uid_gid");
2291                 goto out;
2292         }
2293         if (!expected_uid_gid(open_tree_fd2, FILE2, 0, 30000, 30000)) {
2294                 log_stderr("failure: expected_uid_gid");
2295                 goto out;
2296         }
2297         if (!expected_uid_gid(open_tree_fd2, HARDLINK1, 0, 30000, 30000)) {
2298                 log_stderr("failure: expected_uid_gid");
2299                 goto out;
2300         }
2301         if (!expected_uid_gid(open_tree_fd2, CHRDEV1, 0, 30000, 30000)) {
2302                 log_stderr("failure: expected_uid_gid");
2303                 goto out;
2304         }
2305         if (!expected_uid_gid(open_tree_fd2, SYMLINK1, AT_SYMLINK_NOFOLLOW, 30000, 30000)) {
2306                 log_stderr("failure: expected_uid_gid");
2307                 goto out;
2308         }
2309         if (!expected_uid_gid(open_tree_fd2, SYMLINK1, 0, 30000, 30000)) {
2310                 log_stderr("failure: expected_uid_gid");
2311                 goto out;
2312         }
2313         if (!expected_uid_gid(open_tree_fd2, DIR1, 0, 30000, 30000)) {
2314                 log_stderr("failure: expected_uid_gid");
2315                 goto out;
2316         }
2317
2318         /* Change ownership throught original image mountpoint. */
2319         if (fchownat(t_dir1_fd, FILE1, 2000, 2000, 0)) {
2320                 log_stderr("failure: fchownat");
2321                 goto out;
2322         }
2323         if (fchownat(t_dir1_fd, FILE2, 2000, 2000, 0)) {
2324                 log_stderr("failure: fchownat");
2325                 goto out;
2326         }
2327         if (fchownat(t_dir1_fd, HARDLINK1, 2000, 2000, 0)) {
2328                 log_stderr("failure: fchownat");
2329                 goto out;
2330         }
2331         if (fchownat(t_dir1_fd, CHRDEV1, 2000, 2000, 0)) {
2332                 log_stderr("failure: fchownat");
2333                 goto out;
2334         }
2335         if (fchownat(t_dir1_fd, SYMLINK1, 3000, 3000, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW)) {
2336                 log_stderr("failure: fchownat");
2337                 goto out;
2338         }
2339         if (fchownat(t_dir1_fd, SYMLINK1, 2000, 2000, AT_EMPTY_PATH)) {
2340                 log_stderr("failure: fchownat");
2341                 goto out;
2342         }
2343         if (fchownat(t_dir1_fd, DIR1, 2000, 2000, AT_EMPTY_PATH)) {
2344                 log_stderr("failure: fchownat");
2345                 goto out;
2346         }
2347
2348         /* Check ownership through original mount. */
2349         if (!expected_uid_gid(t_dir1_fd, FILE1, 0, 2000, 2000)) {
2350                 log_stderr("failure: expected_uid_gid");
2351                 goto out;
2352         }
2353         if (!expected_uid_gid(t_dir1_fd, FILE2, 0, 2000, 2000)) {
2354                 log_stderr("failure: expected_uid_gid");
2355                 goto out;
2356         }
2357         if (!expected_uid_gid(t_dir1_fd, HARDLINK1, 0, 2000, 2000)) {
2358                 log_stderr("failure: expected_uid_gid");
2359                 goto out;
2360         }
2361         if (!expected_uid_gid(t_dir1_fd, CHRDEV1, 0, 2000, 2000)) {
2362                 log_stderr("failure: expected_uid_gid");
2363                 goto out;
2364         }
2365         if (!expected_uid_gid(t_dir1_fd, SYMLINK1, AT_SYMLINK_NOFOLLOW, 3000, 3000)) {
2366                 log_stderr("failure: expected_uid_gid");
2367                 goto out;
2368         }
2369         if (!expected_uid_gid(t_dir1_fd, SYMLINK1, 0, 2000, 2000)) {
2370                 log_stderr("failure: expected_uid_gid");
2371                 goto out;
2372         }
2373         if (!expected_uid_gid(t_dir1_fd, DIR1, 0, 2000, 2000)) {
2374                 log_stderr("failure: expected_uid_gid");
2375                 goto out;
2376         }
2377
2378         /* Check ownership through first idmapped mount. */
2379         if (!expected_uid_gid(open_tree_fd1, FILE1, 0, 12000, 12000)) {
2380                 log_stderr("failure:expected_uid_gid ");
2381                 goto out;
2382         }
2383         if (!expected_uid_gid(open_tree_fd1, FILE2, 0, 12000, 12000)) {
2384                 log_stderr("failure: expected_uid_gid");
2385                 goto out;
2386         }
2387         if (!expected_uid_gid(open_tree_fd1, HARDLINK1, 0, 12000, 12000)) {
2388                 log_stderr("failure: expected_uid_gid");
2389                 goto out;
2390         }
2391         if (!expected_uid_gid(open_tree_fd1, CHRDEV1, 0, 12000, 12000)) {
2392                 log_stderr("failure: expected_uid_gid");
2393                 goto out;
2394         }
2395         if (!expected_uid_gid(open_tree_fd1, SYMLINK1, AT_SYMLINK_NOFOLLOW, 13000, 13000)) {
2396                 log_stderr("failure: expected_uid_gid");
2397                 goto out;
2398         }
2399         if (!expected_uid_gid(open_tree_fd1, SYMLINK1, 0, 12000, 12000)) {
2400                 log_stderr("failure:expected_uid_gid ");
2401                 goto out;
2402         }
2403         if (!expected_uid_gid(open_tree_fd1, DIR1, 0, 12000, 12000)) {
2404                 log_stderr("failure: expected_uid_gid");
2405                 goto out;
2406         }
2407
2408         /* Check ownership through second idmapped mount. */
2409         if (!expected_uid_gid(open_tree_fd2, FILE1, 0, 32000, 32000)) {
2410                 log_stderr("failure: expected_uid_gid");
2411                 goto out;
2412         }
2413         if (!expected_uid_gid(open_tree_fd2, FILE2, 0, 32000, 32000)) {
2414                 log_stderr("failure: expected_uid_gid");
2415                 goto out;
2416         }
2417         if (!expected_uid_gid(open_tree_fd2, HARDLINK1, 0, 32000, 32000)) {
2418                 log_stderr("failure: expected_uid_gid");
2419                 goto out;
2420         }
2421         if (!expected_uid_gid(open_tree_fd2, CHRDEV1, 0, 32000, 32000)) {
2422                 log_stderr("failure: expected_uid_gid");
2423                 goto out;
2424         }
2425         if (!expected_uid_gid(open_tree_fd2, SYMLINK1, AT_SYMLINK_NOFOLLOW, t_overflowuid, t_overflowgid)) {
2426                 log_stderr("failure: expected_uid_gid");
2427                 goto out;
2428         }
2429         if (!expected_uid_gid(open_tree_fd2, SYMLINK1, 0, 32000, 32000)) {
2430                 log_stderr("failure: expected_uid_gid");
2431                 goto out;
2432         }
2433         if (!expected_uid_gid(open_tree_fd2, DIR1, 0, 32000, 32000)) {
2434                 log_stderr("failure: expected_uid_gid");
2435                 goto out;
2436         }
2437
2438         pid = fork();
2439         if (pid < 0) {
2440                 log_stderr("failure: fork");
2441                 goto out;
2442         }
2443         if (pid == 0) {
2444                 if (!switch_userns(attr1.userns_fd, 0, 0, false))
2445                         die("failure: switch_userns");
2446
2447                 if (!fchownat(t_dir1_fd, FILE1, 1000, 1000, 0))
2448                         die("failure: fchownat");
2449                 if (!fchownat(t_dir1_fd, FILE2, 1000, 1000, 0))
2450                         die("failure: fchownat");
2451                 if (!fchownat(t_dir1_fd, HARDLINK1, 1000, 1000, 0))
2452                         die("failure: fchownat");
2453                 if (!fchownat(t_dir1_fd, CHRDEV1, 1000, 1000, 0))
2454                         die("failure: fchownat");
2455                 if (!fchownat(t_dir1_fd, SYMLINK1, 2000, 2000, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW))
2456                         die("failure: fchownat");
2457                 if (!fchownat(t_dir1_fd, SYMLINK1, 1000, 1000, AT_EMPTY_PATH))
2458                         die("failure: fchownat");
2459                 if (!fchownat(t_dir1_fd, DIR1, 1000, 1000, AT_EMPTY_PATH))
2460                         die("failure: fchownat");
2461
2462                 if (!fchownat(open_tree_fd2, FILE1, 1000, 1000, 0))
2463                         die("failure: fchownat");
2464                 if (!fchownat(open_tree_fd2, FILE2, 1000, 1000, 0))
2465                         die("failure: fchownat");
2466                 if (!fchownat(open_tree_fd2, HARDLINK1, 1000, 1000, 0))
2467                         die("failure: fchownat");
2468                 if (!fchownat(open_tree_fd2, CHRDEV1, 1000, 1000, 0))
2469                         die("failure: fchownat");
2470                 if (!fchownat(open_tree_fd2, SYMLINK1, 2000, 2000, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW))
2471                         die("failure: fchownat");
2472                 if (!fchownat(open_tree_fd2, SYMLINK1, 1000, 1000, AT_EMPTY_PATH))
2473                         die("failure: fchownat");
2474                 if (!fchownat(open_tree_fd2, DIR1, 1000, 1000, AT_EMPTY_PATH))
2475                         die("failure: fchownat");
2476
2477                 if (fchownat(open_tree_fd1, FILE1, 1000, 1000, 0))
2478                         die("failure: fchownat");
2479                 if (fchownat(open_tree_fd1, FILE2, 1000, 1000, 0))
2480                         die("failure: fchownat");
2481                 if (fchownat(open_tree_fd1, HARDLINK1, 1000, 1000, 0))
2482                         die("failure: fchownat");
2483                 if (fchownat(open_tree_fd1, CHRDEV1, 1000, 1000, 0))
2484                         die("failure: fchownat");
2485                 if (fchownat(open_tree_fd1, SYMLINK1, 2000, 2000, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW))
2486                         die("failure: fchownat");
2487                 if (fchownat(open_tree_fd1, SYMLINK1, 1000, 1000, AT_EMPTY_PATH))
2488                         die("failure: fchownat");
2489                 if (fchownat(open_tree_fd1, DIR1, 1000, 1000, AT_EMPTY_PATH))
2490                         die("failure: fchownat");
2491
2492                 if (!expected_uid_gid(t_dir1_fd, FILE1, 0, t_overflowuid, t_overflowgid))
2493                         die("failure: expected_uid_gid");
2494                 if (!expected_uid_gid(t_dir1_fd, FILE2, 0, t_overflowuid, t_overflowgid))
2495                         die("failure: expected_uid_gid");
2496                 if (!expected_uid_gid(t_dir1_fd, HARDLINK1, 0, t_overflowuid, t_overflowgid))
2497                         die("failure: expected_uid_gid");
2498                 if (!expected_uid_gid(t_dir1_fd, CHRDEV1, 0, t_overflowuid, t_overflowgid))
2499                         die("failure: expected_uid_gid");
2500                 if (!expected_uid_gid(t_dir1_fd, SYMLINK1, AT_SYMLINK_NOFOLLOW, t_overflowuid, t_overflowgid))
2501                         die("failure: expected_uid_gid");
2502                 if (!expected_uid_gid(t_dir1_fd, SYMLINK1, 0, t_overflowuid, t_overflowgid))
2503                         die("failure: expected_uid_gid");
2504                 if (!expected_uid_gid(t_dir1_fd, DIR1, 0, t_overflowuid, t_overflowgid))
2505                         die("failure: expected_uid_gid");
2506
2507                 if (!expected_uid_gid(open_tree_fd2, FILE1, 0, t_overflowuid, t_overflowgid))
2508                         die("failure: expected_uid_gid");
2509                 if (!expected_uid_gid(open_tree_fd2, FILE2, 0, t_overflowuid, t_overflowgid))
2510                         die("failure: expected_uid_gid");
2511                 if (!expected_uid_gid(open_tree_fd2, HARDLINK1, 0, t_overflowuid, t_overflowgid))
2512                         die("failure: expected_uid_gid");
2513                 if (!expected_uid_gid(open_tree_fd2, CHRDEV1, 0, t_overflowuid, t_overflowgid))
2514                         die("failure: expected_uid_gid");
2515                 if (!expected_uid_gid(open_tree_fd2, SYMLINK1, AT_SYMLINK_NOFOLLOW, t_overflowuid, t_overflowgid))
2516                         die("failure: expected_uid_gid");
2517                 if (!expected_uid_gid(open_tree_fd2, SYMLINK1, 0, t_overflowuid, t_overflowgid))
2518                         die("failure: expected_uid_gid");
2519                 if (!expected_uid_gid(open_tree_fd2, DIR1, 0, t_overflowuid, t_overflowgid))
2520                         die("failure: expected_uid_gid");
2521
2522                 if (!expected_uid_gid(open_tree_fd1, FILE1, 0, 1000, 1000))
2523                         die("failure: expected_uid_gid");
2524                 if (!expected_uid_gid(open_tree_fd1, FILE2, 0, 1000, 1000))
2525                         die("failure: expected_uid_gid");
2526                 if (!expected_uid_gid(open_tree_fd1, HARDLINK1, 0, 1000, 1000))
2527                         die("failure: expected_uid_gid");
2528                 if (!expected_uid_gid(open_tree_fd1, CHRDEV1, 0, 1000, 1000))
2529                         die("failure: expected_uid_gid");
2530                 if (!expected_uid_gid(open_tree_fd1, SYMLINK1, AT_SYMLINK_NOFOLLOW, 2000, 2000))
2531                         die("failure: expected_uid_gid");
2532                 if (!expected_uid_gid(open_tree_fd1, SYMLINK1, 0, 1000, 1000))
2533                         die("failure: expected_uid_gid");
2534                 if (!expected_uid_gid(open_tree_fd1, DIR1, 0, 1000, 1000))
2535                         die("failure: expected_uid_gid");
2536
2537                 exit(EXIT_SUCCESS);
2538         }
2539
2540         if (wait_for_pid(pid))
2541                 goto out;
2542
2543         /* Check ownership through original mount. */
2544         if (!expected_uid_gid(t_dir1_fd, FILE1, 0, 1000, 1000)) {
2545                 log_stderr("failure: expected_uid_gid");
2546                 goto out;
2547         }
2548         if (!expected_uid_gid(t_dir1_fd, FILE2, 0, 1000, 1000)) {
2549                 log_stderr("failure: expected_uid_gid");
2550                 goto out;
2551         }
2552         if (!expected_uid_gid(t_dir1_fd, HARDLINK1, 0, 1000, 1000)) {
2553                 log_stderr("failure: expected_uid_gid");
2554                 goto out;
2555         }
2556         if (!expected_uid_gid(t_dir1_fd, CHRDEV1, 0, 1000, 1000)) {
2557                 log_stderr("failure: expected_uid_gid");
2558                 goto out;
2559         }
2560         if (!expected_uid_gid(t_dir1_fd, SYMLINK1, AT_SYMLINK_NOFOLLOW, 2000, 2000)) {
2561                 log_stderr("failure: expected_uid_gid");
2562                 goto out;
2563         }
2564         if (!expected_uid_gid(t_dir1_fd, SYMLINK1, 0, 1000, 1000)) {
2565                 log_stderr("failure: expected_uid_gid");
2566                 goto out;
2567         }
2568         if (!expected_uid_gid(t_dir1_fd, DIR1, 0, 1000, 1000)) {
2569                 log_stderr("failure: expected_uid_gid");
2570                 goto out;
2571         }
2572
2573         /* Check ownership through first idmapped mount. */
2574         if (!expected_uid_gid(open_tree_fd1, FILE1, 0, 11000, 11000)) {
2575                 log_stderr("failure: expected_uid_gid");
2576                 goto out;
2577         }
2578         if (!expected_uid_gid(open_tree_fd1, FILE2, 0, 11000, 11000)) {
2579                 log_stderr("failure: expected_uid_gid");
2580                 goto out;
2581         }
2582         if (!expected_uid_gid(open_tree_fd1, HARDLINK1, 0, 11000, 11000)) {
2583                 log_stderr("failure: expected_uid_gid");
2584                 goto out;
2585         }
2586         if (!expected_uid_gid(open_tree_fd1, CHRDEV1, 0, 11000, 11000)) {
2587                 log_stderr("failure: expected_uid_gid");
2588                 goto out;
2589         }
2590         if (!expected_uid_gid(open_tree_fd1, SYMLINK1, AT_SYMLINK_NOFOLLOW, 12000, 12000)) {
2591                 log_stderr("failure: expected_uid_gid");
2592                 goto out;
2593         }
2594         if (!expected_uid_gid(open_tree_fd1, SYMLINK1, 0, 11000, 11000)) {
2595                 log_stderr("failure: expected_uid_gid");
2596                 goto out;
2597         }
2598         if (!expected_uid_gid(open_tree_fd1, DIR1, 0, 11000, 11000)) {
2599                 log_stderr("failure: expected_uid_gid");
2600                 goto out;
2601         }
2602
2603         /* Check ownership through second idmapped mount. */
2604         if (!expected_uid_gid(open_tree_fd2, FILE1, 0, 31000, 31000)) {
2605                 log_stderr("failure: expected_uid_gid");
2606                 goto out;
2607         }
2608         if (!expected_uid_gid(open_tree_fd2, FILE2, 0, 31000, 31000)) {
2609                 log_stderr("failure: expected_uid_gid");
2610                 goto out;
2611         }
2612         if (!expected_uid_gid(open_tree_fd2, HARDLINK1, 0, 31000, 31000)) {
2613                 log_stderr("failure: expected_uid_gid");
2614                 goto out;
2615         }
2616         if (!expected_uid_gid(open_tree_fd2, CHRDEV1, 0, 31000, 31000)) {
2617                 log_stderr("failure: expected_uid_gid");
2618                 goto out;
2619         }
2620         if (!expected_uid_gid(open_tree_fd2, SYMLINK1, AT_SYMLINK_NOFOLLOW, 32000, 32000)) {
2621                 log_stderr("failure: expected_uid_gid");
2622                 goto out;
2623         }
2624         if (!expected_uid_gid(open_tree_fd2, SYMLINK1, 0, 31000, 31000)) {
2625                 log_stderr("failure: expected_uid_gid");
2626                 goto out;
2627         }
2628         if (!expected_uid_gid(open_tree_fd2, DIR1, 0, 31000, 31000)) {
2629                 log_stderr("failure: expected_uid_gid");
2630                 goto out;
2631         }
2632
2633         pid = fork();
2634         if (pid < 0) {
2635                 log_stderr("failure: fork");
2636                 goto out;
2637         }
2638         if (pid == 0) {
2639                 if (!switch_userns(attr2.userns_fd, 0, 0, false))
2640                         die("failure: switch_userns");
2641
2642                 if (!fchownat(t_dir1_fd, FILE1, 0, 0, 0))
2643                         die("failure: fchownat");
2644                 if (!fchownat(t_dir1_fd, FILE2, 0, 0, 0))
2645                         die("failure: fchownat");
2646                 if (!fchownat(t_dir1_fd, HARDLINK1, 0, 0, 0))
2647                         die("failure: fchownat");
2648                 if (!fchownat(t_dir1_fd, CHRDEV1, 0, 0, 0))
2649                         die("failure: fchownat");
2650                 if (!fchownat(t_dir1_fd, SYMLINK1, 3000, 3000, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW))
2651                         die("failure: fchownat");
2652                 if (!fchownat(t_dir1_fd, SYMLINK1, 0, 0, AT_EMPTY_PATH))
2653                         die("failure: fchownat");
2654                 if (!fchownat(t_dir1_fd, DIR1, 0, 0, AT_EMPTY_PATH))
2655                         die("failure: fchownat");
2656
2657                 if (!fchownat(open_tree_fd1, FILE1, 0, 0, 0))
2658                         die("failure: fchownat");
2659                 if (!fchownat(open_tree_fd1, FILE2, 0, 0, 0))
2660                         die("failure: fchownat");
2661                 if (!fchownat(open_tree_fd1, HARDLINK1, 0, 0, 0))
2662                         die("failure: fchownat");
2663                 if (!fchownat(open_tree_fd1, CHRDEV1, 0, 0, 0))
2664                         die("failure: fchownat");
2665                 if (!fchownat(open_tree_fd1, SYMLINK1, 3000, 3000, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW))
2666                         die("failure: fchownat");
2667                 if (!fchownat(open_tree_fd1, SYMLINK1, 0, 0, AT_EMPTY_PATH))
2668                         die("failure: fchownat");
2669                 if (!fchownat(open_tree_fd1, DIR1, 0, 0, AT_EMPTY_PATH))
2670                         die("failure: fchownat");
2671
2672                 if (fchownat(open_tree_fd2, FILE1, 0, 0, 0))
2673                         die("failure: fchownat");
2674                 if (fchownat(open_tree_fd2, FILE2, 0, 0, 0))
2675                         die("failure: fchownat");
2676                 if (fchownat(open_tree_fd2, HARDLINK1, 0, 0, 0))
2677                         die("failure: fchownat");
2678                 if (fchownat(open_tree_fd2, CHRDEV1, 0, 0, 0))
2679                         die("failure: fchownat");
2680                 if (!fchownat(open_tree_fd2, SYMLINK1, 3000, 3000, AT_EMPTY_PATH | AT_SYMLINK_NOFOLLOW))
2681                         die("failure: fchownat");
2682                 if (fchownat(open_tree_fd2, SYMLINK1, 0, 0, AT_EMPTY_PATH))
2683                         die("failure: fchownat");
2684                 if (fchownat(open_tree_fd2, DIR1, 0, 0, AT_EMPTY_PATH))
2685                         die("failure: fchownat");
2686
2687                 if (!expected_uid_gid(t_dir1_fd, FILE1, 0, t_overflowuid, t_overflowgid))
2688                         die("failure: expected_uid_gid");
2689                 if (!expected_uid_gid(t_dir1_fd, FILE2, 0, t_overflowuid, t_overflowgid))
2690                         die("failure: expected_uid_gid");
2691                 if (!expected_uid_gid(t_dir1_fd, HARDLINK1, 0, t_overflowuid, t_overflowgid))
2692                         die("failure: expected_uid_gid");
2693                 if (!expected_uid_gid(t_dir1_fd, CHRDEV1, 0, t_overflowuid, t_overflowgid))
2694                         die("failure: expected_uid_gid");
2695                 if (!expected_uid_gid(t_dir1_fd, SYMLINK1, AT_SYMLINK_NOFOLLOW, t_overflowuid, t_overflowgid))
2696                         die("failure: expected_uid_gid");
2697                 if (!expected_uid_gid(t_dir1_fd, SYMLINK1, 0, t_overflowuid, t_overflowgid))
2698                         die("failure: expected_uid_gid");
2699                 if (!expected_uid_gid(t_dir1_fd, DIR1, 0, t_overflowuid, t_overflowgid))
2700                         die("failure: expected_uid_gid");
2701
2702                 if (!expected_uid_gid(open_tree_fd1, FILE1, 0, t_overflowuid, t_overflowgid))
2703                         die("failure: expected_uid_gid");
2704                 if (!expected_uid_gid(open_tree_fd1, FILE2, 0, t_overflowuid, t_overflowgid))
2705                         die("failure: expected_uid_gid");
2706                 if (!expected_uid_gid(open_tree_fd1, HARDLINK1, 0, t_overflowuid, t_overflowgid))
2707                         die("failure: expected_uid_gid");
2708                 if (!expected_uid_gid(open_tree_fd1, CHRDEV1, 0, t_overflowuid, t_overflowgid))
2709                         die("failure: expected_uid_gid");
2710                 if (!expected_uid_gid(open_tree_fd1, SYMLINK1, AT_SYMLINK_NOFOLLOW, t_overflowuid, t_overflowgid))
2711                         die("failure: expected_uid_gid");
2712                 if (!expected_uid_gid(open_tree_fd1, SYMLINK1, 0, t_overflowuid, t_overflowgid))
2713                         die("failure: expected_uid_gid");
2714                 if (!expected_uid_gid(open_tree_fd1, DIR1, 0, t_overflowuid, t_overflowgid))
2715                         die("failure: expected_uid_gid");
2716
2717                 if (!expected_uid_gid(open_tree_fd2, FILE1, 0, 0, 0))
2718                         die("failure: expected_uid_gid");
2719                 if (!expected_uid_gid(open_tree_fd2, FILE2, 0, 0, 0))
2720                         die("failure: expected_uid_gid");
2721                 if (!expected_uid_gid(open_tree_fd2, HARDLINK1, 0, 0, 0))
2722                         die("failure: expected_uid_gid");
2723                 if (!expected_uid_gid(open_tree_fd2, CHRDEV1, 0, 0, 0))
2724                         die("failure: expected_uid_gid");
2725                 if (!expected_uid_gid(open_tree_fd2, SYMLINK1, AT_SYMLINK_NOFOLLOW, 2000, 2000))
2726                         die("failure: expected_uid_gid");
2727                 if (!expected_uid_gid(open_tree_fd2, SYMLINK1, 0, 0, 0))
2728                         die("failure: expected_uid_gid");
2729                 if (!expected_uid_gid(open_tree_fd2, DIR1, 0, 0, 0))
2730                         die("failure: expected_uid_gid");
2731
2732                 exit(EXIT_SUCCESS);
2733         }
2734
2735         if (wait_for_pid(pid))
2736                 goto out;
2737
2738         /* Check ownership through original mount. */
2739         if (!expected_uid_gid(t_dir1_fd, FILE1, 0, 0, 0)) {
2740                 log_stderr("failure: expected_uid_gid");
2741                 goto out;
2742         }
2743         if (!expected_uid_gid(t_dir1_fd, FILE2, 0, 0, 0)) {
2744                 log_stderr("failure: expected_uid_gid");
2745                 goto out;
2746         }
2747         if (!expected_uid_gid(t_dir1_fd, HARDLINK1, 0, 0, 0)) {
2748                 log_stderr("failure: expected_uid_gid");
2749                 goto out;
2750         }
2751         if (!expected_uid_gid(t_dir1_fd, CHRDEV1, 0, 0, 0)) {
2752                 log_stderr("failure: expected_uid_gid");
2753                 goto out;
2754         }
2755         if (!expected_uid_gid(t_dir1_fd, SYMLINK1, AT_SYMLINK_NOFOLLOW, 2000, 2000)) {
2756                 log_stderr("failure: expected_uid_gid");
2757                 goto out;
2758         }
2759         if (!expected_uid_gid(t_dir1_fd, SYMLINK1, 0, 0, 0)) {
2760                 log_stderr("failure: expected_uid_gid");
2761                 goto out;
2762         }
2763         if (!expected_uid_gid(t_dir1_fd, DIR1, 0, 0, 0)) {
2764                 log_stderr("failure: expected_uid_gid");
2765                 goto out;
2766         }
2767
2768         /* Check ownership through first idmapped mount. */
2769         if (!expected_uid_gid(open_tree_fd1, FILE1, 0, 10000, 10000)) {
2770                 log_stderr("failure: expected_uid_gid");
2771                 goto out;
2772         }
2773         if (!expected_uid_gid(open_tree_fd1, FILE2, 0, 10000, 10000)) {
2774                 log_stderr("failure: expected_uid_gid");
2775                 goto out;
2776         }
2777         if (!expected_uid_gid(open_tree_fd1, HARDLINK1, 0, 10000, 10000)) {
2778                 log_stderr("failure: expected_uid_gid");
2779                 goto out;
2780         }
2781         if (!expected_uid_gid(open_tree_fd1, CHRDEV1, 0, 10000, 10000)) {
2782                 log_stderr("failure: expected_uid_gid");
2783                 goto out;
2784         }
2785         if (!expected_uid_gid(open_tree_fd1, SYMLINK1, AT_SYMLINK_NOFOLLOW, 12000, 12000)) {
2786                 log_stderr("failure: expected_uid_gid");
2787                 goto out;
2788         }
2789         if (!expected_uid_gid(open_tree_fd1, SYMLINK1, 0, 10000, 10000)) {
2790                 log_stderr("failure: expected_uid_gid");
2791                 goto out;
2792         }
2793         if (!expected_uid_gid(open_tree_fd1, DIR1, 0, 10000, 10000)) {
2794                 log_stderr("failure: expected_uid_gid");
2795                 goto out;
2796         }
2797
2798         /* Check ownership through second idmapped mount. */
2799         if (!expected_uid_gid(open_tree_fd2, FILE1, 0, 30000, 30000)) {
2800                 log_stderr("failure: expected_uid_gid");
2801                 goto out;
2802         }
2803         if (!expected_uid_gid(open_tree_fd2, FILE2, 0, 30000, 30000)) {
2804                 log_stderr("failure: expected_uid_gid");
2805                 goto out;
2806         }
2807         if (!expected_uid_gid(open_tree_fd2, HARDLINK1, 0, 30000, 30000)) {
2808                 log_stderr("failure: expected_uid_gid");
2809                 goto out;
2810         }
2811         if (!expected_uid_gid(open_tree_fd2, CHRDEV1, 0, 30000, 30000)) {
2812                 log_stderr("failure: expected_uid_gid");
2813                 goto out;
2814         }
2815         if (!expected_uid_gid(open_tree_fd2, SYMLINK1, AT_SYMLINK_NOFOLLOW, 32000, 32000)) {
2816                 log_stderr("failure: expected_uid_gid");
2817                 goto out;
2818         }
2819         if (!expected_uid_gid(open_tree_fd2, SYMLINK1, 0, 30000, 30000)) {
2820                 log_stderr("failure: expected_uid_gid");
2821                 goto out;
2822         }
2823         if (!expected_uid_gid(open_tree_fd2, DIR1, 0, 30000, 30000)) {
2824                 log_stderr("failure: expected_uid_gid");
2825                 goto out;
2826         }
2827
2828         fret = 0;
2829         log_debug("Ran test");
2830 out:
2831         safe_close(attr1.userns_fd);
2832         safe_close(attr2.userns_fd);
2833         safe_close(file1_fd);
2834         safe_close(open_tree_fd1);
2835         safe_close(open_tree_fd2);
2836
2837         return fret;
2838 }
2839
2840 static int fscaps(void)
2841 {
2842         int fret = -1;
2843         int file1_fd = -EBADF;
2844         struct mount_attr attr = {
2845                 .attr_set = MOUNT_ATTR_IDMAP,
2846         };
2847         pid_t pid;
2848
2849         file1_fd = openat(t_dir1_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
2850         if (file1_fd < 0) {
2851                 log_stderr("failure: openat");
2852                 goto out;
2853         }
2854
2855         /* Skip if vfs caps are unsupported. */
2856         if (set_dummy_vfs_caps(file1_fd, 0, 1000))
2857                 return 0;
2858
2859         /* Changing mount properties on a detached mount. */
2860         attr.userns_fd  = get_userns_fd(0, 10000, 10000);
2861         if (attr.userns_fd < 0) {
2862                 log_stderr("failure: get_userns_fd");
2863                 goto out;
2864         }
2865
2866         if (!expected_dummy_vfs_caps_uid(file1_fd, 1000)) {
2867                 log_stderr("failure: expected_dummy_vfs_caps_uid");
2868                 goto out;
2869         }
2870
2871         pid = fork();
2872         if (pid < 0) {
2873                 log_stderr("failure: fork");
2874                 goto out;
2875         }
2876         if (pid == 0) {
2877                 if (!switch_userns(attr.userns_fd, 0, 0, false))
2878                         die("failure: switch_userns");
2879
2880                 /*
2881                  * On kernels before 5.12 this would succeed and return the
2882                  * unconverted caps. Then - for whatever reason - this behavior
2883                  * got changed and since 5.12 EOVERFLOW is returned when the
2884                  * rootid stored alongside the vfs caps does not map to uid 0 in
2885                  * the caller's user namespace.
2886                  */
2887                 if (!expected_dummy_vfs_caps_uid(file1_fd, 1000) && errno != EOVERFLOW)
2888                         die("failure: expected_dummy_vfs_caps_uid");
2889
2890                 exit(EXIT_SUCCESS);
2891         }
2892
2893         if (wait_for_pid(pid))
2894                 goto out;
2895
2896         if (fremovexattr(file1_fd, "security.capability")) {
2897                 log_stderr("failure: fremovexattr");
2898                 goto out;
2899         }
2900         if (expected_dummy_vfs_caps_uid(file1_fd, -1)) {
2901                 log_stderr("failure: expected_dummy_vfs_caps_uid");
2902                 goto out;
2903         }
2904         if (errno != ENODATA) {
2905                 log_stderr("failure: errno");
2906                 goto out;
2907         }
2908
2909         if (set_dummy_vfs_caps(file1_fd, 0, 10000)) {
2910                 log_stderr("failure: set_dummy_vfs_caps");
2911                 goto out;
2912         }
2913
2914         if (!expected_dummy_vfs_caps_uid(file1_fd, 10000)) {
2915                 log_stderr("failure: expected_dummy_vfs_caps_uid");
2916                 goto out;
2917         }
2918
2919         pid = fork();
2920         if (pid < 0) {
2921                 log_stderr("failure: fork");
2922                 goto out;
2923         }
2924         if (pid == 0) {
2925                 if (!switch_userns(attr.userns_fd, 0, 0, false))
2926                         die("failure: switch_userns");
2927
2928                 if (!expected_dummy_vfs_caps_uid(file1_fd, 0))
2929                         die("failure: expected_dummy_vfs_caps_uid");
2930
2931                 exit(EXIT_SUCCESS);
2932         }
2933
2934         if (wait_for_pid(pid))
2935                 goto out;
2936
2937         if (fremovexattr(file1_fd, "security.capability")) {
2938                 log_stderr("failure: fremovexattr");
2939                 goto out;
2940         }
2941         if (expected_dummy_vfs_caps_uid(file1_fd, -1)) {
2942                 log_stderr("failure: expected_dummy_vfs_caps_uid");
2943                 goto out;
2944         }
2945         if (errno != ENODATA) {
2946                 log_stderr("failure: errno");
2947                 goto out;
2948         }
2949
2950         fret = 0;
2951         log_debug("Ran test");
2952 out:
2953         safe_close(attr.userns_fd);
2954         safe_close(file1_fd);
2955
2956         return fret;
2957 }
2958
2959 static int fscaps_idmapped_mounts(void)
2960 {
2961         int fret = -1;
2962         int file1_fd = -EBADF, file1_fd2 = -EBADF, open_tree_fd = -EBADF;
2963         struct mount_attr attr = {
2964                 .attr_set = MOUNT_ATTR_IDMAP,
2965         };
2966         pid_t pid;
2967
2968         file1_fd = openat(t_dir1_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
2969         if (file1_fd < 0) {
2970                 log_stderr("failure: openat");
2971                 goto out;
2972         }
2973
2974         /* Skip if vfs caps are unsupported. */
2975         if (set_dummy_vfs_caps(file1_fd, 0, 1000))
2976                 return 0;
2977
2978         if (fremovexattr(file1_fd, "security.capability")) {
2979                 log_stderr("failure: fremovexattr");
2980                 goto out;
2981         }
2982
2983         /* Changing mount properties on a detached mount. */
2984         attr.userns_fd  = get_userns_fd(0, 10000, 10000);
2985         if (attr.userns_fd < 0) {
2986                 log_stderr("failure: get_userns_fd");
2987                 goto out;
2988         }
2989
2990         open_tree_fd = sys_open_tree(t_dir1_fd, "",
2991                                      AT_EMPTY_PATH |
2992                                      AT_NO_AUTOMOUNT |
2993                                      AT_SYMLINK_NOFOLLOW |
2994                                      OPEN_TREE_CLOEXEC |
2995                                      OPEN_TREE_CLONE);
2996         if (open_tree_fd < 0) {
2997                 log_stderr("failure: sys_open_tree");
2998                 goto out;
2999         }
3000
3001         if (sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
3002                 log_stderr("failure: sys_mount_setattr");
3003                 goto out;
3004         }
3005
3006         file1_fd2 = openat(open_tree_fd, FILE1, O_RDWR | O_CLOEXEC, 0);
3007         if (file1_fd2 < 0) {
3008                 log_stderr("failure: openat");
3009                 goto out;
3010         }
3011
3012         if (!set_dummy_vfs_caps(file1_fd2, 0, 1000)) {
3013                 log_stderr("failure: set_dummy_vfs_caps");
3014                 goto out;
3015         }
3016
3017         if (set_dummy_vfs_caps(file1_fd2, 0, 10000)) {
3018                 log_stderr("failure: set_dummy_vfs_caps");
3019                 goto out;
3020         }
3021
3022         if (!expected_dummy_vfs_caps_uid(file1_fd2, 10000)) {
3023                 log_stderr("failure: expected_dummy_vfs_caps_uid");
3024                 goto out;
3025         }
3026
3027         if (!expected_dummy_vfs_caps_uid(file1_fd, 0)) {
3028                 log_stderr("failure: expected_dummy_vfs_caps_uid");
3029                 goto out;
3030         }
3031
3032         pid = fork();
3033         if (pid < 0) {
3034                 log_stderr("failure: fork");
3035                 goto out;
3036         }
3037         if (pid == 0) {
3038                 if (!switch_userns(attr.userns_fd, 0, 0, false))
3039                         die("failure: switch_userns");
3040
3041                 if (!expected_dummy_vfs_caps_uid(file1_fd2, 0))
3042                         die("failure: expected_dummy_vfs_caps_uid");
3043
3044                 exit(EXIT_SUCCESS);
3045         }
3046
3047         if (wait_for_pid(pid))
3048                 goto out;
3049
3050         if (fremovexattr(file1_fd2, "security.capability")) {
3051                 log_stderr("failure: fremovexattr");
3052                 goto out;
3053         }
3054         if (expected_dummy_vfs_caps_uid(file1_fd2, -1)) {
3055                 log_stderr("failure: expected_dummy_vfs_caps_uid");
3056                 goto out;
3057         }
3058         if (errno != ENODATA) {
3059                 log_stderr("failure: errno");
3060                 goto out;
3061         }
3062
3063         if (set_dummy_vfs_caps(file1_fd2, 0, 12000)) {
3064                 log_stderr("failure: set_dummy_vfs_caps");
3065                 goto out;
3066         }
3067
3068         if (!expected_dummy_vfs_caps_uid(file1_fd2, 12000)) {
3069                 log_stderr("failure: expected_dummy_vfs_caps_uid");
3070                 goto out;
3071         }
3072
3073         if (!expected_dummy_vfs_caps_uid(file1_fd, 2000)) {
3074                 log_stderr("failure: expected_dummy_vfs_caps_uid");
3075                 goto out;
3076         }
3077
3078         pid = fork();
3079         if (pid < 0) {
3080                 log_stderr("failure: fork");
3081                 goto out;
3082         }
3083         if (pid == 0) {
3084                 if (!switch_userns(attr.userns_fd, 0, 0, false))
3085                         die("failure: switch_userns");
3086
3087                 if (!expected_dummy_vfs_caps_uid(file1_fd2, 2000))
3088                         die("failure: expected_dummy_vfs_caps_uid");
3089
3090                 exit(EXIT_SUCCESS);
3091         }
3092
3093         if (wait_for_pid(pid))
3094                 goto out;
3095
3096         fret = 0;
3097         log_debug("Ran test");
3098 out:
3099         safe_close(attr.userns_fd);
3100         safe_close(file1_fd);
3101         safe_close(file1_fd2);
3102         safe_close(open_tree_fd);
3103
3104         return fret;
3105 }
3106
3107 static int fscaps_idmapped_mounts_in_userns(void)
3108 {
3109         int fret = -1;
3110         int file1_fd = -EBADF, file1_fd2 = -EBADF, open_tree_fd = -EBADF;
3111         struct mount_attr attr = {
3112                 .attr_set = MOUNT_ATTR_IDMAP,
3113         };
3114         pid_t pid;
3115
3116         file1_fd = openat(t_dir1_fd, FILE1, O_CREAT | O_EXCL | O_CLOEXEC, 0644);
3117         if (file1_fd < 0) {
3118                 log_stderr("failure: openat");
3119                 goto out;
3120         }
3121
3122         /* Skip if vfs caps are unsupported. */
3123         if (set_dummy_vfs_caps(file1_fd, 0, 1000))
3124                 return 0;
3125
3126         if (fremovexattr(file1_fd, "security.capability")) {
3127                 log_stderr("failure: fremovexattr");
3128                 goto out;
3129         }
3130
3131         /* Changing mount properties on a detached mount. */
3132         attr.userns_fd  = get_userns_fd(0, 10000, 10000);
3133         if (attr.userns_fd < 0) {
3134                 log_stderr("failure: get_userns_fd");
3135                 goto out;
3136         }
3137
3138         open_tree_fd = sys_open_tree(t_dir1_fd, "",
3139                                      AT_EMPTY_PATH |
3140                                      AT_NO_AUTOMOUNT |
3141                                      AT_SYMLINK_NOFOLLOW |
3142                                      OPEN_TREE_CLOEXEC |
3143                                      OPEN_TREE_CLONE);
3144         if (open_tree_fd < 0) {
3145                 log_stderr("failure: sys_open_tree");
3146                 goto out;
3147         }
3148
3149         if (sys_mount_setattr(open_tree_fd, "", AT_EMPTY_PATH, &attr, sizeof(attr))) {
3150                 log_stderr("failure: sys_mount_setattr");
3151                 goto out;
3152         }
3153
3154         file1_fd2 = openat(open_tree_fd, FILE1, O_RDWR | O_CLOEXEC, 0);
3155         if (file1_fd2 < 0) {
3156                 log_stderr("failure: openat");
3157                 goto out;
3158         }
3159
3160         pid = fork();
3161         if (pid < 0) {
3162                 log_stderr("failure: fork");
3163                 goto out;
3164         }
3165         if (pid == 0) {
3166                 if (!switch_userns(attr.userns_fd, 0, 0, false))
3167                         die("failure: switch_userns");
3168
3169                 if (expected_dummy_vfs_caps_uid(file1_fd2, -1))
3170                         die("failure: expected_dummy_vfs_caps_uid");
3171                 if (errno != ENODATA)
3172                         die("failure: errno");
3173
3174                 if (set_dummy_vfs_caps(file1_fd2, 0, 1000))
3175                         die("failure: set_dummy_vfs_caps");
3176
3177                 if (!expected_dummy_vfs_caps_uid(file1_fd2, 1000))
3178                         die("failure: expected_dummy_vfs_caps_uid");
3179
3180                 if (!expected_dummy_vfs_caps_uid(file1_fd, 1000) && errno != EOVERFLOW)
3181                         die("failure: expected_dummy_vfs_caps_uid");
3182
3183                 exit(EXIT_SUCCESS);
3184         }
3185
3186         if (wait_for_pid(pid))
3187                 goto out;
3188
3189         if (!expected_dummy_vfs_caps_uid(file1_fd, 1000)) {
3190                 log_stderr("failure: expected_dummy_vfs_caps_uid");
3191                 goto out;
3192         }
3193
3194         fret = 0;
3195         log_debug("Ran test");
3196 out:
3197         safe_close(attr.userns_fd);
3198         safe_close(file1_fd);
3199         safe_close(file1_fd2);
3200         safe_close(open_tree_fd);
3201
3202         return fret;