[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.