| @@ -1045,7 +1045,7 @@ static int is_iter_reg_valid_init(struct bpf_verifier_env *env, struct bpf_reg_s · 1044 unmodified lines |
| 1045 | } | 1045 | } |
| 1046 | | 1046 | |
| 1047 | static int acquire_irq_state(struct bpf_verifier_env *env, int insn_idx); | 1047 | static int acquire_irq_state(struct bpf_verifier_env *env, int insn_idx); |
| 1048 | static int release_irq_state(struct bpf_verifier_state *state, int id); | 1048 | static int release_irq_state(struct bpf_verifier_env *env, int id); |
| 1049 | | 1049 | |
| 1050 | static int mark_stack_slot_irq_flag(struct bpf_verifier_env *env, | 1050 | static int mark_stack_slot_irq_flag(struct bpf_verifier_env *env, |
| 1051 | struct bpf_call_arg_meta *meta, | 1051 | struct bpf_call_arg_meta *meta, |
| @@ -1104,7 +1104,7 @@ static int unmark_stack_slot_irq_flag(struct bpf_verifier_env *env, struct bpf_r · 52 unmodified lines |
| 1104 | return -EINVAL; | 1104 | return -EINVAL; |
| 1105 | } | 1105 | } |
| 1106 | | 1106 | |
| 1107 | err = release_irq_state(env->cur_state, st->id); | 1107 | err = release_irq_state(env, st->id); |
| 1108 | WARN_ON_ONCE(err && err != -EACCES); | 1108 | WARN_ON_ONCE(err && err != -EACCES); |
| 1109 | if (err) { | 1109 | if (err) { |
| 1110 | int insn_idx = 0; | 1110 | int insn_idx = 0; |
| @@ -1439,6 +1439,8 @@ static int acquire_lock_state(struct bpf_verifier_env *env, int insn_idx, enum r · 328 unmodified lines |
| 1439 | state->active_locks++; | 1439 | state->active_locks++; |
| 1440 | state->active_lock_id = id; | 1440 | state->active_lock_id = id; |
| 1441 | state->active_lock_ptr = ptr; | 1441 | state->active_lock_ptr = ptr; |
| | 1442 | bpf_diag_record_context(env, insn_idx, BPF_DIAG_CONTEXT_LOCK, true, |
| | 1443 | state->active_locks); |
| 1442 | return 0; | 1444 | return 0; |
| 1443 | } | 1445 | } |
| 1444 | | 1446 | |
| @@ -1454,6 +1456,8 @@ static int acquire_irq_state(struct bpf_verifier_env *env, int insn_idx) · 9 unmodified lines |
| 1454 | s->id = ++env->id_gen; | 1456 | s->id = ++env->id_gen; |
| 1455 | | 1457 | |
| 1456 | state->active_irq_id = s->id; | 1458 | state->active_irq_id = s->id; |
| | 1459 | bpf_diag_record_context(env, insn_idx, BPF_DIAG_CONTEXT_IRQ, true, |
| | 1460 | bpf_diag_irq_depth(state)); |
| 1457 | return s->id; | 1461 | return s->id; |
| 1458 | } | 1462 | } |
| 1459 | | 1463 | |
| @@ -1495,8 +1499,9 @@ static bool reg_is_referenced(struct bpf_verifier_env *env, const struct bpf_reg · 35 unmodified lines |
| 1495 | return find_reference_state(env->cur_state, reg->id); | 1499 | return find_reference_state(env->cur_state, reg->id); |
| 1496 | } | 1500 | } |
| 1497 | | 1501 | |
| 1498 | static int release_lock_state(struct bpf_verifier_state *state, int type, int id, void *ptr) | 1502 | static int release_lock_state(struct bpf_verifier_env *env, int type, int id, void *ptr) |
| 1499 | { | 1503 | { |
| | 1504 | struct bpf_verifier_state *state = env->cur_state; |
| 1500 | void *prev_ptr = NULL; | 1505 | void *prev_ptr = NULL; |
| 1501 | u32 prev_id = 0; | 1506 | u32 prev_id = 0; |
| 1502 | int i; | 1507 | int i; |
| @@ -1509,6 +1514,8 @@ static int release_lock_state(struct bpf_verifier_state *state, int type, int id · 6 unmodified lines |
| 1509 | /* Reassign active lock (id, ptr). */ | 1514 | /* Reassign active lock (id, ptr). */ |
| 1510 | state->active_lock_id = prev_id; | 1515 | state->active_lock_id = prev_id; |
| 1511 | state->active_lock_ptr = prev_ptr; | 1516 | state->active_lock_ptr = prev_ptr; |
| | 1517 | bpf_diag_record_context(env, env->insn_idx, BPF_DIAG_CONTEXT_LOCK, |
| | 1518 | false, state->active_locks); |
| 1512 | return 0; | 1519 | return 0; |
| 1513 | } | 1520 | } |
| 1514 | if (state->refs[i].type & REF_TYPE_LOCK_MASK) { | 1521 | if (state->refs[i].type & REF_TYPE_LOCK_MASK) { |
| @@ -1519,8 +1526,9 @@ static int release_lock_state(struct bpf_verifier_state *state, int type, int id · 4 unmodified lines |
| 1519 | return -EINVAL; | 1526 | return -EINVAL; |
| 1520 | } | 1527 | } |
| 1521 | | 1528 | |
| 1522 | static int release_irq_state(struct bpf_verifier_state *state, int id) | 1529 | static int release_irq_state(struct bpf_verifier_env *env, int id) |
| 1523 | { | 1530 | { |
| | 1531 | struct bpf_verifier_state *state = env->cur_state; |
| 1524 | u32 prev_id = 0; | 1532 | u32 prev_id = 0; |
| 1525 | int i; | 1533 | int i; |
| 1526 | | 1534 | |
| @@ -1533,6 +1541,8 @@ static int release_irq_state(struct bpf_verifier_state *state, int id) · 6 unmodified lines |
| 1533 | if (state->refs[i].id == id) { | 1541 | if (state->refs[i].id == id) { |
| 1534 | release_reference_state(state, i); | 1542 | release_reference_state(state, i); |
| 1535 | state->active_irq_id = prev_id; | 1543 | state->active_irq_id = prev_id; |
| | 1544 | bpf_diag_record_context(env, env->insn_idx, BPF_DIAG_CONTEXT_IRQ, |
| | 1545 | false, bpf_diag_irq_depth(state)); |
| 1536 | return 0; | 1546 | return 0; |
| 1537 | } else { | 1547 | } else { |
| 1538 | prev_id = state->refs[i].id; | 1548 | prev_id = state->refs[i].id; |
| @@ -7181,7 +7191,7 @@ static int process_spin_lock(struct bpf_verifier_env *env, struct bpf_reg_state · 5642 unmodified lines |
| 7181 | verbose(env, "%s_unlock cannot be out of order\n", lock_str); | 7191 | verbose(env, "%s_unlock cannot be out of order\n", lock_str); |
| 7182 | return -EINVAL; | 7192 | return -EINVAL; |
| 7183 | } | 7193 | } |
| 7184 | if (release_lock_state(cur, type, reg->id, ptr)) { | 7194 | if (release_lock_state(env, type, reg->id, ptr)) { |
| 7185 | verbose(env, "%s_unlock of different lock\n", lock_str); | 7195 | verbose(env, "%s_unlock of different lock\n", lock_str); |
| 7186 | return -EINVAL; | 7196 | return -EINVAL; |
| 7187 | } | 7197 | } |
| @@ -13242,22 +13252,30 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn, · 6054 unmodified lines |
| 13242 | | 13252 | |
| 13243 | if (rcu_lock) { | 13253 | if (rcu_lock) { |
| 13244 | env->cur_state->active_rcu_locks++; | 13254 | env->cur_state->active_rcu_locks++; |
| | 13255 | bpf_diag_record_context(env, insn_idx, BPF_DIAG_CONTEXT_RCU, true, |
| | 13256 | env->cur_state->active_rcu_locks); |
| 13245 | } else if (rcu_unlock) { | 13257 | } else if (rcu_unlock) { |
| 13246 | if (env->cur_state->active_rcu_locks == 0) { | 13258 | if (env->cur_state->active_rcu_locks == 0) { |
| 13247 | verbose(env, "unmatched rcu read unlock (kernel function %s)\n", func_name); | 13259 | verbose(env, "unmatched rcu read unlock (kernel function %s)\n", func_name); |
| 13248 | return -EINVAL; | 13260 | return -EINVAL; |
| 13249 | } | 13261 | } |
| 13250 | env->cur_state->active_rcu_locks--; | 13262 | env->cur_state->active_rcu_locks--; |
| | 13263 | bpf_diag_record_context(env, insn_idx, BPF_DIAG_CONTEXT_RCU, false, |
| | 13264 | env->cur_state->active_rcu_locks); |
| 13251 | if (!in_rcu_cs(env)) | 13265 | if (!in_rcu_cs(env)) |
| 13252 | invalidate_rcu_protected_refs(env); | 13266 | invalidate_rcu_protected_refs(env); |
| 13253 | } else if (preempt_disable) { | 13267 | } else if (preempt_disable) { |
| 13254 | env->cur_state->active_preempt_locks++; | 13268 | env->cur_state->active_preempt_locks++; |
| | 13269 | bpf_diag_record_context(env, insn_idx, BPF_DIAG_CONTEXT_PREEMPT, true, |
| | 13270 | env->cur_state->active_preempt_locks); |
| 13255 | } else if (preempt_enable) { | 13271 | } else if (preempt_enable) { |
| 13256 | if (env->cur_state->active_preempt_locks == 0) { | 13272 | if (env->cur_state->active_preempt_locks == 0) { |
| 13257 | verbose(env, "unmatched attempt to enable preemption (kernel function %s)\n", func_name); | 13273 | verbose(env, "unmatched attempt to enable preemption (kernel function %s)\n", func_name); |
| 13258 | return -EINVAL; | 13274 | return -EINVAL; |
| 13259 | } | 13275 | } |
| 13260 | env->cur_state->active_preempt_locks--; | 13276 | env->cur_state->active_preempt_locks--; |
| | 13277 | bpf_diag_record_context(env, insn_idx, BPF_DIAG_CONTEXT_PREEMPT, false, |
| | 13278 | env->cur_state->active_preempt_locks); |
| 13261 | if (!in_rcu_cs(env)) | 13279 | if (!in_rcu_cs(env)) |
| 13262 | invalidate_rcu_protected_refs(env); | 13280 | invalidate_rcu_protected_refs(env); |
| 13263 | } | 13281 | } |