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

Reply via email to