Daniel Borkmann says: ==================== pull-request: bpf 2022-04-27 We've added 5 non-merge commits during the last 20 day(s) which contain a total of 6 files changed, 34 insertions(+), 12 deletions(-). The main changes are: 1) Fix xsk sockets when rx and tx are separately bound to the same umem, also fix xsk copy mode combined with busy poll, from Maciej Fijalkowski. 2) Fix BPF tunnel/collect_md helpers with bpf_xmit lwt hook usage which triggered a crash due to invalid metadata_dst access, from Eyal Birger. 3) Fix release of page pool in XDP live packet mode, from Toke Høiland-Jørgensen. 4) Fix potential NULL pointer dereference in kretprobes, from Adam Zabrocki. (Masami & Steven preferred this small fix to be routed via bpf tree given it's follow-up fix to Masami's rethook work that went via bpf earlier, too.) * https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: xsk: Fix possible crash when multiple sockets are created kprobes: Fix KRETPROBES when CONFIG_KRETPROBE_ON_RETHOOK is set bpf, lwt: Fix crash when using bpf_skb_set_tunnel_key() from bpf_xmit lwt hook bpf: Fix release of page_pool in BPF_PROG_RUN in test runner xsk: Fix l2fwd for copy mode + busy poll combo ====================
Unified · Split
| @@ -97,6 +97,7 @@ int xp_assign_dev(struct xsk_buff_pool *pool, struct net_device *dev, · 96 unmodified lines | ||
| 97 | 97 | u16 queue_id, u16 flags); |
| 98 | 98 | int xp_assign_dev_shared(struct xsk_buff_pool *pool, struct xdp_umem *umem, |
| 99 | 99 | struct net_device *dev, u16 queue_id); |
| 100 | +int xp_alloc_tx_descs(struct xsk_buff_pool *pool, struct xdp_sock *xs); | |
| 100 | 101 | void xp_destroy(struct xsk_buff_pool *pool); |
| 101 | 102 | void xp_get_pool(struct xsk_buff_pool *pool); |
| 102 | 103 | bool xp_put_pool(struct xsk_buff_pool *pool); |
| @@ -2126,7 +2126,7 @@ static void kretprobe_rethook_handler(struct rethook_node *rh, void *data, · 2125 unmodified lines | ||
| 2126 | 2126 | struct kprobe_ctlblk *kcb; |
| 2127 | 2127 | |
| 2128 | 2128 | /* The data must NOT be null. This means rethook data structure is broken. */ |
| 2129 | − if (WARN_ON_ONCE(!data)) | |
| 2129 | + if (WARN_ON_ONCE(!data) || !rp->handler) | |
| 2130 | 2130 | return; |
| 2131 | 2131 | |
| 2132 | 2132 | __this_cpu_write(current_kprobe, &rp->kp); |
| @@ -108,6 +108,7 @@ struct xdp_test_data { · 107 unmodified lines | ||
| 108 | 108 | struct page_pool *pp; |
| 109 | 109 | struct xdp_frame **frames; |
| 110 | 110 | struct sk_buff **skbs; |
| 111 | + struct xdp_mem_info mem; | |
| 111 | 112 | u32 batch_size; |
| 112 | 113 | u32 frame_cnt; |
| 113 | 114 | }; |
| @@ -147,7 +148,6 @@ static void xdp_test_run_init_page(struct page *page, void *arg) · 33 unmodified lines | ||
| 147 | 148 | |
| 148 | 149 | static int xdp_test_run_setup(struct xdp_test_data *xdp, struct xdp_buff *orig_ctx) |
| 149 | 150 | { |
| 150 | − struct xdp_mem_info mem = {}; | |
| 151 | 151 | struct page_pool *pp; |
| 152 | 152 | int err = -ENOMEM; |
| 153 | 153 | struct page_pool_params pp_params = { |
| @@ -174,7 +174,7 @@ static int xdp_test_run_setup(struct xdp_test_data *xdp, struct xdp_buff *orig_c · 20 unmodified lines | ||
| 174 | 174 | } |
| 175 | 175 | |
| 176 | 176 | /* will copy 'mem.id' into pp->xdp_mem_id */ |
| 177 | − err = xdp_reg_mem_model(&mem, MEM_TYPE_PAGE_POOL, pp); | |
| 177 | + err = xdp_reg_mem_model(&xdp->mem, MEM_TYPE_PAGE_POOL, pp); | |
| 178 | 178 | if (err) |
| 179 | 179 | goto err_mmodel; |
| 180 | 180 | |
| @@ -202,6 +202,7 @@ err_skbs: · 21 unmodified lines | ||
| 202 | 202 | |
| 203 | 203 | static void xdp_test_run_teardown(struct xdp_test_data *xdp) |
| 204 | 204 | { |
| 205 | + xdp_unreg_mem_model(&xdp->mem); | |
| 205 | 206 | page_pool_destroy(xdp->pp); |
| 206 | 207 | kfree(xdp->frames); |
| 207 | 208 | kfree(xdp->skbs); |
| @@ -159,10 +159,8 @@ static int bpf_output(struct net *net, struct sock *sk, struct sk_buff *skb) · 158 unmodified lines | ||
| 159 | 159 | return dst->lwtstate->orig_output(net, sk, skb); |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | −static int xmit_check_hhlen(struct sk_buff *skb) | |
| 162 | +static int xmit_check_hhlen(struct sk_buff *skb, int hh_len) | |
| 163 | 163 | { |
| 164 | − int hh_len = skb_dst(skb)->dev->hard_header_len; | |
| 165 | − | |
| 166 | 164 | if (skb_headroom(skb) < hh_len) { |
| 167 | 165 | int nhead = HH_DATA_ALIGN(hh_len - skb_headroom(skb)); |
| 168 | 166 | |
| @@ -274,6 +272,7 @@ static int bpf_xmit(struct sk_buff *skb) · 105 unmodified lines | ||
| 274 | 272 | |
| 275 | 273 | bpf = bpf_lwt_lwtunnel(dst->lwtstate); |
| 276 | 274 | if (bpf->xmit.prog) { |
| 275 | + int hh_len = dst->dev->hard_header_len; | |
| 277 | 276 | __be16 proto = skb->protocol; |
| 278 | 277 | int ret; |
| 279 | 278 | |
| @@ -291,7 +290,7 @@ static int bpf_xmit(struct sk_buff *skb) · 11 unmodified lines | ||
| 291 | 290 | /* If the header was expanded, headroom might be too |
| 292 | 291 | * small for L2 header to come, expand as needed. |
| 293 | 292 | */ |
| 294 | − ret = xmit_check_hhlen(skb); | |
| 293 | + ret = xmit_check_hhlen(skb, hh_len); | |
| 295 | 294 | if (unlikely(ret)) |
| 296 | 295 | return ret; |
| 297 | 296 | |
| @@ -639,7 +639,7 @@ static int __xsk_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len · 638 unmodified lines | ||
| 639 | 639 | if (sk_can_busy_loop(sk)) |
| 640 | 640 | sk_busy_loop(sk, 1); /* only support non-blocking sockets */ |
| 641 | 641 | |
| 642 | − if (xsk_no_wakeup(sk)) | |
| 642 | + if (xs->zc && xsk_no_wakeup(sk)) | |
| 643 | 643 | return 0; |
| 644 | 644 | |
| 645 | 645 | pool = xs->pool; |
| @@ -967,6 +967,19 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len) · 321 unmodified lines | ||
| 967 | 967 | |
| 968 | 968 | xp_get_pool(umem_xs->pool); |
| 969 | 969 | xs->pool = umem_xs->pool; |
| 970 | + | |
| 971 | + /* If underlying shared umem was created without Tx | |
| 972 | + * ring, allocate Tx descs array that Tx batching API | |
| 973 | + * utilizes | |
| 974 | + */ | |
| 975 | + if (xs->tx && !xs->pool->tx_descs) { | |
| 976 | + err = xp_alloc_tx_descs(xs->pool, xs); | |
| 977 | + if (err) { | |
| 978 | + xp_put_pool(xs->pool); | |
| 979 | + sockfd_put(sock); | |
| 980 | + goto out_unlock; | |
| 981 | + } | |
| 982 | + } | |
| 970 | 983 | } |
| 971 | 984 | |
| 972 | 985 | xdp_get_umem(umem_xs->umem); |
| @@ -42,6 +42,16 @@ void xp_destroy(struct xsk_buff_pool *pool) · 41 unmodified lines | ||
| 42 | 42 | kvfree(pool); |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | +int xp_alloc_tx_descs(struct xsk_buff_pool *pool, struct xdp_sock *xs) | |
| 46 | +{ | |
| 47 | + pool->tx_descs = kvcalloc(xs->tx->nentries, sizeof(*pool->tx_descs), | |
| 48 | + GFP_KERNEL); | |
| 49 | + if (!pool->tx_descs) | |
| 50 | + return -ENOMEM; | |
| 51 | + | |
| 52 | + return 0; | |
| 53 | +} | |
| 54 | + | |
| 45 | 55 | struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs, |
| 46 | 56 | struct xdp_umem *umem) |
| 47 | 57 | { |
| @@ -59,11 +69,9 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs, · 11 unmodified lines | ||
| 59 | 69 | if (!pool->heads) |
| 60 | 70 | goto out; |
| 61 | 71 | |
| 62 | − if (xs->tx) { | |
| 63 | − pool->tx_descs = kcalloc(xs->tx->nentries, sizeof(*pool->tx_descs), GFP_KERNEL); | |
| 64 | − if (!pool->tx_descs) | |
| 72 | + if (xs->tx) | |
| 73 | + if (xp_alloc_tx_descs(pool, xs)) | |
| 65 | 74 | goto out; |
| 66 | − } | |
| 67 | 75 | |
| 68 | 76 | pool->chunk_mask = ~((u64)umem->chunk_size - 1); |
| 69 | 77 | pool->addrs_cnt = umem->size; |