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 | unsigned long flags; | 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 | preempt_disable(); | 157 | preempt_disable(); |
| 158 | if (unlikely(__this_cpu_inc_return(*(htab->map_locked[hash])) != 1)) { | 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 | struct bucket *b, u32 hash, | 171 | struct bucket *b, u32 hash, |
| 172 | unsigned long flags) | 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 | raw_spin_unlock_irqrestore(&b->raw_lock, flags); | 175 | raw_spin_unlock_irqrestore(&b->raw_lock, flags); |
| 176 | __this_cpu_dec(*(htab->map_locked[hash])); | 176 | __this_cpu_dec(*(htab->map_locked[hash])); |
| 177 | preempt_enable(); | 177 | preempt_enable(); |
| @@ -216,9 +216,6 @@ static void __bpf_prog_offload_destroy(struct bpf_prog *prog) · 215 unmodified lines | |||
| 216 | if (offload->dev_state) | 216 | if (offload->dev_state) |
| 217 | offload->offdev->ops->destroy(prog); | 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 | list_del_init(&offload->offloads); | 219 | list_del_init(&offload->offloads); |
| 223 | kfree(offload); | 220 | kfree(offload); |
| 224 | prog->aux->offload = NULL; | 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 | return; | 1972 | return; |
| 1973 | if (audit_enabled == AUDIT_OFF) | 1973 | if (audit_enabled == AUDIT_OFF) |
| 1974 | return; | 1974 | return; |
| 1975 | if (op == BPF_AUDIT_LOAD) | 1975 | if (!in_irq() && !irqs_disabled()) |
| 1976 | ctx = audit_context(); | 1976 | ctx = audit_context(); |
| 1977 | ab = audit_log_start(ctx, GFP_ATOMIC, AUDIT_BPF); | 1977 | ab = audit_log_start(ctx, GFP_ATOMIC, AUDIT_BPF); |
| 1978 | if (unlikely(!ab)) | 1978 | if (unlikely(!ab)) |
| @@ -2001,7 +2001,7 @@ static int bpf_prog_alloc_id(struct bpf_prog *prog) · 22 unmodified lines | |||
| 2001 | return id > 0 ? 0 : id; | 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 | unsigned long flags; | 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 | if (!prog->aux->id) | 2013 | if (!prog->aux->id) |
| 2014 | return; | 2014 | return; |
| 2015 | 2015 | ||
| 2016 | if (do_idr_lock) | 2016 | spin_lock_irqsave(&prog_idr_lock, flags); |
| 2017 | spin_lock_irqsave(&prog_idr_lock, flags); | ||
| 2018 | else | ||
| 2019 | __acquire(&prog_idr_lock); | ||
| 2020 | |||
| 2021 | idr_remove(&prog_idr, prog->aux->id); | 2017 | idr_remove(&prog_idr, prog->aux->id); |
| 2022 | prog->aux->id = 0; | 2018 | prog->aux->id = 0; |
| 2023 | 2019 | spin_unlock_irqrestore(&prog_idr_lock, flags); | |
| 2024 | if (do_idr_lock) | ||
| 2025 | spin_unlock_irqrestore(&prog_idr_lock, flags); | ||
| 2026 | else | ||
| 2027 | __release(&prog_idr_lock); | ||
| 2028 | } | 2020 | } |
| 2029 | 2021 | ||
| 2030 | static void __bpf_prog_put_rcu(struct rcu_head *rcu) | 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 | prog = aux->prog; | 2059 | prog = aux->prog; |
| 2068 | perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_UNLOAD, 0); | 2060 | perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_UNLOAD, 0); |
| 2069 | bpf_audit_prog(prog, BPF_AUDIT_UNLOAD); | 2061 | bpf_audit_prog(prog, BPF_AUDIT_UNLOAD); |
| 2062 | bpf_prog_free_id(prog); | ||
| 2070 | __bpf_prog_put_noref(prog, true); | 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 | struct bpf_prog_aux *aux = prog->aux; | 2068 | struct bpf_prog_aux *aux = prog->aux; |
| 2076 | 2069 | ||
| 2077 | if (atomic64_dec_and_test(&aux->refcnt)) { | 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 | if (in_irq() || irqs_disabled()) { | 2071 | if (in_irq() || irqs_disabled()) { |
| 2082 | INIT_WORK(&aux->work, bpf_prog_put_deferred); | 2072 | INIT_WORK(&aux->work, bpf_prog_put_deferred); |
| 2083 | schedule_work(&aux->work); | 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 | void bpf_prog_put(struct bpf_prog *prog) | 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 | EXPORT_SYMBOL_GPL(bpf_prog_put); | 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 | if (insn->src_reg == 0 && is_callback_calling_function(insn->imm)) | 2749 | if (insn->src_reg == 0 && is_callback_calling_function(insn->imm)) |
| 2750 | return -ENOTSUPP; | 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 | /* regular helper call sets R0 */ | 2757 | /* regular helper call sets R0 */ |
| 2752 | *reg_mask &= ~1; | 2758 | *reg_mask &= ~1; |
| 2753 | if (*reg_mask & 0x3f) { | 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 | bool sanitize = reg && is_spillable_regtype(reg->type); | 3295 | bool sanitize = reg && is_spillable_regtype(reg->type); |
| 3290 | 3296 | ||
| 3291 | for (i = 0; i < size; i++) { | 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 | sanitize = true; | 3301 | sanitize = true; |
| 3294 | break; | 3302 | break; |
| 3295 | } | 3303 | } |
| @@ -848,6 +848,9 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type) · 847 unmodified lines | |||
| 848 | return -EPERM; | 848 | return -EPERM; |
| 849 | if (unlikely(!nmi_uaccess_okay())) | 849 | if (unlikely(!nmi_uaccess_okay())) |
| 850 | return -EPERM; | 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 | if (irqs_disabled()) { | 855 | if (irqs_disabled()) { |
| 853 | /* Do an early check on signal validity. Otherwise, | 856 | /* Do an early check on signal validity. Otherwise, |