Skip to content

Commit a5f1da6

Browse files
author
Martin KaFai Lau
committed
Merge branch 'xsk: Fix unaligned descriptor validation'
Kal Conley says: ==================== This patchset includes the test with the bugfix as requested here: https://lore.kernel.org/all/f1a32d5a-03e7-fce1-f5a5-6095f365f0a9@linux.dev/ Patch #1 (the bugfix) is identical to the previous submission except that I improved the commit message slightly. Magnus: I improved the test code a little different than you asked since I thought this was a little simpler than having a separate function for now. Hopefully, you can live with this :-). ==================== Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
2 parents 34bf934 + c080159 commit a5f1da6

4 files changed

Lines changed: 28 additions & 7 deletions

File tree

include/net/xsk_buff_pool.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -180,13 +180,8 @@ static inline bool xp_desc_crosses_non_contig_pg(struct xsk_buff_pool *pool,
180180
if (likely(!cross_pg))
181181
return false;
182182

183-
if (pool->dma_pages_cnt) {
184-
return !(pool->dma_pages[addr >> PAGE_SHIFT] &
185-
XSK_NEXT_PG_CONTIG_MASK);
186-
}
187-
188-
/* skb path */
189-
return addr + len > pool->addrs_cnt;
183+
return pool->dma_pages_cnt &&
184+
!(pool->dma_pages[addr >> PAGE_SHIFT] & XSK_NEXT_PG_CONTIG_MASK);
190185
}
191186

192187
static inline u64 xp_aligned_extract_addr(struct xsk_buff_pool *pool, u64 addr)

net/xdp/xsk_queue.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ static inline bool xp_unaligned_validate_desc(struct xsk_buff_pool *pool,
162162
return false;
163163

164164
if (base_addr >= pool->addrs_cnt || addr >= pool->addrs_cnt ||
165+
addr + desc->len > pool->addrs_cnt ||
165166
xp_desc_crosses_non_contig_pg(pool, addr, desc->len))
166167
return false;
167168

tools/testing/selftests/bpf/xskxceiver.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
*/
7070

7171
#define _GNU_SOURCE
72+
#include <assert.h>
7273
#include <fcntl.h>
7374
#include <errno.h>
7475
#include <getopt.h>
@@ -1876,6 +1877,29 @@ static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_
18761877
test->ifobj_rx->umem->unaligned_mode = true;
18771878
testapp_invalid_desc(test);
18781879
break;
1880+
case TEST_TYPE_UNALIGNED_INV_DESC_4K1_FRAME: {
1881+
u64 page_size, umem_size;
1882+
1883+
if (!hugepages_present(test->ifobj_tx)) {
1884+
ksft_test_result_skip("No 2M huge pages present.\n");
1885+
return;
1886+
}
1887+
test_spec_set_name(test, "UNALIGNED_INV_DESC_4K1_FRAME_SIZE");
1888+
/* Odd frame size so the UMEM doesn't end near a page boundary. */
1889+
test->ifobj_tx->umem->frame_size = 4001;
1890+
test->ifobj_rx->umem->frame_size = 4001;
1891+
test->ifobj_tx->umem->unaligned_mode = true;
1892+
test->ifobj_rx->umem->unaligned_mode = true;
1893+
/* This test exists to test descriptors that staddle the end of
1894+
* the UMEM but not a page.
1895+
*/
1896+
page_size = sysconf(_SC_PAGESIZE);
1897+
umem_size = test->ifobj_tx->umem->num_frames * test->ifobj_tx->umem->frame_size;
1898+
assert(umem_size % page_size > PKT_SIZE);
1899+
assert(umem_size % page_size < page_size - PKT_SIZE);
1900+
testapp_invalid_desc(test);
1901+
break;
1902+
}
18791903
case TEST_TYPE_UNALIGNED:
18801904
if (!testapp_unaligned(test))
18811905
return;

tools/testing/selftests/bpf/xskxceiver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ enum test_type {
7878
TEST_TYPE_ALIGNED_INV_DESC,
7979
TEST_TYPE_ALIGNED_INV_DESC_2K_FRAME,
8080
TEST_TYPE_UNALIGNED_INV_DESC,
81+
TEST_TYPE_UNALIGNED_INV_DESC_4K1_FRAME,
8182
TEST_TYPE_HEADROOM,
8283
TEST_TYPE_TEARDOWN,
8384
TEST_TYPE_BIDI,

0 commit comments

Comments
 (0)