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