From 5eb9cae0091e94c7a807360ef13019e5e9fef805 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sun, 31 May 2020 00:25:54 +0200 Subject: [PATCH] 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. --- libpkgconf/tuple.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libpkgconf/tuple.c b/libpkgconf/tuple.c index f505abd..e445b9f 100644 --- a/libpkgconf/tuple.c +++ b/libpkgconf/tuple.c @@ -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,7 +274,8 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const for (pptr = ptr + 2; *pptr != '\0'; pptr++) { if (*pptr != '}') - *vptr++ = *pptr; + if (vptr < vend) + *vptr++ = *pptr; else { *vptr = '\0';