When apt is built with clang-19 and ASAN a global-buffer-overflow(read) error occurs in deblistparser.cc in debListParser::ParseDepends().
It is caused by the lack of the closing '>' in the input, which in turn leads to End >= Stop for the second iteration of the loop "while (I != Stop)" on the line 731.
This leads to the following loop "for (;End != Stop && !isspace_ascii(*End) && *End != '>'; ++End);" on line 735 to work incorrectly and overflow.
Since the overflow read goes throught the set environment variables the behaviour might alter because of them, f.e. resulting in a overflow on line 760 instead.
Sanitizer output:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==8457==ERROR: AddressSanitizer: stack-overflow on address 0x7ffe69d73000 (pc 0x7dd45732c42d bp 0x7ffe69d6fe40 sp 0x7ffe69d6fa50 T0)
#0 0x7dd45732c42d in debListParser::ParseDepends(char const*, char const*, std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >&, unsigned int&, bool, bool, bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) /orig/apt/apt-pkg/deb/deblistparser.cc:735
#1 0x7dd45732ab90 in debListParser::ParseDepends(char const*, char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, unsigned int&, bool const&, bool const&, bool const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /orig/apt/apt-pkg/deb/deblistparser.cc:559
#2 0x7dd457a056f2 in DoBuildDep(CommandLine&) /orig/apt/apt-private/private-source.cc:721
#3 0x7dd45726ec85 in CommandLine::DispatchArg(CommandLine::Dispatch const*, bool) /orig/apt/apt-pkg/contrib/cmndline.cc:373
#4 0x7dd457909f85 in DispatchCommandLine(CommandLine&, std::vector<CommandLine::Dispatch, std::allocator<CommandLine::Dispatch> > const&) /orig/apt/apt-private/private-cmndline.cc:704
#5 0x570503be689c in main /orig/apt/cmdline/apt.cc:148
#6 0x7dd4569e01c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 8e9fd827446c24067541ac5390e6f527fb5947bb)
#7 0x7dd4569e028a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 8e9fd827446c24067541ac5390e6f527fb5947bb)
#8 0x570503be5744 in _start (/orig/apt/cmdline/apt+0x6744) (BuildId: 2783315d6ae80f24080be3c68579595c00461472)
SUMMARY: AddressSanitizer: stack-overflow /orig/apt/apt-pkg/deb/deblistparser.cc:735 in debListParser::ParseDepends(char const*, char const*, std::basic_string_view<char, std::char_traits<char> >&, std::basic_string_view<char, std::char_traits<char> >&, unsigned int&, bool, bool, bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
==8457==ABORTING
Steps to reproduce:
To reproduce build the project with ASAN and in cmdline/ do
./apt satisfy $'0<\t'
or, preferrably
/usr/bin/env -i ./apt satisfy $'0<\t'
Suggested fixes:
I don't know how exactly to fix it, a more elegant fix should be possible, but as a straightforward solution the following works:
Option 1) Add an extra check.
Diff:
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -730,6 +730,8 @@ const char *debListParser::ParseDepends(const char *Start, const char *Stop,
// the end of this list
while (I != Stop)
{
+ if (unlikely(End >= Stop))
+ return 0;
// look for whitespace or ending '>'
// End now points to the character after the current term
for (;End != Stop && !isspace_ascii(*End) && *End != '>'; ++End);