]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
FreeBSD syscall: improve utrace wrapper
authorPaul Floyd <pjfloyd@wanadoo.fr>
Tue, 4 Feb 2025 19:34:57 +0000 (20:34 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Tue, 4 Feb 2025 19:34:57 +0000 (20:34 +0100)
The public wrapper is just a void pointer and length.
Internally, the struct used has holes which generate
errors (since ld.so which is probably the only user
of this syscall doesn't memset the struct to zero). Added
the struct definition and PRE_MEM_READ for each field.

.gitignore
coregrind/m_syswrap/syswrap-freebsd.c
memcheck/tests/freebsd/Makefile.am
memcheck/tests/freebsd/scalar.stderr.exp
memcheck/tests/freebsd/scalar.stderr.exp-x86
memcheck/tests/freebsd/utrace.stderr.exp [new file with mode: 0644]
memcheck/tests/freebsd/utrace.vgtest [new file with mode: 0644]

index 483b077ca389af78e2631db5f7866a1a2ac69ab8..c5a2b0592c259aa689a12b656c9172a4a5c0627f 100644 (file)
 /memcheck/tests/freebsd/timing_safe
 /memcheck/tests/freebsd/utimens
 /memcheck/tests/freebsd/utimes
+/memcheck/tests/freebsd/utrace
 
 # /memcheck/tests/amd64-freebsd
 /memcheck/tests/amd64-freebsd/*.stderr.diff
index 3397249383c04f0535d3321fa2680e9adadad5a3..6fd4367a831ced0a35e608ab8c22186ee24728f9 100644 (file)
@@ -3109,13 +3109,40 @@ POST(sys_sched_rr_get_interval)
    POST_MEM_WRITE(ARG2, sizeof(struct vki_timespec));
 }
 
+/*
+ * Putting this here rather than in vki-freebsd.h because this is a workaround
+ * (see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=284563)
+ * The syscall interface doesn't allow us to properly validate the memory,
+ * and struct utrace_rtld isn't public.
+ */
+#define        VKI_RTLD_UTRACE_SIG_SZ 4
+
+struct vki_utrace_rtld {
+    char sig[VKI_RTLD_UTRACE_SIG_SZ];
+    int event;
+    void *handle;
+    void *mapbase;
+    size_t mapsize;
+    int refcnt;
+    char name[VKI_PATH_MAX];
+};
+
 // SYS_utrace  335
 // int utrace(const void *addr, size_t len);
 PRE(sys_utrace)
 {
    PRINT("sys_utrace ( %#" FMT_REGWORD "x, %" FMT_REGWORD "u )", ARG1, ARG2);
    PRE_REG_READ2(int, "utrace", const void *, addr, vki_size_t, len);
-   PRE_MEM_READ( "utrace(addr)", ARG1, ARG2 );
+   if (ARG1 && ARG2 >= sizeof(struct vki_utrace_rtld) && ML_(safe_to_deref)((const void*)ARG1, ARG2)) {
+       struct vki_utrace_rtld* ut = (struct vki_utrace_rtld*)ARG1;
+       PRE_MEM_READ("utrace(addr.sig)", (Addr)&ut->sig, VKI_RTLD_UTRACE_SIG_SZ*sizeof(char));
+       PRE_MEM_READ("utrace(addr.event)", (Addr)&ut->event, sizeof(int));
+       PRE_MEM_READ("utrace(addr.handle)", (Addr)&ut->handle, sizeof(void*));
+       PRE_MEM_READ("utrace(addr.mapbase)", (Addr)&ut->mapbase, sizeof(void*));
+       PRE_MEM_READ("utrace(addr.mapsize)", (Addr)&ut->mapsize, sizeof(size_t));
+       PRE_MEM_READ("utrace(addr.refcnt)", (Addr)&ut->handle, sizeof(int));
+       PRE_MEM_READ("utrace(addr.name)", (Addr)&ut->name, VKI_PATH_MAX*sizeof(char));
+   }
 }
 
 // SYS_kldsym  337
index 4b6b36c6ce00b0ea989eaa617bbac9a556b38746..1213b318988b8206e1e66ab583057e566121c56d 100644 (file)
@@ -137,7 +137,10 @@ EXTRA_DIST = \
        utimens.stderr.exp \
        utimes.vgtest \
        utimes.stderr.exp-x86 \
-       utimes.stderr.exp
+       utimes.stderr.exp \
+       utrace.vgtest \
+       utrace.stderr.exp
+
 
 check_PROGRAMS = \
        access aio aio_read aligned_alloc bug464476 bug470713 \
index 4a57e002aa70187d67d6bf8c76dd6fa6bcdb125b..0e47fe1aacd94afd3ad3b082b99d970a1e5c1d7d 100644 (file)
@@ -2391,10 +2391,6 @@ Syscall param utrace(addr) contains uninitialised byte(s)
 Syscall param utrace(len) contains uninitialised byte(s)
    ...
 
-Syscall param utrace(addr) points to unaddressable byte(s)
-   ...
- Address 0x........ is not stack'd, malloc'd or (recently) free'd
-
 ---------------------------------------------------------
 337:              SYS_kldsym 3s 1m
 ---------------------------------------------------------
index 86599836de22ce3188d1aa5e5ca6f88903a05cbe..6a532ae8e07e9796d43b71d19c35f4c853164d09 100644 (file)
@@ -2397,10 +2397,6 @@ Syscall param utrace(addr) contains uninitialised byte(s)
 Syscall param utrace(len) contains uninitialised byte(s)
    ...
 
-Syscall param utrace(addr) points to unaddressable byte(s)
-   ...
- Address 0x........ is not stack'd, malloc'd or (recently) free'd
-
 ---------------------------------------------------------
 337:              SYS_kldsym 3s 1m
 ---------------------------------------------------------
diff --git a/memcheck/tests/freebsd/utrace.stderr.exp b/memcheck/tests/freebsd/utrace.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/memcheck/tests/freebsd/utrace.vgtest b/memcheck/tests/freebsd/utrace.vgtest
new file mode 100644 (file)
index 0000000..2b69572
--- /dev/null
@@ -0,0 +1,6 @@
+# This produces no output (only does so under truss or ktrace)
+# but there was an issue with the syscall that generated false positives
+# due to holes in the struct used
+env: LD_UTRACE=1
+prog: ../../../tests/true
+vgopts: -q