kernel: sched: Fix validation of priority levels

A priority value cannot be simultaneously higher than the maximum
possible value and smaller than the minimum value.  Rewrite the
_VALID_PRIO() macro as a function so that this if either of these
invariants are invalid, the priority is considered invalid.

Coverity-CID: 182584
Coverity-CID: 182585
Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
This commit is contained in:
Leandro Pereira 2018-02-16 17:05:08 -08:00 committed by Anas Nashif
commit 541c3cb18b
3 changed files with 40 additions and 22 deletions

View file

@ -60,26 +60,6 @@ static inline int _is_idle_thread_ptr(k_tid_t thread)
#endif
}
#ifdef CONFIG_MULTITHREADING
#define _VALID_PRIO(prio, entry_point) \
(((prio) == K_IDLE_PRIO && _is_idle_thread(entry_point)) || \
(_is_prio_higher_or_equal((prio), \
K_LOWEST_APPLICATION_THREAD_PRIO) && \
_is_prio_lower_or_equal((prio), \
K_HIGHEST_APPLICATION_THREAD_PRIO)))
#define _ASSERT_VALID_PRIO(prio, entry_point) do { \
__ASSERT(_VALID_PRIO((prio), (entry_point)), \
"invalid priority (%d); allowed range: %d to %d", \
(prio), \
K_LOWEST_APPLICATION_THREAD_PRIO, \
K_HIGHEST_APPLICATION_THREAD_PRIO); \
} while ((0))
#else
#define _VALID_PRIO(prio, entry_point) ((prio) == -1)
#define _ASSERT_VALID_PRIO(prio, entry_point) __ASSERT((prio) == -1, "")
#endif
/*
* The _is_prio_higher family: I created this because higher priorities are
* lower numerically and I always found somewhat confusing seeing, e.g.:
@ -144,6 +124,44 @@ static inline int _is_higher_prio_than_current(struct k_thread *thread)
return _is_t1_higher_prio_than_t2(thread, _current);
}
#ifdef CONFIG_MULTITHREADING
static inline int _is_valid_prio(int prio, void *entry_point)
{
if (prio == K_IDLE_PRIO && _is_idle_thread(entry_point)) {
return 1;
}
if (!_is_prio_higher_or_equal(prio,
K_LOWEST_APPLICATION_THREAD_PRIO)) {
return 0;
}
if (!_is_prio_lower_or_equal(prio,
K_HIGHEST_APPLICATION_THREAD_PRIO)) {
return 0;
}
return 1;
}
#define _ASSERT_VALID_PRIO(prio, entry_point) do { \
__ASSERT(_is_valid_prio((prio), (entry_point)) == 1, \
"invalid priority (%d); allowed range: %d to %d", \
(prio), \
K_LOWEST_APPLICATION_THREAD_PRIO, \
K_HIGHEST_APPLICATION_THREAD_PRIO); \
} while ((0))
#else
static inline int _is_valid_prio(int prio, void *entry_point)
{
ARG_UNUSED(entry_point);
return prio == -1;
}
#define _ASSERT_VALID_PRIO(prio, entry_point) \
__ASSERT(_is_valid_prio((prio)) == 1, "")
#endif
/* is thread currenlty cooperative ? */
static inline int _is_coop(struct k_thread *thread)
{

View file

@ -302,7 +302,7 @@ _SYSCALL_HANDLER(k_thread_priority_set, thread_p, prio)
struct k_thread *thread = (struct k_thread *)thread_p;
_SYSCALL_OBJ(thread, K_OBJ_THREAD);
_SYSCALL_VERIFY_MSG(_VALID_PRIO(prio, NULL),
_SYSCALL_VERIFY_MSG(_is_valid_prio(prio, NULL),
"invalid thread priority %d", (int)prio);
_SYSCALL_VERIFY_MSG((s8_t)prio >= thread->base.prio,
"thread priority may only be downgraded (%d < %d)",

View file

@ -405,7 +405,7 @@ _SYSCALL_HANDLER(k_thread_create,
/* Check validity of prio argument; must be the same or worse priority
* than the caller
*/
_SYSCALL_VERIFY(_VALID_PRIO(prio, NULL));
_SYSCALL_VERIFY(_is_valid_prio(prio, NULL));
_SYSCALL_VERIFY(_is_prio_lower_or_equal(prio, _current->base.prio));
_setup_new_thread((struct k_thread *)new_thread, stack, stack_size,