Reland copy file range san (#129114)

This commit is contained in:
David CARLIER 2025-02-27 20:58:51 +00:00 committed by GitHub
parent 14bab65cbf
commit 9a54c77aa3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 64 additions and 0 deletions

View File

@ -3205,6 +3205,28 @@ POST_SYSCALL(futex)
COMMON_SYSCALL_BLOCKING_END();
}
PRE_SYSCALL(copy_file_range)
(int fdin, __sanitizer___kernel_off_t *offin, int fdout,
__sanitizer___kernel_off_t *offout, SIZE_T size, unsigned int flags) {
if (offin != nullptr) {
PRE_READ(offin, sizeof(*offin));
}
if (offout != nullptr) {
PRE_READ(offout, sizeof(*offout));
}
}
POST_SYSCALL(copy_file_range)
(SSIZE_T, int fdin, __sanitizer___kernel_off_t *offin, int fdout,
__sanitizer___kernel_off_t *offout, SIZE_T size, unsigned int flags) {
if (offin != nullptr) {
POST_WRITE(offin, sizeof(*offin));
}
if (offout != nullptr) {
POST_WRITE(offout, sizeof(*offout));
}
}
} // extern "C"
# undef PRE_SYSCALL

View File

@ -0,0 +1,42 @@
// RUN: %clangxx -O0 %s -D_FILE_OFFSET_BITS=64 -o %t
// REQUIRES: glibc
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <assert.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
#if !defined(__GLIBC_PREREQ)
# define __GLIBC_PREREQ(a, b) 0
#endif
#if !__GLIBC_PREREQ(2, 27)
# define copy_file_range(a, b, c, d, e, f) \
(ssize_t) syscall(__NR_copy_file_range, a, b, c, d, e, f)
#endif
int main(void) {
int fdin = open("/proc/self/maps", O_RDONLY);
assert(fdin > 0);
char tmp[] = "/tmp/map.XXXXXX";
int fdout = mkstemp(tmp);
assert(fdout > 0);
off_t offin = -1, offout = 0;
ssize_t cpy = copy_file_range(fdin, &offin, fdout, &offout, 8, 0);
assert(cpy < 0);
offin = 0;
offout = 16;
cpy = copy_file_range(fdin, &offin, fdout, &offout, 8, 0);
assert(cpy < 0);
offout = 0;
cpy = copy_file_range(fdin, &offin, fdout, &offout, 8, 0);
assert(cpy == 8);
close(fdout);
close(fdin);
return 0;
}