mirror of
https://github.com/torvalds/linux.git
synced 2026-09-14 16:10:02 +02:00
bpf: Remove dynptr check in check_stack_range_initialized()
For a MEM_UNINIT ("raw mode") helper argument,
check_stack_range_initialized() open-coded a scan that rejected any
STACK_DYNPTR slot in the range with "potential write to dynptr". This
duplicated, and was stricter than, the handling that runs when the
buffer is actually marked initialized. check_helper_call() later replays
the write byte by byte via check_mem_access(), which goes through
destroy_if_dynptr_stack_slot(), which rejects overwritting a referenced
dynptr. Therefore drop the redundant scan and rely on check_mem_access().
Signed-off-by: Amery Hung <ameryhung@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20260715064047.1793790-2-ameryhung@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
This commit is contained in:
parent
f68df52fba
commit
c28cbef2f8
|
|
@ -6733,31 +6733,6 @@ static int check_stack_range_initialized(
|
|||
}
|
||||
|
||||
if (meta && meta->raw_mode) {
|
||||
/* Ensure we won't be overwriting dynptrs when simulating byte
|
||||
* by byte access in check_helper_call using meta.access_size.
|
||||
* This would be a problem if we have a helper in the future
|
||||
* which takes:
|
||||
*
|
||||
* helper(uninit_mem, len, dynptr)
|
||||
*
|
||||
* Now, uninint_mem may overlap with dynptr pointer. Hence, it
|
||||
* may end up writing to dynptr itself when touching memory from
|
||||
* arg 1. This can be relaxed on a case by case basis for known
|
||||
* safe cases, but reject due to the possibilitiy of aliasing by
|
||||
* default.
|
||||
*/
|
||||
for (i = min_off; i < max_off + access_size; i++) {
|
||||
int stack_off = -i - 1;
|
||||
|
||||
spi = bpf_get_spi(i);
|
||||
/* raw_mode may write past allocated_stack */
|
||||
if (state->allocated_stack <= stack_off)
|
||||
continue;
|
||||
if (state->stack[spi].slot_type[stack_off % BPF_REG_SIZE] == STACK_DYNPTR) {
|
||||
verbose(env, "potential write to dynptr at off=%d disallowed\n", i);
|
||||
return -EACCES;
|
||||
}
|
||||
}
|
||||
meta->access_size = access_size;
|
||||
meta->regno = reg_from_argno(argno);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1112,7 +1112,7 @@ int dynptr_overwrite_ref(void *ctx)
|
|||
|
||||
/* Reject writes to dynptr slot from bpf_dynptr_read */
|
||||
SEC("?raw_tp")
|
||||
__failure __msg("potential write to dynptr at off=-16")
|
||||
__failure __msg("cannot overwrite referenced dynptr")
|
||||
int dynptr_read_into_slot(void *ctx)
|
||||
{
|
||||
union {
|
||||
|
|
@ -1558,7 +1558,7 @@ int BPF_PROG(skb_invalid_ctx_fexit, void *skb)
|
|||
|
||||
/* Reject writes to dynptr slot for uninit arg */
|
||||
SEC("?raw_tp")
|
||||
__failure __msg("potential write to dynptr at off=-16")
|
||||
__failure __msg("cannot overwrite referenced dynptr")
|
||||
int uninit_write_into_slot(void *ctx)
|
||||
{
|
||||
struct {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user