Bug#1129942: apt: stack buffer overflow in SaveInConfig()
Ilia Kashintsev <[email protected]> Fri, 06 Mar 2026 10:15:57 +0000
| Newsgroups | gmane.linux.debian.apt.devel |
|---|---|
| Message-ID | <177279215744.12265.15719424787749818659.reportbug__15337.1475565777$1772792249$gmane$org@d69c18a0c9fb> |
Package: apt Version: 3.1.16 Severity: normal X-Debbugs-Cc: [email protected] Hello mainteiners! When apt is built with clang-19 and ASAN sanitizer error dynamic-stack-buffer-overflow arises in apt-pkg/contrib/cmdnline.cc in CommandLine::SaveInConfig() because length becomes equal to 100 + argc * 50 on the last iteration of the for loop at line 402. Sanitizer report: ==8539==ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address 0x7fffdce86c7a at pc 0x7d64f755d4e5 bp 0x7fffdce86b50 sp 0x7fffdce86b40 WRITE of size 1 at 0x7fffdce86c7a thread T0 #0 0x7d64f755d4e4 in CommandLine::SaveInConfig(unsigned int const&, char const* const*) /orig/apt/apt-pkg/contrib/cmndline.cc:428 #1 0x7d64f755ae69 in CommandLine::Parse(int, char const**) /orig/apt/apt-pkg/contrib/cmndline.cc:192 #2 0x7d64f7bf73b1 in ParseCommandLine(CommandLine&, APT_CMD, Configuration* const*, pkgSystem**, int, char const**, bool (*)(CommandLine&), std::vector<aptDispatchWithHelp, std::allocator<aptDispatchWithHelp> > (*)()) /orig/apt/apt-private/private-cmndline.cc:664 #3 0x6418cbeb36a7 in main /orig/apt/cmdline/apt.cc:133 #4 0x7d64f6cce1c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 8e9fd827446c24067541ac5390e6f527fb5947bb) #5 0x7d64f6cce28a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 8e9fd827446c24067541ac5390e6f527fb5947bb) #6 0x6418cbeb2744 in _start (/orig/apt/cmdline/apt+0x6744) (BuildId: 2783315d6ae80f24080be3c68579595c00461472) Address 0x7fffdce86c7a is located in stack of thread T0 SUMMARY: AddressSanitizer: dynamic-stack-buffer-overflow /orig/apt/apt-pkg/contrib/cmndline.cc:428 in CommandLine::SaveInConfig(unsigned int const&, char const* const*) Shadow bytes around the buggy address: 0x7fffdce86980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7fffdce86a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7fffdce86a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7fffdce86b00: 00 00 00 00 00 00 00 00 00 00 00 00 ca ca ca ca 0x7fffdce86b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x7fffdce86c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00[02] 0x7fffdce86c80: cb cb cb cb 00 00 00 00 00 00 00 00 00 00 00 00 0x7fffdce86d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7fffdce86d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7fffdce86e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7fffdce86e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==8539==ABORTING Reproducing: To reproduce build the project with ASAN and in cmdline/ do ./apt 0o "000000000000==================================================================================================================== " Quotation marks are present to preserve a space in argv[2]. Suggested fixes: I don't know how exactly to fix it, but there are a couple suggestions: Option 1) Add an extra length check. Diff: --- a/apt-pkg/contrib/cmndline.cc +++ b/apt-pkg/contrib/cmndline.cc @@ -417,6 +417,8 @@ void CommandLine::SaveInConfig(unsigned int const &argc, char const * const * co closeQuote = true; } } + if (length >= sizeof(cmdline) - 2) + continue; if (closeQuote == true) { cmdline[length++] = '\''; Option 2) Allocate more memory for the cmdline variable based on argv length (could be excessive in the suggestion below). Diff: --- a/apt-pkg/contrib/cmndline.cc +++ b/apt-pkg/contrib/cmndline.cc @@ -394,7 +394,11 @@ bool CommandLine::DispatchArg(Dispatch const * const Map,bool NoMatch) than nothing after all. */ void CommandLine::SaveInConfig(unsigned int const &argc, char const * const * const argv) { - char cmdline[100 + argc * 50]; + unsigned int argvLength = 0; + for (int i = 0; i < argc; i++) + { + argvLength += strlen(argv[i]) + 1; + } + char cmdline[100 + argvLength * 3]; memset(cmdline, 0, sizeof(cmdline)); unsigned int length = 0; bool lastWasOption = false; -- System Information: Debian Release: trixie/sid Architecture: amd64 (x86_64) Kernel: Linux 6.12.11-1-generic (SMP w/12 CPU threads; PREEMPT) Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=C, LC_CTYPE=C.UTF-8 (charmap=UTF-8), LANGUAGE not set Shell: /bin/sh linked to /usr/bin/dash Init: unable to detect