Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc5b5d35 authored by Krzysztof Kazimierczak's avatar Krzysztof Kazimierczak Committed by Daniel Borkmann
Browse files

xsk: Check if a queue exists during umem setup



In the xdp_umem_assign_dev() path, the xsk code does not
check if a queue for which umem is to be created exists.
It leads to a situation where umem is not assigned to any
Tx/Rx queue of a netdevice, without notifying the stack
about an error. This affects both XDP_SKB and XDP_DRV
modes - in case of XDP_DRV_ZC, queue index is checked by
the driver.

This patch fixes xsk code, so that in both XDP_SKB and
XDP_DRV mode of AF_XDP, an error is returned when requested
queue index exceedes an existing maximum.

Fixes: c9b47cc1 ("xsk: fix bug when trying to use both copy and zero-copy on one queue id")
Reported-by: default avatarJakub Spizewski <jakub.spizewski@intel.com>
Signed-off-by: default avatarKrzysztof Kazimierczak <krzysztof.kazimierczak@intel.com>
Acked-by: default avatarBjörn Töpel <bjorn.topel@intel.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent 7939f8be
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -41,13 +41,20 @@ void xdp_del_sk_umem(struct xdp_umem *umem, struct xdp_sock *xs)
 * not know if the device has more tx queues than rx, or the opposite.
 * This might also change during run time.
 */
static void xdp_reg_umem_at_qid(struct net_device *dev, struct xdp_umem *umem,
static int xdp_reg_umem_at_qid(struct net_device *dev, struct xdp_umem *umem,
			       u16 queue_id)
{
	if (queue_id >= max_t(unsigned int,
			      dev->real_num_rx_queues,
			      dev->real_num_tx_queues))
		return -EINVAL;

	if (queue_id < dev->real_num_rx_queues)
		dev->_rx[queue_id].umem = umem;
	if (queue_id < dev->real_num_tx_queues)
		dev->_tx[queue_id].umem = umem;

	return 0;
}

struct xdp_umem *xdp_get_umem_from_qid(struct net_device *dev,
@@ -88,7 +95,10 @@ int xdp_umem_assign_dev(struct xdp_umem *umem, struct net_device *dev,
		goto out_rtnl_unlock;
	}

	xdp_reg_umem_at_qid(dev, umem, queue_id);
	err = xdp_reg_umem_at_qid(dev, umem, queue_id);
	if (err)
		goto out_rtnl_unlock;

	umem->dev = dev;
	umem->queue_id = queue_id;
	if (force_copy)