]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 516748 - clock_nanosleep was also wrong
authorPaul Floyd <pjfloyd@wanadoo.fr>
Mon, 2 Mar 2026 19:15:32 +0000 (20:15 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Mon, 2 Mar 2026 19:49:37 +0000 (20:49 +0100)
clock_nanosleep returns 0 or an errno error code, not 0/-1 and it does not set errno.

The code was copied and pasted from Linux which does return 0/-1.
That means that the POST only needs a POST_MEM_WRITE for ARG4 if
the remainder timespec pointer is not NULL and RES is EINTR.
The error flag is not set so the syscall appears to have succeeded.

.gitignore
coregrind/m_syswrap/syswrap-freebsd.c
memcheck/tests/freebsd/Makefile.am
memcheck/tests/freebsd/clock_nanosleep1.c [new file with mode: 0644]
memcheck/tests/freebsd/clock_nanosleep1.stderr.exp [new file with mode: 0644]
memcheck/tests/freebsd/clock_nanosleep1.vgtest [new file with mode: 0644]
memcheck/tests/freebsd/clock_nanosleep2.c [new file with mode: 0644]
memcheck/tests/freebsd/clock_nanosleep2.vgtest [new file with mode: 0644]
memcheck/tests/freebsd/clock_nanosleep_interrupt.c [deleted file]
memcheck/tests/freebsd/clock_nanosleep_interrupt.stderr.exp [deleted file]
memcheck/tests/freebsd/clock_nanosleep_interrupt.vgtest [deleted file]

index 42581df318e95913ab43102c87940d4494618c9a..8f9ba9ece783ccc4f188fdd23f841a1203d1d03c 100644 (file)
 /memcheck/tests/freebsd/capsicum
 /memcheck/tests/freebsd/chflags
 /memcheck/tests/freebsd/chmod_chown
-/memcheck/tests/freebsd/clock_nanosleep_interrupt
+/memcheck/tests/freebsd/clock_nanosleep1
+/memcheck/tests/freebsd/clock_nanosleep2
 /memcheck/tests/freebsd/delete_sized_mismatch
 /memcheck/tests/freebsd/errno_aligned_allocs
 /memcheck/tests/freebsd/eventfd1
index c9a393947840ff6be959bbf5eef65a1ce534b9af..7dc778595d3e8f6ba4570153e7c71c72aff49774 100644 (file)
@@ -2613,7 +2613,7 @@ PRE(sys_clock_nanosleep)
 
 POST(sys_clock_nanosleep)
 {
-   if (ARG4 != 0 && FAILURE && ERR == VKI_EINTR) {
+   if (ARG4 != 0 && RES == VKI_EINTR) {
       POST_MEM_WRITE( ARG4, sizeof(struct vki_timespec) );
    }
 }
index c59a02b7989f5882feb676a7d1d8d54cc1b09ad9..ae0bd1e48bb547ddcbd1c52f0f8c2f9b4899d76e 100644 (file)
@@ -35,8 +35,9 @@ EXTRA_DIST = \
                chflags.stderr.exp-x86 \
        chmod_chown.vgtest \
        chmod_chown.stderr.exp \
-       clock_nanosleep_interrupt.vgtest \
-       clock_nanosleep_interrupt.stderr.exp \
+       clock_nanosleep1.vgtest \
+       clock_nanosleep1.stderr.exp \
+       clock_nanosleep2.vgtest \
        delete_sized_mismatch.vgtest \
        delete_sized_mismatch.stderr.exp \
        delete_sized_mismatch_xml.vgtest \
@@ -150,7 +151,7 @@ check_PROGRAMS = \
        access aio aio_read aligned_alloc bug464476 bug470713 \
        bug483786 \
        capsicum chflags \
-       chmod_chown clock_nanosleep_interrupt \
+       chmod_chown clock_nanosleep1 clock_nanosleep2 \
        delete_sized_mismatch errno_aligned_allocs \
        extattr fbsd278566 \
        fexecve \
@@ -233,7 +234,7 @@ endif
 access_CFLAGS                  = ${AM_CFLAGS} @FLAG_W_NO_UNINITIALIZED@ @FLAG_W_NO_USE_AFTER_FREE@
 aligned_alloc_CFLAGS           = ${AM_CFLAGS} @FLAG_W_NO_NON_POWER_OF_TWO_ALIGNMENT@
 capsicum_CFLAGS                = ${AM_CFLAGS} @FLAG_W_NO_UNINITIALIZED@ @FLAG_W_NO_USE_AFTER_FREE@
-clock_nanosleep_interrupt_CFLAGS = ${AM_CFLAGS} @FLAG_W_NO_ALLOC_SIZE@
+clock_nanosleep1_CFLAGS                = ${AM_CFLAGS} @FLAG_W_NO_ALLOC_SIZE@
 chflags_CFLAGS                         = ${AM_CFLAGS} @FLAG_W_NO_UNINITIALIZED@ @FLAG_W_NO_USE_AFTER_FREE@
 chmod_chown_CFLAGS             = ${AM_CFLAGS} @FLAG_W_NO_UNINITIALIZED@ @FLAG_W_NO_USE_AFTER_FREE@
 delete_sized_mismatch_CXXFLAGS = ${AM_CXXFLAGS} --std=c++14
diff --git a/memcheck/tests/freebsd/clock_nanosleep1.c b/memcheck/tests/freebsd/clock_nanosleep1.c
new file mode 100644 (file)
index 0000000..14d13fa
--- /dev/null
@@ -0,0 +1,43 @@
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+volatile int     ticks = 0;
+struct itimerval timert;
+struct sigaction timer_action;
+
+void handle_alrm(int sig) { ticks++; }
+
+int main(int argc, char* argv[])
+{
+   timer_action.sa_handler = handle_alrm;
+   sigemptyset(&timer_action.sa_mask);
+   timer_action.sa_flags = SA_RESTART;
+
+   sigaction(SIGALRM, &timer_action, NULL);
+
+   timert.it_interval.tv_sec = timert.it_value.tv_sec = 0;
+   timert.it_interval.tv_usec = timert.it_value.tv_usec = 100;
+   setitimer(ITIMER_REAL, &timert, NULL);
+   
+   struct timespec ts_initialized = {0, 1000000};
+   int ret;
+
+   ret = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts_initialized,
+                         NULL);
+   assert(ret == EINTR);
+
+   struct timespec* too_small = malloc(1);
+
+   ret = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts_initialized,
+                         too_small);
+   assert(ret == EINTR);
+
+   ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, NULL,
+                         &ts_initialized);
+   assert(ret == EFAULT);
+}
diff --git a/memcheck/tests/freebsd/clock_nanosleep1.stderr.exp b/memcheck/tests/freebsd/clock_nanosleep1.stderr.exp
new file mode 100644 (file)
index 0000000..bd5566e
--- /dev/null
@@ -0,0 +1,12 @@
+Syscall param clock_nanosleep(rmtp) points to unaddressable byte(s)
+   ...
+   by 0x........: main (clock_nanosleep1.c:36)
+ Address 0x........ is 0 bytes after a block of size 1 alloc'd
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: main (clock_nanosleep1.c:34)
+
+Syscall param clock_nanosleep(rqtp) points to unaddressable byte(s)
+   ...
+   by 0x........: main (clock_nanosleep1.c:40)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
diff --git a/memcheck/tests/freebsd/clock_nanosleep1.vgtest b/memcheck/tests/freebsd/clock_nanosleep1.vgtest
new file mode 100644 (file)
index 0000000..3d514bf
--- /dev/null
@@ -0,0 +1,2 @@
+prog: clock_nanosleep1
+vgopts: -q
diff --git a/memcheck/tests/freebsd/clock_nanosleep2.c b/memcheck/tests/freebsd/clock_nanosleep2.c
new file mode 100644 (file)
index 0000000..ab22894
--- /dev/null
@@ -0,0 +1,48 @@
+#include <time.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+static void handler(int sig) { (void)sig; }
+
+int main(void)
+{
+    struct sigaction sa;
+    memset(&sa, 0, sizeof(sa));
+    sa.sa_handler = handler;
+    sigaction(SIGUSR1, &sa, NULL);   /* no SA_RESTART */
+
+    /* Child will interrupt us */
+    if (fork() == 0) {
+        usleep(100000);  /* 100ms */
+        kill(getppid(), SIGUSR1);
+        _exit(0);
+    }
+
+    struct timespec req = { .tv_sec = 2, .tv_nsec = 0 };
+    struct timespec rem;
+
+    int ret = clock_nanosleep(CLOCK_MONOTONIC, 0, &req, &rem);
+
+    if (ret != EINTR)
+    {
+        printf("Unexpected return: %d\n", ret);
+        return 1;
+    }
+
+    /* Force full struct read */
+    volatile long sec  = rem.tv_sec;
+    volatile long nsec = rem.tv_nsec;
+
+    /* Trigger uninit read error if rem was not marked as initialised */
+    if (sec || nsec)
+    {
+        return 1;
+    }
+
+    return 0;
+}
+
diff --git a/memcheck/tests/freebsd/clock_nanosleep2.vgtest b/memcheck/tests/freebsd/clock_nanosleep2.vgtest
new file mode 100644 (file)
index 0000000..c848fa3
--- /dev/null
@@ -0,0 +1,2 @@
+prog: clock_nanosleep2
+vgopts: -q
diff --git a/memcheck/tests/freebsd/clock_nanosleep_interrupt.c b/memcheck/tests/freebsd/clock_nanosleep_interrupt.c
deleted file mode 100644 (file)
index 49f4a28..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-volatile int     ticks = 0;
-struct itimerval timert;
-struct sigaction timer_action;
-
-void handle_vtalrm(int sig) { ticks++; }
-
-
-int main(int argc, char* argv[])
-{
-   timer_action.sa_handler = handle_vtalrm;
-   sigemptyset(&timer_action.sa_mask);
-   timer_action.sa_flags = SA_RESTART;
-
-   sigaction(SIGVTALRM, &timer_action, NULL);
-
-   timert.it_interval.tv_sec = timert.it_value.tv_sec = 0;
-   timert.it_interval.tv_usec = timert.it_value.tv_usec = 500;
-   setitimer(ITIMER_VIRTUAL, &timert, NULL);
-   
-   struct timespec ts_initialized = {0, 1000000};
-   struct timespec* too_small = malloc(1);
-
-   clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts_initialized,
-                   too_small);
-}
diff --git a/memcheck/tests/freebsd/clock_nanosleep_interrupt.stderr.exp b/memcheck/tests/freebsd/clock_nanosleep_interrupt.stderr.exp
deleted file mode 100644 (file)
index 1152ed2..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-Syscall param clock_nanosleep(rmtp) points to unaddressable byte(s)
-   ...
-   by 0x........: main (clock_nanosleep_interrupt.c:30)
- Address 0x........ is 0 bytes after a block of size 1 alloc'd
-   at 0x........: malloc (vg_replace_malloc.c:...)
-   by 0x........: main (clock_nanosleep_interrupt.c:28)
-
diff --git a/memcheck/tests/freebsd/clock_nanosleep_interrupt.vgtest b/memcheck/tests/freebsd/clock_nanosleep_interrupt.vgtest
deleted file mode 100644 (file)
index c4b785d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-prog: clock_nanosleep_interrupt
-vgopts: -q