Re: [Rpm-maint] [rpm-software-management/rpm] implement rpmbuild --changelog=FILE support (#69)
My preferred way would be something like: ``` %changelog %include changelog.txt ``` --- You are receiving this because you commented. Reply to this email directly or view it on GitHub: https://github.com/rpm-software-management/rpm/pull/69#issuecomment-223894319___ Rpm-maint mailing list Rpm-maint@lists.rpm.org http://lists.rpm.org/mailman/listinfo/rpm-maint
[Rpm-maint] [PATCH 2/4] Add dwz debuginfo compression support.
Support for dwz compression has been in Fedora since a couple of years. https://fedoraproject.org/wiki/Features/DwarfCompressor The original find-debuginfo.sh patch was written by Jakub Jelinek. https://bugzilla.redhat.com/show_bug.cgi?id=833311 The new testcase using the macros.debug was added by me. Signed-off-by: Mark Wielaard --- macros.debug | 13 macros.in| 2 +- scripts/find-debuginfo.sh| 53 ++ tests/data/SPECS/hello2.spec | 62 +++ tests/rpmbuild.at| 78 5 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 tests/data/SPECS/hello2.spec diff --git a/macros.debug b/macros.debug index bb2c02f..6a8432e 100644 --- a/macros.debug +++ b/macros.debug @@ -28,3 +28,16 @@ # Should missing buildids terminate a build? %_missing_build_ids_terminate_build1 + +# Number of debugging information entries (DIEs) above which +# dwz will stop considering file for multifile optimizations +# and enter a low memory mode, in which it will optimize +# in about half the memory needed otherwise. +%_dwz_low_mem_die_limit 1000 +# Number of DIEs above which dwz will stop processing +# a file altogether. +%_dwz_max_die_limit 5000 + +%_find_debuginfo_dwz_opts --run-dwz\\\ + --dwz-low-mem-die-limit %{_dwz_low_mem_die_limit}\\\ + --dwz-max-die-limit %{_dwz_max_die_limit} diff --git a/macros.in b/macros.in index 58b122f..8e831c5 100644 --- a/macros.in +++ b/macros.in @@ -178,7 +178,7 @@ # the script. See the script for details. # %__debug_install_post \ - %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_include_minidebuginfo:-m} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\ + %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_include_minidebuginfo:-m} %{?_find_debuginfo_dwz_opts} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\ %{nil} # Template for debug information sub-package. diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh index 5c2c381..8de7bad 100644 --- a/scripts/find-debuginfo.sh +++ b/scripts/find-debuginfo.sh @@ -4,6 +4,8 @@ # # Usage: find-debuginfo.sh [--strict-build-id] [-g] [-r] [-m] # [-o debugfiles.list] +# [--run-dwz] [--dwz-low-mem-die-limit N] +# [--dwz-max-die-limit N] # [[-l filelist]... [-p 'pattern'] -o debuginfo.list] # [builddir] # @@ -20,6 +22,10 @@ # The -p argument is an grep -E -style regexp matching the a file name, # and must not use anchors (^ or $). # +# The --run-dwz flag instructs find-debuginfo.sh to run the dwz utility +# if available, and --dwz-low-mem-die-limit and --dwz-max-die-limit +# provide detailed limits. See dwz(1) -l and -L option for details. +# # All file names in switches are relative to builddir (. if not given). # @@ -35,6 +41,11 @@ include_minidebug=false # Barf on missing build IDs. strict=false +# DWZ parameters. +run_dwz=false +dwz_low_mem_die_limit= +dwz_max_die_limit= + BUILDDIR=. out=debugfiles.list nout=0 @@ -43,6 +54,17 @@ while [ $# -gt 0 ]; do --strict-build-id) strict=true ;; + --run-dwz) +run_dwz=true +;; + --dwz-low-mem-die-limit) +dwz_low_mem_die_limit=$2 +shift +;; + --dwz-max-die-limit) +dwz_max_die_limit=$2 +shift +;; -g) strip_g=true ;; @@ -302,6 +324,37 @@ while read nlinks inum f; do fi done || exit +# Invoke the DWARF Compressor utility. +if $run_dwz && type dwz >/dev/null 2>&1 \ + && [ -d "${RPM_BUILD_ROOT}/usr/lib/debug" ]; then + dwz_files="`cd "${RPM_BUILD_ROOT}/usr/lib/debug"; find -type f -name \*.debug`" + if [ -n "${dwz_files}" ]; then + dwz_multifile_name="${RPM_PACKAGE_NAME}-${RPM_PACKAGE_VERSION}-${RPM_PACKAGE_RELEASE}.${RPM_ARCH}" +dwz_multifile_suffix= +dwz_multifile_idx=0 +while [ -f "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz/${dwz_multifile_name}${dwz_multifile_suffix}" ]; do + let ++dwz_multifile_idx + dwz_multifile_suffix=".${dwz_multifile_idx}" +done +dwz_multfile_name="${dwz_multifile_name}${dwz_multifile_suffix}" +dwz_opts="-h -q -r -m .dwz/${dwz_multifile_name}" +mkdir -p "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz" +[ -n "${dwz_low_mem_die_limit}" ] \ + && dwz_opts="${dwz_opts} -l ${dwz_low_mem_die_limit}" +[ -n "${dwz_max_die_limit}" ] \ + && dwz_opts="${dwz_opts} -L ${dwz_max_die_limit}" +( cd "${RPM_BUILD_ROOT}/usr/lib/debug" && dwz $dwz_opts $dwz_files ) +# Remove .dwz directory if empty +rmdir "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz" 2>/dev/null +if [ -f "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz/${dwz_multifile_name}" ]; then + id="`readelf -Wn "${RPM_BUILD_ROOT}/usr/li
[Rpm-maint] Some rpm debuginfo improvements
Hi, As discussed on rpm-ecosystem I am working on some debuginfo improvements. Some improvements have been accepted as new feature for Fedora 25: https://fedoraproject.org/wiki/Changes/ParallelInstallableDebuginfo I am keeping track of all ideas here: http://taiga.fedorainfracloud.org/project/mjw-better-rpm-debuginfo-package-creation/kanban Here are the first 4 patches that have been sent to this list previously: [PATCH 1/4] Add find-debuginfo.sh -m minisymtab support. [PATCH 2/4] Add dwz debuginfo compression support. [PATCH 3/4] Add sepdebugcrcfix to fixup old style gnu_debuglink CRC [PATCH 4/4] Add build-id links to rpm for all ELF files. All fixes come with new testcases. Let me know if there is anything missing to get this integrated. Thanks, Mark ___ Rpm-maint mailing list Rpm-maint@lists.rpm.org http://lists.rpm.org/mailman/listinfo/rpm-maint
[Rpm-maint] [PATCH 1/4] Add find-debuginfo.sh -m minisymtab support.
Support for minisymtab (a minimal function symbol table in a compressed section in the main binary) has been in gdb and elfutils based tools since some years. Fedora has had this as rpm-4.10.0-minidebuginfo.patch since 2012. The patch adjusts macros to pass -m to find-debuginfo.sh when _include_minidebuginfo has been set. find-debuginfo.sh now takes -m as argument to generate the .gnu_debugdata ELF section to be added to the main executable. To support the testcases a new macros.debug is added that is used to generate debuginfo packages in the rpmbuild.at testsuite. The original support was added to Fedora rpm by Alexander Larsson. Lubos Kardos fixed a bug in it when strip -g was used. I added some configuration macros and two testcases to check the basic support works and for the strip -g bug. Signed-off-by: Mark Wielaard --- Makefile.am | 3 ++ macros.debug | 30 ++ macros.in | 8 - scripts/find-debuginfo.sh | 37 ++- tests/rpmbuild.at | 77 +++ 5 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 macros.debug diff --git a/Makefile.am b/Makefile.am index 939a6a0..157e79d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -198,6 +198,9 @@ macros: $(top_srcdir)/macros.in CLEANFILES += macros EXTRA_DIST += macros.in +# Used for the testsuite to test creating debuginfo packages +EXTRA_DIST += macros.debug + noinst_DATA += platform platform: $(top_srcdir)/platform.in @$(SED) \ diff --git a/macros.debug b/macros.debug new file mode 100644 index 000..bb2c02f --- /dev/null +++ b/macros.debug @@ -0,0 +1,30 @@ +# macros to include to generate debuginfo + +%_enable_debug_packages 1 +%_include_minidebuginfo 1 + +# Expanded at end of %install scriptlet + +%__arch_install_post %{nil} + +%__os_install_post \ +%{_rpmconfigdir}/brp-compress \ +%{!?__debug_package:\ +%{_rpmconfigdir}/brp-strip %{__strip} \ +%{_rpmconfigdir}/brp-strip-comment-note %{__strip} %{__objdump} \ +} \ +%{_rpmconfigdir}/brp-strip-static-archive %{__strip} \ +%{nil} + +%__spec_install_post\ +%{?__debug_package:%{__debug_install_post}}\ +%{__arch_install_post}\ +%{__os_install_post}\ +%{nil} + +%install %{?_enable_debug_packages:%{?buildsubdir:%{debug_package}}}\ +%%install\ +%{nil} + +# Should missing buildids terminate a build? +%_missing_build_ids_terminate_build1 diff --git a/macros.in b/macros.in index f9172d0..58b122f 100644 --- a/macros.in +++ b/macros.in @@ -178,7 +178,7 @@ # the script. See the script for details. # %__debug_install_post \ - %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\ + %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_include_minidebuginfo:-m} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\ %{nil} # Template for debug information sub-package. @@ -441,6 +441,12 @@ package or when debugging this package.\ #%_missing_build_ids_terminate_build 1 # +# Include minimal debug information in build binaries. +# Requires _enable_debug_packages. +# +#%_include_minidebuginfo 1 + +# # Use internal dependency generator rather than external helpers? %_use_internal_dependency_generator1 diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh index 17522e0..5c2c381 100644 --- a/scripts/find-debuginfo.sh +++ b/scripts/find-debuginfo.sh @@ -2,7 +2,7 @@ #find-debuginfo.sh - automagically generate debug info and file list #for inclusion in an rpm spec file. # -# Usage: find-debuginfo.sh [--strict-build-id] [-g] [-r] +# Usage: find-debuginfo.sh [--strict-build-id] [-g] [-r] [-m] # [-o debugfiles.list] # [[-l filelist]... [-p 'pattern'] -o debuginfo.list] # [builddir] @@ -29,6 +29,9 @@ strip_g=false # with -r arg, pass --reloc-debug-sections to eu-strip. strip_r=false +# with -m arg, add minimal debuginfo to binary. +include_minidebug=false + # Barf on missing build IDs. strict=false @@ -43,6 +46,9 @@ while [ $# -gt 0 ]; do -g) strip_g=true ;; + -m) +include_minidebug=true +;; -o) if [ -z "${lists[$nout]}" -a -z "${ptns[$nout]}" ]; then out=$2 @@ -106,6 +112,32 @@ strip_to_debug() chmod 444 "$1" || exit } +add_minidebug() +{ + local debuginfo="$1" + local binary="$2" + + local dynsyms=`mktemp` + local funcsyms=`mktemp` + local keep_symbols=`mktemp` + local mini_debuginfo=`mktemp` + + # Extract the dynamic symbols from the main binary, there is no need to also have these + # in the normal symbol table + nm -D "$binary" --format=posix --defined-only | awk '{ print $1 }' | sort > "$dynsyms" + # Extract all the text (i.e. function) symbols from the debuginfo + nm "$debuginfo" --format
[Rpm-maint] [PATCH 3/4] Add sepdebugcrcfix to fixup old style gnu_debuglink CRC checksum.
Some old tools might still use the .gnu_debuglink section to find separate debuginfo files instead of build-id style lookups. When dwz has compresses the .debug files the original CRC in the main ELF file will no longer match. Make sure to run sepdebugcrcfix after dwz to recalculate the CRC. The original fix was created by Jan Kratochvil based on code from GNU binutils BFD. https://bugzilla.redhat.com/show_bug.cgi?id=971119 I added a testcase to make sure the CRCs were all correctly updated after dwz has run to compress a debuginfo package. Signed-off-by: Mark Wielaard --- Makefile.am | 4 + scripts/find-debuginfo.sh | 9 ++ tests/rpmbuild.at | 36 + tools/sepdebugcrcfix.c| 344 ++ 4 files changed, 393 insertions(+) create mode 100644 tools/sepdebugcrcfix.c diff --git a/Makefile.am b/Makefile.am index 157e79d..08d8c8e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -170,6 +170,10 @@ rpmlibexec_PROGRAMS += elfdeps elfdeps_SOURCES = tools/elfdeps.c elfdeps_LDADD =rpmio/librpmio.la elfdeps_LDADD += @WITH_LIBELF_LIB@ @WITH_POPT_LIB@ + +rpmlibexec_PROGRAMS += sepdebugcrcfix +sepdebugcrcfix_SOURCES = tools/sepdebugcrcfix.c +sepdebugcrcfix_LDADD = @WITH_LIBELF_LIB@ endif endif diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh index 8de7bad..c5d3ce6 100644 --- a/scripts/find-debuginfo.sh +++ b/scripts/find-debuginfo.sh @@ -114,10 +114,12 @@ done LISTFILE="$BUILDDIR/$out" SOURCEFILE="$BUILDDIR/debugsources.list" LINKSFILE="$BUILDDIR/debuglinks.list" +ELFBINSFILE="$BUILDDIR/elfbins.list" > "$SOURCEFILE" > "$LISTFILE" > "$LINKSFILE" +> "$ELFBINSFILE" debugdir="${RPM_BUILD_ROOT}/usr/lib/debug" @@ -318,6 +320,8 @@ while read nlinks inum f; do # strip -g implies we have full symtab, don't add mini symtab in that case. $strip_g || ($include_minidebug && add_minidebug "${debugfn}" "$f") + echo "./${f#$RPM_BUILD_ROOT}" >> "$ELFBINSFILE" + if [ -n "$id" ]; then make_id_link "$id" "$dn/$(basename $f)" make_id_link "$id" "/usr/lib/debug$dn/$bn" .debug @@ -352,6 +356,11 @@ if $run_dwz && type dwz >/dev/null 2>&1 \ [ -n "$id" ] \ && make_id_link "$id" "/usr/lib/debug/.dwz/${dwz_multifile_name}" .debug fi + +# dwz invalidates .gnu_debuglink CRC32 in the main files. +cat "$ELFBINSFILE" | +(cd "$RPM_BUILD_ROOT"; \ + xargs -d '\n' /usr/lib/rpm/sepdebugcrcfix usr/lib/debug) fi fi diff --git a/tests/rpmbuild.at b/tests/rpmbuild.at index 2fea1b6..5672279 100644 --- a/tests/rpmbuild.at +++ b/tests/rpmbuild.at @@ -459,3 +459,39 @@ test "$canonmultiref" = "$canonmultifile" || exit 1 [], [ignore]) AT_CLEANUP + +# -- +# Check that old style gnu_debuglink CRC checksums are correct even after +# using dwz to compress the debuginfo files. +AT_SETUP([rpmbuild debuginfo dwz gnu_debuglink crc]) +AT_KEYWORDS([build] [debuginfo]) +AT_CHECK([ +rm -rf ${TOPDIR} +AS_MKDIR_P(${TOPDIR}/SOURCES) + +# Build a package that +cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES + +run rpmbuild --quiet \ + --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \ + --rcfile=${abs_top_builddir}/rpmrc \ + -ba "${abs_srcdir}"/data/SPECS/hello2.spec + +# Unpack the main and debuginfo rpms so we can check binaries and .debug files. +rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-debuginfo-1.0-1.*.rpm \ + | cpio -diu +rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-1.0-1.*.rpm \ + | cpio -diu + +# Check that dwz has ran and a multi file has been produced +test -f ./usr/lib/debug/.dwz/hello2-1.0-1.* || exit 1 + +# Run sepdbugcrcfix on the binaries, both should have correct CRC already. +${abs_top_builddir}/sepdebugcrcfix ./usr/lib/debug \ + ./usr/local/bin/hello ./usr/local/bin/hello2 | grep CRC32 | cut -f2 -d: +], +[0], +[ Updated 0 CRC32s, 2 CRC32s did match. +], +[ignore]) +AT_CLEANUP diff --git a/tools/sepdebugcrcfix.c b/tools/sepdebugcrcfix.c new file mode 100644 index 000..8e45abf --- /dev/null +++ b/tools/sepdebugcrcfix.c @@ -0,0 +1,344 @@ +/* Copyright (C) 2013 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see
[Rpm-maint] [PATCH 2/5] Fix various memory leaks in file signature related functions.
Fix various memory leaks in file signature related functions. Signed-off-by: Stefan Berger --- lib/rpmsignfiles.c | 2 ++ rpmsign.c | 4 +++- sign/rpmgensig.c | 24 +--- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/lib/rpmsignfiles.c b/lib/rpmsignfiles.c index 95ac851..b7d9ccc 100644 --- a/lib/rpmsignfiles.c +++ b/lib/rpmsignfiles.c @@ -152,10 +152,12 @@ rpmRC rpmSignFiles(Header h, const char *key, char *keypass) goto exit; } if (!headerPutString(h, RPMTAG_FILESIGNATURES, signature)) { + free(signature); rpmlog(RPMLOG_ERR, _("headerPutString failed\n")); rc = RPMRC_FAIL; goto exit; } + free(signature); } exit: diff --git a/rpmsign.c b/rpmsign.c index a61981a..ddbc5c5 100644 --- a/rpmsign.c +++ b/rpmsign.c @@ -60,6 +60,7 @@ static int doSign(poptContext optCon) char * passPhrase = NULL; char * name = rpmExpand("%{?_gpg_name}", NULL); struct rpmSignArgs sig = {NULL, 0, 0}; +char *key = NULL; if (rstreq(name, "")) { fprintf(stderr, _("You must set \"%%_gpg_name\" in your macro file\n")); @@ -71,7 +72,7 @@ static int doSign(poptContext optCon) } if (signfiles) { - const char *key = rpmExpand("%{?_file_signing_key}", NULL); + key = rpmExpand("%{?_file_signing_key}", NULL); if (rstreq(key, "")) { fprintf(stderr, _("You must set \"$$_file_signing_key\" in your macro file or on the command line with --fskpath\n")); goto exit; @@ -102,6 +103,7 @@ static int doSign(poptContext optCon) } exit: +free(key); free(passPhrase); free(name); return rc; diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c index 77b6d5a..0b23db3 100644 --- a/sign/rpmgensig.c +++ b/sign/rpmgensig.c @@ -576,8 +576,10 @@ static rpmRC includeFileSignatures(FD_t fd, const char *rpm, key = rpmExpand("%{?_file_signing_key}", NULL); keypass = rpmExpand("%{_file_signing_key_password}", NULL); -if (rstreq(keypass, "")) +if (rstreq(keypass, "")) { + free(keypass); keypass = NULL; +} rc = rpmSignFiles(*hdrp, key, keypass); if (rc != RPMRC_OK) { @@ -641,11 +643,15 @@ static rpmRC includeFileSignatures(FD_t fd, const char *rpm, sigTargetSize = Ftell(fd) - headerStart; fdFiniDigest(fd, PGPHASHALGO_MD5, (void **)&MD5, &md5len, 0); -if (headerGet(*sigp, RPMSIGTAG_MD5, &osigtd, HEADERGET_DEFAULT)) +if (headerGet(*sigp, RPMSIGTAG_MD5, &osigtd, HEADERGET_DEFAULT)) { memcpy(o_md5, osigtd.data, 16); + rpmtdFreeData(&osigtd); +} -if (headerGet(*sigp, RPMSIGTAG_SHA1, &osigtd, HEADERGET_DEFAULT)) +if (headerGet(*sigp, RPMSIGTAG_SHA1, &osigtd, HEADERGET_DEFAULT)) { o_sha1 = xstrdup(osigtd.data); + rpmtdFreeData(&osigtd); +} if (memcmp(MD5, o_md5, md5len) == 0 && strcmp(SHA1, o_sha1) == 0) rpmlog(RPMLOG_WARNING, @@ -655,6 +661,12 @@ static rpmRC includeFileSignatures(FD_t fd, const char *rpm, replaceSigDigests(fd, rpm, sigp, sigStart, sigTargetSize, SHA1, MD5); exit: +free(trpm); +free(MD5); +free(SHA1); +free(o_sha1); +free(keypass); +free(key); if (ofd) (void) closeFile(&ofd); return rc; @@ -675,7 +687,7 @@ static int rpmSign(const char *rpm, int deleting, int signfiles) char *trpm = NULL; Header sigh = NULL; Header h = NULL; -char * msg = NULL; +char *msg = NULL; int res = -1; /* assume failure */ rpmRC rc; struct rpmtd_s utd; @@ -693,7 +705,6 @@ static int rpmSign(const char *rpm, int deleting, int signfiles) if ((rc = rpmLeadRead(fd, &lead, NULL, &msg)) != RPMRC_OK) { rpmlog(RPMLOG_ERR, "%s: %s\n", rpm, msg); - free(msg); goto exit; } @@ -702,14 +713,12 @@ static int rpmSign(const char *rpm, int deleting, int signfiles) if (rc != RPMRC_OK) { rpmlog(RPMLOG_ERR, _("%s: rpmReadSignature failed: %s"), rpm, (msg && *msg ? msg : "\n")); - msg = _free(msg); goto exit; } headerStart = Ftell(fd); if (rpmReadHeader(NULL, fd, &h, &msg) != RPMRC_OK) { rpmlog(RPMLOG_ERR, _("%s: headerRead failed: %s\n"), rpm, msg); - msg = _free(msg); goto exit; } @@ -845,6 +854,7 @@ exit: rpmFreeSignature(sigh); headerFree(h); rpmLeadFree(lead); +free(msg); /* Clean up intermediate target */ if (trpm) { -- 2.5.5 ___ Rpm-maint mailing list Rpm-maint@lists.rpm.org http://lists.rpm.org/mailman/listinfo/rpm-maint
[Rpm-maint] [PATCH 5/5] Fix handling of zero-length file digests
Do not try to convert a zero-length file digest to a binary representation. Zero-length file digests may stem from directory entries and symbolic links. Return an empty signature in this case. Returning an empty signature results in the ima.so plugin getting a sequence of zeroes that it would write into security.ima xattr. Check for a signature consisting of only zeroes and do not write it into the filesystem. Signed-off-by: Stefan Berger --- lib/rpmsignfiles.c | 4 plugins/ima.c | 36 +++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/rpmsignfiles.c b/lib/rpmsignfiles.c index 97a5be4..3cd2b1a 100644 --- a/lib/rpmsignfiles.c +++ b/lib/rpmsignfiles.c @@ -82,6 +82,10 @@ const char *key, char *keypass) /* convert file digest hex to binary */ memset(digest, 0, diglen); +/* some entries don't have a digest - we return an empty signature */ +if (strlen(fdigest) != diglen * 2) +return strdup(""); + for (int i = 0; i < diglen; ++i, fdigest += 2) digest[i] = (rnibble(fdigest[0]) << 4) | rnibble(fdigest[1]); diff --git a/plugins/ima.c b/plugins/ima.c index 0dfdd8b..2b998d0 100644 --- a/plugins/ima.c +++ b/plugins/ima.c @@ -12,6 +12,40 @@ #define XATTR_NAME_IMA "security.ima" +/* security.ima signature header */ +struct signature_v2_hdr { + uint8_t type; + uint8_t version; + uint8_t hash_algo; + uint32_t keyid; + uint16_t sig_size; + uint8_t sig[0]; +} __attribute__((PACKED)); + +static const struct signature_v2_hdr zero_hdr = { + .type = 0, + .version = 0, + .hash_algo = 0, + .keyid = 0, + .sig_size = 0, +}; + +/* + * check_zero_hdr: Check the signature for a zero header + * + * Check whether the given signature has a header with all zeros + * + * Returns -1 in case the signature is too short to compare + * (invalid signature), 0 in case the header is not only zeroes, + * and 1 if it is only zeroes. + */ +static int check_zero_hdr(const unsigned char *fsig, size_t siglen) +{ + if (siglen < sizeof(zero_hdr)) + return -1; + return (memcmp(fsig, &zero_hdr, sizeof(zero_hdr)) == 0); +} + static rpmRC ima_psm_post(rpmPlugin plugin, rpmte te, int res) { rpmfi fi = rpmteFI(te); @@ -30,7 +64,7 @@ static rpmRC ima_psm_post(rpmPlugin plugin, rpmte te, int res) if (!(rpmfiFFlags(fi) & RPMFILE_CONFIG)) { fpath = rpmfiFN(fi); fsig = rpmfiFSignature(fi, &len); - if (fsig) { + if (fsig && (check_zero_hdr(fsig, len) == 0)) { lsetxattr(fpath, XATTR_NAME_IMA, fsig, len, 0); } } -- 2.5.5 ___ Rpm-maint mailing list Rpm-maint@lists.rpm.org http://lists.rpm.org/mailman/listinfo/rpm-maint
[Rpm-maint] [PATCH 0/5] Fix issues related to signed files
This series of patches fixes several issues related to signed files produced by rpmsign. Stefan Stefan Berger (5): Fix indentation and formatting Fix various memory leaks in file signature related functions. Check range of algo index parameter before accessing array with it Extend header size to 64MB due to file signatures Fix handling of zero-length file digests lib/header.c | 2 +- lib/header_internal.h | 5 +++-- lib/rpmsignfiles.c| 24 ++-- plugins/ima.c | 36 +++- rpmsign.c | 4 +++- sign/rpmgensig.c | 27 +++ 6 files changed, 79 insertions(+), 19 deletions(-) -- 2.5.5 ___ Rpm-maint mailing list Rpm-maint@lists.rpm.org http://lists.rpm.org/mailman/listinfo/rpm-maint
Re: [Rpm-maint] [PATCH] Add find-debuginfo.sh -m minisymtab support.
On tor, 2016-05-12 at 14:02 +0200, Mark Wielaard wrote: > On Wed, 2016-05-11 at 22:29 +0300, Panu Matilainen wrote: > > > > On 05/11/2016 05:41 PM, Mark Wielaard wrote: > > > > > > The original rpm-4.10.0-minidebuginfo.patch in Fedora was created > > > by > > > Panu Matilainen and Lubos Kardos. > > Credit where credit is due: I merely added the patch into Fedora, > > minidebuginfo was actually implemented by Alexander Larsson, the > > original submission being here I think: > > http://lists.rpm.org/pipermail/rpm-maint/2012-June/003214.html > Sorry, I should have remembered. I discussed things with Alex when I > implemented the elfutils support. My apologies. > > I have updated the commit message to more accurately describe the > origin. Do you need a signed-off-by from Alex too? No idea what is needed, but its fine with me. Signed-off-by: Alexander Larsson http://lists.rpm.org/mailman/listinfo/rpm-maint
[Rpm-maint] [PATCH 4/5] Extend header size to 64MB due to file signatures
Extend the header size to 64MB in case an RPM has a lot of files and the file signatures do not fit within the current limit of 16MB. An example for an RPM with many files is kcbench-data-4.0. It contains more than 52000 files. With each signature with a 2048 bit key requiring 256 bytes plus a preamble, its representation in text from, and other overhead, the size of the header (index length and data length) exceeds 32Mb. If this RPM's files have been signed using this patch, older versions of the rpm tool will report the header being too large. So this failure is expected then. Signed-off-by: Stefan Berger --- lib/header.c | 2 +- lib/header_internal.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/header.c b/lib/header.c index 81f2038..ae292f9 100644 --- a/lib/header.c +++ b/lib/header.c @@ -99,7 +99,7 @@ struct headerToken_s { /** \ingroup header * Maximum no. of bytes permitted in a header. */ -static const size_t headerMaxbytes = (32*1024*1024); +static const size_t headerMaxbytes = (64*1024*1024); #defineINDEX_MALLOC_SIZE 8 diff --git a/lib/header_internal.h b/lib/header_internal.h index bbe2097..410ad58 100644 --- a/lib/header_internal.h +++ b/lib/header_internal.h @@ -45,9 +45,10 @@ struct indexEntry_s { /** * Sanity check on data size and/or offset and/or count. - * This check imposes a limit of 16 MB, more than enough. + * This check imposes a limit of 64 MB -- file signatures + * may require a lot of space in the header. */ -#define HEADER_DATA_MAX 0x00ff +#define HEADER_DATA_MAX 0x03ff #define hdrchkData(_nbytes) ((_nbytes) & (~HEADER_DATA_MAX)) /** -- 2.5.5 ___ Rpm-maint mailing list Rpm-maint@lists.rpm.org http://lists.rpm.org/mailman/listinfo/rpm-maint
Re: [Rpm-maint] [PATCH] Fix array bounds check of decoding[] in base64_decode_value.
On 25/05/16 14:32 +0200, Mark Wielaard wrote: This issue was reported against the libb64 public domain code from which rpmio/base64.c was derived. https://sourceforge.net/p/libb64/bugs/2/ The char signedness issue was already solved differently in our code, but the array bounds check was missing in rpmio/base64.c. N.B. the >= change was just merged here: https://github.com/rpm-software-management/rpm/pull/68/files The value_in < 43 check isn't strictly needed for RPM, because the code was changed to use unsigned char (unlike upstream libb64 which uses char), and so if value_in is less than 43 it will wrap to a positive value greater than 212, which will fail the sizeof(decoding)/sizeof(int) check. Fixed suggested by Jakub Wilk and Jonathan Wakely. Signed-off-by: Mark Wielaard --- rpmio/base64.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rpmio/base64.c b/rpmio/base64.c index 60e67d4..a3767ca 100644 --- a/rpmio/base64.c +++ b/rpmio/base64.c @@ -103,8 +103,9 @@ char *rpmBase64Encode(const void *data, size_t len, int linelen) static int base64_decode_value(unsigned char value_in) { static const int decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51}; + if (value_in < 43) return -1; value_in -= 43; - if (value_in > sizeof(decoding)/sizeof(int)) + if (value_in >= sizeof(decoding)/sizeof(int)) return -1; return decoding[value_in]; } -- 2.5.5 ___ Rpm-maint mailing list Rpm-maint@lists.rpm.org http://lists.rpm.org/mailman/listinfo/rpm-maint
[Rpm-maint] [PATCH 4/4] Add build-id links to rpm for all ELF files.
This patch moves the main ELF file build-id symlinks from the debuginfo package into the main package. And uses different base directories for the main ELF file build-id symlink. For the main build-id use /usr/lib/.build-id and for the debug build-id use /usr/lib/debug/.build-id. There are two reasons for doing this. The main package and the debuginfo package might get out of sync, or the debuginfo package might not be installed at all. In which case finding the main ELF file through the build-id symlink becomes impossible. Secondly by moving the main ELF build-id symlink in its own directory the /usr/lib/debug directory gets populated with only debuginfo files which is convenient if the user might want to have that directory populated through a network mountpoint. To support the new logic the symlink code has been moved from find-debuginfo.sh to build/files.c. This also includes support for a new config %_build_id_links that defaults to compat. The other settings are none, alldebug (the old style) and separate. compat is like separate, but adds a compatibility link under /usr/lib/debug/.build-id for the main build-id symlink. There are several new testcases added to test the various settings using the new keyword "buildid". Signed-off-by: Mark Wielaard --- build/Makefile.am | 4 + build/files.c | 375 configure.ac | 15 + macros.in | 28 ++ scripts/find-debuginfo.sh | 60 tests/Makefile.am | 1 + tests/data/SPECS/hello2cp.spec | 64 tests/data/SPECS/hello2ln.spec | 63 tests/rpmbuildid.at| 761 + tests/rpmtests.at | 1 + 10 files changed, 1312 insertions(+), 60 deletions(-) create mode 100644 tests/data/SPECS/hello2cp.spec create mode 100644 tests/data/SPECS/hello2ln.spec create mode 100644 tests/rpmbuildid.at diff --git a/build/Makefile.am b/build/Makefile.am index 8318cc8..f0f55a9 100644 --- a/build/Makefile.am +++ b/build/Makefile.am @@ -27,3 +27,7 @@ librpmbuild_la_LIBADD = \ @LTLIBICONV@ \ @WITH_POPT_LIB@ \ @WITH_MAGIC_LIB@ + +if LIBDW +librpmbuild_la_LIBADD += @WITH_LIBELF_LIB@ @WITH_LIBDW_LIB@ +endif diff --git a/build/files.c b/build/files.c index 07bc94e..b3d821f 100644 --- a/build/files.c +++ b/build/files.c @@ -14,6 +14,11 @@ #include #endif +#if HAVE_LIBDW +#include +#include +#endif + #include #include #include @@ -1544,6 +1549,368 @@ exit: return rc; } +#if HAVE_LIBDW +/* How build id links are generated. See macros.in for description. */ +#define BUILD_IDS_NONE 0 +#define BUILD_IDS_ALLDEBUG 1 +#define BUILD_IDS_SEPARATE 2 +#define BUILD_IDS_COMPAT 3 + +static int addNewIDSymlink(FileList fl, + char *targetpath, char *idlinkpath, + int isDbg, int isCompat) +{ +const char *linkerr = _("failed symlink"); +int rc = 0; +int nr = 0; +char *origpath, *linkpath; + +if (isDbg) + rasprintf(&linkpath, "%s.debug", idlinkpath); +else + linkpath = idlinkpath; +origpath = linkpath; + +while (faccessat(AT_FDCWD, linkpath, F_OK, AT_SYMLINK_NOFOLLOW) == 0) { + if (nr > 0) + free(linkpath); + nr++; + rasprintf(&linkpath, "%s.%d%s", idlinkpath, nr, + isDbg ? ".debug" : ""); +} + +char *symtarget = targetpath; +if (nr > 0 && isCompat) + rasprintf (&symtarget, "%s.%d", targetpath, nr); + +if (symlink(symtarget, linkpath) < 0) { + rc = 1; + rpmlog(RPMLOG_ERR, "%s: %s -> %s: %m\n", + linkerr, linkpath, symtarget); +} else { + fl->cur.isDir = 0; + rc = addFile(fl, linkpath, NULL); +} + +/* Don't warn (again) if this is a compat id-link, we retarget it. */ +if (nr > 0 && !isCompat) { + /* Lets see why there are multiple build-ids. If the original + targets are hard linked, then it is OK, otherwise warn + something fishy is going on. Would be nice to call + something like eu-elfcmp to see if they are really the same + ELF file or not. */ + struct stat st1, st2; + if (stat (origpath, &st1) != 0) { + rpmlog(RPMLOG_WARNING, _("Duplicate build-id, stat %s: %m\n"), + origpath); + } else if (stat (linkpath, &st2) != 0) { + rpmlog(RPMLOG_WARNING, _("Duplicate build-id, stat %s: %m\n"), + linkpath); + } else if (!(S_ISREG(st1.st_mode) && S_ISREG(st2.st_mode) + && st1.st_nlink > 1 && st2.st_nlink == st1.st_nlink + && st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev)) { + char *rpath1 = realpath(origpath, NULL); + char *rpath2 = realpath(linkpath, NULL); + rpmlog(RPMLOG_WARNING, _("Duplicate build-ids %s and %s\n"), + rpath1, rpath2); + free(rpath1);
[Rpm-maint] [PATCH 3/5] Check range of algo index parameter before accessing array with it
Check the range of the algo index parameter before using it for accessing an array. Signed-off-by: Stefan Berger --- lib/rpmsignfiles.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/lib/rpmsignfiles.c b/lib/rpmsignfiles.c index b7d9ccc..97a5be4 100644 --- a/lib/rpmsignfiles.c +++ b/lib/rpmsignfiles.c @@ -32,6 +32,8 @@ static const char *hash_algo_name[] = { [PGPHASHALGO_SHA224] = "sha224", }; +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + char *get_fskpass(void) { struct termios flags, tmp_flags; @@ -130,6 +132,10 @@ rpmRC rpmSignFiles(Header h, const char *key, char *keypass) rpmlog(RPMLOG_ERR, _("missing RPMTAG_FILEDIGESTALGO\n")); return RPMRC_FAIL; } +if (algo < 0 || algo >= ARRAY_SIZE(hash_algo_name)) { + rpmlog(RPMLOG_ERR, _("File digest algorithm id is invalid")); + return RPMRC_FAIL; +} diglen = rpmDigestLength(algo); algoname = hash_algo_name[algo]; -- 2.5.5 ___ Rpm-maint mailing list Rpm-maint@lists.rpm.org http://lists.rpm.org/mailman/listinfo/rpm-maint
Re: [Rpm-maint] [PATCH] RFC: Add build-id links to rpm for all ELF.
On Thu, Jun 02, 2016 at 04:35:55PM +0200, Mark Wielaard wrote: > Yeah, I had to move the symlinking code from find-debuginfo.sh (which > uses debugedit to get the build-ids) to the main rpm code since there is > no way for find-debuginfo.sh to add anything to an existing package file > list. And the whole goal of the patch is to not have all the build-id > symlinks in the same place in the debuginfo package since they will go > stale there when the main subpackage and the debuginfo package don't > match up (which we do want to allow so you can create parallel > installable debuginfo packages). > > Let me know how you like me to improve the code/logic. > I just posted a new version of the patch which still needs some extra > tests and handle duplicate build-ids like the find-debuginfo.sh script > did. Here is the final version. It uses rasprintf, hopefully fixes all the indentation issues, adds duplicate/linked files support and adds lots of testcases (which found some bugs in the original code). Since this depends on the various backports from fedora for other debuginfo improvements for the testcases and find-debuginfo.sh fixups I'll also post it in context as a full patch series. Please let me know if there are any outstanding issues with the patch. Thanks, Mark >From f3fa91926924f569424a8c3ad00639a700b663ec Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 6 Jun 2016 22:23:04 +0200 Subject: [PATCH] Add build-id links to rpm for all ELF files. This patch moves the main ELF file build-id symlinks from the debuginfo package into the main package. And uses different base directories for the main ELF file build-id symlink. For the main build-id use /usr/lib/.build-id and for the debug build-id use /usr/lib/debug/.build-id. There are two reasons for doing this. The main package and the debuginfo package might get out of sync, or the debuginfo package might not be installed at all. In which case finding the main ELF file through the build-id symlink becomes impossible. Secondly by moving the main ELF build-id symlink in its own directory the /usr/lib/debug directory gets populated with only debuginfo files which is convenient if the user might want to have that directory populated through a network mountpoint. To support the new logic the symlink code has been moved from find-debuginfo.sh to build/files.c. This also includes support for a new config %_build_id_links that defaults to compat. The other settings are none, alldebug (the old style) and separate. compat is like separate, but adds a compatibility link under /usr/lib/debug/.build-id for the main build-id symlink. There are several new testcases added to test the various settings using the new keyword "buildid". Signed-off-by: Mark Wielaard --- build/Makefile.am | 4 + build/files.c | 375 configure.ac | 15 + macros.in | 28 ++ scripts/find-debuginfo.sh | 60 tests/Makefile.am | 1 + tests/data/SPECS/hello2cp.spec | 64 tests/data/SPECS/hello2ln.spec | 63 tests/rpmbuildid.at| 761 + tests/rpmtests.at | 1 + 10 files changed, 1312 insertions(+), 60 deletions(-) create mode 100644 tests/data/SPECS/hello2cp.spec create mode 100644 tests/data/SPECS/hello2ln.spec create mode 100644 tests/rpmbuildid.at diff --git a/build/Makefile.am b/build/Makefile.am index 8318cc8..f0f55a9 100644 --- a/build/Makefile.am +++ b/build/Makefile.am @@ -27,3 +27,7 @@ librpmbuild_la_LIBADD = \ @LTLIBICONV@ \ @WITH_POPT_LIB@ \ @WITH_MAGIC_LIB@ + +if LIBDW +librpmbuild_la_LIBADD += @WITH_LIBELF_LIB@ @WITH_LIBDW_LIB@ +endif diff --git a/build/files.c b/build/files.c index 07bc94e..b3d821f 100644 --- a/build/files.c +++ b/build/files.c @@ -14,6 +14,11 @@ #include #endif +#if HAVE_LIBDW +#include +#include +#endif + #include #include #include @@ -1544,6 +1549,368 @@ exit: return rc; } +#if HAVE_LIBDW +/* How build id links are generated. See macros.in for description. */ +#define BUILD_IDS_NONE 0 +#define BUILD_IDS_ALLDEBUG 1 +#define BUILD_IDS_SEPARATE 2 +#define BUILD_IDS_COMPAT 3 + +static int addNewIDSymlink(FileList fl, + char *targetpath, char *idlinkpath, + int isDbg, int isCompat) +{ +const char *linkerr = _("failed symlink"); +int rc = 0; +int nr = 0; +char *origpath, *linkpath; + +if (isDbg) + rasprintf(&linkpath, "%s.debug", idlinkpath); +else + linkpath = idlinkpath; +origpath = linkpath; + +while (faccessat(AT_FDCWD, linkpath, F_OK, AT_SYMLINK_NOFOLLOW) == 0) { + if (nr > 0) + free(linkpath); + nr++; + rasprintf(&linkpath, "%s.%d%s", idlinkpath, nr, + isDbg ? ".debug" : ""); +} + +char *symtarget = targetpath; +if (nr > 0 && isCompat) + rasprintf
[Rpm-maint] [PATCH 1/5] Fix indentation and formatting
Fix the indentation and formatting in signature related files. Signed-off-by: Stefan Berger --- lib/rpmsignfiles.c | 12 ++-- sign/rpmgensig.c | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/rpmsignfiles.c b/lib/rpmsignfiles.c index 61ea33e..95ac851 100644 --- a/lib/rpmsignfiles.c +++ b/lib/rpmsignfiles.c @@ -138,13 +138,13 @@ rpmRC rpmSignFiles(Header h, const char *key, char *keypass) return RPMRC_FAIL; } - headerDel(h, RPMTAG_FILESIGNATURELENGTH); - headerDel(h, RPMTAG_FILESIGNATURES); - siglen = signatureLength(algoname, diglen, key, keypass); - headerPutUint32(h, RPMTAG_FILESIGNATURELENGTH, &siglen, 1); +headerDel(h, RPMTAG_FILESIGNATURELENGTH); +headerDel(h, RPMTAG_FILESIGNATURES); +siglen = signatureLength(algoname, diglen, key, keypass); +headerPutUint32(h, RPMTAG_FILESIGNATURELENGTH, &siglen, 1); - headerGet(h, RPMTAG_FILEDIGESTS, &digests, HEADERGET_MINMEM); - while ((digest = rpmtdNextString(&digests))) { +headerGet(h, RPMTAG_FILEDIGESTS, &digests, HEADERGET_MINMEM); +while ((digest = rpmtdNextString(&digests))) { signature = signFile(algoname, digest, diglen, key, keypass); if (!signature) { rpmlog(RPMLOG_ERR, _("signFile failed\n")); diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c index 9341fa8..77b6d5a 100644 --- a/sign/rpmgensig.c +++ b/sign/rpmgensig.c @@ -655,7 +655,8 @@ static rpmRC includeFileSignatures(FD_t fd, const char *rpm, replaceSigDigests(fd, rpm, sigp, sigStart, sigTargetSize, SHA1, MD5); exit: -if (ofd)(void) closeFile(&ofd); +if (ofd) + (void) closeFile(&ofd); return rc; } -- 2.5.5 ___ Rpm-maint mailing list Rpm-maint@lists.rpm.org http://lists.rpm.org/mailman/listinfo/rpm-maint
Re: [Rpm-maint] [PATCH 2/4] Add dwz debuginfo compression support.
On 6 June 2016 at 23:00, Mark Wielaard wrote: > Support for dwz compression has been in Fedora since a couple of years. > https://fedoraproject.org/wiki/Features/DwarfCompressor And in some other distros as well (eg: Mageia). So if this this lands upstream, we'll be happy too :-) ___ Rpm-maint mailing list Rpm-maint@lists.rpm.org http://lists.rpm.org/mailman/listinfo/rpm-maint