It is possible to set the instruction pointer to undefined values by
using an operator larger than ':' in ASCII.
Since the personality function array does not have 256 entries, an
invalid operator can overflow the array.
Proof of concept:
$ echo "a _ b" > poc
$ ln -s $(which pkgconf) poc-pkgconf
$ ./poc-pkgconf
Every version line has a newline at the end; the malformed whitespace checker
should just check for trailing spaces and tabs.
Resolves https://todo.sr.ht/~kaniini/pkgconf/15
It is possible to trigger an out of boundary access with specially
crafted files. If a line consist of only a key and spaces, then
op will point to '\0'-ending of the buffer. Since p is iterated by
one byte right past this ending '\0', the next read access to p is
effectively out of bounds.
Theoretically this can also lead to out of boundary writes if spaces
are encountered.
Proof of concept (I recommend to compile with address sanitizer):
$ echo -n a > poc.pc
$ dd if=/dev/zero bs=1 count=65533 | tr '\0' ' ' >> poc.pc
$ pkgconf poc.pc
pkgconf_fgetline is called with a user-defined buffer, its size, and
a FILE stream to read input from.
If the buffer is almost completely filled and the file stream contains
an escaped character, then it is possible to trigger an off-by-one
buffer overflow with a '\0' character.
Easiest example to trigger this:
char buf[2];
pkgconf_fgetline(buf, sizeof(buf), stdin);
Enter "\\" (two backslashes) and press enter. If the library and the
program are compiled with address sanitizer, you will see the program
crashing. Otherwise it depends on your architecture what happens.
Since nobody should be using a buffer of only size 1 or 2, keep enough
space for a possibly escaped character in while loop by subtracting one
more byte for this situation, not just for '\0'.
This fixes a problem where on Windows the prefix would
not match if the prefix is generated with backslashes
and the rest of the variables use normal slashes
If a key is defined with no value, dequote will allocate a buffer with a
length of 0. Since the buffer's length is 0, any manipulation of its
content is UB.
Example .pc file:
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
xcflags=
xlibs= -lSM -lICE -lX11
Name: Obt
Description: Openbox Toolkit Library
Version: 3.6
Requires: glib-2.0 libxml-2.0
Libs: -L${libdir} -lobt ${xlibs}
Cflags: -I${includedir}/openbox/3.6 ${xcflags}
Output using pkgconf 1.5.2 on x86_64 Linux/musl:
% pkgconf --cflags obt-3.5
-I/usr/include/openbox/3.6 \�\\�I\�\ -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/libxml2
On Debian/Ubuntu I get:
CC libpkgconf/personality.lo
libpkgconf/personality.c: In function ‘load_personality_with_path’:
libpkgconf/personality.c:195:3: warning: implicit declaration of function ‘strlcpy’ [-Wimplicit-function-declaration]
strlcpy(pathbuf, path, sizeof pathbuf);
^~~~~~~
CC libpkgconf/parser.lo
CCLD libpkgconf.la
ar: `u' modifier ignored since `D' is the default (see `U')
CC cli/pkgconf-main.o
CC cli/pkgconf-getopt_long.o
CC cli/pkgconf-renderer-msvc.o
CCLD pkgconf
./.libs/libpkgconf.so: undefined reference to `strlcpy'
client: use BELIBRARIES
On Haiku, BELIBRARIES is the equivalent to LIBRARY_PATH on many other
systems, while LIBRARY_PATH is instead the LD_LIBRARY_PATH of Haiku.
pkg: bootstrap package search paths with Haiku's find_paths
This commit adds build_default_pkgconfig_path. The function appends
to the list given the default pkgconfig paths, and will supersede
get_default_pkgconfig_path