From fbda200dd80a27f10ef0ee337f42939076c27c6b Mon Sep 17 00:00:00 2001 From: Lubos Kardos Date: Feb 02 2016 16:15:04 +0000 Subject: - Remove size limit when expanding macros - Resolves: #1301677 --- diff --git a/rpm-4.13.0-unlimited-macro-expand.patch b/rpm-4.13.0-unlimited-macro-expand.patch new file mode 100644 index 0000000..4f1a1a7 --- /dev/null +++ b/rpm-4.13.0-unlimited-macro-expand.patch @@ -0,0 +1,388 @@ +From 61838b0fdacb71a881baac164043b8e40ddfbec5 Mon Sep 17 00:00:00 2001 +From: Tom Hughes +Date: Tue, 17 Nov 2015 17:36:16 +0000 +Subject: [PATCH] Remove size limit when expanding macros + +This removes a seemingly undocumented, and not even well defined, limit +on the size of a macro expansion when parsing a spec file. + +[lkardos@redhat.com: created new funtion expandMacrosU() (Unlimited) +instead of modifying expandMacros() in order not to change API/ABI] + +Signed-off-by: Lubos Kardos +--- + build/files.c | 6 ++++-- + build/pack.c | 6 ++++-- + build/parseSpec.c | 10 ++++++---- + rpmio/macro.c | 17 +++++++++++++++++ + rpmio/rpmmacro.h | 12 ++++++++++++ + 5 files changed, 43 insertions(+), 8 deletions(-) + +diff --git a/build/files.c b/build/files.c +index ea595b9..2fc434e 100644 +--- a/build/files.c ++++ b/build/files.c +@@ -1631,11 +1631,13 @@ static rpmRC readFilesManifest(rpmSpec spec, Package pkg, const char *path) + while (fgets(buf, sizeof(buf), fd)) { + if (handleComments(buf)) + continue; +- if (expandMacros(spec, spec->macros, buf, sizeof(buf))) { ++ char *expanded = expandMacrosU(spec, spec->macros, buf); ++ if (expanded == NULL) { + rpmlog(RPMLOG_ERR, _("line: %s\n"), buf); + goto exit; + } +- argvAdd(&(pkg->fileList), buf); ++ argvAdd(&(pkg->fileList), expanded); ++ free(expanded); + nlines++; + } + +diff --git a/build/pack.c b/build/pack.c +index 213d85e..6ffe450 100644 +--- a/build/pack.c ++++ b/build/pack.c +@@ -132,11 +132,13 @@ static rpmRC addFileToTag(rpmSpec spec, const char * file, + } + + while (fgets(buf, sizeof(buf), f)) { +- if (expandMacros(spec, spec->macros, buf, sizeof(buf))) { ++ char *expanded = expandMacrosU(spec, spec->macros, buf); ++ if (expanded == NULL) { + rpmlog(RPMLOG_ERR, _("%s: line: %s\n"), fn, buf); + goto exit; + } +- appendStringBuf(sb, buf); ++ appendStringBuf(sb, expanded); ++ free(expanded); + } + headerPutString(h, tag, getStringBuf(sb)); + rc = RPMRC_OK; +diff --git a/build/parseSpec.c b/build/parseSpec.c +index edc3d00..610e371 100644 +--- a/build/parseSpec.c ++++ b/build/parseSpec.c +@@ -180,13 +180,15 @@ static int expandMacrosInSpecBuf(rpmSpec spec, int strip) + if (lbuf[0] == '#') + isComment = 1; + +- lbuf = xstrdup(spec->lbuf); ++ lbuf = spec->lbuf; + +- rc = expandMacros(spec, spec->macros, spec->lbuf, spec->lbufSize); +- if (rc) { ++ spec->lbuf = expandMacrosU(spec, spec->macros, lbuf); ++ if (spec->lbuf == NULL) { + rpmlog(RPMLOG_ERR, _("line %d: %s\n"), +- spec->lineNum, spec->lbuf); ++ spec->lineNum, lbuf); + goto exit; ++ } else { ++ spec->lbufSize = strlen(spec->lbuf) + 1; + } + + if (strip & STRIP_COMMENTS && isComment) { +diff --git a/rpmio/macro.c b/rpmio/macro.c +index 4b3c41b..4c8934e 100644 +--- a/rpmio/macro.c ++++ b/rpmio/macro.c +@@ -1471,6 +1471,23 @@ int expandMacros(void * spec, rpmMacroContext mc, char * sbuf, size_t slen) + return rc; + } + ++char *expandMacrosU(void * spec, rpmMacroContext mc, char * sbuf) ++{ ++ char *target = NULL; ++ int rc; ++ ++ mc = rpmmctxAcquire(mc); ++ rc = doExpandMacros(mc, sbuf, &target); ++ rpmmctxRelease(mc); ++ ++ if (rc) { ++ free(target); ++ target = NULL; ++ } ++ ++ return target; ++} ++ + void + rpmDumpMacroTable(rpmMacroContext mc, FILE * fp) + { +diff --git a/rpmio/rpmmacro.h b/rpmio/rpmmacro.h +index 765c78c..a4884b0 100644 +--- a/rpmio/rpmmacro.h ++++ b/rpmio/rpmmacro.h +@@ -66,6 +66,18 @@ int expandMacros (void * spec, rpmMacroContext mc, + size_t slen); + + /** \ingroup rpmmacro ++ * Expand macro into buffer. ++ * @deprecated Use rpmExpand(). ++ * @todo Eliminate from API. ++ * @param spec cookie (unused) ++ * @param mc macro context (NULL uses global context). ++ * @retval sbuf input macro to expand ++ * @return macro expansion (malloc'ed) or NULL on failure ++ */ ++char *expandMacrosU (void * spec, rpmMacroContext mc, ++ char * sbuf); ++ ++/** \ingroup rpmmacro + * Add macro to context. + * @deprecated Use rpmDefineMacro(). + * @param mc macro context (NULL uses global context). +-- +1.9.3 + +From aee8446eb498fec7bfd7a2848ab97440b7bb7226 Mon Sep 17 00:00:00 2001 +From: Tom Hughes +Date: Mon, 23 Nov 2015 09:38:37 +0000 +Subject: [PATCH 1/2] Rename expandMacrosU to rpmExpandMacros + +Address review issues from #32 by renaming the function and +cleaning up the comment and parameter list. +--- + build/files.c | 2 +- + build/pack.c | 2 +- + build/parseSpec.c | 2 +- + rpmio/macro.c | 2 +- + rpmio/rpmmacro.h | 10 ++++------ + 5 files changed, 8 insertions(+), 10 deletions(-) + +diff --git a/build/files.c b/build/files.c +index 4d49449..0bc4acc 100644 +--- a/build/files.c ++++ b/build/files.c +@@ -1624,7 +1624,7 @@ static rpmRC readFilesManifest(rpmSpec spec, Package pkg, const char *path) + while (fgets(buf, sizeof(buf), fd)) { + if (handleComments(buf)) + continue; +- char *expanded = expandMacrosU(spec, spec->macros, buf); ++ char *expanded = rpmExpandMacros(spec->macros, buf, 0); + if (expanded == NULL) { + rpmlog(RPMLOG_ERR, _("line: %s\n"), buf); + goto exit; +diff --git a/build/pack.c b/build/pack.c +index 6ffe450..ec06bc8 100644 +--- a/build/pack.c ++++ b/build/pack.c +@@ -132,7 +132,7 @@ static rpmRC addFileToTag(rpmSpec spec, const char * file, + } + + while (fgets(buf, sizeof(buf), f)) { +- char *expanded = expandMacrosU(spec, spec->macros, buf); ++ char *expanded = rpmExpandMacros(spec->macros, buf, 0); + if (expanded == NULL) { + rpmlog(RPMLOG_ERR, _("%s: line: %s\n"), fn, buf); + goto exit; +diff --git a/build/parseSpec.c b/build/parseSpec.c +index 610e371..6171bb0 100644 +--- a/build/parseSpec.c ++++ b/build/parseSpec.c +@@ -182,7 +182,7 @@ static int expandMacrosInSpecBuf(rpmSpec spec, int strip) + + lbuf = spec->lbuf; + +- spec->lbuf = expandMacrosU(spec, spec->macros, lbuf); ++ spec->lbuf = rpmExpandMacros(spec->macros, lbuf, 0); + if (spec->lbuf == NULL) { + rpmlog(RPMLOG_ERR, _("line %d: %s\n"), + spec->lineNum, lbuf); +diff --git a/rpmio/macro.c b/rpmio/macro.c +index 4c8934e..f9ca027 100644 +--- a/rpmio/macro.c ++++ b/rpmio/macro.c +@@ -1471,7 +1471,7 @@ int expandMacros(void * spec, rpmMacroContext mc, char * sbuf, size_t slen) + return rc; + } + +-char *expandMacrosU(void * spec, rpmMacroContext mc, char * sbuf) ++char *rpmExpandMacros(rpmMacroContext mc, const char * sbuf, int flags) + { + char *target = NULL; + int rc; +diff --git a/rpmio/rpmmacro.h b/rpmio/rpmmacro.h +index a4884b0..f5ddcac 100644 +--- a/rpmio/rpmmacro.h ++++ b/rpmio/rpmmacro.h +@@ -67,15 +67,13 @@ int expandMacros (void * spec, rpmMacroContext mc, + + /** \ingroup rpmmacro + * Expand macro into buffer. +- * @deprecated Use rpmExpand(). +- * @todo Eliminate from API. +- * @param spec cookie (unused) + * @param mc macro context (NULL uses global context). +- * @retval sbuf input macro to expand ++ * @param sbuf input macro to expand ++ * @param flags flags (currently unused) + * @return macro expansion (malloc'ed) or NULL on failure + */ +-char *expandMacrosU (void * spec, rpmMacroContext mc, +- char * sbuf); ++char *rpmExpandMacros (rpmMacroContext mc, const char * sbuf, ++ int flags); + + /** \ingroup rpmmacro + * Add macro to context. +-- +1.9.3 + +From ddf9ec7befe83ba1a12453a56e4e471aa9bcf4d3 Mon Sep 17 00:00:00 2001 +From: Lubos Kardos +Date: Thu, 26 Nov 2015 15:20:05 +0100 +Subject: [PATCH 2/2] rpmExpandMacros() is modified to be able to return more + return codes + +Now rpmExpandMacros() returns integer as a return value. Negative return +value implies failure. Return values can be more utilized in the future. +E. g. return value could specify how many macros were expanded in given +string. +--- + build/files.c | 4 ++-- + build/pack.c | 4 ++-- + build/parseSpec.c | 21 +++++++++------------ + rpmio/macro.c | 9 +++++---- + rpmio/rpmmacro.h | 7 ++++--- + 5 files changed, 22 insertions(+), 23 deletions(-) + +diff --git a/build/files.c b/build/files.c +index 0bc4acc..d00a785 100644 +--- a/build/files.c ++++ b/build/files.c +@@ -1604,6 +1604,7 @@ static rpmRC readFilesManifest(rpmSpec spec, Package pkg, const char *path) + FILE *fd = NULL; + rpmRC rc = RPMRC_FAIL; + unsigned int nlines = 0; ++ char *expanded; + + if (*path == '/') { + fn = rpmGetPath(path, NULL); +@@ -1624,8 +1625,7 @@ static rpmRC readFilesManifest(rpmSpec spec, Package pkg, const char *path) + while (fgets(buf, sizeof(buf), fd)) { + if (handleComments(buf)) + continue; +- char *expanded = rpmExpandMacros(spec->macros, buf, 0); +- if (expanded == NULL) { ++ if(rpmExpandMacros(spec->macros, buf, &expanded, 0) < 0) { + rpmlog(RPMLOG_ERR, _("line: %s\n"), buf); + goto exit; + } +diff --git a/build/pack.c b/build/pack.c +index ec06bc8..bfb4c73 100644 +--- a/build/pack.c ++++ b/build/pack.c +@@ -132,8 +132,8 @@ static rpmRC addFileToTag(rpmSpec spec, const char * file, + } + + while (fgets(buf, sizeof(buf), f)) { +- char *expanded = rpmExpandMacros(spec->macros, buf, 0); +- if (expanded == NULL) { ++ char *expanded; ++ if(rpmExpandMacros(spec->macros, buf, &expanded, 0) < 0) { + rpmlog(RPMLOG_ERR, _("%s: line: %s\n"), fn, buf); + goto exit; + } +diff --git a/build/parseSpec.c b/build/parseSpec.c +index 6171bb0..9fff0e2 100644 +--- a/build/parseSpec.c ++++ b/build/parseSpec.c +@@ -169,7 +169,7 @@ static int restoreFirstChar(rpmSpec spec) + static int expandMacrosInSpecBuf(rpmSpec spec, int strip) + { + char *lbuf = NULL; +- int rc = 0, isComment = 0; ++ int isComment = 0; + + /* Don't expand macros (eg. %define) in false branch of %if clause */ + if (!spec->readStack->reading) +@@ -180,17 +180,17 @@ static int expandMacrosInSpecBuf(rpmSpec spec, int strip) + if (lbuf[0] == '#') + isComment = 1; + +- lbuf = spec->lbuf; + +- spec->lbuf = rpmExpandMacros(spec->macros, lbuf, 0); +- if (spec->lbuf == NULL) { ++ if(rpmExpandMacros(spec->macros, spec->lbuf, &lbuf, 0) < 0) { + rpmlog(RPMLOG_ERR, _("line %d: %s\n"), +- spec->lineNum, lbuf); +- goto exit; +- } else { +- spec->lbufSize = strlen(spec->lbuf) + 1; ++ spec->lineNum, spec->lbuf); ++ return 1; + } + ++ free(spec->lbuf); ++ spec->lbuf = lbuf; ++ spec->lbufSize = strlen(spec->lbuf) + 1; ++ + if (strip & STRIP_COMMENTS && isComment) { + char *bufA = lbuf; + char *bufB = spec->lbuf; +@@ -212,10 +212,7 @@ static int expandMacrosInSpecBuf(rpmSpec spec, int strip) + spec->lineNum, lbuf); + } + +-exit: +- free(lbuf); +- +- return rc; ++ return 0; + } + + /* Return zero on success, 1 if we need to read more and -1 on errors. */ +diff --git a/rpmio/macro.c b/rpmio/macro.c +index f9ca027..0c009ea 100644 +--- a/rpmio/macro.c ++++ b/rpmio/macro.c +@@ -1471,7 +1471,7 @@ int expandMacros(void * spec, rpmMacroContext mc, char * sbuf, size_t slen) + return rc; + } + +-char *rpmExpandMacros(rpmMacroContext mc, const char * sbuf, int flags) ++int rpmExpandMacros(rpmMacroContext mc, const char * sbuf, char ** obuf, int flags) + { + char *target = NULL; + int rc; +@@ -1482,10 +1482,11 @@ char *rpmExpandMacros(rpmMacroContext mc, const char * sbuf, int flags) + + if (rc) { + free(target); +- target = NULL; ++ return -1; ++ } else { ++ *obuf = target; ++ return 1; + } +- +- return target; + } + + void +diff --git a/rpmio/rpmmacro.h b/rpmio/rpmmacro.h +index f5ddcac..8027f98 100644 +--- a/rpmio/rpmmacro.h ++++ b/rpmio/rpmmacro.h +@@ -69,11 +69,12 @@ int expandMacros (void * spec, rpmMacroContext mc, + * Expand macro into buffer. + * @param mc macro context (NULL uses global context). + * @param sbuf input macro to expand ++ * @param obuf macro expansion (malloc'ed) + * @param flags flags (currently unused) +- * @return macro expansion (malloc'ed) or NULL on failure ++ * @return negative on failure + */ +-char *rpmExpandMacros (rpmMacroContext mc, const char * sbuf, +- int flags); ++int rpmExpandMacros (rpmMacroContext mc, const char * sbuf, ++ char ** obuf, int flags); + + /** \ingroup rpmmacro + * Add macro to context. +-- +1.9.3 + diff --git a/rpm.spec b/rpm.spec index a273363..d955517 100644 --- a/rpm.spec +++ b/rpm.spec @@ -29,7 +29,7 @@ Summary: The RPM package management system Name: rpm Version: %{rpmver} -Release: %{?snapver:0.%{snapver}.}22%{?dist} +Release: %{?snapver:0.%{snapver}.}23%{?dist} Group: System Environment/Base Url: http://www.rpm.org/ Source0: http://rpm.org/releases/rpm-4.12.x/%{name}-%{srcver}.tar.bz2 @@ -67,6 +67,7 @@ Patch111: rpm-4.13.0-chroot-file-triggers.patch Patch112: rpm-4.13.0-missingok.patch Patch113: rpm-4.13.0-recursing-rpmdeps.patch Patch114: rpm-4.13.0-autosetup-errors.patch +Patch115: rpm-4.13.0-unlimited-macro-expand.patch # These are not yet upstream Patch302: rpm-4.7.1-geode-i686.patch @@ -577,6 +578,9 @@ exit 0 %doc doc/librpm/html/* %changelog +* Mon Feb 02 2016 Lubos Kardos - 4.13.0-0.rc1.23 +- Remove size limit when expanding macros (#1301677) + * Mon Feb 01 2016 Lubos Kardos - 4.13.0-0.rc1.22 - Harden rpm package again, previous attempt had to be reverted (#1289734)