]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
syswrap readlink and linux readlinkat: check that buf is accessible for proc self...
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 4 Jan 2026 08:34:54 +0000 (09:34 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 4 Jan 2026 08:34:54 +0000 (09:34 +0100)
Also update the t testcases to cover this.

coregrind/m_syswrap/syswrap-generic.c
coregrind/m_syswrap/syswrap-linux.c
none/tests/Makefile.am
none/tests/bug514094.c
none/tests/linux/Makefile.am
none/tests/linux/readlinkat_self.c

index 406e6960b0bb7f76f9b2a151d462247c1b93d9c7..aa4a0caf11f9bece83ee658aecebbdcb97241e2a 100644 (file)
@@ -5096,8 +5096,12 @@ PRE(sys_readlink)
          HChar* out_name = (HChar*)ARG2;
          SizeT res = VG_(strlen)(VG_(resolved_exename));
          res = VG_MIN(res, ARG3);
-         VG_(strncpy)(out_name, VG_(resolved_exename), res);
-         SET_STATUS_Success(res);
+         if (ML_(safe_to_deref)(out_name, res)) {
+            VG_(strncpy)(out_name, VG_(resolved_exename), res);
+            SET_STATUS_Success(res);
+         } else {
+            SET_STATUS_Failure(VKI_EFAULT);
+         }
          fuse_may_block = False;
       }
    }
index 53b620585b5d3d58bc4cd8e7995d5b5d7f991e6b..6853e5e9453077b9bb206b24b8a11f9e44f557f7 100644 (file)
@@ -6699,8 +6699,12 @@ PRE(sys_readlinkat)
        HChar* out_name = (HChar*)ARG3;
        SizeT res = VG_(strlen)(VG_(resolved_exename));
        res = VG_MIN(res, ARG4);
-       VG_(strncpy)(out_name, VG_(resolved_exename), res);
-       SET_STATUS_Success(res);
+       if (ML_(safe_to_deref)(out_name, res)) {
+          VG_(strncpy)(out_name, VG_(resolved_exename), res);
+          SET_STATUS_Success(res);
+       } else {
+          SET_STATUS_Failure(VKI_EFAULT);
+       }
        fuse_may_block = False;
    }
 
index 4b9b1fe94d562da8b524c4555b1657edc962fe9e..51b5a5b172402ef0c75f5902fbea5d8a67641185 100644 (file)
@@ -392,6 +392,7 @@ bug290061_LDFLAGS   = @FLAG_PIE@
 bug491394_LDADD                = -lc
 bug491394_LDFLAGS      = -nostdlib -static
 bug491394_CFLAGS       = ${AM_CFLAGS} -Os
+bug514094_CFLAGS       = ${AM_CFLAGS} @FLAG_W_NO_STRINGOP_OVERFLOW@
 execve_CFLAGS          = $(AM_CFLAGS) @FLAG_W_NO_NONNULL@
 if VGCONF_OS_IS_SOLARIS
 fcntl_setown_LDADD     = -lsocket -lnsl
index 5010272cbf31387f94ed62bb69cd68baab56b2c3..a62a6406b72271472bc08ff74d9015ed5af60f5f 100644 (file)
@@ -5,6 +5,7 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <limits.h>
+#include <errno.h>
 #include "../../config.h"
 
 int main(int argc, char** argv)
@@ -36,5 +37,12 @@ int main(int argc, char** argv)
    assert(strncmp(resolved, small_buf, 10) == 0);
    assert(small_buf[10] == '#');
 
+#if defined(VGO_solaris)
+   ret = readlink("/proc/self/path/a.out", (char*)1, 100);
+#else
+   ret = readlink("/proc/self/exe", (char*)1, 100);
+#endif
+   assert(ret == -1);
+   assert(errno = EFAULT);
 }
 
index 20540247f3e09a2221d60b085fc5e0f70c92dcf4..a1389fe0de703b8239cd044dd68ad12991e70dfa 100644 (file)
@@ -59,6 +59,7 @@ open_client_SOURCES = open_client.cpp
 endif
 clonev_LDADD = -lpthread
 pthread_stack_LDADD = -lpthread
+readlinkat_self_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_STRINGOP_OVERFLOW@
 
 stack_overflow_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@ \
                        @FLAG_W_NO_INFINITE_RECURSION@
index 5a36d55d8cdc42de82a878984c596f6eef6997aa..586581a0d9667ae4ec369cc4bf4f91fbb3bf1a22 100644 (file)
@@ -5,6 +5,7 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <limits.h>
+#include <errno.h>
 #include "../../config.h"
 
 int main(int argc, char** argv)
@@ -18,5 +19,16 @@ int main(int argc, char** argv)
    char resolved[PATH_MAX];
    realpath(argv[0], resolved);
    assert(strcmp(resolved, buf) == 0);
+
+   const size_t small_buf_size = 11;
+   char small_buf[small_buf_size];
+   memset(small_buf, '#', small_buf_size);
+   ret = readlinkat(100, "/proc/self/exe", small_buf, 10);
+   assert(strncmp(resolved, small_buf, 10) == 0);
+   assert(small_buf[10] == '#');
+
+   ret = readlinkat(101, "/proc/self/exe", (char*)1, 100);
+   assert(ret == -1);
+   assert(errno = EFAULT);
 }