Skip to content

Commit

Permalink
LibPthread: Add magic bytes to the start of sem_t structures
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
IdanHo authored and awesomekling committed Jul 21, 2022
1 parent e80c0bd commit 3f83876
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
36 changes: 35 additions & 1 deletion Userland/Libraries/LibC/semaphore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <semaphore.h>
#include <serenity.h>

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;
Expand Down Expand Up @@ -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;
Expand All @@ -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]]
Expand All @@ -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) {
Expand All @@ -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;

Expand Down
1 change: 1 addition & 0 deletions Userland/Libraries/LibC/semaphore.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
__BEGIN_DECLS

typedef struct {
uint32_t magic;
uint32_t value;
} sem_t;

Expand Down

0 comments on commit 3f83876

Please sign in to comment.