|SUCCESS| [v2] app/testpmd: avoid cmdline use-after-free on SIGINT
dpdklab at iol.unh.edu
dpdklab at iol.unh.edu
Mon Apr 27 16:30:19 CEST 2026
Test-Label: ai-code-review
Test-Status: SUCCESS
https://dpdk.org/patch/163308
_AI Code Review_
=== Patch Review: series.patch (via Claude) ===
Review date: 2026-04-27
Reviewing commit for potential issues:
Commit: (sha from patch headers)
Author: Sunyang Wu <sunyang.wu at jaguarmicro.com>
Subject: app/testpmd: avoid cmdline use-after-free on SIGINT
This patch addresses a use-after-free race condition in testpmd's signal
handling by using atomic operations to manage the testpmd_cl global pointer
lifetime.
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index c5abeb5730..bdc5c3e3eb 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -14500,22 +14500,31 @@ cmdline_read_from_file(const char *filename, bool echo)
> void
> prompt_exit(void)
> {
> - cmdline_quit(testpmd_cl);
> + struct cmdline *cl;
> +
> + cl = __atomic_load_n(&testpmd_cl, __ATOMIC_ACQUIRE);
> + if (cl != NULL)
> + cmdline_quit(cl);
Does this code fully prevent the use-after-free? After the atomic load
returns a non-NULL pointer, the prompt() function running on another
thread could still call cmdline_stdin_exit(cl) and free the object
before cmdline_quit(cl) executes here. The atomic operations prevent
observing a stale pointer value, but they don't prevent the race between
checking the pointer and using it (TOCTOU issue).
Consider whether a reference counting scheme or a mutex protecting both
the pointer check and cmdline_quit() call would be more appropriate to
ensure the cmdline object remains valid throughout prompt_exit()'s
execution.
> }
>
> /* 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);
> + __atomic_store_n(&testpmd_cl, cl, __ATOMIC_RELEASE);
> + cmdline_interact(cl);
> + /* Clear global pointer before freeing cmdline object. */
> + __atomic_store_n(&testpmd_cl, NULL, __ATOMIC_RELEASE);
> + cmdline_stdin_exit(cl);
Does the window between setting testpmd_cl to NULL and calling
cmdline_stdin_exit(cl) introduce another race? If a SIGINT arrives after
testpmd_cl is set to NULL but before cmdline_stdin_exit() completes, and
prompt_exit() sees NULL and returns without calling cmdline_quit(), could
this leave cmdline_interact() in an inconsistent state since it wasn't
properly interrupted?
Would it be safer to call cmdline_stdin_exit(cl) first and then clear
testpmd_cl, or does the order matter for the signal handling semantics?
More information about the test-report
mailing list