]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Linux FreeBSD and Darwin: refactor *at syscall dirfd checks
authorPaul Floyd <pjfloyd@wanadoo.fr>
Fri, 29 Aug 2025 05:59:28 +0000 (07:59 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Fri, 29 Aug 2025 06:02:46 +0000 (08:02 +0200)
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.

12 files changed:
coregrind/m_syswrap/priv_syswrap-generic.h
coregrind/m_syswrap/syswrap-amd64-freebsd.c
coregrind/m_syswrap/syswrap-arm-linux.c
coregrind/m_syswrap/syswrap-arm64-freebsd.c
coregrind/m_syswrap/syswrap-darwin.c
coregrind/m_syswrap/syswrap-freebsd.c
coregrind/m_syswrap/syswrap-generic.c
coregrind/m_syswrap/syswrap-linux.c
coregrind/m_syswrap/syswrap-mips32-linux.c
coregrind/m_syswrap/syswrap-ppc32-linux.c
coregrind/m_syswrap/syswrap-x86-freebsd.c
coregrind/m_syswrap/syswrap-x86-linux.c

index eb815840d9c21b1c8c08205c22974340b0771303..9dbc1e6f2b4a8096b4ba6f47589364a0233a178e 100644 (file)
@@ -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);
index 4d3c178481ecd8167a5e491702f882971526f2c7..b2fc6114f9b0e990d77f70e27f19e5084d75ad95 100644 (file)
@@ -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
index 1fca10183de3c439f831fe5a4a5f7f5aa80ef26f..1aae03c02df406d0b9edcf2b5a8809526d251263 100644 (file)
@@ -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) );
index 6054c641e20e3222a8ba26439453e387e68b060e..fe2d16194068312c9a98cb9e9ac308a132a389e8 100644 (file)
@@ -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
index ba90495bbe395df85eb0b68686cce1ab67269ad4..761965d61072623b70d97a9215bd8e87c6617c43 100644 (file)
@@ -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;
index 7fc96c7c59a19aa8dcabde3a7dd308b2901459e2..8934b76ad280db1cc20d21b356088ffd96b9d44d 100644 (file)
@@ -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
index c7d58bc10601d8a9595ea7078af855e3c54de676..c8c421c95f29d8f50797813f6d1fed461ca74abb 100644 (file)
@@ -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
index f876f839bd91631bf8f1e5f1a9a85023e67a6b4d..f5723f8cdaac8804e6d4345d0ce721f901d5435c 100644 (file)
@@ -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/<pid>/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/<pid>/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
index 59c7d4e9779233e6015091351e561602ef5098e4..09d292ea88b065dbc1e941388ff78e1bf4c37fe1 100644 (file)
@@ -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));
 }
index b6c3401b8d19ed04bcef63438e30a50ef91fb712..cb44107953ac25dfda1ee05c9aca3f81af592b6e 100644 (file)
@@ -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) );
 }
index 5ea0524c76825302c2aeeb9f6ea717c72d64b6e7..483ca67ece6efab6258273722a72f3684647e77d 100644 (file)
@@ -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
index 867c31d06d6b34456f046c1ab9ee9bf02b9e4cf4..45c76a6db5e99ac5807a55d7cc6b01604fe575d8 100644 (file)
@@ -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) );
 }