There were various issues related to the limited size of integers used in the verifier: - `off + size` overflow in __check_map_access() - `off + reg->off` overflow in check_mem_access() - `off + reg->var_off.value` overflow or 32-bit truncation of `reg->var_off.value` in check_mem_access() - 32-bit truncation in check_stack_boundary() Make sure that any integer math cannot overflow by not allowing pointer math with large values. Also reduce the scope of "scalar op scalar" tracking.
Showing the changes to include/linux (1 of 2 files). Show all
Unified · Split
| @@ -15,11 +15,11 @@ · 14 unmodified lines | ||
| 15 | 15 | * In practice this is far bigger than any realistic pointer offset; this limit |
| 16 | 16 | * ensures that umax_value + (int)off + (int)size cannot overflow a u64. |
| 17 | 17 | */ |
| 18 | −#define BPF_MAX_VAR_OFF (1ULL << 31) | |
| 18 | +#define BPF_MAX_VAR_OFF (1 << 29) | |
| 19 | 19 | /* Maximum variable size permitted for ARG_CONST_SIZE[_OR_ZERO]. This ensures |
| 20 | 20 | * that converting umax_value to int cannot overflow. |
| 21 | 21 | */ |
| 22 | −#define BPF_MAX_VAR_SIZ INT_MAX | |
| 22 | +#define BPF_MAX_VAR_SIZ (1 << 29) | |
| 23 | 23 | |
| 24 | 24 | /* Liveness marks, used for registers and spilled-regs (in stack slots). |
| 25 | 25 | * Read marks propagate upwards until they find a write mark; they record that |