Skip to content

Commit

Permalink
kernel: userspace: manipulate _thread_idx_map on per-byte basis
Browse files Browse the repository at this point in the history
The sys_bitfield_(clear/set)_bit() work on pointer size element.
However, _thread_idx_map[] is a byte array. On little endian
systems, the bitops should work fine. However, on big endian
systems, changing the lower bits may actually be manipulating
memory outside the array when CONFIG_MAX_THREAD_BYTES is not
multiple of 4. So modify the code to perform bit ops on
a per-byte basis.

Fixes zephyrproject-rtos#72430

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
  • Loading branch information
dcpleung committed May 15, 2024
1 parent 859cc2f commit 25a4aef
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions kernel/userspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,10 @@ static bool thread_idx_alloc(uintptr_t *tidx)
if (idx != 0) {
*tidx = base + (idx - 1);

sys_bitfield_clear_bit((mem_addr_t)_thread_idx_map,
*tidx);
/* Clear the bit. We already know the array index,
* and the bit to be cleared.
*/
_thread_idx_map[i] &= ~(BIT(idx - 1));

/* Clear permission from all objects */
k_object_wordlist_foreach(clear_perms_cb,
Expand Down Expand Up @@ -308,7 +310,8 @@ static void thread_idx_free(uintptr_t tidx)
/* To prevent leaked permission when index is recycled */
k_object_wordlist_foreach(clear_perms_cb, (void *)tidx);

sys_bitfield_set_bit((mem_addr_t)_thread_idx_map, tidx);
/* _thread_idx_map[] is of uint8_t */
_thread_idx_map[tidx / 8] |= BIT(tidx % 8);
}

static struct k_object *dynamic_object_create(enum k_objects otype, size_t align,
Expand Down

0 comments on commit 25a4aef

Please sign in to comment.