已合并
bpf: Fix invalid prog->stats access when update_effective_progs fails #304
chenyangw创建于 3月5日
bpf: Fix invalid prog->stats access when update_effective_progs fails #304
已合并
共 3 个文件变更+15-6
| @@ -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); |
| @@ -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 | } |
| @@ -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); |