[PATCH net-next 5/5] selftests/xsk: make pkt_stream_even_odd_sequence rollback-safe
Tushar Vyavahare <[email protected]>
| Newsgroups | org.kernel.vger.bpf,org.kernel.vger.netdev |
|---|---|
| Message-ID | <[email protected]> |
If __pkt_stream_generate() fails midway through building per-socket streams, the original code overwrites xsk_arr[i].pkt_stream with a partial or NULL pointer before all allocations complete. Allocate all TX and RX streams into temporary arrays first and only assign them to xsk_arr after every allocation succeeds. On any failure free the already-allocated temporaries and return -ENOMEM with no xsk_arr pointers modified. Signed-off-by: Magnus Karlsson <[email protected]> Signed-off-by: Tushar Vyavahare <[email protected]> --- .../selftests/bpf/prog_tests/test_xsk.c | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.c b/tools/testing/selftests/bpf/prog_tests/test_xsk.c index 1665339844b5..ccfd9e8436a7 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_xsk.c +++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.c @@ -597,26 +597,41 @@ static int pkt_stream_receive_half(struct test_spec *test) static int pkt_stream_even_odd_sequence(struct test_spec *test) { + struct pkt_stream *tx_streams[MAX_SOCKETS] = {}; + struct pkt_stream *rx_streams[MAX_SOCKETS] = {}; struct pkt_stream *pkt_stream; u32 i; for (i = 0; i < test->nb_sockets; i++) { pkt_stream = test->ifobj_tx->xsk_arr[i].pkt_stream; - pkt_stream = __pkt_stream_generate(pkt_stream->nb_pkts / 2, - pkt_stream->pkts[0].len, i, 2); - if (!pkt_stream) - return -ENOMEM; - test->ifobj_tx->xsk_arr[i].pkt_stream = pkt_stream; + tx_streams[i] = __pkt_stream_generate(pkt_stream->nb_pkts / 2, + pkt_stream->pkts[0].len, i, 2); + if (!tx_streams[i]) + goto err; pkt_stream = test->ifobj_rx->xsk_arr[i].pkt_stream; - pkt_stream = __pkt_stream_generate(pkt_stream->nb_pkts / 2, - pkt_stream->pkts[0].len, i, 2); - if (!pkt_stream) - return -ENOMEM; - test->ifobj_rx->xsk_arr[i].pkt_stream = pkt_stream; + rx_streams[i] = __pkt_stream_generate(pkt_stream->nb_pkts / 2, + pkt_stream->pkts[0].len, i, 2); + if (!rx_streams[i]) + goto err; + } + + for (i = 0; i < test->nb_sockets; i++) { + test->ifobj_tx->xsk_arr[i].pkt_stream = tx_streams[i]; + test->ifobj_rx->xsk_arr[i].pkt_stream = rx_streams[i]; } return 0; + +err: + for (i = 0; i < test->nb_sockets; i++) { + if (tx_streams[i]) + pkt_stream_delete(tx_streams[i]); + if (rx_streams[i]) + pkt_stream_delete(rx_streams[i]); + } + + return -ENOMEM; } static int pkt_stream_len_seq(struct test_spec *test, u32 short_len, u32 long_len) -- 2.43.0