瀏覽代碼

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.
Idan Horowitz 3 年之前
父節點
當前提交
3f838768d9
共有 2 個文件被更改,包括 36 次插入1 次删除
  1. 35 1
      Userland/Libraries/LibC/semaphore.cpp
  2. 1 0
      Userland/Libraries/LibC/semaphore.h

+ 35 - 1
Userland/Libraries/LibC/semaphore.cpp

@@ -12,6 +12,8 @@
 #include <semaphore.h>
 #include <semaphore.h>
 #include <serenity.h>
 #include <serenity.h>
 
 
+static constexpr u32 SEM_MAGIC = 0x78951230;
+
 // Whether sem_wait() or sem_post() is responsible for waking any sleeping
 // Whether sem_wait() or sem_post() is responsible for waking any sleeping
 // threads.
 // threads.
 static constexpr u32 POST_WAKES = 1 << 31;
 static constexpr u32 POST_WAKES = 1 << 31;
@@ -50,19 +52,31 @@ int sem_init(sem_t* sem, int shared, unsigned int value)
         return -1;
         return -1;
     }
     }
 
 
+    sem->magic = SEM_MAGIC;
     sem->value = value;
     sem->value = value;
     return 0;
     return 0;
 }
 }
 
 
 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_destroy.html
 // 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;
     return 0;
 }
 }
 
 
 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_getvalue.html
 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_getvalue.html
 int sem_getvalue(sem_t* sem, int* sval)
 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);
     u32 value = AK::atomic_load(&sem->value, AK::memory_order_relaxed);
     *sval = value & ~POST_WAKES;
     *sval = value & ~POST_WAKES;
     return 0;
     return 0;
@@ -71,6 +85,11 @@ int sem_getvalue(sem_t* sem, int* sval)
 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_post.html
 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_post.html
 int sem_post(sem_t* sem)
 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);
     u32 value = AK::atomic_fetch_add(&sem->value, 1u, AK::memory_order_release);
     // Fast path: no need to wake.
     // Fast path: no need to wake.
     if (!(value & POST_WAKES)) [[likely]]
     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
 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_trywait.html
 int sem_trywait(sem_t* sem)
 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 value = AK::atomic_load(&sem->value, AK::memory_order_relaxed);
     u32 count = value & ~POST_WAKES;
     u32 count = value & ~POST_WAKES;
     if (count == 0) {
     if (count == 0) {
@@ -111,12 +135,22 @@ int sem_trywait(sem_t* sem)
 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_wait.html
 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_wait.html
 int sem_wait(sem_t* sem)
 int sem_wait(sem_t* sem)
 {
 {
+    if (sem->magic != SEM_MAGIC) {
+        errno = EINVAL;
+        return -1;
+    }
+
     return sem_timedwait(sem, nullptr);
     return sem_timedwait(sem, nullptr);
 }
 }
 
 
 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_timedwait.html
 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_timedwait.html
 int sem_timedwait(sem_t* sem, const struct timespec* abstime)
 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);
     u32 value = AK::atomic_load(&sem->value, AK::memory_order_relaxed);
     bool responsible_for_waking = false;
     bool responsible_for_waking = false;
 
 

+ 1 - 0
Userland/Libraries/LibC/semaphore.h

@@ -14,6 +14,7 @@
 __BEGIN_DECLS
 __BEGIN_DECLS
 
 
 typedef struct {
 typedef struct {
+    uint32_t magic;
     uint32_t value;
     uint32_t value;
 } sem_t;
 } sem_t;