Commit d769ccaf authored by Kal Conley's avatar Kal Conley Committed by Martin KaFai Lau

xsk: Fix unaligned descriptor validation

Make sure unaligned descriptors that straddle the end of the UMEM are
considered invalid. Currently, descriptor validation is broken for
zero-copy mode which only checks descriptors at page granularity.
For example, descriptors in zero-copy mode that overrun the end of the
UMEM but not a page boundary are (incorrectly) considered valid. The
UMEM boundary check needs to happen before the page boundary and
contiguity checks in xp_desc_crosses_non_contig_pg(). Do this check in
xp_unaligned_validate_desc() instead like xp_check_unaligned() already
does.

Fixes: 2b43470a ("xsk: Introduce AF_XDP buffer allocation API")
Signed-off-by: default avatarKal Conley <kal.conley@dectris.com>
Acked-by: default avatarMagnus Karlsson <magnus.karlsson@intel.com>
Link: https://lore.kernel.org/r/20230405235920.7305-2-kal.conley@dectris.comSigned-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
parent 34bf9347
...@@ -180,13 +180,8 @@ static inline bool xp_desc_crosses_non_contig_pg(struct xsk_buff_pool *pool, ...@@ -180,13 +180,8 @@ static inline bool xp_desc_crosses_non_contig_pg(struct xsk_buff_pool *pool,
if (likely(!cross_pg)) if (likely(!cross_pg))
return false; return false;
if (pool->dma_pages_cnt) { return pool->dma_pages_cnt &&
return !(pool->dma_pages[addr >> PAGE_SHIFT] & !(pool->dma_pages[addr >> PAGE_SHIFT] & XSK_NEXT_PG_CONTIG_MASK);
XSK_NEXT_PG_CONTIG_MASK);
}
/* skb path */
return addr + len > pool->addrs_cnt;
} }
static inline u64 xp_aligned_extract_addr(struct xsk_buff_pool *pool, u64 addr) static inline u64 xp_aligned_extract_addr(struct xsk_buff_pool *pool, u64 addr)
......
...@@ -162,6 +162,7 @@ static inline bool xp_unaligned_validate_desc(struct xsk_buff_pool *pool, ...@@ -162,6 +162,7 @@ static inline bool xp_unaligned_validate_desc(struct xsk_buff_pool *pool,
return false; return false;
if (base_addr >= pool->addrs_cnt || addr >= pool->addrs_cnt || if (base_addr >= pool->addrs_cnt || addr >= pool->addrs_cnt ||
addr + desc->len > pool->addrs_cnt ||
xp_desc_crosses_non_contig_pg(pool, addr, desc->len)) xp_desc_crosses_non_contig_pg(pool, addr, desc->len))
return false; return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment