Daniel Borkmann says: ==================== bpf 2023-01-16 We've added 6 non-merge commits during the last 8 day(s) which contain a total of 6 files changed, 22 insertions(+), 24 deletions(-). The main changes are: 1) Mitigate a Spectre v4 leak in unprivileged BPF from speculative pointer-as-scalar type confusion, from Luis Gerhorst. 2) Fix a splat when pid 1 attaches a BPF program that attempts to send killing signal to itself, from Hao Sun. 3) Fix BPF program ID information in BPF_AUDIT_UNLOAD as well as PERF_BPF_EVENT_PROG_UNLOAD events, from Paul Moore. 4) Fix BPF verifier warning triggered from invalid kfunc call in backtrack_insn, also from Hao Sun. 5) Fix potential deadlock in htab_lock_bucket from same bucket index but different map_locked index, from Tonghao Zhang. * tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: bpf: Fix pointer-leak due to insufficient speculative store bypass mitigation bpf: hash map, avoid deadlock with suitable hash mask bpf: remove the do_idr_lock parameter from bpf_prog_free_id() bpf: restore the ebpf program ID for BPF_AUDIT_UNLOAD and PERF_BPF_EVENT_PROG_UNLOAD bpf: Skip task with pid=1 in send_signal_common() bpf: Skip invalid kfunc call in backtrack_insn ====================
Showing the changes to kernel (5 of 6 files). Show all
Unified · Split
| @@ -152,7 +152,7 @@ static inline int htab_lock_bucket(const struct bpf_htab *htab, · 151 unmodified lines | ||
| 152 | 152 | { |
| 153 | 153 | unsigned long flags; |
| 154 | 154 | |
| 155 | − hash = hash & HASHTAB_MAP_LOCK_MASK; | |
| 155 | + hash = hash & min_t(u32, HASHTAB_MAP_LOCK_MASK, htab->n_buckets - 1); | |
| 156 | 156 | |
| 157 | 157 | preempt_disable(); |
| 158 | 158 | if (unlikely(__this_cpu_inc_return(*(htab->map_locked[hash])) != 1)) { |
| @@ -171,7 +171,7 @@ static inline void htab_unlock_bucket(const struct bpf_htab *htab, · 12 unmodified lines | ||
| 171 | 171 | struct bucket *b, u32 hash, |
| 172 | 172 | unsigned long flags) |
| 173 | 173 | { |
| 174 | − hash = hash & HASHTAB_MAP_LOCK_MASK; | |
| 174 | + hash = hash & min_t(u32, HASHTAB_MAP_LOCK_MASK, htab->n_buckets - 1); | |
| 175 | 175 | raw_spin_unlock_irqrestore(&b->raw_lock, flags); |
| 176 | 176 | __this_cpu_dec(*(htab->map_locked[hash])); |
| 177 | 177 | preempt_enable(); |
| @@ -216,9 +216,6 @@ static void __bpf_prog_offload_destroy(struct bpf_prog *prog) · 215 unmodified lines | ||
| 216 | 216 | if (offload->dev_state) |
| 217 | 217 | offload->offdev->ops->destroy(prog); |
| 218 | 218 | |
| 219 | − /* Make sure BPF_PROG_GET_NEXT_ID can't find this dead program */ | |
| 220 | − bpf_prog_free_id(prog, true); | |
| 221 | − | |
| 222 | 219 | list_del_init(&offload->offloads); |
| 223 | 220 | kfree(offload); |
| 224 | 221 | prog->aux->offload = NULL; |
| @@ -1972,7 +1972,7 @@ static void bpf_audit_prog(const struct bpf_prog *prog, unsigned int op) · 1971 unmodified lines | ||
| 1972 | 1972 | return; |
| 1973 | 1973 | if (audit_enabled == AUDIT_OFF) |
| 1974 | 1974 | return; |
| 1975 | − if (op == BPF_AUDIT_LOAD) | |
| 1975 | + if (!in_irq() && !irqs_disabled()) | |
| 1976 | 1976 | ctx = audit_context(); |
| 1977 | 1977 | ab = audit_log_start(ctx, GFP_ATOMIC, AUDIT_BPF); |
| 1978 | 1978 | if (unlikely(!ab)) |
| @@ -2001,7 +2001,7 @@ static int bpf_prog_alloc_id(struct bpf_prog *prog) · 22 unmodified lines | ||
| 2001 | 2001 | return id > 0 ? 0 : id; |
| 2002 | 2002 | } |
| 2003 | 2003 | |
| 2004 | −void bpf_prog_free_id(struct bpf_prog *prog, bool do_idr_lock) | |
| 2004 | +void bpf_prog_free_id(struct bpf_prog *prog) | |
| 2005 | 2005 | { |
| 2006 | 2006 | unsigned long flags; |
| 2007 | 2007 | |
| @@ -2013,18 +2013,10 @@ void bpf_prog_free_id(struct bpf_prog *prog, bool do_idr_lock) · 5 unmodified lines | ||
| 2013 | 2013 | if (!prog->aux->id) |
| 2014 | 2014 | return; |
| 2015 | 2015 | |
| 2016 | − if (do_idr_lock) | |
| 2017 | − spin_lock_irqsave(&prog_idr_lock, flags); | |
| 2018 | − else | |
| 2019 | − __acquire(&prog_idr_lock); | |
| 2020 | − | |
| 2016 | + spin_lock_irqsave(&prog_idr_lock, flags); | |
| 2021 | 2017 | idr_remove(&prog_idr, prog->aux->id); |
| 2022 | 2018 | prog->aux->id = 0; |
| 2023 | − | |
| 2024 | − if (do_idr_lock) | |
| 2025 | − spin_unlock_irqrestore(&prog_idr_lock, flags); | |
| 2026 | − else | |
| 2027 | − __release(&prog_idr_lock); | |
| 2019 | + spin_unlock_irqrestore(&prog_idr_lock, flags); | |
| 2028 | 2020 | } |
| 2029 | 2021 | |
| 2030 | 2022 | static void __bpf_prog_put_rcu(struct rcu_head *rcu) |
| @@ -2067,17 +2059,15 @@ static void bpf_prog_put_deferred(struct work_struct *work) · 36 unmodified lines | ||
| 2067 | 2059 | prog = aux->prog; |
| 2068 | 2060 | perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_UNLOAD, 0); |
| 2069 | 2061 | bpf_audit_prog(prog, BPF_AUDIT_UNLOAD); |
| 2062 | + bpf_prog_free_id(prog); | |
| 2070 | 2063 | __bpf_prog_put_noref(prog, true); |
| 2071 | 2064 | } |
| 2072 | 2065 | |
| 2073 | −static void __bpf_prog_put(struct bpf_prog *prog, bool do_idr_lock) | |
| 2066 | +static void __bpf_prog_put(struct bpf_prog *prog) | |
| 2074 | 2067 | { |
| 2075 | 2068 | struct bpf_prog_aux *aux = prog->aux; |
| 2076 | 2069 | |
| 2077 | 2070 | if (atomic64_dec_and_test(&aux->refcnt)) { |
| 2078 | − /* bpf_prog_free_id() must be called first */ | |
| 2079 | − bpf_prog_free_id(prog, do_idr_lock); | |
| 2080 | − | |
| 2081 | 2071 | if (in_irq() || irqs_disabled()) { |
| 2082 | 2072 | INIT_WORK(&aux->work, bpf_prog_put_deferred); |
| 2083 | 2073 | schedule_work(&aux->work); |
| @@ -2089,7 +2079,7 @@ static void __bpf_prog_put(struct bpf_prog *prog, bool do_idr_lock) · 5 unmodified lines | ||
| 2089 | 2079 | |
| 2090 | 2080 | void bpf_prog_put(struct bpf_prog *prog) |
| 2091 | 2081 | { |
| 2092 | − __bpf_prog_put(prog, true); | |
| 2082 | + __bpf_prog_put(prog); | |
| 2093 | 2083 | } |
| 2094 | 2084 | EXPORT_SYMBOL_GPL(bpf_prog_put); |
| 2095 | 2085 | |
| @@ -2748,6 +2748,12 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, · 2747 unmodified lines | ||
| 2748 | 2748 | */ |
| 2749 | 2749 | if (insn->src_reg == 0 && is_callback_calling_function(insn->imm)) |
| 2750 | 2750 | return -ENOTSUPP; |
| 2751 | + /* kfunc with imm==0 is invalid and fixup_kfunc_call will | |
| 2752 | + * catch this error later. Make backtracking conservative | |
| 2753 | + * with ENOTSUPP. | |
| 2754 | + */ | |
| 2755 | + if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL && insn->imm == 0) | |
| 2756 | + return -ENOTSUPP; | |
| 2751 | 2757 | /* regular helper call sets R0 */ |
| 2752 | 2758 | *reg_mask &= ~1; |
| 2753 | 2759 | if (*reg_mask & 0x3f) { |
| @@ -3289,7 +3295,9 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env, · 535 unmodified lines | ||
| 3289 | 3295 | bool sanitize = reg && is_spillable_regtype(reg->type); |
| 3290 | 3296 | |
| 3291 | 3297 | for (i = 0; i < size; i++) { |
| 3292 | − if (state->stack[spi].slot_type[i] == STACK_INVALID) { | |
| 3298 | + u8 type = state->stack[spi].slot_type[i]; | |
| 3299 | + | |
| 3300 | + if (type != STACK_MISC && type != STACK_ZERO) { | |
| 3293 | 3301 | sanitize = true; |
| 3294 | 3302 | break; |
| 3295 | 3303 | } |
| @@ -848,6 +848,9 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type) · 847 unmodified lines | ||
| 848 | 848 | return -EPERM; |
| 849 | 849 | if (unlikely(!nmi_uaccess_okay())) |
| 850 | 850 | return -EPERM; |
| 851 | + /* Task should not be pid=1 to avoid kernel panic. */ | |
| 852 | + if (unlikely(is_global_init(current))) | |
| 853 | + return -EPERM; | |
| 851 | 854 | |
| 852 | 855 | if (irqs_disabled()) { |
| 853 | 856 | /* Do an early check on signal validity. Otherwise, |