From: Paul Floyd Date: Fri, 29 Aug 2025 05:59:28 +0000 (+0200) Subject: Linux FreeBSD and Darwin: refactor *at syscall dirfd checks X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9f5d3d32b5bd5bc546eea74a8f75e53d4a228519;p=thirdparty%2Fvalgrind.git Linux FreeBSD and Darwin: refactor *at syscall dirfd checks I haven't done Solaris. The code there is less messy because Solaris doesn't use a negative value for AT_FDCWD, meaning no explicit or implicit cast from unsigned word to signed int is needed before comparing to the int dirfd parameter. --- diff --git a/coregrind/m_syswrap/priv_syswrap-generic.h b/coregrind/m_syswrap/priv_syswrap-generic.h index eb815840d..9dbc1e6f2 100644 --- a/coregrind/m_syswrap/priv_syswrap-generic.h +++ b/coregrind/m_syswrap/priv_syswrap-generic.h @@ -59,6 +59,17 @@ extern Bool ML_(fd_allowed)(Int fd, const HChar *syscallname, ThreadId tid, Bool isNewFD); +// used bye "*at" syscalls that take a directory fd for use +// with relative paths. Need to check that +// 1. the path is relative +// 2. the directory is not the specail value VKI_AT_FDCWD +// 3. the directory fd is allowd (as above) +extern +void ML_(fd_at_check_allowed)(Int fd, const HChar* path, + const HChar* function_name, ThreadId tid, + SyscallStatus* status); + + extern void ML_(record_fd_close) (ThreadId tid, Int fd); extern Int ML_(get_fd_count) (void); extern void ML_(record_fd_close_range) (ThreadId tid, Int fd); diff --git a/coregrind/m_syswrap/syswrap-amd64-freebsd.c b/coregrind/m_syswrap/syswrap-amd64-freebsd.c index 4d3c17848..b2fc6114f 100644 --- a/coregrind/m_syswrap/syswrap-amd64-freebsd.c +++ b/coregrind/m_syswrap/syswrap-amd64-freebsd.c @@ -983,15 +983,11 @@ POST(sys_procctl) // int mknodat(int fd, const char *path, mode_t mode, dev_t dev); PRE(sys_mknodat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_mknodat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4 ); PRE_REG_READ4(long, "mknodat", int, fd, const char *, path, vki_mode_t, mode, vki_dev_t, dev); PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 ); - if ((ML_(safe_to_deref) (path, 1)) && (path[0] != '/')) - if ((arg_1 != VKI_AT_FDCWD) && !ML_(fd_allowed)(arg_1, "mknodat", tid, False) ) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "mknodat", tid, status); } // SYS_cpuset_getdomain 561 diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c index 1fca10183..1aae03c02 100644 --- a/coregrind/m_syswrap/syswrap-arm-linux.c +++ b/coregrind/m_syswrap/syswrap-arm-linux.c @@ -284,10 +284,7 @@ PRE(sys_fstatat64) SARG1, ARG2, (HChar*)ARG2, ARG3); PRE_REG_READ3(long, "fstatat64", int, dfd, char *, file_name, struct stat64 *, buf); - if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && *(Char *)(Addr)ARG2 != '/' - && ((Int)ARG1) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG1, "fstatat64", tid, False)) + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "fstatat64", tid, status); SET_STATUS_Failure( VKI_EBADF ); PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 ); PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) ); diff --git a/coregrind/m_syswrap/syswrap-arm64-freebsd.c b/coregrind/m_syswrap/syswrap-arm64-freebsd.c index 6054c641e..fe2d16194 100644 --- a/coregrind/m_syswrap/syswrap-arm64-freebsd.c +++ b/coregrind/m_syswrap/syswrap-arm64-freebsd.c @@ -949,17 +949,13 @@ POST(sys_procctl) // int mknodat(int fd, const char *path, mode_t mode, dev_t dev); PRE(sys_mknodat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_mknodat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1, ARG2, (char*)ARG2, ARG3, ARG4); PRE_REG_READ4(long, "mknodat", int, fd, const char*, path, vki_mode_t, mode, vki_dev_t, dev); PRE_MEM_RASCIIZ("mknodat(pathname)", ARG2); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "mknodat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "mknodat", tid, status); } // SYS_cpuset_getdomain 561 diff --git a/coregrind/m_syswrap/syswrap-darwin.c b/coregrind/m_syswrap/syswrap-darwin.c index ba90495bb..761965d61 100644 --- a/coregrind/m_syswrap/syswrap-darwin.c +++ b/coregrind/m_syswrap/syswrap-darwin.c @@ -9858,29 +9858,21 @@ POST(getattrlistbulk) PRE(faccessat) { - Int fd = ARG1; PRINT("faccessat(fd:%d, path:%#lx(%s), amode:%#lx, flag:%#lx)", fd, ARG2, ARG2 ? (HChar*)ARG2 : "null", ARG3, ARG4); PRE_REG_READ4(int, "faccessat", int, fd, user_addr_t, path, int, amode, int, flag); - - if (fd != VKI_AT_FDCWD && !ML_(fd_allowed)(fd, "faccessat", tid, False)) { - SET_STATUS_Failure( VKI_EBADF ); - } + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "faccessat", tid, status); PRE_MEM_RASCIIZ( "faccessat(path)", ARG2 ); } PRE(fstatat64) { - Int fd = ARG1; PRINT("fstatat64(fd:%d, path:%#lx(%s), ub:%#lx, flag:%#lx)", fd, ARG2, ARG2 ? (HChar*)ARG2 : "null", ARG3, ARG4); PRE_REG_READ4(int, "fstatat64", int, fd, user_addr_t, path, user_addr_t, ub, int, flag); - - if (fd != VKI_AT_FDCWD && !ML_(fd_allowed)(fd, "fstatat64", tid, False)) { - SET_STATUS_Failure( VKI_EBADF ); - } + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "fstatat64", tid, status); PRE_MEM_RASCIIZ( "fstatat64(path)", ARG2 ); PRE_MEM_WRITE( "fstatat64(ub)", ARG3, sizeof(struct vki_stat64) ); } @@ -9891,15 +9883,11 @@ POST(fstatat64) PRE(readlinkat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("readlinkat ( %ld, %#lx(%s), %#lx, %ld )", SARG1, ARG2, (HChar*)ARG2, ARG3, SARG4); PRE_REG_READ4(long, "readlinkat", int, dfd, const char *, path, char *, buf, int, bufsiz); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "readlinkat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "readlinkat", tid, status); PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 ); PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 ); @@ -10010,11 +9998,7 @@ PRE(openat) /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD, filename is relative to cwd. When comparing dfd against AT_FDCWD, be sure only to compare the bottom 32 bits. */ - if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && *(Char *)(Addr)ARG2 != '/' - && ((Int)ARG1) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG1, "openat", tid, False)) - SET_STATUS_Failure( VKI_EBADF ); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "openat", tid, status); /* Otherwise handle normally */ *flags |= SfMayBlock; @@ -10035,14 +10019,10 @@ POST(openat) PRE(mkdirat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("mkdirat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,ARG2,(char*)ARG2,ARG3); PRE_REG_READ3(int, "mkdirat", int, fd, const char *, path, unsigned int, mode); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "symlinkat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "mkdirat", tid, status); PRE_MEM_RASCIIZ( "mkdirat(path)", ARG2 ); *flags |= SfMayBlock; } @@ -10500,11 +10480,7 @@ PRE(openat_nocancel) /* For absolute filenames, dfd is ignored. If dfd is AT_FDCWD, filename is relative to cwd. When comparing dfd against AT_FDCWD, be sure only to compare the bottom 32 bits. */ - if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && *(Char *)(Addr)ARG2 != '/' - && ((Int)ARG1) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG1, "openat_nocancel", tid, False)) - SET_STATUS_Failure( VKI_EBADF ); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "openat_nocancel", tid, status); /* Otherwise handle normally */ *flags |= SfMayBlock; diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index 7fc96c7c5..8934b76ad 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -5186,14 +5186,10 @@ POST(sys_cpuset) // int faccessat(int fd, const char *path, int mode, int flag); PRE(sys_faccessat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_faccessat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,ARG2,(char*)ARG2,ARG3); PRE_REG_READ3(int, "faccessat", int, fd, const char *, path, int, flag); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "faccessat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "faccessat", tid, status); PRE_MEM_RASCIIZ( "faccessat(path)", ARG2 ); } @@ -5201,14 +5197,10 @@ PRE(sys_faccessat) // int fchmodat(int fd, const char *path, mode_t mode, int flag); PRE(sys_fchmodat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_fchmodat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,ARG2,(char*)ARG2,ARG3); PRE_REG_READ4(int, "fchmodat", int, fd, const char *, path, vki_mode_t, mode, int, flag); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "fchmodat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "fchmodat", tid, status); PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 ); } @@ -5216,13 +5208,9 @@ PRE(sys_fchmodat) // int fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag); PRE(sys_fchownat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_fchownat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x, %" FMT_REGWORD "d )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4, SARG5); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "fchownat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "fchownat", tid, status); PRE_REG_READ5(int, "fchownat", int, fd, const char *, path, vki_uid_t, owner, vki_gid_t, group, int, flag); @@ -5311,14 +5299,10 @@ PRE(sys_fexecve) // int fstatat(int fd, const char *path, struct stat *sb, int flag); PRE(sys_freebsd11_fstatat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_freebsd11_fstatat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3); PRE_REG_READ4(int, "fstatat", int, fd, const char *, path, struct freebsd11_stat *, buf, int, flag); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "freebsd11_fstatat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "freebsd11_fstatat", tid, status); PRE_MEM_RASCIIZ( "freebsd11_fstatat(path)", ARG2 ); PRE_MEM_WRITE( "freebsd11_fstatat(sb)", ARG3, sizeof(struct vki_freebsd11_stat) ); } @@ -5332,14 +5316,10 @@ POST(sys_freebsd11_fstatat) // int futimesat(int fd, const char *path, const struct timeval times[2]); PRE(sys_futimesat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_futimesat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3); PRE_REG_READ3(int, "futimesat", int, fd, const char *, path, struct timeval *, times); - if ((ML_(safe_to_deref) (path, 1)) && (path[0] != '/')) - if ((arg_1 != VKI_AT_FDCWD) && !ML_(fd_allowed)(arg_1, "futimesat", tid, False) ) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "futimesat", tid, status); if (ARG2 != 0) { PRE_MEM_RASCIIZ( "futimesat(path)", ARG2 ); } @@ -5352,17 +5332,13 @@ PRE(sys_futimesat) // int linkat(int fd1, const char *name1, int fd2, const char *name2, int flag); PRE(sys_linkat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; *flags |= SfMayBlock; PRINT("sys_linkat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",ARG1,ARG2,(char*)ARG2,ARG3,ARG4,(char*)ARG4,ARG5); PRE_REG_READ5(int, "linkat", int, fd1, const char *, name1, int, fd2, const char *, name2, int, flag); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "linkat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "linkat", tid, status); PRE_MEM_RASCIIZ( "linkat(name1)", ARG2); PRE_MEM_RASCIIZ( "linkat(name2)", ARG4); } @@ -5371,15 +5347,11 @@ PRE(sys_linkat) // int mkdirat(int fd, const char *path, mode_t mode); PRE(sys_mkdirat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; *flags |= SfMayBlock; PRINT("sys_mkdirat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )", ARG1,ARG2,(char*)ARG2,ARG3); PRE_REG_READ3(int, "mkdirat", int, fd, const char *, path, unsigned int, mode); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "mkdirat", tid, False)) - SET_STATUS_Failure(VKI_EBADF);; + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "mkdirat", tid, status); PRE_MEM_RASCIIZ( "mkdirat(path)", ARG2 ); } @@ -5387,13 +5359,9 @@ PRE(sys_mkdirat) // int mkfifoat(int fd, const char *path, mode_t mode); PRE(sys_mkfifoat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_mkfifoat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x )", SARG1,ARG2,(HChar*)ARG2,ARG3 ); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "mkfifoat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "mkfifoat", tid, status); PRE_REG_READ3(int, "mkfifoat", int, fd, const char *, path, vki_mode_t, mode); PRE_MEM_RASCIIZ( "mkfifoat(path)", ARG2 ); @@ -5403,14 +5371,10 @@ PRE(sys_mkfifoat) // int mknodat(int fd, const char *path, mode_t mode, dev_t dev); PRE(sys_freebsd11_mknodat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_freebsd11_mknodat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4 ); PRE_REG_READ4(long, "freebsd11_mknodat", int, dfd, const char *, pathname, int, mode, unsigned, dev); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "freebsd11_mknodat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "freebsd11_mknodat", tid, status); PRE_MEM_RASCIIZ( "freebsd11_mknodat(pathname)", ARG2 ); } @@ -5462,20 +5426,7 @@ no_client_write: PRE_REG_READ3(int, "openat", int, fd, const char *, path, int, flags); } - Int arg_1 = (Int) ARG1; - const HChar *path = (const HChar*)ARG2; - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "openat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); - - /* For absolute filenames, dirfd is ignored. If dirfd is AT_FDCWD, - filename is relative to cwd. When comparing dirfd against AT_FDCWD, - be sure only to compare the bottom 32 bits. */ - if (ML_(safe_to_deref)((void*)(Addr)ARG2, 1) - && *(Char *)(Addr)ARG2 != '/' - && ((Int)ARG1) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG1, "openat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "openat", tid, status); PRE_MEM_RASCIIZ("openat(path)", ARG2); /* Otherwise handle normally */ @@ -5502,16 +5453,12 @@ POST(sys_openat) // size_t bufsize); PRE(sys_readlinkat) { - Bool curproc_file = False; - Int arg_1 = (Int)ARG1; const HChar *path = (const HChar*)ARG2; PRINT("sys_readlinkat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %llu )", ARG1,ARG2,(char*)ARG2,ARG3,(ULong)ARG4); PRE_REG_READ4(ssize_t, "readlinkat", int, fd, const char *, path, char *, buf, int, bufsize); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "readlinkat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "readlinkat", tid, status); PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 ); PRE_MEM_WRITE("readlinkat(buf)", ARG3, ARG4); @@ -5535,15 +5482,12 @@ POST(sys_readlinkat) // int renameat(int fromfd, const char *from, int tofd, const char *to); PRE(sys_renameat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_renameat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s) )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4,(char*)ARG4); PRE_REG_READ4(int, "renameat", int, fromfd, const char *, from, int, tofd, const char *, to); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "renameat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "renameat(fromfd)", tid, status); + ML_(fd_at_check_allowed)(SARG3, (const HChar*)ARG4, "renameat(tofd)", tid, status); PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 ); PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 ); } @@ -5552,15 +5496,11 @@ PRE(sys_renameat) // int symlinkat(const char *name1, int fd, const char *name2); PRE(sys_symlinkat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; *flags |= SfMayBlock; PRINT("sys_symlinkat ( %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s) )",ARG1,(char*)ARG1,ARG2,ARG3,(char*)ARG3); PRE_REG_READ3(int, "symlinkat", const char *, name1, int, fd, const char *, name2); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "symlinkat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "symlinkat", tid, status); PRE_MEM_RASCIIZ( "symlinkat(name1)", ARG1 ); PRE_MEM_RASCIIZ( "symlinkat(name2)", ARG3 ); } @@ -5569,12 +5509,9 @@ PRE(sys_symlinkat) // int unlinkat(int fd, const char *path, int flag); PRE(sys_unlinkat) { - *flags |= SfMayBlock; - Int arg_1 = (Int)ARG1; PRINT("sys_unlinkat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u ", ARG1, ARG2, (char*)ARG2, ARG3); - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "unlinkat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "unlinkat", tid, status); PRE_REG_READ3(int, "unlinkat", int, fd, const char *, path, int, flag); PRE_MEM_RASCIIZ( "unlinkat(path)", ARG2 ); } @@ -6192,15 +6129,10 @@ POST(sys_cap_fcntls_get) // int bindat(int fd, int s, const struct sockaddr *addr, socklen_t addrlen); PRE(sys_bindat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_bindat ( %" FMT_REGWORD "d, %" FMT_REGWORD "dx, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", SARG1, SARG2, ARG3, ARG4); PRE_REG_READ4(int, "bindat", int, fd, int, s, const struct vki_sockaddr *, name, vki_socklen_t, namelen); - if ((ML_(safe_to_deref) (path, 1)) && (path[0] != '/')) - if ((arg_1 != VKI_AT_FDCWD) && !ML_(fd_allowed)(arg_1, "bindat", tid, False) ) - SET_STATUS_Failure(VKI_EBADF); - + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "bindat", tid, status); PRE_MEM_READ("bindat(name)", ARG3, ARG4); } @@ -6208,14 +6140,10 @@ PRE(sys_bindat) // int connectat(int fd, int s, const struct sockaddr *name, socklen_t namelen); PRE(sys_connectat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_connectat ( %" FMT_REGWORD "d, %" FMT_REGWORD "dx, %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", SARG1, SARG2, ARG3, ARG4); PRE_REG_READ4(int, "connectat", int, fd, int, s, const struct vki_sockaddr *, name, vki_socklen_t, namelen); - if ((ML_(safe_to_deref) (path, 1)) && (path[0] != '/')) - if ((arg_1 != VKI_AT_FDCWD) && !ML_(fd_allowed)(arg_1, "connectat", tid, False) ) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "connectat", tid, status); PRE_MEM_READ("connectat(name)", ARG3, ARG4); } @@ -6223,15 +6151,10 @@ PRE(sys_connectat) // int chflagsat(int fd, const char *path, unsigned long flags, int atflag); PRE(sys_chflagsat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_chglagsat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "u, %" FMT_REGWORD "d )", SARG1, ARG2, ARG3, SARG4); PRE_REG_READ4(int, "chflagsat", int, fd, const char *, path, unsigned long, flags, int, atflag); - if ((ML_(safe_to_deref) (path, 1)) && (path[0] != '/')) - if ((arg_1 != VKI_AT_FDCWD) && !ML_(fd_allowed)(arg_1, "chflagsat", tid, False) ) - SET_STATUS_Failure(VKI_EBADF); - + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "chflagsat", tid, status); PRE_MEM_RASCIIZ("chflagsat(path)", ARG2); } @@ -6372,8 +6295,7 @@ PRE(sys_utimensat) SARG1, ARG2, ARG3, SARG4); PRE_REG_READ4(int, "utimensat", int, fd, const char *,path, const struct timespec *, times, int, flag); - if (!ML_(fd_allowed)(ARG1, "utimensat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "utimensat", tid, status); PRE_MEM_RASCIIZ("utimensat(path)", ARG2); PRE_MEM_READ("utimensat(times)", ARG3, 2*sizeof(struct vki_timespec)); } @@ -6406,14 +6328,10 @@ POST(sys_fstat) // int fstatat(int fd, const char *path, struct stat *sb, int flag); PRE(sys_fstatat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_fstatat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %" FMT_REGWORD "d )", SARG1,ARG2,(char*)ARG2,ARG3,SARG4); PRE_REG_READ4(int, "fstatat", int, fd, const char *, path, struct stat *, sb, int, flag); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "fstatat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "fstatat", tid, status); PRE_MEM_RASCIIZ( "fstatat(path)", ARG2 ); PRE_MEM_WRITE( "fstatat(sb)", ARG3, sizeof(struct vki_stat) ); } @@ -6598,13 +6516,9 @@ POST(sys_getrandom) // int getfhat(int fd, const char *path, fhandle_t *fhp, int flag); PRE(sys_getfhat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_getfhat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x, %" FMT_REGWORD "x, %" FMT_REGWORD "d ", SARG1, ARG2, ARG3, SARG4); PRE_REG_READ4(int, "getfhat", int, fd, const char*, path, vki_fhandle_t*, fhp, int, flag); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "getfhat", tid, False)) - SET_STATUS_Failure(VKI_EBADF);; + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "getfhat", tid, status); PRE_MEM_RASCIIZ( "getfhat(path)", ARG2 ); PRE_MEM_WRITE("getfhat(fhp)", ARG3, sizeof(vki_fhandle_t)); } @@ -6653,15 +6567,11 @@ POST(sys_fhreadlink) // int funlinkat(int dfd, const char *path, int fd, int flag); PRE(sys_funlinkat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; *flags |= SfMayBlock; PRINT("sys_funlinkat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %" FMT_REGWORD"u )", SARG1, ARG2, (char*)ARG2, ARG4, ARG5); PRE_REG_READ4(int, "funlinkat", int, dfd, const char *, path, int, fd, int, flag); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "funlinkat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "funlinkat", tid, status); PRE_MEM_RASCIIZ( "funlinkat(path)", ARG2 ); } @@ -6838,15 +6748,11 @@ PRE(sys_sigfastblock) // int flags) PRE(sys___realpathat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys___realpathat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %" FMT_REGWORD "u %" FMT_REGWORD "d )", SARG1,ARG2,(const char*)ARG2,ARG3,ARG4,SARG5 ); PRE_REG_READ5(int, "__realpathat", int, fd, const char *, path, char *, buf, vki_size_t, size, int, flags); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "__realpathat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "__realpathat", tid, status); PRE_MEM_RASCIIZ("__realpathat(path)", (Addr)ARG2); PRE_MEM_WRITE("__realpathat(buf)", (Addr)ARG3, ARG4); } @@ -7282,17 +7188,10 @@ PRE(sys_exterrctl) // int inotify_add_watch_at(int fd, int dfd, _In_z_ const char *path, uint32_t mask); PRE(sys_inotify_add_watch_at) { - Int arg_2 = (Int)ARG2; - const HChar *path = (const HChar*)ARG3; PRINT("sys_inotify_add_watch_at(%" FMT_REGWORD "d, %" FMT_REGWORD "d, %" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x)", SARG1, SARG2, ARG3, (HChar*)ARG3, ARG4); PRE_REG_READ4(int, "inotify_add_watch_at", int, fd, int, dfd, const char*, path, uint32_t, mask); PRE_MEM_RASCIIZ("inotify_add_watch_at(path)", ARG3); - if (!ML_(fd_allowed)(ARG1, "inotify_add_watch_at", tid, False)) { - SET_STATUS_Failure( VKI_EBADF ); - } - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_2 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_2, "inotify_add_watch_at", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "inotify_add_watch_at", tid, status); } // SYS_inotify_rm_watch diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index c7d58bc10..c8c421c95 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -1794,6 +1794,12 @@ Bool ML_(fd_allowed)(Int fd, const HChar *syscallname, ThreadId tid, return allowed; } +void ML_(fd_at_check_allowed)(Int fd, const HChar* path, const HChar* function_name, ThreadId tid, SyscallStatus* status) +{ + if ((ML_(safe_to_deref) (path, 1)) && (path[0] != '/')) + if ((fd != VKI_AT_FDCWD) && !ML_(fd_allowed)(fd, function_name, tid, False)) + SET_STATUS_Failure(VKI_EBADF); +} /* --------------------------------------------------------------------- Deal with a bunch of socket-related syscalls diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index f876f839b..f5723f8cd 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -114,19 +114,6 @@ static VgSchedReturnCode thread_wrapper(Word /*ThreadId*/ tidW) return ret; } -/* - * Used by *at() functions that take a directory fd as a root for relative paths - * I did want to put this in pub_core_syswrap.h but that's difficult as - * it pulls in several dependent headers resulting in one that can't - * be accessed every place that uses this pub_core_syswrap.h - */ -static inline void fd_at_check_allowed(Int fd, const HChar* path, const HChar* function_name, ThreadId tid, SyscallStatus* status) -{ - if ((ML_(safe_to_deref) (path, 1)) && (path[0] != '/')) - if ((fd != VKI_AT_FDCWD) && !ML_(fd_allowed)(fd, function_name, tid, False) ) - SET_STATUS_Failure( VKI_EBADF ); -} - /* --------------------------------------------------------------------- clone-related stuff ------------------------------------------------------------------ */ @@ -6125,11 +6112,7 @@ no_client_write: /* For absolute filenames, dirfd is ignored. If dirfd is AT_FDCWD, filename is relative to cwd. When comparing dirfd against AT_FDCWD, be sure only to compare the bottom 32 bits. */ - if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && *(Char *)(Addr)ARG2 != '/' - && ((Int)ARG1) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG1, "openat", tid, False)) - SET_STATUS_Failure( VKI_EBADF ); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "openat", tid, status); /* Handle the case where the open is of /proc/self/cmdline or /proc//cmdline, and just give it a copy of the fd for the @@ -6194,7 +6177,7 @@ PRE(sys_mkdirat) *flags |= SfMayBlock; PRINT("sys_mkdirat ( %ld, %#" FMT_REGWORD "x(%s), %ld )", SARG1, ARG2, (HChar*)(Addr)ARG2, SARG3); - fd_at_check_allowed(SARG1, (const HChar*)ARG2, "mkdirat", tid, status); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "mkdirat", tid, status); PRE_REG_READ3(long, "mkdirat", int, dfd, const char *, pathname, int, mode); PRE_MEM_RASCIIZ( "mkdirat(pathname)", ARG2 ); @@ -6205,7 +6188,7 @@ PRE(sys_mknodat) FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_mknodat ( %ld, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4 ); - fd_at_check_allowed(SARG1, (const HChar*)ARG2, "mknodat", tid, status); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "mknodat", tid, status); PRE_REG_READ4(long, "mknodat", int, dfd, const char *, pathname, int, mode, unsigned, dev); PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 ); @@ -6213,41 +6196,28 @@ PRE(sys_mknodat) PRE(sys_fchownat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*) ARG2; FUSE_COMPATIBLE_MAY_BLOCK(); - PRINT("sys_fchownat ( %d, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" - FMT_REGWORD "x )", arg_1, ARG2, path, ARG3, ARG4); + PRINT("sys_fchownat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" + FMT_REGWORD "x )", SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4); PRE_REG_READ4(long, "fchownat", int, dfd, const char *, path, vki_uid_t, owner, vki_gid_t, group); PRE_MEM_RASCIIZ( "fchownat(path)", ARG2 ); - if ((ML_(safe_to_deref) (path, 1)) && (path[0] != '/')) - if ( (arg_1 != VKI_AT_FDCWD) && !ML_(fd_allowed)(arg_1, "fchownat", tid, False) ) - SET_STATUS_Failure( VKI_EBADF ); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "fchownat", tid, status); } PRE(sys_futimesat) { FUSE_COMPATIBLE_MAY_BLOCK(); - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*) ARG2; - PRINT("sys_futimesat ( %d, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", - arg_1, ARG2, path, ARG3); + PRINT("sys_futimesat ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x )", + SARG1, ARG2, (HChar*)ARG2, ARG3); PRE_REG_READ3(long, "futimesat", int, dfd, char *, filename, struct timeval *, tvp); if (ARG2 != 0) PRE_MEM_RASCIIZ( "futimesat(filename)", ARG2 ); if (ARG3 != 0) PRE_MEM_READ( "futimesat(tvp)", ARG3, 2 * sizeof(struct vki_timeval) ); - if (ML_(safe_to_deref) (path, 1)) { - /* If pathname is relative and dirfd is the special value AT_FDCWD, then pathname is interpreted ... */ - if (path[0] != '/') - if ( arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "futimesat", tid, False) ) - SET_STATUS_Failure( VKI_EBADF ); - /* If pathname is absolute, then dirfd is ignored. */ - } - + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "futimesat", tid, status); } PRE(sys_utimensat) @@ -6257,7 +6227,7 @@ PRE(sys_utimensat) FMT_REGWORD "x )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4); PRE_REG_READ4(long, "utimensat", int, dfd, char *, filename, struct timespec *, utimes, int, flags); - fd_at_check_allowed(SARG1, (const HChar*)ARG2, "utimensat", tid, status); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "utimensat", tid, status); if (ARG2 != 0) PRE_MEM_RASCIIZ( "utimensat(filename)", ARG2 ); if (ARG3 != 0) { @@ -6289,7 +6259,7 @@ PRE(sys_utimensat_time64) SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4); PRE_REG_READ4(long, "utimensat_time64", int, dfd, char *, filename, struct timespec *, utimes, int, flags); - fd_at_check_allowed(SARG1, (const HChar*)ARG2, "utimensat_time64", tid, status); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "utimensat_time64", tid, status); if (ARG2 != 0) PRE_MEM_RASCIIZ( "utimensat_time64(filename)", ARG2 ); if (ARG3 != 0) { @@ -6321,7 +6291,7 @@ PRE(sys_newfstatat) SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3); PRE_REG_READ3(long, "fstatat", int, dfd, char *, file_name, struct stat *, buf); - fd_at_check_allowed(SARG1, (const HChar*)ARG2, "newfstatat", tid, status); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "newfstatat", tid, status); // See the comment about Rust in PRE(sys_statx). When glibc does support // statx rust uses that instead of the system call, but glibc's statx is // implemented in terms of fstatat, so the filename being NULL is @@ -6344,7 +6314,7 @@ PRE(sys_unlinkat) PRINT("sys_unlinkat ( %ld, %#" FMT_REGWORD "x(%s) )", SARG1, ARG2, (HChar*)(Addr)ARG2); PRE_REG_READ2(long, "unlinkat", int, dfd, const char *, pathname); - fd_at_check_allowed(SARG1, (const HChar*)ARG2, "unlinkat", tid, status); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "unlinkat", tid, status); PRE_MEM_RASCIIZ( "unlinkat(pathname)", ARG2 ); } @@ -6357,7 +6327,7 @@ PRE(sys_renameat) PRE_REG_READ4(long, "renameat", int, olddfd, const char *, oldpath, int, newdfd, const char *, newpath); - fd_at_check_allowed(SARG1, (const HChar*)ARG2, "renameat", tid, status); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "renameat", tid, status); PRE_MEM_RASCIIZ( "renameat(oldpath)", ARG2 ); PRE_MEM_RASCIIZ( "renameat(newpath)", ARG4 ); } @@ -6372,17 +6342,8 @@ PRE(sys_renameat2) int, olddfd, const char *, oldpath, int, newdfd, const char *, newpath, unsigned int, flags); - if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && *(Char *)(Addr)ARG2 != '/' - && ((Int)ARG1) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG1, "renameat2(olddfd)", tid, False)) - SET_STATUS_Failure( VKI_EBADF ); - if (ML_(safe_to_deref)( (void*)(Addr)ARG4, 1 ) - && *(Char *)(Addr)ARG4 != '/' - && ((Int)ARG3) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG3, "renameat2(newsfd)", tid, False)) - SET_STATUS_Failure( VKI_EBADF ); - + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "renameat2(olddirfd)", tid, status); + ML_(fd_at_check_allowed)(SARG3, (const HChar*)ARG4, "renameat2(newdirfd)", tid, status); PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 ); PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 ); } @@ -6397,7 +6358,7 @@ PRE(sys_linkat) int, olddfd, const char *, oldpath, int, newdfd, const char *, newpath, int, flags); - fd_at_check_allowed(SARG1, (const HChar*)ARG2, "linkat", tid, status); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "linkat", tid, status); PRE_MEM_RASCIIZ( "linkat(oldpath)", ARG2); PRE_MEM_RASCIIZ( "linkat(newpath)", ARG4); } @@ -6409,7 +6370,7 @@ PRE(sys_symlinkat) "x(%s) )", ARG1, (HChar*)(Addr)ARG1, SARG2, ARG3, (HChar*)(Addr)ARG3); PRE_REG_READ3(long, "symlinkat", const char *, oldpath, int, newdfd, const char *, newpath); - fd_at_check_allowed(SARG1, (const HChar*)ARG2, "symlinkat", tid, status); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "symlinkat", tid, status); PRE_MEM_RASCIIZ( "symlinkat(oldpath)", ARG1 ); PRE_MEM_RASCIIZ( "symlinkat(newpath)", ARG3 ); } @@ -6421,7 +6382,7 @@ PRE(sys_readlinkat) FMT_REGWORD "u )", SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4); PRE_REG_READ4(long, "readlinkat", int, dfd, const char *, path, char *, buf, vki_size_t, bufsiz); - fd_at_check_allowed(SARG1, (const HChar*)ARG2, "readlinkat", tid, status); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "readlinkat", tid, status); PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 ); PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 ); } @@ -6459,13 +6420,7 @@ PRE(sys_fchmodat) PRE_REG_READ3(long, "fchmodat", int, dfd, const char *, path, vki_mode_t, mode); PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 ); - if (ML_(safe_to_deref) (path, 1)) { - // If pathname is relative and dirfd is the special value AT_FDCWD, then pathname is interpreted ... - if (path[0] != '/') - if ( arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "fchmodat", tid, False) ) - SET_STATUS_Failure( VKI_EBADF ); - // If pathname is absolute, then dirfd is ignored - } + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "fchmodat", tid, status); } PRE(sys_cachestat) @@ -6490,23 +6445,15 @@ POST(sys_cachestat) PRE(sys_fchmodat2) { - Int arg_1 = (Int) ARG1; - const HChar *path = (const HChar*) ARG2; FUSE_COMPATIBLE_MAY_BLOCK(); - PRINT("sys_fchmodat2 ( %d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %" + PRINT("sys_fchmodat2 ( %" FMT_REGWORD "d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %" FMT_REGWORD "u )", - arg_1, ARG2, path, ARG3, ARG4); + SARG1, ARG2, (const HChar*)ARG2, ARG3, ARG4); PRE_REG_READ4(long, "fchmodat2", int, dfd, const char *, path, vki_mode_t, mode, unsigned int, flags); PRE_MEM_RASCIIZ( "fchmodat2(pathname)", ARG2 ); - if (ML_(safe_to_deref) (path, 1)) { - // If pathname is relative and dirfd is the special value AT_FDCWD, then pathname is interpreted ... - if (path[0] != '/') - if ( arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "fchmodat2", tid, False) ) - SET_STATUS_Failure( VKI_EBADF ); - // If pathname is absolute, then dirfd is ignored - } + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "fchmodat2", tid, status); } PRE(sys_faccessat) @@ -6520,9 +6467,7 @@ PRE(sys_faccessat) PRE_REG_READ3(long, "faccessat", int, dfd, const char *, pathname, int, mode); PRE_MEM_RASCIIZ( "faccessat(pathname)", ARG2 ); - if ((ML_(safe_to_deref) (path, 1)) && (path[0] != '/')) - if ( arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "faccessat", tid, False) ) - SET_STATUS_Failure( VKI_EBADF ); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "faccessat", tid, status); } PRE(sys_faccessat2) @@ -6537,9 +6482,7 @@ PRE(sys_faccessat2) PRE_REG_READ4(long, "faccessat2", int, dfd, const char *, pathname, int, mode, int, flags); PRE_MEM_RASCIIZ( "faccessat2(pathname)", ARG2 ); - if ((ML_(safe_to_deref) (path, 1)) && (path[0] != '/')) - if ( arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "faccessat2", tid, False) ) - SET_STATUS_Failure( VKI_EBADF ); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "faccessat2", tid, status); } PRE(sys_name_to_handle_at) @@ -14205,11 +14148,8 @@ PRE(sys_openat2) /* For absolute filenames, dirfd is ignored. If dirfd is AT_FDCWD, filename is relative to cwd. When comparing dirfd against AT_FDCWD, be sure only to compare the bottom 32 bits. */ - if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && *(Char *)(Addr)ARG2 != '/' - && ((Int)ARG1) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG1, "openat2", tid, False)) - SET_STATUS_Failure( VKI_EBADF ); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "openat2", tid, status); + /* Handle the case where the open is of /proc/self/cmdline or /proc//cmdline, and just give it a copy of the fd for the fake file we cooked up at startup (in m_main). Also, seek the diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c index 59c7d4e97..09d292ea8 100644 --- a/coregrind/m_syswrap/syswrap-mips32-linux.c +++ b/coregrind/m_syswrap/syswrap-mips32-linux.c @@ -551,11 +551,7 @@ PRE(sys_fstatat64) SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4); PRE_REG_READ4(long, "fstatat64", int, dfd, char *, file_name, struct stat64 *, buf, int, flags); - if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && *(Char *)(Addr)ARG2 != '/' - && ((Int)ARG1) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG1, "fstatat64", tid, False)) - SET_STATUS_Failure( VKI_EBADF ); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "fstatat64", tid, status); PRE_MEM_RASCIIZ ("fstatat64(file_name)", ARG2); PRE_MEM_WRITE ("fstatat64(buf)", ARG3, sizeof (struct vki_stat64)); } diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index b6c3401b8..cb4410795 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -315,11 +315,7 @@ PRE(sys_fstatat64) ARG3); PRE_REG_READ3(long, "fstatat64", int, dfd, char *, file_name, struct stat64 *, buf); - if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && *(Char *)(Addr)ARG2 != '/' - && ((Int)ARG1) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG1, "fstatat64", tid, False)) - SET_STATUS_Failure( VKI_EBADF ); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "fstatat64", tid, status); PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 ); PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) ); } diff --git a/coregrind/m_syswrap/syswrap-x86-freebsd.c b/coregrind/m_syswrap/syswrap-x86-freebsd.c index 5ea0524c7..483ca67ec 100644 --- a/coregrind/m_syswrap/syswrap-x86-freebsd.c +++ b/coregrind/m_syswrap/syswrap-x86-freebsd.c @@ -1388,15 +1388,11 @@ POST(sys_procctl) // int mknodat(int fd, const char *path, mode_t mode, dev_t dev); PRE(sys_mknodat) { - Int arg_1 = (Int)ARG1; - const HChar *path = (const HChar*)ARG2; PRINT("sys_mknodat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), 0x%" FMT_REGWORD "x, 0x%" FMT_REGWORD "x )", ARG1,ARG2,(char*)ARG2,ARG3,ARG4 ); PRE_REG_READ5(long, "mknodat", int, fd, const char *, path, vki_mode_t, mode, vki_uint32_t, MERGE64_FIRST(dev), vki_uint32_t, MERGE64_SECOND(idev)) PRE_MEM_RASCIIZ( "mknodat(pathname)", ARG2 ); - if ((ML_(safe_to_deref)(path, 1)) && (path[0] != '/')) - if (arg_1 != VKI_AT_FDCWD && !ML_(fd_allowed)(arg_1, "mknodat", tid, False)) - SET_STATUS_Failure(VKI_EBADF); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "mknodat", tid, status); } // SYS_cpuset_getdomain 561 diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 867c31d06..45c76a6db 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -1032,11 +1032,7 @@ PRE(sys_fstatat64) SARG1, ARG2, (HChar*)ARG2, ARG3, ARG4); PRE_REG_READ4(long, "fstatat64", int, dfd, char *, file_name, struct stat64 *, buf, int, flags); - if (ML_(safe_to_deref)( (void*)(Addr)ARG2, 1 ) - && *(Char *)(Addr)ARG2 != '/' - && ((Int)ARG1) != ((Int)VKI_AT_FDCWD) - && !ML_(fd_allowed)(ARG1, "fstatat64", tid, False)) - SET_STATUS_Failure( VKI_EBADF ); + ML_(fd_at_check_allowed)(SARG1, (const HChar*)ARG2, "fstatat64", tid, status); PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 ); PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) ); }