1 /*
2 * Check decoding of fchownat syscall.
3 *
4 * Copyright (c) 2016-2018 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2016-2021 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "tests.h"
12 #include "scno.h"
13 #include <fcntl.h>
14
15 #if defined AT_FDCWD && defined AT_SYMLINK_NOFOLLOW
16
17 # include <stdio.h>
18 # include <unistd.h>
19
20 # include "secontext.h"
21
22 int
23 main(void)
24 {
25 /*
26 * Make sure the current workdir of the tracee
27 * is different from the current workdir of the tracer.
28 */
29 create_and_enter_subdir("fchownat_subdir");
30
31 char *my_secontext = SECONTEXT_PID_MY();
32 uid_t uid = geteuid();
33 uid_t gid = getegid();
34
35 static const char sample[] = "fchownat_sample";
36 int fd = open(sample, O_RDONLY | O_CREAT, 0400);
37 if (fd == -1)
38 perror_msg_and_fail("open");
39 close(fd);
40
41 char *sample_secontext = SECONTEXT_FILE(sample);
42
43 /*
44 * Tests with AT_FDCWD.
45 */
46
47 long rc = syscall(__NR_fchownat, AT_FDCWD, sample, uid, gid, 0);
48 printf("%s%s(AT_FDCWD, \"%s\"%s, %d, %d, 0) = %s\n",
49 my_secontext, "fchownat",
50 sample, sample_secontext,
51 uid, gid, sprintrc(rc));
52
53 if (unlink(sample))
54 perror_msg_and_fail("unlink");
55
56 rc = syscall(__NR_fchownat, AT_FDCWD,
57 sample, -1, -1L, AT_SYMLINK_NOFOLLOW);
58 printf("%s%s(AT_FDCWD, \"%s\", -1, -1, AT_SYMLINK_NOFOLLOW) = %s\n",
59 my_secontext, "fchownat",
60 sample, sprintrc(rc));
61
62 /*
63 * Tests with dirfd.
64 */
65
66 int cwd_fd = get_dir_fd(".");
67 char *cwd = get_fd_path(cwd_fd);
68 char *cwd_secontext = SECONTEXT_FILE(".");
69 char *sample_realpath = xasprintf("%s/%s", cwd, sample);
70
71 /* no file */
72 rc = syscall(__NR_fchownat, cwd_fd, sample, uid, gid, 0);
73 printf("%s%s(%d%s, \"%s\", %d, %d, 0) = %s\n",
74 my_secontext, "fchownat",
75 cwd_fd, cwd_secontext,
76 sample,
77 uid, gid,
78 sprintrc(rc));
79
80 fd = open(sample, O_RDONLY | O_CREAT, 0400);
81 if (fd == -1)
82 perror_msg_and_fail("open");
83 close(fd);
84
85 rc = syscall(__NR_fchownat, cwd_fd, sample, uid, gid, 0);
86 printf("%s%s(%d%s, \"%s\"%s, %d, %d, 0) = %s\n",
87 my_secontext, "fchownat",
88 cwd_fd, cwd_secontext,
89 sample, sample_secontext,
90 uid, gid,
91 sprintrc(rc));
92
93 /* cwd_fd ignored when path is absolute */
94 if (chdir("../.."))
95 perror_msg_and_fail("chdir");
96
97 rc = syscall(__NR_fchownat, cwd_fd, sample_realpath, uid, gid, 0);
98 printf("%s%s(%d%s, \"%s\"%s, %d, %d, 0) = %s\n",
99 my_secontext, "fchownat",
100 cwd_fd, cwd_secontext,
101 sample_realpath, sample_secontext,
102 uid, gid,
103 sprintrc(rc));
104
105 if (fchdir(cwd_fd))
106 perror_msg_and_fail("fchdir");
107
108 if (unlink(sample))
109 perror_msg_and_fail("unlink");
110
111 leave_and_remove_subdir();
112
113 puts("+++ exited with 0 +++");
114 return 0;
115 }
116
117 #else
118
119 SKIP_MAIN_UNDEFINED("AT_FDCWD && AT_SYMLINK_NOFOLLOW")
120
121 #endif