From 94623389ba61a3a93decc726ed63e52cca7b3d39 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Mon, 10 Feb 2020 13:15:06 +0200 Subject: [PATCH] Fix buffer overflow in %{S:...} and %{P:...} macro primitives We can't assume that a buffer allocated for one thing is sufficient for another thing. The S and P macros share the same exact logic, refactor to use common code to avoid having to fix twice, cleaning up doFoo() a bit in the process. Fixes: #1019 --- rpmio/macro.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/rpmio/macro.c b/rpmio/macro.c index 2a60aaa15..e901328d4 100644 --- a/rpmio/macro.c +++ b/rpmio/macro.c @@ -140,6 +140,8 @@ static void doLua(MacroBuf mb, int chkexist, int negate, const char * f, size_t fn, const char * g, size_t gn); static void doOutput(MacroBuf mb, int chkexist, int negate, const char * f, size_t fn, const char * g, size_t gn); +static void doSP(MacroBuf mb, int chkexist, int negate, + const char * f, size_t fn, const char * g, size_t gn); static void doTrace(MacroBuf mb, int chkexist, int negate, const char * f, size_t fn, const char * g, size_t gn); @@ -553,8 +555,8 @@ static struct builtins_s { parseFunc parse; int havearg; } const builtinmacros[] = { - { STR_AND_LEN("P"), doFoo, NULL, 1 }, - { STR_AND_LEN("S"), doFoo, NULL, 1 }, + { STR_AND_LEN("P"), doSP, NULL, 1 }, + { STR_AND_LEN("S"), doSP, NULL, 1 }, { STR_AND_LEN("basename"), doFoo, NULL, 1 }, { STR_AND_LEN("define"), NULL, doDef, 0 }, { STR_AND_LEN("dirname"), doFoo, NULL, 1 }, @@ -1053,6 +1055,25 @@ static void doLua(MacroBuf mb, int chkexist, int negate, const char * f, size_t #endif } +static void +doSP(MacroBuf mb, int chkexist, int negate, + const char * f, size_t fn, const char * g, size_t gn) +{ + const char *b = ""; + char *buf = NULL; + char *s = NULL; + + if (gn > 0) { + expandThis(mb, g, gn, &buf); + b = buf; + } + + s = rstrscat(NULL, (*f == 'S') ? "%SOURCE" : "%PATCH", b, NULL); + expandMacro(mb, s, 0); + free(s); + free(buf); +} + /** * Execute macro primitives. * @param mb macro expansion state @@ -1186,22 +1207,6 @@ doFoo(MacroBuf mb, int chkexist, int negate, const char * f, size_t fn, } else if (STREQ("getncpus", f, fn)) { sprintf(buf, "%u", getncpus()); b = buf; - } else if (STREQ("S", f, fn)) { - for (b = buf; (c = *b) && risdigit(c);) - b++; - if (!c) { /* digit index */ - b++; - sprintf(b, "%%SOURCE%s", buf); - } else - b = buf; - } else if (STREQ("P", f, fn)) { - for (b = buf; (c = *b) && risdigit(c);) - b++; - if (!c) { /* digit index */ - b++; - sprintf(b, "%%PATCH%s", buf); - } else - b = buf; } if (b) {