7 #include "capsicum-test.h"
10 #define TOPDIR "cap_copy_file_range"
11 #define INFILE "infile"
12 #define OUTFILE "outfile"
14 /* Test that copy_file_range() checks capabilities correctly.
15 * When used without offset arguments, copy_file_range() should
16 * require only CAP_READ on the source and CAP_WRITE on the destination
17 * file descriptors, respectively.
18 * When used with offset arguments, copy_file_range() should
19 * additionally require CAP_SEEK.
21 class CopyFileRangeTest : public ::testing::Test {
24 int rc = mkdir(TmpFile(TOPDIR), 0755);
27 EXPECT_EQ(EEXIST, errno);
29 wd_ = open(TmpFile(TOPDIR), O_DIRECTORY);
31 CreateFile(TmpFile(TOPDIR "/" INFILE));
32 CreateFile(TmpFile(TOPDIR "/" OUTFILE));
34 ~CopyFileRangeTest() {
36 unlink(TmpFile(TOPDIR "/" INFILE));
37 unlink(TmpFile(TOPDIR "/" OUTFILE));
38 rmdir(TmpFile(TOPDIR));
42 void CreateFile(const char *filename) {
43 int fd = open(filename, O_CREAT|O_RDWR, 0644);
44 const char *contents = "lorem ipsum dolor sit amet";
46 for (int i = 0; i < 100; i++) {
47 EXPECT_OK(write(fd, contents, strlen(contents)));
55 int openInFile(cap_rights_t *rights) {
56 int fd = openat(wd_, INFILE, O_RDONLY);
58 EXPECT_OK(cap_rights_limit(fd, rights));
61 int openOutFile(cap_rights_t *rights) {
62 int fd = openat(wd_, OUTFILE, O_WRONLY);
64 EXPECT_OK(cap_rights_limit(fd, rights));
69 TEST_F(CopyFileRangeTest, WriteReadNeg) {
70 cap_rights_t rights_in, rights_out;
72 cap_rights_init(&rights_in, CAP_WRITE);
73 cap_rights_init(&rights_out, CAP_READ);
75 int fd_in = openInFile(&rights_in);
76 int fd_out = openOutFile(&rights_out);
77 off_t off_in = 0, off_out = 0;
79 EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0));
80 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
81 EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
82 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));
85 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
86 EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
87 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));
92 TEST_F(CopyFileRangeTest, ReadReadNeg) {
93 cap_rights_t rights_in, rights_out;
95 cap_rights_init(&rights_in, CAP_READ);
96 cap_rights_init(&rights_out, CAP_READ);
98 int fd_in = openInFile(&rights_in);
99 int fd_out = openOutFile(&rights_out);
100 off_t off_in = 0, off_out = 0;
102 EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0));
103 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
104 EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
105 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));
108 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
109 EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
110 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));
115 TEST_F(CopyFileRangeTest, WriteWriteNeg) {
116 cap_rights_t rights_in, rights_out;
118 cap_rights_init(&rights_in, CAP_WRITE);
119 cap_rights_init(&rights_out, CAP_WRITE);
121 int fd_in = openInFile(&rights_in);
122 int fd_out = openOutFile(&rights_out);
123 off_t off_in = 0, off_out = 0;
125 EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0));
126 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
127 EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
128 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));
131 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
132 EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
133 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));
138 TEST_F(CopyFileRangeTest, ReadWrite) {
139 cap_rights_t rights_in, rights_out;
141 cap_rights_init(&rights_in, CAP_READ);
142 cap_rights_init(&rights_out, CAP_WRITE);
144 int fd_in = openInFile(&rights_in);
145 int fd_out = openOutFile(&rights_out);
146 off_t off_in = 0, off_out = 0;
148 EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0));
149 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
150 EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
151 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));
154 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
155 EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
156 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));
161 TEST_F(CopyFileRangeTest, ReadSeekWrite) {
162 cap_rights_t rights_in, rights_out;
164 cap_rights_init(&rights_in, CAP_READ, CAP_SEEK);
165 cap_rights_init(&rights_out, CAP_WRITE);
167 int fd_in = openInFile(&rights_in);
168 int fd_out = openOutFile(&rights_out);
169 off_t off_in = 0, off_out = 0;
171 EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0));
172 EXPECT_OK(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
173 EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
174 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));
177 EXPECT_OK(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
178 EXPECT_NOTCAPABLE(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
179 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));
184 TEST_F(CopyFileRangeTest, ReadWriteSeek) {
185 cap_rights_t rights_in, rights_out;
187 cap_rights_init(&rights_in, CAP_READ);
188 cap_rights_init(&rights_out, CAP_WRITE, CAP_SEEK);
190 int fd_in = openInFile(&rights_in);
191 int fd_out = openOutFile(&rights_out);
192 off_t off_in = 0, off_out = 0;
194 EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0));
195 EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
196 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
197 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));
200 EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
201 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
202 EXPECT_NOTCAPABLE(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));
207 TEST_F(CopyFileRangeTest, ReadSeekWriteSeek) {
208 cap_rights_t rights_in, rights_out;
210 cap_rights_init(&rights_in, CAP_READ, CAP_SEEK);
211 cap_rights_init(&rights_out, CAP_WRITE, CAP_SEEK);
213 int fd_in = openInFile(&rights_in);
214 int fd_out = openOutFile(&rights_out);
215 off_t off_in = 0, off_out = 0;
217 EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, NULL, 8, 0));
218 EXPECT_OK(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
219 EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
220 EXPECT_OK(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));
223 EXPECT_OK(copy_file_range(fd_in, NULL, fd_out, &off_out, 8, 0));
224 EXPECT_OK(copy_file_range(fd_in, &off_in, fd_out, NULL, 8, 0));
225 EXPECT_OK(copy_file_range(fd_in, &off_in, fd_out, &off_out, 8, 0));