Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/capsicum-test/copy_file_range.cc
39475 views
1
#include <sys/types.h>
2
#include <fcntl.h>
3
4
#include <string>
5
6
#include "capsicum.h"
7
#include "capsicum-test.h"
8
#include "syscalls.h"
9
10
#define TOPDIR "cap_copy_file_range"
11
#define INFILE "infile"
12
#define OUTFILE "outfile"
13
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.
20
*/
21
class CopyFileRangeTest : public ::testing::Test {
22
public:
23
CopyFileRangeTest() {
24
int rc = mkdir(TmpFile(TOPDIR), 0755);
25
EXPECT_OK(rc);
26
if (rc < 0) {
27
EXPECT_EQ(EEXIST, errno);
28
}
29
wd_ = open(TmpFile(TOPDIR), O_DIRECTORY);
30
EXPECT_OK(wd_);
31
CreateFile(TmpFile(TOPDIR "/" INFILE));
32
CreateFile(TmpFile(TOPDIR "/" OUTFILE));
33
}
34
~CopyFileRangeTest() {
35
close(wd_);
36
unlink(TmpFile(TOPDIR "/" INFILE));
37
unlink(TmpFile(TOPDIR "/" OUTFILE));
38
rmdir(TmpFile(TOPDIR));
39
}
40
41
private:
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";
45
EXPECT_OK(fd);
46
for (int i = 0; i < 100; i++) {
47
EXPECT_OK(write(fd, contents, strlen(contents)));
48
}
49
close(fd);
50
}
51
52
protected:
53
int wd_;
54
55
int openInFile(cap_rights_t *rights) {
56
int fd = openat(wd_, INFILE, O_RDONLY);
57
EXPECT_OK(fd);
58
EXPECT_OK(cap_rights_limit(fd, rights));
59
return fd;
60
}
61
int openOutFile(cap_rights_t *rights) {
62
int fd = openat(wd_, OUTFILE, O_WRONLY);
63
EXPECT_OK(fd);
64
EXPECT_OK(cap_rights_limit(fd, rights));
65
return fd;
66
}
67
};
68
69
TEST_F(CopyFileRangeTest, WriteReadNeg) {
70
cap_rights_t rights_in, rights_out;
71
72
cap_rights_init(&rights_in, CAP_WRITE);
73
cap_rights_init(&rights_out, CAP_READ);
74
75
int fd_in = openInFile(&rights_in);
76
int fd_out = openOutFile(&rights_out);
77
off_t off_in = 0, off_out = 0;
78
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));
83
off_in = 20;
84
off_out = 20;
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));
88
close(fd_in);
89
close(fd_out);
90
}
91
92
TEST_F(CopyFileRangeTest, ReadReadNeg) {
93
cap_rights_t rights_in, rights_out;
94
95
cap_rights_init(&rights_in, CAP_READ);
96
cap_rights_init(&rights_out, CAP_READ);
97
98
int fd_in = openInFile(&rights_in);
99
int fd_out = openOutFile(&rights_out);
100
off_t off_in = 0, off_out = 0;
101
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));
106
off_in = 20;
107
off_out = 20;
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));
111
close(fd_in);
112
close(fd_out);
113
}
114
115
TEST_F(CopyFileRangeTest, WriteWriteNeg) {
116
cap_rights_t rights_in, rights_out;
117
118
cap_rights_init(&rights_in, CAP_WRITE);
119
cap_rights_init(&rights_out, CAP_WRITE);
120
121
int fd_in = openInFile(&rights_in);
122
int fd_out = openOutFile(&rights_out);
123
off_t off_in = 0, off_out = 0;
124
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));
129
off_in = 20;
130
off_out = 20;
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));
134
close(fd_in);
135
close(fd_out);
136
}
137
138
TEST_F(CopyFileRangeTest, ReadWrite) {
139
cap_rights_t rights_in, rights_out;
140
141
cap_rights_init(&rights_in, CAP_READ);
142
cap_rights_init(&rights_out, CAP_WRITE);
143
144
int fd_in = openInFile(&rights_in);
145
int fd_out = openOutFile(&rights_out);
146
off_t off_in = 0, off_out = 0;
147
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));
152
off_in = 20;
153
off_out = 20;
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));
157
close(fd_in);
158
close(fd_out);
159
}
160
161
TEST_F(CopyFileRangeTest, ReadSeekWrite) {
162
cap_rights_t rights_in, rights_out;
163
164
cap_rights_init(&rights_in, CAP_READ, CAP_SEEK);
165
cap_rights_init(&rights_out, CAP_WRITE);
166
167
int fd_in = openInFile(&rights_in);
168
int fd_out = openOutFile(&rights_out);
169
off_t off_in = 0, off_out = 0;
170
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));
175
off_in = 20;
176
off_out = 20;
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));
180
close(fd_in);
181
close(fd_out);
182
}
183
184
TEST_F(CopyFileRangeTest, ReadWriteSeek) {
185
cap_rights_t rights_in, rights_out;
186
187
cap_rights_init(&rights_in, CAP_READ);
188
cap_rights_init(&rights_out, CAP_WRITE, CAP_SEEK);
189
190
int fd_in = openInFile(&rights_in);
191
int fd_out = openOutFile(&rights_out);
192
off_t off_in = 0, off_out = 0;
193
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));
198
off_in = 20;
199
off_out = 20;
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));
203
close(fd_in);
204
close(fd_out);
205
}
206
207
TEST_F(CopyFileRangeTest, ReadSeekWriteSeek) {
208
cap_rights_t rights_in, rights_out;
209
210
cap_rights_init(&rights_in, CAP_READ, CAP_SEEK);
211
cap_rights_init(&rights_out, CAP_WRITE, CAP_SEEK);
212
213
int fd_in = openInFile(&rights_in);
214
int fd_out = openOutFile(&rights_out);
215
off_t off_in = 0, off_out = 0;
216
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));
221
off_in = 20;
222
off_out = 20;
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));
226
close(fd_in);
227
close(fd_out);
228
}
229
230