Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260805141033.841558-8-matthias.goergens@gmail.com>
Date: Wed,  5 Aug 2026 22:10:30 +0800
From: Matthias Goergens <matthias.goergens@...il.com>
To: musl@...ts.openwall.com
Cc: Matthias Goergens <matthias.goergens@...il.com>
Subject: [PATCH 07/10] regression: test expired deadline in timed waits

An extreme past absolute deadline must report ETIMEDOUT
immediately instead of overflowing the relative-time subtraction
into an unintended wait, while an available semaphore must still
succeed. An alarm bounds the wait so a broken implementation fails
instead of hanging.

Covered by the musl patch "thread: avoid overflow for expired
timed waits".
---
 .../sem-timedwait-expired-deadline.c          | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 src/regression/sem-timedwait-expired-deadline.c

diff --git a/src/regression/sem-timedwait-expired-deadline.c b/src/regression/sem-timedwait-expired-deadline.c
new file mode 100644
index 0000000..ce8814c
--- /dev/null
+++ b/src/regression/sem-timedwait-expired-deadline.c
@@ -0,0 +1,61 @@
+// __timedwait subtracted the current clock from an absolute deadline
+// before deciding whether it had expired, so an extreme past deadline
+// overflowed time_t and became an unintended near-infinite wait.
+// sem_timedwait on an unavailable semaphore must report ETIMEDOUT
+// immediately for an already-expired deadline, while an available
+// semaphore must still succeed. The alarm bounds the wait so a broken
+// implementation fails instead of hanging the test.
+#include <errno.h>
+#include <limits.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+#include "test.h"
+
+static void handler(int sig)
+{
+	(void)sig;
+}
+
+int main(void)
+{
+	sem_t sem;
+	struct timespec at = { .tv_sec = (time_t)INT64_MIN };
+	struct sigaction sa = { .sa_handler = handler };
+	int r;
+
+	if (sigaction(SIGALRM, &sa, 0)) {
+		t_error("sigaction failed\n");
+		return t_status;
+	}
+	if (sem_init(&sem, 0, 0)) {
+		t_error("sem_init failed\n");
+		return t_status;
+	}
+
+	alarm(2);
+	errno = 0;
+	r = sem_timedwait(&sem, &at);
+	alarm(0);
+	if (r != -1 || errno != ETIMEDOUT)
+		t_error("sem_timedwait with expired deadline = %d (errno %d), want -1/ETIMEDOUT\n",
+			r, errno);
+
+	/* control: an available semaphore succeeds despite the deadline */
+	if (sem_post(&sem)) {
+		t_error("sem_post failed\n");
+		return t_status;
+	}
+	alarm(2);
+	errno = 0;
+	r = sem_timedwait(&sem, &at);
+	alarm(0);
+	if (r != 0)
+		t_error("sem_timedwait on available semaphore = %d (errno %d), want 0\n",
+			r, errno);
+
+	sem_destroy(&sem);
+	return t_status;
+}
-- 
2.55.0

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.