From 307872f71b357a3839fd037514a1c3dabfacc611 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Mon, 3 Feb 2020 14:54:16 +0200 Subject: [PATCH] Fix POPT_ARG_STRING memleaks in librpmbuild popt always returned malloc'ed memory for POPT_ARG_STRING items, but for whatever historical reason rpm systematically passed const char * pointers as targets, making them look non-freeable. Besides changing just the types and adding free()'s, const-correctness requires extra tweaks as there's mixed use from string literals and poptGetArg() which does return const pointers. --- build/parseDescription.c | 11 +++++++---- build/parseFiles.c | 5 +++-- build/parsePolicies.c | 5 +++-- build/parsePrep.c | 6 +++++- build/parseScript.c | 11 +++++++---- build/policies.c | 8 ++++++-- 6 files changed, 31 insertions(+), 15 deletions(-) diff --git a/build/parseDescription.c b/build/parseDescription.c index c0737c0..72811f5 100644 --- a/build/parseDescription.c +++ b/build/parseDescription.c @@ -19,8 +19,8 @@ int parseDescription(rpmSpec spec) int rc, argc; int arg; const char **argv = NULL; - const char *name = NULL; - const char *lang = RPMBUILD_DEFAULT_LANG; + char *name = NULL; + char *lang = NULL; const char *descr = ""; poptContext optCon = NULL; struct poptOption optionsTable[] = { @@ -52,7 +52,7 @@ int parseDescription(rpmSpec spec) if (poptPeekArg(optCon)) { if (name == NULL) - name = poptGetArg(optCon); + name = xstrdup(poptGetArg(optCon)); if (poptPeekArg(optCon)) { rpmlog(RPMLOG_ERR, _("line %d: Too many names: %s\n"), spec->lineNum, @@ -75,12 +75,15 @@ int parseDescription(rpmSpec spec) } if (addLangTag(spec, pkg->header, - RPMTAG_DESCRIPTION, descr, lang)) { + RPMTAG_DESCRIPTION, descr, + lang ? lang : RPMBUILD_DEFAULT_LANG)) { nextPart = PART_ERROR; } exit: freeStringBuf(sb); + free(lang); + free(name); free(argv); poptFreeContext(optCon); return nextPart; diff --git a/build/parseFiles.c b/build/parseFiles.c index 69935d4..0dc1f17 100644 --- a/build/parseFiles.c +++ b/build/parseFiles.c @@ -17,7 +17,7 @@ int parseFiles(rpmSpec spec) int rc, argc; int arg; const char ** argv = NULL; - const char *name = NULL; + char *name = NULL; int flag = PART_SUBNAME; poptContext optCon = NULL; struct poptOption optionsTable[] = { @@ -52,7 +52,7 @@ int parseFiles(rpmSpec spec) if (poptPeekArg(optCon)) { if (name == NULL) - name = poptGetArg(optCon); + name = xstrdup(poptGetArg(optCon)); if (poptPeekArg(optCon)) { rpmlog(RPMLOG_ERR, _("line %d: Too many names: %s\n"), spec->lineNum, @@ -89,6 +89,7 @@ int parseFiles(rpmSpec spec) exit: rpmPopMacro(NULL, "license"); free(argv); + free(name); poptFreeContext(optCon); return res; diff --git a/build/parsePolicies.c b/build/parsePolicies.c index 118b92c..64b95b1 100644 --- a/build/parsePolicies.c +++ b/build/parsePolicies.c @@ -19,7 +19,7 @@ int parsePolicies(rpmSpec spec) int rc, argc; int arg; const char **argv = NULL; - const char *name = NULL; + char *name = NULL; int flag = PART_SUBNAME; poptContext optCon = NULL; @@ -50,7 +50,7 @@ int parsePolicies(rpmSpec spec) if (poptPeekArg(optCon)) { if (name == NULL) - name = poptGetArg(optCon); + name = xstrdup(poptGetArg(optCon)); if (poptPeekArg(optCon)) { rpmlog(RPMLOG_ERR, _("line %d: Too many names: %s\n"), spec->lineNum, spec->line); @@ -66,6 +66,7 @@ int parsePolicies(rpmSpec spec) exit: free(argv); + free(name); poptFreeContext(optCon); return res; diff --git a/build/parsePrep.c b/build/parsePrep.c index fe37575..cafb050 100644 --- a/build/parsePrep.c +++ b/build/parsePrep.c @@ -242,7 +242,7 @@ static int doSetupMacro(rpmSpec spec, const char *line) int leaveDirs = 0, skipDefaultAction = 0; int createDir = 0, quietly = 0; int buildInPlace = 0; - const char * dirName = NULL; + char * dirName = NULL; struct poptOption optionsTable[] = { { NULL, 'a', POPT_ARG_STRING, NULL, 'a', NULL, NULL}, { NULL, 'b', POPT_ARG_STRING, NULL, 'b', NULL, NULL}, @@ -373,6 +373,7 @@ exit: freeStringBuf(before); freeStringBuf(after); poptFreeContext(optCon); + free(dirName); free(argv); return rc; @@ -484,6 +485,9 @@ static rpmRC doPatchMacro(rpmSpec spec, const char *line) exit: argvFree(patchnums); + free(opt_b); + free(opt_d); + free(opt_o); free(argv); poptFreeContext(optCon); return rc; diff --git a/build/parseScript.c b/build/parseScript.c index bdf6ab3..e037bba 100644 --- a/build/parseScript.c +++ b/build/parseScript.c @@ -100,9 +100,9 @@ int parseScript(rpmSpec spec, int parsePart) int arg; const char **argv = NULL; poptContext optCon = NULL; - const char *name = NULL; - const char *prog = "/bin/sh"; - const char *file = NULL; + char *name = NULL; + char *prog = xstrdup("/bin/sh"); + char *file = NULL; int priority = 1000000; struct poptOption optionsTable[] = { { NULL, 'p', POPT_ARG_STRING, &prog, 'p', NULL, NULL}, @@ -326,7 +326,7 @@ int parseScript(rpmSpec spec, int parsePart) if (poptPeekArg(optCon)) { if (name == NULL) - name = poptGetArg(optCon); + name = xstrdup(poptGetArg(optCon)); if (poptPeekArg(optCon)) { rpmlog(RPMLOG_ERR, _("line %d: Too many names: %s\n"), spec->lineNum, @@ -465,6 +465,9 @@ exit: free(reqargs); freeStringBuf(sb); free(progArgv); + free(prog); + free(name); + free(file); free(argv); poptFreeContext(optCon); diff --git a/build/policies.c b/build/policies.c index d3b1930..e92df19 100644 --- a/build/policies.c +++ b/build/policies.c @@ -276,16 +276,20 @@ static rpmRC processPolicies(rpmSpec spec, Package pkg, int test) } if (writeModuleToHeader(mod, pkg) != RPMRC_OK) { - freeModule(mod); goto exit; } - freeModule(mod); + mod = freeModule(mod); + name = _free(name); + types = _free(types); } rc = RPMRC_OK; exit: + freeModule(mod); + free(name); + free(types); return rc; } -- 2.27.0