Skip to content

Commit 60246cd

Browse files
devnexengregkh
authored andcommitted
octeon_ep_vf: add NULL check for napi_build_skb()
[ Upstream commit dd66b42 ] napi_build_skb() can return NULL on allocation failure. In __octep_vf_oq_process_rx(), the result is used directly without a NULL check in both the single-buffer and multi-fragment paths, leading to a NULL pointer dereference. Add NULL checks after both napi_build_skb() calls, properly advancing descriptors and consuming remaining fragments on failure. Fixes: 1cd3b40 ("octeon_ep_vf: add Tx/Rx processing and interrupt support") Cc: stable@vger.kernel.org Signed-off-by: David Carlier <devnexen@gmail.com> Link: https://patch.msgid.link/20260409184009.930359-3-devnexen@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> [ inlined missing octep_vf_oq_next_idx() helper as read_idx++ with wraparound ] Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 270e5c5 commit 60246cd

1 file changed

Lines changed: 34 additions & 2 deletions

File tree

drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,10 +409,17 @@ static int __octep_vf_oq_process_rx(struct octep_vf_device *oct,
409409
data_offset = OCTEP_VF_OQ_RESP_HW_SIZE;
410410
rx_ol_flags = 0;
411411
}
412-
rx_bytes += buff_info->len;
413-
414412
if (buff_info->len <= oq->max_single_buffer_size) {
415413
skb = napi_build_skb((void *)resp_hw, PAGE_SIZE);
414+
if (!skb) {
415+
oq->stats->alloc_failures++;
416+
desc_used++;
417+
read_idx++;
418+
if (read_idx == oq->max_count)
419+
read_idx = 0;
420+
continue;
421+
}
422+
rx_bytes += buff_info->len;
416423
skb_reserve(skb, data_offset);
417424
skb_put(skb, buff_info->len);
418425
read_idx++;
@@ -424,6 +431,31 @@ static int __octep_vf_oq_process_rx(struct octep_vf_device *oct,
424431
u16 data_len;
425432

426433
skb = napi_build_skb((void *)resp_hw, PAGE_SIZE);
434+
if (!skb) {
435+
oq->stats->alloc_failures++;
436+
desc_used++;
437+
read_idx++;
438+
if (read_idx == oq->max_count)
439+
read_idx = 0;
440+
data_len = buff_info->len - oq->max_single_buffer_size;
441+
while (data_len) {
442+
dma_unmap_page(oq->dev, oq->desc_ring[read_idx].buffer_ptr,
443+
PAGE_SIZE, DMA_FROM_DEVICE);
444+
buff_info = (struct octep_vf_rx_buffer *)
445+
&oq->buff_info[read_idx];
446+
buff_info->page = NULL;
447+
if (data_len < oq->buffer_size)
448+
data_len = 0;
449+
else
450+
data_len -= oq->buffer_size;
451+
desc_used++;
452+
read_idx++;
453+
if (read_idx == oq->max_count)
454+
read_idx = 0;
455+
}
456+
continue;
457+
}
458+
rx_bytes += buff_info->len;
427459
skb_reserve(skb, data_offset);
428460
/* Head fragment includes response header(s);
429461
* subsequent fragments contains only data.

0 commit comments

Comments
 (0)