]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Improve FreeBSD sysctl kern.usrstack
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 3 Jul 2022 11:58:18 +0000 (13:58 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 3 Jul 2022 13:12:20 +0000 (15:12 +0200)
This was handled by sysctl but not sysctlbyname.
The value returned was wrong.
Added a regtest.

.gitignore
coregrind/m_main.c
coregrind/m_syswrap/syswrap-freebsd.c
none/tests/freebsd/Makefile.am
none/tests/freebsd/usrstack.c [new file with mode: 0644]
none/tests/freebsd/usrstack.stderr.exp [new file with mode: 0644]
none/tests/freebsd/usrstack.stdout.exp [new file with mode: 0644]
none/tests/freebsd/usrstack.vgtest [new file with mode: 0644]

index b749c130c9460b9b3d6d74fc8307637a0b44f634..d816acf815d2ef4c9feef2266ea5a851e9c37d45 100644 (file)
 /none/tests/freebsd/fexecve
 /none/tests/freebsd/hello_world
 /none/tests/freebsd/452275
+/none/tests/freebsd/usrstack
 
 # /none/tests/x86/
 /none/tests/x86/*.dSYM
index d0fbc0c56c7cb33b923ca0c71557d6c1e755479e..f12ba01b5fbd23f8b4734993035add8b908c0cf1 100644 (file)
@@ -3897,7 +3897,7 @@ UWord voucher_mach_msg_set ( UWord arg1 )
 
 Word VG_(get_usrstack)(void)
 {
-   return VG_PGROUNDDN(the_iicii.clstack_end - the_iifii.clstack_max_size);
+   return VG_PGROUNDDN(the_iicii.clstack_end) + VKI_PAGE_SIZE;
 }
 
 
index aeb2a1cd620f42e851b5dbc47091fd7968ca0f28..b963f56763e9366f9afac8bb99bde0746d6e4c13 100644 (file)
@@ -1960,6 +1960,12 @@ static Bool sysctl_kern_ps_strings(SizeT* out, SizeT* outlen)
    return False;
 }
 
+static void sysctl_kern_usrstack(SizeT* out, SizeT* outlen)
+{
+   *out = VG_(get_usrstack)();
+   *outlen = sizeof(ULong);
+}
+
 // SYS___sysctl   202
 /* int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); */
 /*               ARG1        ARG2          ARG3         ARG4           ARG5        ARG6 */
@@ -2028,11 +2034,7 @@ PRE(sys___sysctl)
    if (SARG2 >= 2 && ML_(safe_to_deref)(name, 2*sizeof(int))) {
       if (name[0] == 1 && name[1] == 33) {
          // kern.userstack
-         Word tmp = VG_(get_usrstack)();
-         size_t* out = (size_t*)ARG3;
-         size_t* outlen = (size_t*)ARG4;
-         *out = tmp;
-         *outlen = sizeof(ULong);
+         sysctl_kern_usrstack((size_t*)ARG3, (size_t*)ARG4);
          SET_STATUS_Success(0);
       }
    }
@@ -6281,10 +6283,16 @@ PRE(sys___sysctlbyname)
    if (ML_(safe_to_deref)(name, sizeof("kern.ps_strings")) &&
        VG_(strcmp)(name, "kern.ps_strings") == 0) {
       if (sysctl_kern_ps_strings((SizeT*)ARG3, (SizeT*)ARG4)) {
-        SET_STATUS_Success(0);
+         SET_STATUS_Success(0);
       }
    }
 
+   if (ML_(safe_to_deref)(name, sizeof("kern.usrstack")) &&
+      VG_(strcmp)(name, "kern.usrstack") == 0) {
+      sysctl_kern_usrstack((size_t*)ARG3, (size_t*)ARG4);
+      SET_STATUS_Success(0);
+   }
+
    // read number of ints specified in ARG2 from mem pointed to by ARG1
    PRE_MEM_READ("__sysctlbyname(name)", (Addr)ARG1, ARG2 * sizeof(int));
 
index 4a29928238107a48d93b5fe250afd540995793a9..f1f8a5628b961b3cf16b9fa7641a6ce37ecae6cd 100644 (file)
@@ -30,10 +30,13 @@ EXTRA_DIST = \
        fexecve_txt.vgtest \
        fexecve_txt.stderr.exp \
        452275.vgtest \
-       452275.stderr.exp
+       452275.stderr.exp \
+       usrstack.vgtest \
+       usrstack.stderr.exp \
+       usrstack.stdout.exp
 
 check_PROGRAMS = \
-       auxv osrel swapcontext hello_world fexecve 452275
+       auxv osrel swapcontext hello_world fexecve 452275 usrstack
 
 AM_CFLAGS   += $(AM_FLAG_M3264_PRI)
 AM_CXXFLAGS += $(AM_FLAG_M3264_PRI)
diff --git a/none/tests/freebsd/usrstack.c b/none/tests/freebsd/usrstack.c
new file mode 100644 (file)
index 0000000..4f3d692
--- /dev/null
@@ -0,0 +1,43 @@
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(void)
+{
+   int stack_variable = 1;
+   unsigned long v1;
+   unsigned long v2;
+   int name[] = {CTL_KERN, KERN_USRSTACK};
+   size_t len = sizeof(unsigned long);
+
+   if (sysctlbyname("kern.usrstack", &v1, &len, NULL, 0) < 0) {
+      perror("sysctlbyname failed:");
+      exit(-1);
+   }
+   
+   if (sysctl(name, 2, &v2, &len, NULL, 0) < 0) {
+      perror("sysctl failed:");
+      exit(-1);
+   }
+   
+   if (v1 == v2) {
+       printf("OK 1\n");
+   } else {
+       printf("FAIL usrstack different\n");
+       printf("v1 %lx v2 %lx\n", v1, v2);
+   }
+
+
+   /* the purpose of this is to check that the sysctl isn't
+      returning the host stack. I expec the difference to be less than 0x1000 */
+   if (v1 - (unsigned long)&stack_variable > 0x2000U) {
+      printf("FAIL usrstack fishy\n");
+      printf("v1 %lx stack_variable %p diff %lx\n", v1, &stack_variable,  v1 - (unsigned long)&stack_variable);
+   } else {
+      printf("OK 2\n");
+   }
+}
+
diff --git a/none/tests/freebsd/usrstack.stderr.exp b/none/tests/freebsd/usrstack.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/freebsd/usrstack.stdout.exp b/none/tests/freebsd/usrstack.stdout.exp
new file mode 100644 (file)
index 0000000..58ff19a
--- /dev/null
@@ -0,0 +1,2 @@
+OK 1
+OK 2
diff --git a/none/tests/freebsd/usrstack.vgtest b/none/tests/freebsd/usrstack.vgtest
new file mode 100644 (file)
index 0000000..fd25654
--- /dev/null
@@ -0,0 +1,3 @@
+prog: usrstack
+vgopts: -q
+