Skip to content

Commit 2ad265c

Browse files
dcpleungjhedberg
authored andcommitted
kernel: userspace: manipulate _thread_idx_map on per-byte basis
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 #72430 Signed-off-by: Daniel Leung <daniel.leung@intel.com>
1 parent f58ac34 commit 2ad265c

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

kernel/userspace.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,10 @@ static bool thread_idx_alloc(uintptr_t *tidx)
277277
if (idx != 0) {
278278
*tidx = base + (idx - 1);
279279

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

283285
/* Clear permission from all objects */
284286
k_object_wordlist_foreach(clear_perms_cb,
@@ -308,7 +310,11 @@ static void thread_idx_free(uintptr_t tidx)
308310
/* To prevent leaked permission when index is recycled */
309311
k_object_wordlist_foreach(clear_perms_cb, (void *)tidx);
310312

311-
sys_bitfield_set_bit((mem_addr_t)_thread_idx_map, tidx);
313+
/* Figure out which bits to set in _thread_idx_map[] and set it. */
314+
int base = tidx / NUM_BITS(_thread_idx_map[0]);
315+
int offset = tidx % NUM_BITS(_thread_idx_map[0]);
316+
317+
_thread_idx_map[base] |= BIT(offset);
312318
}
313319

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

0 commit comments

Comments
 (0)