Extract the per-argument FP-derived pointer handling from record_call_access() into a new record_arg_access() helper. The existing loop body — checking arg_is_fp, querying stack access bytes, and calling record_stack_access/record_imprecise — will be reused for stack argument slots in the next patch. Factoring it out now avoids duplicating the logic. No functional change.
Unified · Split
| @@ -1343,6 +1343,42 @@ static int record_load_store_access(struct bpf_verifier_env *env, · 1342 unmodified lines | |||
| 1343 | return 0; | 1343 | return 0; |
| 1344 | } | 1344 | } |
| 1345 | 1345 | ||
| 1346 | static int record_arg_access(struct bpf_verifier_env *env, | ||
| 1347 | struct func_instance *instance, | ||
| 1348 | struct bpf_insn *insn, | ||
| 1349 | struct arg_track *at, int arg_idx, | ||
| 1350 | int insn_idx) | ||
| 1351 | { | ||
| 1352 | int depth = instance->depth; | ||
| 1353 | int frame = at->frame; | ||
| 1354 | int err = 0; | ||
| 1355 | s64 bytes; | ||
| 1356 | |||
| 1357 | if (!arg_is_fp(at)) | ||
| 1358 | return 0; | ||
| 1359 | |||
| 1360 | if (bpf_helper_call(insn)) { | ||
| 1361 | bytes = bpf_helper_stack_access_bytes(env, insn, arg_idx, insn_idx); | ||
| 1362 | } else if (bpf_pseudo_kfunc_call(insn)) { | ||
| 1363 | bytes = bpf_kfunc_stack_access_bytes(env, insn, arg_idx, insn_idx); | ||
| 1364 | } else { | ||
| 1365 | for (int f = 0; f <= depth; f++) { | ||
| 1366 | err = mark_stack_read(instance, f, insn_idx, SPIS_ALL); | ||
| 1367 | if (err) | ||
| 1368 | return err; | ||
| 1369 | } | ||
| 1370 | return 0; | ||
| 1371 | } | ||
| 1372 | if (bytes == 0) | ||
| 1373 | return 0; | ||
| 1374 | |||
| 1375 | if (frame >= 0 && frame <= depth) | ||
| 1376 | err = record_stack_access(instance, at, bytes, frame, insn_idx); | ||
| 1377 | else if (frame == ARG_IMPRECISE) | ||
| 1378 | err = record_imprecise(instance, at->mask, insn_idx); | ||
| 1379 | return err; | ||
| 1380 | } | ||
| 1381 | |||
| 1346 | /* Record stack access for a given 'at' state of helper/kfunc 'insn' */ | 1382 | /* Record stack access for a given 'at' state of helper/kfunc 'insn' */ |
| 1347 | static int record_call_access(struct bpf_verifier_env *env, | 1383 | static int record_call_access(struct bpf_verifier_env *env, |
| 1348 | struct func_instance *instance, | 1384 | struct func_instance *instance, |
| @@ -1350,9 +1386,8 @@ static int record_call_access(struct bpf_verifier_env *env, · 1 unmodified line | |||
| 1350 | int insn_idx) | 1386 | int insn_idx) |
| 1351 | { | 1387 | { |
| 1352 | struct bpf_insn *insn = &env->prog->insnsi[insn_idx]; | 1388 | struct bpf_insn *insn = &env->prog->insnsi[insn_idx]; |
| 1353 | int depth = instance->depth; | ||
| 1354 | struct bpf_call_summary cs; | 1389 | struct bpf_call_summary cs; |
| 1355 | int r, err = 0, num_params = 5; | 1390 | int r, err, num_params = 5; |
| 1356 | 1391 | ||
| 1357 | if (bpf_pseudo_call(insn)) | 1392 | if (bpf_pseudo_call(insn)) |
| 1358 | return 0; | 1393 | return 0; |
| @@ -1361,31 +1396,7 @@ static int record_call_access(struct bpf_verifier_env *env, · 2 unmodified lines | |||
| 1361 | num_params = cs.num_params; | 1396 | num_params = cs.num_params; |
| 1362 | 1397 | ||
| 1363 | for (r = BPF_REG_1; r < BPF_REG_1 + num_params; r++) { | 1398 | for (r = BPF_REG_1; r < BPF_REG_1 + num_params; r++) { |
| 1364 | int frame = at[r].frame; | 1399 | err = record_arg_access(env, instance, insn, &at[r], r - 1, insn_idx); |
| 1365 | s64 bytes; | ||
| 1366 | |||
| 1367 | if (!arg_is_fp(&at[r])) | ||
| 1368 | continue; | ||
| 1369 | |||
| 1370 | if (bpf_helper_call(insn)) { | ||
| 1371 | bytes = bpf_helper_stack_access_bytes(env, insn, r - 1, insn_idx); | ||
| 1372 | } else if (bpf_pseudo_kfunc_call(insn)) { | ||
| 1373 | bytes = bpf_kfunc_stack_access_bytes(env, insn, r - 1, insn_idx); | ||
| 1374 | } else { | ||
| 1375 | for (int f = 0; f <= depth; f++) { | ||
| 1376 | err = mark_stack_read(instance, f, insn_idx, SPIS_ALL); | ||
| 1377 | if (err) | ||
| 1378 | return err; | ||
| 1379 | } | ||
| 1380 | return 0; | ||
| 1381 | } | ||
| 1382 | if (bytes == 0) | ||
| 1383 | continue; | ||
| 1384 | |||
| 1385 | if (frame >= 0 && frame <= depth) | ||
| 1386 | err = record_stack_access(instance, &at[r], bytes, frame, insn_idx); | ||
| 1387 | else if (frame == ARG_IMPRECISE) | ||
| 1388 | err = record_imprecise(instance, at[r].mask, insn_idx); | ||
| 1389 | if (err) | 1400 | if (err) |
| 1390 | return err; | 1401 | return err; |
| 1391 | } | 1402 | } |