Re: [PATCH v2 net] octeontx2-pf: fix NULL deref of af_xdp_zc_qidx on rep setup

[email protected]
Newsgroups org.kernel.vger.bpf
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [High] The patch adds NULL checks before test_bit() but misses set_bit() and clear_bit() on af_xdp_zc_qidx, leaving a probe race condition that leads to a NULL pointer dereference.
- [High] NAPI is not disabled during XSK pool setup, causing a data race on the completion queue.
- [High] Incorrect conditional check for XDP queues when attaching XSK buffer pools leads to misconfiguration and breaks zero-copy TX.
--

--- Patch [1]: [PATCH v2 net] octeontx2-pf: fix NULL deref of af_xdp_zc_qidx on rep setup ---
commit 5f1a1574e7a51207651e67a7a10d7e4ef025c443
Author: Suman Ghosh <[email protected]>

octeontx2-pf: fix NULL deref of af_xdp_zc_qidx on rep setup

af_xdp_zc_qidx tracks receive queues using AF_XDP zero-copy and is
allocated during PF/VF probe. Representors and other non-AF_XDP paths
leave the pointer NULL, but several call sites used test_bit() on it
unconditionally.

Switching to devlink eswitch mode creates representors and runs
otx2_init_hw_resources(), which reaches otx2_pool_aq_init() and oopses
when dereferencing the NULL bitmap. Add NULL checks before every
af_xdp_zc_qidx test_bit() use in the RSS, ethtool, XSK, and pool init
paths.

> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
> index ca73a94db7943..175992188c18a 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
[ ... ]
> @@ -333,7 +333,8 @@ int otx2_set_rss_table(struct otx2_nic *pfvf, int ctx_id, const u32 *ind_tbl)
>  	/* Get memory to put this msg */
>  	for (idx = 0; idx < rss->rss_size; idx++) {
>  		/* Ignore the queue if AF_XDP zero copy is enabled */
> -		if (test_bit(ind_tbl[idx], pfvf->af_xdp_zc_qidx))
> +		if (pfvf->af_xdp_zc_qidx &&
> +		    test_bit(ind_tbl[idx], pfvf->af_xdp_zc_qidx))

[Severity: High]
This isn't a bug introduced by this patch, but since we are adding NULL
checks for test_bit() on af_xdp_zc_qidx, are we missing similar NULL checks
for set_bit() and clear_bit()?

Looking at otx2_probe() in
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c, register_netdev()
is called before pf->af_xdp_zc_qidx is allocated:

drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c:otx2_probe() {
    ...
    err = register_netdev(netdev);
    ...
}

This creates a race window where a userspace program could immediately open
an AF_XDP socket and bind it, invoking otx2_xsk_pool_enable() which calls
set_bit() on the still-NULL pointer:

drivers/net/ethernet/marvell/octeontx2/nic/otx2_xsk.c:otx2_xsk_pool_enable() {
    ...
    set_bit(qidx, pf->af_xdp_zc_qidx);
    ...
}

Could this lead to a NULL pointer dereference?

[Severity: High]
This is also a pre-existing issue, but does the queue index boundary check
in otx2_sq_init() correctly identify XDP queues when attaching XSK buffers?

Looking at drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c:

drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c:otx2_sq_init() {
    ...
    if (qidx > pfvf->hw.xdp_queues)
        otx2_attach_xsk_buff(pfvf, sq, (qidx - pfvf->hw.xdp_queues));
    ...
}

If there are more normal TX queues than XDP queues (for example, 4 TX queues
and 2 XDP queues), normal TX queues (indexed 0 to 3) will evaluate to true
(e.g., 3 > 2) and erroneously receive an XSK pool.

Concurrently, the first XDP queue (index 2) would fail the evaluation
(2 > 2 is false) and its xsk_pool remains NULL.

Could this break zero-copy TX on the first XDP queue and corrupt normal
TX queues when otx2_tx_napi_handler() injects packets concurrently?

[ ... ]
> diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_xsk.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_xsk.c
> index 7d67b4cbaf716..0e8a6a6486c4a 100644
> --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_xsk.c
> +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_xsk.c
[ ... ]
> @@ -193,7 +193,8 @@ int otx2_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
>  
>  void otx2_attach_xsk_buff(struct otx2_nic *pfvf, struct otx2_snd_queue *sq, int qidx)
>  {
> -	if (test_bit(qidx, pfvf->af_xdp_zc_qidx))
> +	if (pfvf->af_xdp_zc_qidx &&
> +	    test_bit(qidx, pfvf->af_xdp_zc_qidx))
>  		sq->xsk_pool = xsk_get_pool_from_qid(pfvf->netdev, qidx);
>  }

[Severity: High]
This is a pre-existing issue, but looking at how AF_XDP pools are enabled
in otx2_xsk_pool_enable() in this same file, it modifies the completion
queue hardware context without first disabling NAPI:

drivers/net/ethernet/marvell/octeontx2/nic/otx2_xsk.c:otx2_xsk_pool_enable() {
    ...
    otx2_clean_up_rq(pf, qidx);
    ...
}

drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c:otx2_cleanup_rx_cqes() {
    ...
    while (cq->pend_cqe) {
        cqe = (struct nix_cqe_rx_s *)otx2_get_next_cqe(cq);
    ...
}

If traffic arrives concurrently and otx2_napi_handler() in softirq context
polls the same completion queue simultaneously, can this cause a data race
and corrupt the completion queue?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.