libpkgconf: tuple: fix out of boundary write

This is the same issue which has been fixed in dependency code.

If a line contains a variable which is longer than PKGCONF_ITEM_SIZE,
then the varname buffer overflows.

The code itself still does not check if a closing } exists and
truncates variable names which are too long. Since these would
be functional changes and this commit is about a protection against
undefined behaviour on a language level, these changes are not
included.

Proof of concept:
$ echo "Description: poc" > poc.pc
$ echo "Version: 1" >> poc.pc
$ echo -n 'Name: ${'
$ dd if=/dev/zero bs=1 count=66535 | tr '\0' 'x' >> poc.pc
$ echo >> poc.pc
$ pkgconf poc.pc

On my Linux system, when compiled with gcc, the varname buffer overflows
directly into buf, which means that no crash can be notified.

It's easiest to figure out when adding strlen() and sizeof() output
as debug lines.
pull/197/head
Tobias Stoeckmann 2020-05-31 00:25:54 +02:00
parent c862e030cf
commit a1f064ff2c
1 changed files with 3 additions and 1 deletions

View File

@ -264,6 +264,7 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
else if (*(ptr + 1) == '{')
{
char varname[PKGCONF_ITEM_SIZE];
char *vend = varname + PKGCONF_ITEM_SIZE - 1;
char *vptr = varname;
const char *pptr;
char *kv, *parsekv;
@ -273,6 +274,7 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
for (pptr = ptr + 2; *pptr != '\0'; pptr++)
{
if (*pptr != '}')
if (vptr < vend)
*vptr++ = *pptr;
else
{