]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Make fchmodat and fchmodat2 syscall wrappers accept AT_FDCWD
authorMartin Cermak <mcermak@redhat.com>
Tue, 5 Aug 2025 15:36:29 +0000 (17:36 +0200)
committerMark Wielaard <mark@klomp.org>
Wed, 6 Aug 2025 16:59:11 +0000 (18:59 +0200)
The fchmodat and fchmodat2 syscall wrappers should accept special
value AT_FDCWD as a valid file descriptor.

https://bugs.kde.org/show_bug.cgi?id=507873

NEWS
coregrind/m_syswrap/syswrap-linux.c

diff --git a/NEWS b/NEWS
index cecbd6db7b947d4796d73faff997d1187cefccea..6b21446ec718f5c9e6039a976697e33fbf8ccccc 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -68,6 +68,7 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 506967  Implement and override mallinfo2
 506970  mmap needs an EBADF fd_allowed check
 507173  s390x: Crash when constant folding is disabled
+507873  Make fchmodat and fchmodat2 syscall wrappers accept AT_FDCWD
 507897  Allow for patching LTP sources
 
 To see details of a given bug, visit
index c81d941a74a4f31d2223a28641481f5d7c69cf06..96d22e6f4406d2c3245b67b31b5f73b7705c1df4 100644 (file)
@@ -6407,15 +6407,21 @@ POST(sys_readlinkat)
 
 PRE(sys_fchmodat)
 {
+   Int arg_1 = (Int) ARG1;
+   const HChar *path = (const HChar*) ARG2;
    FUSE_COMPATIBLE_MAY_BLOCK();
-   PRINT("sys_fchmodat ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
-         SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3);
+   PRINT("sys_fchmodat ( %d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u )",
+         arg_1, ARG2, path, ARG3);
    PRE_REG_READ3(long, "fchmodat",
                  int, dfd, const char *, path, vki_mode_t, mode);
    PRE_MEM_RASCIIZ( "fchmodat(path)", ARG2 );
-   if ( !ML_(fd_allowed)(SARG1, "fchmodat", tid, False) )
-     SET_STATUS_Failure( VKI_EBADF );
-
+   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
+   }
 }
 
 PRE(sys_cachestat)
@@ -6440,16 +6446,23 @@ POST(sys_cachestat)
 
 PRE(sys_fchmodat2)
 {
+   Int arg_1 = (Int) ARG1;
+   const HChar *path = (const HChar*) ARG2;
    FUSE_COMPATIBLE_MAY_BLOCK();
-   PRINT("sys_fchmodat2 ( %ld, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %"
+   PRINT("sys_fchmodat2 ( %d, %#" FMT_REGWORD "x(%s), %" FMT_REGWORD "u, %"
          FMT_REGWORD "u )",
-         SARG1, ARG2, (HChar*)(Addr)ARG2, ARG3, ARG4);
+         arg_1, ARG2, path, 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_(fd_allowed)(SARG1, "fchmodat2", tid, False) )
-     SET_STATUS_Failure( VKI_EBADF );
+   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
+   }
 }
 
 PRE(sys_faccessat)