From: Paul Floyd Date: Thu, 28 Aug 2025 19:33:43 +0000 (+0200) Subject: Bug 507869 - Various at syscalls don't check dirfd argument X-Git-Tag: VALGRIND_3_26_0~190 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2a898f1d601a1fddc5437b3e2adc357eced40497;p=thirdparty%2Fvalgrind.git Bug 507869 - Various at syscalls don't check dirfd argument --- diff --git a/NEWS b/NEWS index 66912d73b..46f466cca 100644 --- a/NEWS +++ b/NEWS @@ -77,6 +77,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 507721 Wire up illumos and Solaris mallinfo 507853 faccessat and faccessat2 should handle AT_FDCWD and absolute paths 507868 futimesat doesn't handle AT_FDCWD +507869 Various at syscalls don't check dirfd argument 507873 Make fchmodat and fchmodat2 syscall wrappers accept AT_FDCWD 507897 Allow for patching LTP sources 507970 -Wcalloc-transposed-args warnings in valgrind-di-server.c diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c index 4ba9801ce..1fca10183 100644 --- a/coregrind/m_syswrap/syswrap-arm-linux.c +++ b/coregrind/m_syswrap/syswrap-arm-linux.c @@ -284,6 +284,11 @@ 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)) + 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-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 48c4048aa..f876f839b 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -6372,6 +6372,17 @@ 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 ); + PRE_MEM_RASCIIZ( "renameat2(oldpath)", ARG2 ); PRE_MEM_RASCIIZ( "renameat2(newpath)", ARG4 ); } diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c index 13cb5d05b..59c7d4e97 100644 --- a/coregrind/m_syswrap/syswrap-mips32-linux.c +++ b/coregrind/m_syswrap/syswrap-mips32-linux.c @@ -551,6 +551,11 @@ 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 ); 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 00d0f56d7..b6c3401b8 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -315,6 +315,11 @@ 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 ); 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-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 9b8c9d861..867c31d06 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -1032,6 +1032,11 @@ 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 ); PRE_MEM_RASCIIZ( "fstatat64(file_name)", ARG2 ); PRE_MEM_WRITE( "fstatat64(buf)", ARG3, sizeof(struct vki_stat64) ); }