From: Kal Conley Date: Wed, 5 Apr 2023 23:59:18 +0000 (+0200) Subject: xsk: Fix unaligned descriptor validation X-Git-Tag: v6.1.37~1710 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3ee343914c1f9300b18685e4ee697458e948ac1d;p=platform%2Fkernel%2Flinux-starfive.git xsk: Fix unaligned descriptor validation [ Upstream commit d769ccaf957fe7391f357c0a923de71f594b8a2b ] 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: 2b43470add8c ("xsk: Introduce AF_XDP buffer allocation API") Signed-off-by: Kal Conley Acked-by: Magnus Karlsson Link: https://lore.kernel.org/r/20230405235920.7305-2-kal.conley@dectris.com Signed-off-by: Martin KaFai Lau Signed-off-by: Sasha Levin --- diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h index f787c3f..996eaf1 100644 --- a/include/net/xsk_buff_pool.h +++ b/include/net/xsk_buff_pool.h @@ -175,13 +175,8 @@ static inline bool xp_desc_crosses_non_contig_pg(struct xsk_buff_pool *pool, if (likely(!cross_pg)) return false; - if (pool->dma_pages_cnt) { - return !(pool->dma_pages[addr >> PAGE_SHIFT] & - XSK_NEXT_PG_CONTIG_MASK); - } - - /* skb path */ - return addr + len > pool->addrs_cnt; + return pool->dma_pages_cnt && + !(pool->dma_pages[addr >> PAGE_SHIFT] & XSK_NEXT_PG_CONTIG_MASK); } static inline u64 xp_aligned_extract_addr(struct xsk_buff_pool *pool, u64 addr) diff --git a/net/xdp/xsk_queue.h b/net/xdp/xsk_queue.h index c6fb6b7..bdeba20 100644 --- a/net/xdp/xsk_queue.h +++ b/net/xdp/xsk_queue.h @@ -161,6 +161,7 @@ static inline bool xp_unaligned_validate_desc(struct xsk_buff_pool *pool, return false; 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)) return false;