已合并
bpf: Fix invalid prog->stats access when update_effective_progs fails #304
bpf: Fix invalid prog->stats access when update_effective_progs fails #304
已合并
chenyangw创建于 3月5日
3 个文件变更+15-6
Mdrivers/net/usb/usbnet.c+2-0
@@ -702,6 +702,7 @@ void usbnet_resume_rx(struct usbnet *dev)
702 struct sk_buff *skb;702 struct sk_buff *skb;
703 int num = 0;703 int num = 0;
704 704 
705+ local_bh_disable();
705 clear_bit(EVENT_RX_PAUSED, &dev->flags);706 clear_bit(EVENT_RX_PAUSED, &dev->flags);
706 707 
707 while ((skb = skb_dequeue(&dev->rxq_pause)) != NULL) {708 while ((skb = skb_dequeue(&dev->rxq_pause)) != NULL) {
@@ -710,6 +711,7 @@ void usbnet_resume_rx(struct usbnet *dev)
710 }711 }
711 712 
712 tasklet_schedule(&dev->bh);713 tasklet_schedule(&dev->bh);
714+ local_bh_enable();
713 715 
714 netif_dbg(dev, rx_status, dev->net,716 netif_dbg(dev, rx_status, dev->net,
715 "paused rx queue disabled, %d skbs requeued\n", num);717 "paused rx queue disabled, %d skbs requeued\n", num);
Minclude/linux/filter.h+10-6
@@ -599,15 +599,19 @@ static __always_inline u32 __bpf_prog_run(const struct bpf_prog *prog,
599 cant_migrate();599 cant_migrate();
600 if (static_branch_unlikely(&bpf_stats_enabled_key)) {600 if (static_branch_unlikely(&bpf_stats_enabled_key)) {
601 struct bpf_prog_stats *stats;601 struct bpf_prog_stats *stats;
602- u64 start = sched_clock();602+ u64 duration, start = sched_clock();
603 unsigned long flags;603 unsigned long flags;
604 604 
605 ret = dfunc(ctx, prog->insnsi, prog->bpf_func);605 ret = dfunc(ctx, prog->insnsi, prog->bpf_func);
606- stats = this_cpu_ptr(prog->stats);606+ 
607- flags = u64_stats_update_begin_irqsave(&stats->syncp);607+ duration = sched_clock() - start;
608- u64_stats_inc(&stats->cnt);608+ if (likely(prog->stats)) {
609- u64_stats_add(&stats->nsecs, sched_clock() - start);609+ stats = this_cpu_ptr(prog->stats);
610- u64_stats_update_end_irqrestore(&stats->syncp, flags);610+ flags = u64_stats_update_begin_irqsave(&stats->syncp);
611+ u64_stats_inc(&stats->cnt);
612+ u64_stats_add(&stats->nsecs, duration);
613+ u64_stats_update_end_irqrestore(&stats->syncp, flags);
614+ }
611 } else {615 } else {
612 ret = dfunc(ctx, prog->insnsi, prog->bpf_func);616 ret = dfunc(ctx, prog->insnsi, prog->bpf_func);
613 }617 }
Mkernel/bpf/syscall.c+3-0
@@ -2218,6 +2218,9 @@ void notrace bpf_prog_inc_misses_counter(struct bpf_prog *prog)
2218 struct bpf_prog_stats *stats;2218 struct bpf_prog_stats *stats;
2219 unsigned int flags;2219 unsigned int flags;
2220 2220 
2221+ if (unlikely(!prog->stats))
2222+ return;
2223+ 
2221 stats = this_cpu_ptr(prog->stats);2224 stats = this_cpu_ptr(prog->stats);
2222 flags = u64_stats_update_begin_irqsave(&stats->syncp);2225 flags = u64_stats_update_begin_irqsave(&stats->syncp);
2223 u64_stats_inc(&stats->misses);2226 u64_stats_inc(&stats->misses);