Skip to content

Commit f5f95ee

Browse files
lpereiraAnas Nashif
authored andcommitted
kernel: sem: Ensure that initial count is lesser or equal than limit
Ensure this value during static initialization (with build assertions), and dynamic initializations through system calls. If initial count is larger than the limit, it's possible for the count to wraparound, causing locking issues. Expanding the BUILD_ASSERT() macros after declaring a k_sem struct in K_SEM_DEFINE() is necessary to support cases where a semaphore is defined statically. Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
1 parent 05169a0 commit f5f95ee

File tree

2 files changed

+5
-2
lines changed

2 files changed

+5
-2
lines changed

include/kernel.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2695,7 +2695,9 @@ static inline unsigned int _impl_k_sem_count_get(struct k_sem *sem)
26952695
#define K_SEM_DEFINE(name, initial_count, count_limit) \
26962696
struct k_sem name \
26972697
__in_section(_k_sem, static, name) = \
2698-
_K_SEM_INITIALIZER(name, initial_count, count_limit)
2698+
_K_SEM_INITIALIZER(name, initial_count, count_limit); \
2699+
BUILD_ASSERT((count_limit) != 0); \
2700+
BUILD_ASSERT((initial_count) <= (count_limit));
26992701

27002702
/** @} */
27012703

kernel/sem.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ void _impl_k_sem_init(struct k_sem *sem, unsigned int initial_count,
5858
unsigned int limit)
5959
{
6060
__ASSERT(limit != 0, "limit cannot be zero");
61+
__ASSERT(initial_count <= limit, "count cannot be greater than limit");
6162

6263
sem->count = initial_count;
6364
sem->limit = limit;
@@ -75,7 +76,7 @@ void _impl_k_sem_init(struct k_sem *sem, unsigned int initial_count,
7576
_SYSCALL_HANDLER(k_sem_init, sem, initial_count, limit)
7677
{
7778
_SYSCALL_OBJ_INIT(sem, K_OBJ_SEM);
78-
_SYSCALL_VERIFY(limit != 0);
79+
_SYSCALL_VERIFY(limit != 0 && initial_count <= limit);
7980
_impl_k_sem_init((struct k_sem *)sem, initial_count, limit);
8081
return 0;
8182
}

0 commit comments

Comments
 (0)