From 3f838768d95e40808c9e96653565de7b0af96f85 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Thu, 14 Jul 2022 03:02:08 +0300 Subject: [PATCH] LibPthread: Add magic bytes to the start of sem_t structures This helps ensure random pointers are not passed in as semaphores, but more importantly once named semaphores are implemented, this will ensure that random files are not used as semaphores. --- Userland/Libraries/LibC/semaphore.cpp | 36 ++++++++++++++++++++++++++- Userland/Libraries/LibC/semaphore.h | 1 + 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibC/semaphore.cpp b/Userland/Libraries/LibC/semaphore.cpp index a3546459cd..264edcbf92 100644 --- a/Userland/Libraries/LibC/semaphore.cpp +++ b/Userland/Libraries/LibC/semaphore.cpp @@ -12,6 +12,8 @@ #include #include +static constexpr u32 SEM_MAGIC = 0x78951230; + // Whether sem_wait() or sem_post() is responsible for waking any sleeping // threads. static constexpr u32 POST_WAKES = 1 << 31; @@ -50,19 +52,31 @@ int sem_init(sem_t* sem, int shared, unsigned int value) return -1; } + sem->magic = SEM_MAGIC; sem->value = value; return 0; } // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_destroy.html -int sem_destroy(sem_t*) +int sem_destroy(sem_t* sem) { + if (sem->magic != SEM_MAGIC) { + errno = EINVAL; + return -1; + } + + sem->magic = 0; return 0; } // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_getvalue.html int sem_getvalue(sem_t* sem, int* sval) { + if (sem->magic != SEM_MAGIC) { + errno = EINVAL; + return -1; + } + u32 value = AK::atomic_load(&sem->value, AK::memory_order_relaxed); *sval = value & ~POST_WAKES; return 0; @@ -71,6 +85,11 @@ int sem_getvalue(sem_t* sem, int* sval) // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_post.html int sem_post(sem_t* sem) { + if (sem->magic != SEM_MAGIC) { + errno = EINVAL; + return -1; + } + u32 value = AK::atomic_fetch_add(&sem->value, 1u, AK::memory_order_release); // Fast path: no need to wake. if (!(value & POST_WAKES)) [[likely]] @@ -91,6 +110,11 @@ int sem_post(sem_t* sem) // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_trywait.html int sem_trywait(sem_t* sem) { + if (sem->magic != SEM_MAGIC) { + errno = EINVAL; + return -1; + } + u32 value = AK::atomic_load(&sem->value, AK::memory_order_relaxed); u32 count = value & ~POST_WAKES; if (count == 0) { @@ -111,12 +135,22 @@ int sem_trywait(sem_t* sem) // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_wait.html int sem_wait(sem_t* sem) { + if (sem->magic != SEM_MAGIC) { + errno = EINVAL; + return -1; + } + return sem_timedwait(sem, nullptr); } // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_timedwait.html int sem_timedwait(sem_t* sem, const struct timespec* abstime) { + if (sem->magic != SEM_MAGIC) { + errno = EINVAL; + return -1; + } + u32 value = AK::atomic_load(&sem->value, AK::memory_order_relaxed); bool responsible_for_waking = false; diff --git a/Userland/Libraries/LibC/semaphore.h b/Userland/Libraries/LibC/semaphore.h index d04c22943e..3485fb58aa 100644 --- a/Userland/Libraries/LibC/semaphore.h +++ b/Userland/Libraries/LibC/semaphore.h @@ -14,6 +14,7 @@ __BEGIN_DECLS typedef struct { + uint32_t magic; uint32_t value; } sem_t;