History

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().

Amery Hung committed 4 months ago

Commit c28cbef1 parent f68df522 files · +2 −27Browse files

Showing the changes to kernel (1 of 2 files). Show all

Unified · Split

kernel/bpf/verifier.c+0−25
@@ -6733,31 +6733,6 @@ static int check_stack_range_initialized( · 6732 unmodified lines
67336733 }
67346734
67356735 if (meta && meta->raw_mode) {
6736− /* Ensure we won't be overwriting dynptrs when simulating byte
6737− * by byte access in check_helper_call using meta.access_size.
6738− * This would be a problem if we have a helper in the future
6739− * which takes:
6740− *
6741− * helper(uninit_mem, len, dynptr)
6742− *
6743− * Now, uninint_mem may overlap with dynptr pointer. Hence, it
6744− * may end up writing to dynptr itself when touching memory from
6745− * arg 1. This can be relaxed on a case by case basis for known
6746− * safe cases, but reject due to the possibilitiy of aliasing by
6747− * default.
6748− */
6749− for (i = min_off; i < max_off + access_size; i++) {
6750− int stack_off = -i - 1;
6751−
6752− spi = bpf_get_spi(i);
6753− /* raw_mode may write past allocated_stack */
6754− if (state->allocated_stack <= stack_off)
6755− continue;
6756− if (state->stack[spi].slot_type[stack_off % BPF_REG_SIZE] == STACK_DYNPTR) {
6757− verbose(env, "potential write to dynptr at off=%d disallowed\n", i);
6758− return -EACCES;
6759− }
6760− }
67616736 meta->access_size = access_size;
67626737 meta->regno = reg_from_argno(argno);
67636738 return 0;