1 |
commit: 632cc66ba52eb6aa7fd3e457c64d9186389a20b4 |
2 |
Author: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sat Nov 6 03:14:42 2021 +0000 |
4 |
Commit: Mike Frysinger <vapier <AT> gentoo <DOT> org> |
5 |
CommitDate: Sat Nov 6 03:14:42 2021 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=632cc66b |
7 |
|
8 |
change FS calls to use 64-bit interfaces explicitly |
9 |
|
10 |
Make sure we use 64-bit FS interfaces when accessing the FS. This |
11 |
is needed not only to stat or open large files, but even files with |
12 |
64-bit inodes. |
13 |
|
14 |
Bug: https://bugs.gentoo.org/583282 |
15 |
Signed-off-by: Mike Frysinger <vapier <AT> gentoo.org> |
16 |
|
17 |
configure.ac | 7 +++++++ |
18 |
libsandbox/canonicalize.c | 8 ++++---- |
19 |
libsandbox/libsandbox.c | 14 +++++++------- |
20 |
libsandbox/pre_check_mkdirat.c | 6 +++--- |
21 |
libsandbox/trace.c | 2 +- |
22 |
libsandbox/wrapper-funcs/__wrapper_exec.c | 4 ++-- |
23 |
libsbutil/include/rcscripts/util/file.h | 2 +- |
24 |
libsbutil/sb_close.c | 4 ++-- |
25 |
libsbutil/src/file.c | 24 ++++++++++++------------ |
26 |
src/namespaces.c | 4 ++-- |
27 |
tests/get-group.c | 4 ++-- |
28 |
tests/get-user.c | 4 ++-- |
29 |
tests/test-skel-0.c | 2 +- |
30 |
tests/trace-memory_static_tst.c | 4 ++-- |
31 |
14 files changed, 48 insertions(+), 41 deletions(-) |
32 |
|
33 |
diff --git a/configure.ac b/configure.ac |
34 |
index 56ca87f..698051f 100644 |
35 |
--- a/configure.ac |
36 |
+++ b/configure.ac |
37 |
@@ -25,6 +25,13 @@ AS_IF([test "$ac_cv_prog_cc_c99" = "no"], [AC_MSG_ERROR([A C99+ compiler is requ |
38 |
AM_PROG_CC_C_O |
39 |
AC_ISC_POSIX |
40 |
AC_USE_SYSTEM_EXTENSIONS |
41 |
+dnl http://www.gnu.org/s/libc/manual/html_node/Feature-Test-Macros.html |
42 |
+dnl _LARGEFILE_SOURCE: enable support for new LFS funcs (ftello/etc...) |
43 |
+dnl _LARGEFILE64_SOURCE: enable support for 64-bit variants (off64_t/fseeko64/etc...) |
44 |
+dnl NB: We do not want -D_FILE_OFFSET_BITS=64 because we need to interpose both 32-bit |
45 |
+dnl and 64-bit FS interfaces, and having the C library rewrite them makes that difficult. |
46 |
+dnl Along those lines, we do not use AC_SYS_LARGEFILE. |
47 |
+AS_VAR_APPEND([CPPFLAGS], [" -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE"]) |
48 |
|
49 |
dnl Checks for programs. |
50 |
AM_PROG_AR |
51 |
|
52 |
diff --git a/libsandbox/canonicalize.c b/libsandbox/canonicalize.c |
53 |
index 6519340..f742ed4 100644 |
54 |
--- a/libsandbox/canonicalize.c |
55 |
+++ b/libsandbox/canonicalize.c |
56 |
@@ -92,7 +92,7 @@ erealpath(const char *name, char *resolved) |
57 |
goto error; |
58 |
} |
59 |
|
60 |
- /* This stat() business uses relative paths atm */ |
61 |
+ /* This stat business uses relative paths atm. */ |
62 |
if (trace_pid) |
63 |
goto no_recover; |
64 |
|
65 |
@@ -100,14 +100,14 @@ erealpath(const char *name, char *resolved) |
66 |
* If not, try a little harder to consume this path in |
67 |
* case it has symlinks out into a better world ... |
68 |
*/ |
69 |
- struct stat st; |
70 |
- if (lstat(rpath, &st) == -1 && errno == EACCES) { |
71 |
+ struct stat64 st; |
72 |
+ if (lstat64(rpath, &st) == -1 && errno == EACCES) { |
73 |
char *p = rpath; |
74 |
strcpy(rpath, name); |
75 |
do { |
76 |
p = strchr(p, '/'); |
77 |
if (p) *p = '\0'; |
78 |
- if (lstat(rpath, &st)) |
79 |
+ if (lstat64(rpath, &st)) |
80 |
break; |
81 |
if (S_ISLNK(st.st_mode)) { |
82 |
ssize_t cnt = readlink(rpath, rpath, path_max); |
83 |
|
84 |
diff --git a/libsandbox/libsandbox.c b/libsandbox/libsandbox.c |
85 |
index b4db9ba..0ca2bc9 100644 |
86 |
--- a/libsandbox/libsandbox.c |
87 |
+++ b/libsandbox/libsandbox.c |
88 |
@@ -333,7 +333,7 @@ static char *resolve_path(const char *path, int follow_link) |
89 |
|
90 |
char *egetcwd(char *buf, size_t size) |
91 |
{ |
92 |
- struct stat st; |
93 |
+ struct stat64 st; |
94 |
char *tmpbuf; |
95 |
|
96 |
/* We can't let the C lib allocate memory for us since we have our |
97 |
@@ -376,12 +376,12 @@ char *egetcwd(char *buf, size_t size) |
98 |
*/ |
99 |
if ((tmpbuf) && (errno == 0)) { |
100 |
save_errno(); |
101 |
- if (!lstat(buf, &st)) |
102 |
+ if (!lstat64(buf, &st)) |
103 |
/* errno is set only on failure */ |
104 |
errno = 0; |
105 |
|
106 |
if (errno == ENOENT) |
107 |
- /* If lstat() failed with eerror = ENOENT, then its |
108 |
+ /* If lstat failed with eerror = ENOENT, then its |
109 |
* possible that we are running on an older kernel |
110 |
* which had issues with returning invalid paths if |
111 |
* they got too long. Return with errno = ENAMETOOLONG, |
112 |
@@ -396,8 +396,8 @@ char *egetcwd(char *buf, size_t size) |
113 |
free(buf); |
114 |
|
115 |
/* Not sure if we should quit here, but I guess if |
116 |
- * lstat() fails, getcwd could have messed up. Not |
117 |
- * sure what to do about errno - use lstat()'s for |
118 |
+ * lstat fails, getcwd could have messed up. Not |
119 |
+ * sure what to do about errno - use lstat's for |
120 |
* now. |
121 |
*/ |
122 |
return NULL; |
123 |
@@ -435,12 +435,12 @@ void __sb_dump_backtrace(void) |
124 |
static bool write_logfile(const char *logfile, const char *func, const char *path, |
125 |
const char *apath, const char *rpath, bool access) |
126 |
{ |
127 |
- struct stat log_stat; |
128 |
+ struct stat64 log_stat; |
129 |
int stat_ret; |
130 |
int logfd; |
131 |
bool ret = false; |
132 |
|
133 |
- stat_ret = lstat(logfile, &log_stat); |
134 |
+ stat_ret = lstat64(logfile, &log_stat); |
135 |
/* Do not care about failure */ |
136 |
errno = 0; |
137 |
if (stat_ret == 0 && S_ISREG(log_stat.st_mode) == 0) |
138 |
|
139 |
diff --git a/libsandbox/pre_check_mkdirat.c b/libsandbox/pre_check_mkdirat.c |
140 |
index 8fb38bb..b1e86cf 100644 |
141 |
--- a/libsandbox/pre_check_mkdirat.c |
142 |
+++ b/libsandbox/pre_check_mkdirat.c |
143 |
@@ -36,8 +36,8 @@ bool sb_mkdirat_pre_check(const char *func, const char *pathname, int dirfd) |
144 |
* not want to pass this attempt up to the higher levels as those |
145 |
* will trigger a sandbox violation. |
146 |
*/ |
147 |
- struct stat st; |
148 |
- if (0 == lstat(canonic, &st)) { |
149 |
+ struct stat64 st; |
150 |
+ if (0 == lstat64(canonic, &st)) { |
151 |
int new_errno; |
152 |
sb_debug_dyn("EARLY FAIL: %s(%s[%s]) @ lstat: %s\n", |
153 |
func, pathname, canonic, strerror(errno)); |
154 |
@@ -45,7 +45,7 @@ bool sb_mkdirat_pre_check(const char *func, const char *pathname, int dirfd) |
155 |
new_errno = EEXIST; |
156 |
|
157 |
/* Hmm, is this a broken symlink we're trying to extend ? */ |
158 |
- if (S_ISLNK(st.st_mode) && stat(pathname, &st) != 0) { |
159 |
+ if (S_ISLNK(st.st_mode) && stat64(pathname, &st) != 0) { |
160 |
/* XXX: This awful hack should probably be turned into a |
161 |
* common func that does a better job. For now, we have |
162 |
* enough crap to catch gnulib tests #297026. |
163 |
|
164 |
diff --git a/libsandbox/trace.c b/libsandbox/trace.c |
165 |
index 036d57f..d70f3bc 100644 |
166 |
--- a/libsandbox/trace.c |
167 |
+++ b/libsandbox/trace.c |
168 |
@@ -51,7 +51,7 @@ static int trace_yama_level(void) |
169 |
char ch; |
170 |
int fd, level; |
171 |
|
172 |
- fd = open("/proc/sys/kernel/yama/ptrace_scope", O_RDONLY | O_CLOEXEC); |
173 |
+ fd = open64("/proc/sys/kernel/yama/ptrace_scope", O_RDONLY | O_CLOEXEC); |
174 |
if (fd == -1) |
175 |
return 0; |
176 |
|
177 |
|
178 |
diff --git a/libsandbox/wrapper-funcs/__wrapper_exec.c b/libsandbox/wrapper-funcs/__wrapper_exec.c |
179 |
index d66e3a0..f603257 100644 |
180 |
--- a/libsandbox/wrapper-funcs/__wrapper_exec.c |
181 |
+++ b/libsandbox/wrapper-funcs/__wrapper_exec.c |
182 |
@@ -27,7 +27,7 @@ static bool sb_check_exec(const char *filename, char *const argv[]) |
183 |
{ |
184 |
int fd; |
185 |
unsigned char *elf; |
186 |
- struct stat st; |
187 |
+ struct stat64 st; |
188 |
bool do_trace = false; |
189 |
bool run_in_process = true; |
190 |
sandbox_method_t method = get_sandbox_method(); |
191 |
@@ -38,7 +38,7 @@ static bool sb_check_exec(const char *filename, char *const argv[]) |
192 |
fd = sb_unwrapped_open_DEFAULT(filename, O_RDONLY|O_CLOEXEC, 0); |
193 |
if (fd == -1) |
194 |
return true; |
195 |
- if (fstat(fd, &st)) |
196 |
+ if (fstat64(fd, &st)) |
197 |
goto out_fd; |
198 |
if (st.st_size < sizeof(Elf64_Ehdr)) |
199 |
goto out_fd; |
200 |
|
201 |
diff --git a/libsbutil/include/rcscripts/util/file.h b/libsbutil/include/rcscripts/util/file.h |
202 |
index 197f211..8bbde00 100644 |
203 |
--- a/libsbutil/include/rcscripts/util/file.h |
204 |
+++ b/libsbutil/include/rcscripts/util/file.h |
205 |
@@ -23,7 +23,7 @@ bool rc_is_dir (const char *pathname, bool follow_link); |
206 |
/* The following functions do not care about errors - it only returns |
207 |
* the size/mtime of 'pathname' if it exists, and is the type requested, |
208 |
* or else 0. */ |
209 |
-off_t rc_get_size (const char *pathname, bool follow_link); |
210 |
+off64_t rc_get_size (const char *pathname, bool follow_link); |
211 |
|
212 |
/* The following return a pointer on success, or NULL with errno set on error. |
213 |
* If it returned NULL, but errno is not set, then there was no error, but |
214 |
|
215 |
diff --git a/libsbutil/sb_close.c b/libsbutil/sb_close.c |
216 |
index 5379197..113deab 100644 |
217 |
--- a/libsbutil/sb_close.c |
218 |
+++ b/libsbutil/sb_close.c |
219 |
@@ -34,7 +34,7 @@ int sb_close(int fd) |
220 |
void sb_close_all_fds(void) |
221 |
{ |
222 |
DIR *dirp; |
223 |
- struct dirent *de; |
224 |
+ struct dirent64 *de; |
225 |
int dfd, fd; |
226 |
const char *fd_dir = sb_get_fd_dir(); |
227 |
|
228 |
@@ -43,7 +43,7 @@ void sb_close_all_fds(void) |
229 |
sb_ebort("could not process %s\n", fd_dir); |
230 |
dfd = dirfd(dirp); |
231 |
|
232 |
- while ((de = readdir(dirp)) != NULL) { |
233 |
+ while ((de = readdir64(dirp)) != NULL) { |
234 |
if (de->d_name[0] == '.') |
235 |
continue; |
236 |
fd = atoi(de->d_name); |
237 |
|
238 |
diff --git a/libsbutil/src/file.c b/libsbutil/src/file.c |
239 |
index a1a4a0e..5a361f4 100644 |
240 |
--- a/libsbutil/src/file.c |
241 |
+++ b/libsbutil/src/file.c |
242 |
@@ -21,13 +21,13 @@ rc_file_exists (const char *pathname) |
243 |
bool |
244 |
rc_is_file (const char *pathname, bool follow_link) |
245 |
{ |
246 |
- struct stat buf; |
247 |
+ struct stat64 buf; |
248 |
int retval; |
249 |
|
250 |
if (!check_str (pathname)) |
251 |
return false; |
252 |
|
253 |
- retval = follow_link ? stat (pathname, &buf) : lstat (pathname, &buf); |
254 |
+ retval = follow_link ? stat64 (pathname, &buf) : lstat64 (pathname, &buf); |
255 |
if ((-1 != retval) && (S_ISREG (buf.st_mode))) |
256 |
retval = true; |
257 |
else |
258 |
@@ -39,13 +39,13 @@ rc_is_file (const char *pathname, bool follow_link) |
259 |
bool |
260 |
rc_is_dir (const char *pathname, bool follow_link) |
261 |
{ |
262 |
- struct stat buf; |
263 |
+ struct stat64 buf; |
264 |
int retval; |
265 |
|
266 |
if (!check_str (pathname)) |
267 |
return false; |
268 |
|
269 |
- retval = follow_link ? stat (pathname, &buf) : lstat (pathname, &buf); |
270 |
+ retval = follow_link ? stat64 (pathname, &buf) : lstat64 (pathname, &buf); |
271 |
if ((-1 != retval) && (S_ISDIR (buf.st_mode))) |
272 |
retval = true; |
273 |
else |
274 |
@@ -54,16 +54,16 @@ rc_is_dir (const char *pathname, bool follow_link) |
275 |
return retval; |
276 |
} |
277 |
|
278 |
-off_t |
279 |
+off64_t |
280 |
rc_get_size (const char *pathname, bool follow_link) |
281 |
{ |
282 |
- struct stat buf; |
283 |
+ struct stat64 buf; |
284 |
int retval; |
285 |
|
286 |
if (!check_str (pathname)) |
287 |
return 0; |
288 |
|
289 |
- retval = follow_link ? stat (pathname, &buf) : lstat (pathname, &buf); |
290 |
+ retval = follow_link ? stat64 (pathname, &buf) : lstat64 (pathname, &buf); |
291 |
if (-1 != retval) |
292 |
retval = buf.st_size; |
293 |
else |
294 |
@@ -76,7 +76,7 @@ char ** |
295 |
rc_ls_dir (const char *pathname, bool hidden, bool sort) |
296 |
{ |
297 |
DIR *dp; |
298 |
- struct dirent *dir_entry; |
299 |
+ struct dirent64 *dir_entry; |
300 |
char **dirlist = NULL; |
301 |
|
302 |
if (!check_arg_str (pathname)) |
303 |
@@ -102,7 +102,7 @@ rc_ls_dir (const char *pathname, bool hidden, bool sort) |
304 |
{ |
305 |
/* Clear errno to distinguish between EOF and error */ |
306 |
errno = 0; |
307 |
- dir_entry = readdir (dp); |
308 |
+ dir_entry = readdir64 (dp); |
309 |
/* Only an error if 'errno' != 0, else EOF */ |
310 |
if ((NULL == dir_entry) && (0 != errno)) |
311 |
{ |
312 |
@@ -184,10 +184,10 @@ error: |
313 |
int |
314 |
rc_file_map (const char *filename, char **buf, size_t * bufsize) |
315 |
{ |
316 |
- struct stat stats; |
317 |
+ struct stat64 stats; |
318 |
int fd; |
319 |
|
320 |
- fd = open (filename, O_RDONLY); |
321 |
+ fd = open64 (filename, O_RDONLY); |
322 |
if (fd < 0) |
323 |
{ |
324 |
rc_errno_set (errno); |
325 |
@@ -195,7 +195,7 @@ rc_file_map (const char *filename, char **buf, size_t * bufsize) |
326 |
return -1; |
327 |
} |
328 |
|
329 |
- if (fstat (fd, &stats) < 0) |
330 |
+ if (fstat64 (fd, &stats) < 0) |
331 |
{ |
332 |
rc_errno_set (errno); |
333 |
DBG_MSG ("Failed to stat file!\n"); |
334 |
|
335 |
diff --git a/src/namespaces.c b/src/namespaces.c |
336 |
index ee9f82a..290111a 100644 |
337 |
--- a/src/namespaces.c |
338 |
+++ b/src/namespaces.c |
339 |
@@ -28,7 +28,7 @@ |
340 |
|
341 |
#define xfopen(path, ...) \ |
342 |
({ \ |
343 |
- FILE *_ret = fopen(path, __VA_ARGS__); \ |
344 |
+ FILE *_ret = fopen64(path, __VA_ARGS__); \ |
345 |
if (_ret == 0) \ |
346 |
sb_perr("fopen(%s) failed", #path); \ |
347 |
_ret; \ |
348 |
@@ -107,7 +107,7 @@ static void ns_mount_setup(void) |
349 |
/* Now map in all the files/dirs we do want to expose. */ |
350 |
int fd; |
351 |
#define bind_file(node) \ |
352 |
- fd = open("/dev/shm/" node, O_CREAT, 0); \ |
353 |
+ fd = open64("/dev/shm/" node, O_CREAT, 0); \ |
354 |
sb_assert(fd != -1); \ |
355 |
close(fd); \ |
356 |
xmount("/dev/" node, "/dev/shm/" node, NULL, MS_BIND, NULL) |
357 |
|
358 |
diff --git a/tests/get-group.c b/tests/get-group.c |
359 |
index 8138967..30cdfc9 100644 |
360 |
--- a/tests/get-group.c |
361 |
+++ b/tests/get-group.c |
362 |
@@ -31,8 +31,8 @@ int main(int argc, char *argv[]) |
363 |
printf("%i\n", grp->gr_gid); |
364 |
} else { |
365 |
const char *file = argv[1]; |
366 |
- struct stat st; |
367 |
- if (lstat(file, &st)) |
368 |
+ struct stat64 st; |
369 |
+ if (lstat64(file, &st)) |
370 |
errp("lstat(%s) failed", file); |
371 |
printf("%i\n", st.st_gid); |
372 |
} |
373 |
|
374 |
diff --git a/tests/get-user.c b/tests/get-user.c |
375 |
index f85e299..be448d7 100644 |
376 |
--- a/tests/get-user.c |
377 |
+++ b/tests/get-user.c |
378 |
@@ -31,8 +31,8 @@ int main(int argc, char *argv[]) |
379 |
printf("%i\n", pwd->pw_uid); |
380 |
} else { |
381 |
const char *file = argv[1]; |
382 |
- struct stat st; |
383 |
- if (lstat(file, &st)) |
384 |
+ struct stat64 st; |
385 |
+ if (lstat64(file, &st)) |
386 |
errp("lstat(%s) failed", file); |
387 |
printf("%i\n", st.st_uid); |
388 |
} |
389 |
|
390 |
diff --git a/tests/test-skel-0.c b/tests/test-skel-0.c |
391 |
index de88cf4..91128d3 100644 |
392 |
--- a/tests/test-skel-0.c |
393 |
+++ b/tests/test-skel-0.c |
394 |
@@ -128,7 +128,7 @@ int at_get_fd(const char *str_dirfd) |
395 |
} |
396 |
str_mode = strtok(NULL, ":"); |
397 |
|
398 |
- return open(str_path, f_get_flags(str_flags), sscanf_mode_t(str_mode)); |
399 |
+ return open64(str_path, f_get_flags(str_flags), sscanf_mode_t(str_mode)); |
400 |
} |
401 |
|
402 |
#define V_TIMESPEC "NULL | NOW | #[,#]" |
403 |
|
404 |
diff --git a/tests/trace-memory_static_tst.c b/tests/trace-memory_static_tst.c |
405 |
index 14c6477..86a47fe 100644 |
406 |
--- a/tests/trace-memory_static_tst.c |
407 |
+++ b/tests/trace-memory_static_tst.c |
408 |
@@ -26,7 +26,7 @@ volatile uintptr_t offset = 0; |
409 |
#define check_ptr(addr) \ |
410 |
({ \ |
411 |
printf(" open(%p)\n", addr); \ |
412 |
- ret = open(non_const_ptr(addr), O_RDONLY); \ |
413 |
+ ret = open64(non_const_ptr(addr), O_RDONLY); \ |
414 |
assert(ret == -1 && errno == EFAULT); \ |
415 |
}) |
416 |
|
417 |
@@ -53,7 +53,7 @@ int main(int argc, char *argv[]) |
418 |
printf(" open(%p -> %p [+%#zx])\n", p, p + len, len); |
419 |
memset(p, 'a', len); |
420 |
path[end] = '\0'; |
421 |
- ret = open(p, O_RDONLY); |
422 |
+ ret = open64(p, O_RDONLY); |
423 |
assert(ret == -1 && (errno == ENOENT || errno == ENAMETOOLONG)); |
424 |
} |
425 |
} |