ALU operations on pointers such as scalar_reg += map_value_ptr are handled in adjust_ptr_min_max_vals(). Problem is however that map_ptr and range in the register state share a union, so transferring state through dst_reg->range = ptr_reg->range is just buggy as any new map_ptr in the dst_reg is then truncated (or null) for subsequent checks. Fix this by adding a raw member and use it for copying state over to dst_reg.
Showing the changes to include/linux (1 of 2 files). Show all
Unified · Split
| @@ -51,6 +51,9 @@ struct bpf_reg_state { · 50 unmodified lines | ||
| 51 | 51 | * PTR_TO_MAP_VALUE_OR_NULL |
| 52 | 52 | */ |
| 53 | 53 | struct bpf_map *map_ptr; |
| 54 | + | |
| 55 | + /* Max size from any of the above. */ | |
| 56 | + unsigned long raw; | |
| 54 | 57 | }; |
| 55 | 58 | /* Fixed part of pointer offset, pointer types only */ |
| 56 | 59 | s32 off; |