|SUCCESS| [v3] app/testpmd: avoid cmdline use-after-free on SIGINT

dpdklab at iol.unh.edu dpdklab at iol.unh.edu
Mon Apr 27 16:31:07 CEST 2026


Test-Label: ai-code-review
Test-Status: SUCCESS
https://dpdk.org/patch/163309

_AI Code Review_

=== Patch Review: series.patch (via Claude) ===
Review date: 2026-04-27

Subject: Re: [PATCH v3] app/testpmd: avoid cmdline use-after-free on SIGINT

Commit: 20260427111347.40520-1-sunyang.wu at jaguarmicro.com
Author: Sunyang Wu <sunyang.wu at jaguarmicro.com>

app/testpmd: avoid cmdline use-after-free on SIGINT

This patch addresses a use-after-free issue when SIGINT is received
during testpmd shutdown, by using atomic operations to manage the
testpmd_cl pointer lifetime.

> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index c5abeb5730..ee1eff737b 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -41,6 +41,7 @@
>  #endif
>  #include <rte_mbuf_dyn.h>
>  #include <rte_mbuf_history.h>
> +#include <rte_stdatomic.h>
>  #include <rte_trace.h>
>  
>  #include <cmdline_rdline.h>
> @@ -70,7 +71,7 @@
>  #include "cmdline_tm.h"
>  #include "bpf_cmd.h"
>  
> -static struct cmdline *testpmd_cl;
> +static RTE_ATOMIC(struct cmdline *) testpmd_cl;

[ ... ]

> @@ -14500,22 +14501,31 @@ cmdline_read_from_file(const char *filename, bool echo)
>  void
>  prompt_exit(void)
>  {
> -	cmdline_quit(testpmd_cl);
> +	struct cmdline *cl;
> +
> +	cl = rte_atomic_load_explicit(&testpmd_cl, rte_memory_order_acquire);
> +	if (cl != NULL)
> +		cmdline_quit(cl);

Does prompt_exit() fully prevent the use-after-free?  Between the atomic
load and the cmdline_quit() call, can prompt() clear testpmd_cl and free
the cmdline object?  If a signal arrives immediately after the atomic load
but before cmdline_quit() executes, does this create a race where the
loaded pointer becomes stale?

>  }
>  
>  /* prompt function, called from main on MAIN lcore */
>  void
>  prompt(void)
>  {
> -	testpmd_cl = cmdline_stdin_new(main_ctx, "testpmd> ");
> -	if (testpmd_cl == NULL) {
> +	struct cmdline *cl;
> +
> +	cl = cmdline_stdin_new(main_ctx, "testpmd> ");
> +	if (cl == NULL) {
>  		fprintf(stderr,
>  			"Failed to create stdin based cmdline context\n");
>  		return;
>  	}
>  
> -	cmdline_interact(testpmd_cl);
> -	cmdline_stdin_exit(testpmd_cl);
> +	rte_atomic_store_explicit(&testpmd_cl, cl, rte_memory_order_release);
> +	cmdline_interact(cl);
> +	/* Clear global pointer before freeing cmdline object. */
> +	rte_atomic_store_explicit(&testpmd_cl, NULL, rte_memory_order_release);
> +	cmdline_stdin_exit(cl);

Does this sequence fully close the race window?  After storing NULL into
testpmd_cl but before cmdline_stdin_exit() completes, can prompt_exit()
load NULL and skip cmdline_quit(), leaving the cmdline object in an
inconsistent state if cmdline_interact() is still active?

Can prompt() be called multiple times concurrently, or is there external
serialization that prevents this code from running on multiple threads
simultaneously?


More information about the test-report mailing list