Skip to content

Commit

Permalink
xsk: Fix broken Tx ring validation
Browse files Browse the repository at this point in the history
[ Upstream commit f654fae ]

Fix broken Tx ring validation for AF_XDP. The commit under the Fixes
tag, fixed an off-by-one error in the validation but introduced
another error. Descriptors are now let through even if they straddle a
chunk boundary which they are not allowed to do in aligned mode. Worse
is that they are let through even if they straddle the end of the umem
itself, tricking the kernel to read data outside the allowed umem
region which might or might not be mapped at all.

Fix this by reintroducing the old code, but subtract the length by one
to fix the off-by-one error that the original patch was
addressing. The test chunk != chunk_end makes sure packets do not
straddle chunk boundraries. Note that packets of zero length are
allowed in the interface, therefore the test if the length is
non-zero.

Fixes: ac31565 ("xsk: Fix for xp_aligned_validate_desc() when len == chunk_size")
Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Björn Töpel <bjorn@kernel.org>
Link: https://lore.kernel.org/bpf/20210618075805.14412-1-magnus.karlsson@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
magnus-karlsson authored and gregkh committed Jul 14, 2021
1 parent dda6334 commit 5ab8b17
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions net/xdp/xsk_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,15 @@ static inline bool xskq_cons_read_addr_unchecked(struct xsk_queue *q, u64 *addr)
static inline bool xp_aligned_validate_desc(struct xsk_buff_pool *pool,
struct xdp_desc *desc)
{
u64 chunk;

if (desc->len > pool->chunk_size)
return false;
u64 chunk, chunk_end;

chunk = xp_aligned_extract_addr(pool, desc->addr);
if (likely(desc->len)) {
chunk_end = xp_aligned_extract_addr(pool, desc->addr + desc->len - 1);
if (chunk != chunk_end)
return false;
}

if (chunk >= pool->addrs_cnt)
return false;

Expand Down

0 comments on commit 5ab8b17

Please sign in to comment.