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