diff options
Diffstat (limited to 'kernel/bpf/verifier.c')
-rw-r--r-- | kernel/bpf/verifier.c | 108 |
1 files changed, 94 insertions, 14 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 6a86723c5b64..af9e84a4944e 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
@@ -504,6 +504,7 @@ static void reset_reg_range_values(struct bpf_reg_state *regs, u32 regno) | |||
504 | { | 504 | { |
505 | regs[regno].min_value = BPF_REGISTER_MIN_RANGE; | 505 | regs[regno].min_value = BPF_REGISTER_MIN_RANGE; |
506 | regs[regno].max_value = BPF_REGISTER_MAX_RANGE; | 506 | regs[regno].max_value = BPF_REGISTER_MAX_RANGE; |
507 | regs[regno].value_from_signed = false; | ||
507 | regs[regno].min_align = 0; | 508 | regs[regno].min_align = 0; |
508 | } | 509 | } |
509 | 510 | ||
@@ -777,12 +778,13 @@ static int check_ctx_access(struct bpf_verifier_env *env, int insn_idx, int off, | |||
777 | return -EACCES; | 778 | return -EACCES; |
778 | } | 779 | } |
779 | 780 | ||
780 | static bool is_pointer_value(struct bpf_verifier_env *env, int regno) | 781 | static bool __is_pointer_value(bool allow_ptr_leaks, |
782 | const struct bpf_reg_state *reg) | ||
781 | { | 783 | { |
782 | if (env->allow_ptr_leaks) | 784 | if (allow_ptr_leaks) |
783 | return false; | 785 | return false; |
784 | 786 | ||
785 | switch (env->cur_state.regs[regno].type) { | 787 | switch (reg->type) { |
786 | case UNKNOWN_VALUE: | 788 | case UNKNOWN_VALUE: |
787 | case CONST_IMM: | 789 | case CONST_IMM: |
788 | return false; | 790 | return false; |
@@ -791,6 +793,11 @@ static bool is_pointer_value(struct bpf_verifier_env *env, int regno) | |||
791 | } | 793 | } |
792 | } | 794 | } |
793 | 795 | ||
796 | static bool is_pointer_value(struct bpf_verifier_env *env, int regno) | ||
797 | { | ||
798 | return __is_pointer_value(env->allow_ptr_leaks, &env->cur_state.regs[regno]); | ||
799 | } | ||
800 | |||
794 | static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg, | 801 | static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg, |
795 | int off, int size, bool strict) | 802 | int off, int size, bool strict) |
796 | { | 803 | { |
@@ -1832,10 +1839,24 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, | |||
1832 | dst_align = dst_reg->min_align; | 1839 | dst_align = dst_reg->min_align; |
1833 | 1840 | ||
1834 | /* We don't know anything about what was done to this register, mark it | 1841 | /* We don't know anything about what was done to this register, mark it |
1835 | * as unknown. | 1842 | * as unknown. Also, if both derived bounds came from signed/unsigned |
1843 | * mixed compares and one side is unbounded, we cannot really do anything | ||
1844 | * with them as boundaries cannot be trusted. Thus, arithmetic of two | ||
1845 | * regs of such kind will get invalidated bounds on the dst side. | ||
1836 | */ | 1846 | */ |
1837 | if (min_val == BPF_REGISTER_MIN_RANGE && | 1847 | if ((min_val == BPF_REGISTER_MIN_RANGE && |
1838 | max_val == BPF_REGISTER_MAX_RANGE) { | 1848 | max_val == BPF_REGISTER_MAX_RANGE) || |
1849 | (BPF_SRC(insn->code) == BPF_X && | ||
1850 | ((min_val != BPF_REGISTER_MIN_RANGE && | ||
1851 | max_val == BPF_REGISTER_MAX_RANGE) || | ||
1852 | (min_val == BPF_REGISTER_MIN_RANGE && | ||
1853 | max_val != BPF_REGISTER_MAX_RANGE) || | ||
1854 | (dst_reg->min_value != BPF_REGISTER_MIN_RANGE && | ||
1855 | dst_reg->max_value == BPF_REGISTER_MAX_RANGE) || | ||
1856 | (dst_reg->min_value == BPF_REGISTER_MIN_RANGE && | ||
1857 | dst_reg->max_value != BPF_REGISTER_MAX_RANGE)) && | ||
1858 | regs[insn->dst_reg].value_from_signed != | ||
1859 | regs[insn->src_reg].value_from_signed)) { | ||
1839 | reset_reg_range_values(regs, insn->dst_reg); | 1860 | reset_reg_range_values(regs, insn->dst_reg); |
1840 | return; | 1861 | return; |
1841 | } | 1862 | } |
@@ -2023,6 +2044,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) | |||
2023 | regs[insn->dst_reg].max_value = insn->imm; | 2044 | regs[insn->dst_reg].max_value = insn->imm; |
2024 | regs[insn->dst_reg].min_value = insn->imm; | 2045 | regs[insn->dst_reg].min_value = insn->imm; |
2025 | regs[insn->dst_reg].min_align = calc_align(insn->imm); | 2046 | regs[insn->dst_reg].min_align = calc_align(insn->imm); |
2047 | regs[insn->dst_reg].value_from_signed = false; | ||
2026 | } | 2048 | } |
2027 | 2049 | ||
2028 | } else if (opcode > BPF_END) { | 2050 | } else if (opcode > BPF_END) { |
@@ -2198,40 +2220,63 @@ static void reg_set_min_max(struct bpf_reg_state *true_reg, | |||
2198 | struct bpf_reg_state *false_reg, u64 val, | 2220 | struct bpf_reg_state *false_reg, u64 val, |
2199 | u8 opcode) | 2221 | u8 opcode) |
2200 | { | 2222 | { |
2223 | bool value_from_signed = true; | ||
2224 | bool is_range = true; | ||
2225 | |||
2201 | switch (opcode) { | 2226 | switch (opcode) { |
2202 | case BPF_JEQ: | 2227 | case BPF_JEQ: |
2203 | /* If this is false then we know nothing Jon Snow, but if it is | 2228 | /* If this is false then we know nothing Jon Snow, but if it is |
2204 | * true then we know for sure. | 2229 | * true then we know for sure. |
2205 | */ | 2230 | */ |
2206 | true_reg->max_value = true_reg->min_value = val; | 2231 | true_reg->max_value = true_reg->min_value = val; |
2232 | is_range = false; | ||
2207 | break; | 2233 | break; |
2208 | case BPF_JNE: | 2234 | case BPF_JNE: |
2209 | /* If this is true we know nothing Jon Snow, but if it is false | 2235 | /* If this is true we know nothing Jon Snow, but if it is false |
2210 | * we know the value for sure; | 2236 | * we know the value for sure; |
2211 | */ | 2237 | */ |
2212 | false_reg->max_value = false_reg->min_value = val; | 2238 | false_reg->max_value = false_reg->min_value = val; |
2239 | is_range = false; | ||
2213 | break; | 2240 | break; |
2214 | case BPF_JGT: | 2241 | case BPF_JGT: |
2215 | /* Unsigned comparison, the minimum value is 0. */ | 2242 | value_from_signed = false; |
2216 | false_reg->min_value = 0; | ||
2217 | /* fallthrough */ | 2243 | /* fallthrough */ |
2218 | case BPF_JSGT: | 2244 | case BPF_JSGT: |
2245 | if (true_reg->value_from_signed != value_from_signed) | ||
2246 | reset_reg_range_values(true_reg, 0); | ||
2247 | if (false_reg->value_from_signed != value_from_signed) | ||
2248 | reset_reg_range_values(false_reg, 0); | ||
2249 | if (opcode == BPF_JGT) { | ||
2250 | /* Unsigned comparison, the minimum value is 0. */ | ||
2251 | false_reg->min_value = 0; | ||
2252 | } | ||
2219 | /* If this is false then we know the maximum val is val, | 2253 | /* If this is false then we know the maximum val is val, |
2220 | * otherwise we know the min val is val+1. | 2254 | * otherwise we know the min val is val+1. |
2221 | */ | 2255 | */ |
2222 | false_reg->max_value = val; | 2256 | false_reg->max_value = val; |
2257 | false_reg->value_from_signed = value_from_signed; | ||
2223 | true_reg->min_value = val + 1; | 2258 | true_reg->min_value = val + 1; |
2259 | true_reg->value_from_signed = value_from_signed; | ||
2224 | break; | 2260 | break; |
2225 | case BPF_JGE: | 2261 | case BPF_JGE: |
2226 | /* Unsigned comparison, the minimum value is 0. */ | 2262 | value_from_signed = false; |
2227 | false_reg->min_value = 0; | ||
2228 | /* fallthrough */ | 2263 | /* fallthrough */ |
2229 | case BPF_JSGE: | 2264 | case BPF_JSGE: |
2265 | if (true_reg->value_from_signed != value_from_signed) | ||
2266 | reset_reg_range_values(true_reg, 0); | ||
2267 | if (false_reg->value_from_signed != value_from_signed) | ||
2268 | reset_reg_range_values(false_reg, 0); | ||
2269 | if (opcode == BPF_JGE) { | ||
2270 | /* Unsigned comparison, the minimum value is 0. */ | ||
2271 | false_reg->min_value = 0; | ||
2272 | } | ||
2230 | /* If this is false then we know the maximum value is val - 1, | 2273 | /* If this is false then we know the maximum value is val - 1, |
2231 | * otherwise we know the mimimum value is val. | 2274 | * otherwise we know the mimimum value is val. |
2232 | */ | 2275 | */ |
2233 | false_reg->max_value = val - 1; | 2276 | false_reg->max_value = val - 1; |
2277 | false_reg->value_from_signed = value_from_signed; | ||
2234 | true_reg->min_value = val; | 2278 | true_reg->min_value = val; |
2279 | true_reg->value_from_signed = value_from_signed; | ||
2235 | break; | 2280 | break; |
2236 | default: | 2281 | default: |
2237 | break; | 2282 | break; |
@@ -2239,6 +2284,12 @@ static void reg_set_min_max(struct bpf_reg_state *true_reg, | |||
2239 | 2284 | ||
2240 | check_reg_overflow(false_reg); | 2285 | check_reg_overflow(false_reg); |
2241 | check_reg_overflow(true_reg); | 2286 | check_reg_overflow(true_reg); |
2287 | if (is_range) { | ||
2288 | if (__is_pointer_value(false, false_reg)) | ||
2289 | reset_reg_range_values(false_reg, 0); | ||
2290 | if (__is_pointer_value(false, true_reg)) | ||
2291 | reset_reg_range_values(true_reg, 0); | ||
2292 | } | ||
2242 | } | 2293 | } |
2243 | 2294 | ||
2244 | /* Same as above, but for the case that dst_reg is a CONST_IMM reg and src_reg | 2295 | /* Same as above, but for the case that dst_reg is a CONST_IMM reg and src_reg |
@@ -2248,41 +2299,64 @@ static void reg_set_min_max_inv(struct bpf_reg_state *true_reg, | |||
2248 | struct bpf_reg_state *false_reg, u64 val, | 2299 | struct bpf_reg_state *false_reg, u64 val, |
2249 | u8 opcode) | 2300 | u8 opcode) |
2250 | { | 2301 | { |
2302 | bool value_from_signed = true; | ||
2303 | bool is_range = true; | ||
2304 | |||
2251 | switch (opcode) { | 2305 | switch (opcode) { |
2252 | case BPF_JEQ: | 2306 | case BPF_JEQ: |
2253 | /* If this is false then we know nothing Jon Snow, but if it is | 2307 | /* If this is false then we know nothing Jon Snow, but if it is |
2254 | * true then we know for sure. | 2308 | * true then we know for sure. |
2255 | */ | 2309 | */ |
2256 | true_reg->max_value = true_reg->min_value = val; | 2310 | true_reg->max_value = true_reg->min_value = val; |
2311 | is_range = false; | ||
2257 | break; | 2312 | break; |
2258 | case BPF_JNE: | 2313 | case BPF_JNE: |
2259 | /* If this is true we know nothing Jon Snow, but if it is false | 2314 | /* If this is true we know nothing Jon Snow, but if it is false |
2260 | * we know the value for sure; | 2315 | * we know the value for sure; |
2261 | */ | 2316 | */ |
2262 | false_reg->max_value = false_reg->min_value = val; | 2317 | false_reg->max_value = false_reg->min_value = val; |
2318 | is_range = false; | ||
2263 | break; | 2319 | break; |
2264 | case BPF_JGT: | 2320 | case BPF_JGT: |
2265 | /* Unsigned comparison, the minimum value is 0. */ | 2321 | value_from_signed = false; |
2266 | true_reg->min_value = 0; | ||
2267 | /* fallthrough */ | 2322 | /* fallthrough */ |
2268 | case BPF_JSGT: | 2323 | case BPF_JSGT: |
2324 | if (true_reg->value_from_signed != value_from_signed) | ||
2325 | reset_reg_range_values(true_reg, 0); | ||
2326 | if (false_reg->value_from_signed != value_from_signed) | ||
2327 | reset_reg_range_values(false_reg, 0); | ||
2328 | if (opcode == BPF_JGT) { | ||
2329 | /* Unsigned comparison, the minimum value is 0. */ | ||
2330 | true_reg->min_value = 0; | ||
2331 | } | ||
2269 | /* | 2332 | /* |
2270 | * If this is false, then the val is <= the register, if it is | 2333 | * If this is false, then the val is <= the register, if it is |
2271 | * true the register <= to the val. | 2334 | * true the register <= to the val. |
2272 | */ | 2335 | */ |
2273 | false_reg->min_value = val; | 2336 | false_reg->min_value = val; |
2337 | false_reg->value_from_signed = value_from_signed; | ||
2274 | true_reg->max_value = val - 1; | 2338 | true_reg->max_value = val - 1; |
2339 | true_reg->value_from_signed = value_from_signed; | ||
2275 | break; | 2340 | break; |
2276 | case BPF_JGE: | 2341 | case BPF_JGE: |
2277 | /* Unsigned comparison, the minimum value is 0. */ | 2342 | value_from_signed = false; |
2278 | true_reg->min_value = 0; | ||
2279 | /* fallthrough */ | 2343 | /* fallthrough */ |
2280 | case BPF_JSGE: | 2344 | case BPF_JSGE: |
2345 | if (true_reg->value_from_signed != value_from_signed) | ||
2346 | reset_reg_range_values(true_reg, 0); | ||
2347 | if (false_reg->value_from_signed != value_from_signed) | ||
2348 | reset_reg_range_values(false_reg, 0); | ||
2349 | if (opcode == BPF_JGE) { | ||
2350 | /* Unsigned comparison, the minimum value is 0. */ | ||
2351 | true_reg->min_value = 0; | ||
2352 | } | ||
2281 | /* If this is false then constant < register, if it is true then | 2353 | /* If this is false then constant < register, if it is true then |
2282 | * the register < constant. | 2354 | * the register < constant. |
2283 | */ | 2355 | */ |
2284 | false_reg->min_value = val + 1; | 2356 | false_reg->min_value = val + 1; |
2357 | false_reg->value_from_signed = value_from_signed; | ||
2285 | true_reg->max_value = val; | 2358 | true_reg->max_value = val; |
2359 | true_reg->value_from_signed = value_from_signed; | ||
2286 | break; | 2360 | break; |
2287 | default: | 2361 | default: |
2288 | break; | 2362 | break; |
@@ -2290,6 +2364,12 @@ static void reg_set_min_max_inv(struct bpf_reg_state *true_reg, | |||
2290 | 2364 | ||
2291 | check_reg_overflow(false_reg); | 2365 | check_reg_overflow(false_reg); |
2292 | check_reg_overflow(true_reg); | 2366 | check_reg_overflow(true_reg); |
2367 | if (is_range) { | ||
2368 | if (__is_pointer_value(false, false_reg)) | ||
2369 | reset_reg_range_values(false_reg, 0); | ||
2370 | if (__is_pointer_value(false, true_reg)) | ||
2371 | reset_reg_range_values(true_reg, 0); | ||
2372 | } | ||
2293 | } | 2373 | } |
2294 | 2374 | ||
2295 | static void mark_map_reg(struct bpf_reg_state *regs, u32 regno, u32 id, | 2375 | static void mark_map_reg(struct bpf_reg_state *regs, u32 regno, u32 id, |