commit
0713da68ed
@ -0,0 +1 @@
|
|||||||
|
SOURCES/rpm-4.16.1.3.tar.bz2
|
@ -0,0 +1 @@
|
|||||||
|
4c70c0dc08aec5ba29f3ee72eda774bd32230f77 SOURCES/rpm-4.16.1.3.tar.bz2
|
@ -0,0 +1,40 @@
|
|||||||
|
From 48546ffc0a3f3eb15bfd439a19fc9722eaea592f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Festi <ffesti@redhat.com>
|
||||||
|
Date: Tue, 28 Jun 2022 12:50:54 +0200
|
||||||
|
Subject: [PATCH] Give warning on not supported hash for RSA keys
|
||||||
|
|
||||||
|
This can happen when old keys are used on systems that have disabled SHA1
|
||||||
|
e.g. for FIPS requirements.
|
||||||
|
|
||||||
|
This is less than ideal but there is currently no way to pass a meaningful
|
||||||
|
error code up to rpmtsImportPubkey. rpmPubkeyNew just returns a valid key
|
||||||
|
or NULL.
|
||||||
|
|
||||||
|
See rhbz#2069877
|
||||||
|
---
|
||||||
|
rpmio/digest_openssl.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/rpmio/digest_openssl.c b/rpmio/digest_openssl.c
|
||||||
|
index a28a13acc..2ec5140f1 100644
|
||||||
|
--- a/rpmio/digest_openssl.c
|
||||||
|
+++ b/rpmio/digest_openssl.c
|
||||||
|
@@ -4,6 +4,7 @@
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
#include <openssl/dsa.h>
|
||||||
|
#include <rpm/rpmpgp.h>
|
||||||
|
+#include <rpm/rpmlog.h>
|
||||||
|
|
||||||
|
#include "rpmio/digest.h"
|
||||||
|
|
||||||
|
@@ -483,6 +484,7 @@ static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig,
|
||||||
|
|
||||||
|
ret = EVP_PKEY_CTX_set_signature_md(pkey_ctx, getEVPMD(hash_algo));
|
||||||
|
if (ret < 0) {
|
||||||
|
+ rpmlog(RPMLOG_WARNING, "Signature not supported. Hash algorithm %s not available.\n", pgpValString(PGPVAL_HASHALGO, hash_algo));
|
||||||
|
rc = 1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.36.1
|
||||||
|
|
@ -0,0 +1,28 @@
|
|||||||
|
From 5a80033676f331de2b0979fe7be9557279b6bff3 Mon Sep 17 00:00:00 2001
|
||||||
|
Message-Id: <5a80033676f331de2b0979fe7be9557279b6bff3.1603865959.git.pmatilai@redhat.com>
|
||||||
|
From: Panu Matilainen <pmatilai@redhat.com>
|
||||||
|
Date: Wed, 28 Oct 2020 08:14:55 +0200
|
||||||
|
Subject: [PATCH] Issue deprecation warning when creating BDB databases
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/backend/db3.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/lib/backend/db3.c b/lib/backend/db3.c
|
||||||
|
index 68cfa6fb2..cb31676e7 100644
|
||||||
|
--- a/lib/backend/db3.c
|
||||||
|
+++ b/lib/backend/db3.c
|
||||||
|
@@ -874,6 +874,10 @@ static int db3_dbiOpen(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flag
|
||||||
|
oflags &= ~DB_RDONLY;
|
||||||
|
dbtype = (rpmtag == RPMDBI_PACKAGES) ? DB_HASH : DB_BTREE;
|
||||||
|
retry_open--;
|
||||||
|
+ if (rpmtag == RPMDBI_PACKAGES) {
|
||||||
|
+ rpmlog(RPMLOG_WARNING,
|
||||||
|
+ "using deprecated bdb database backend");
|
||||||
|
+ }
|
||||||
|
} else {
|
||||||
|
retry_open = 0;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.28.0
|
||||||
|
|
@ -0,0 +1,61 @@
|
|||||||
|
From a93b0f5c9f0abef6efb5413df9e98b047a2a9a46 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
Date: Mon, 17 Aug 2020 16:56:56 +0200
|
||||||
|
Subject: [PATCH 1/6] [NFC] debugedit: Protect macro arguments by parentheses
|
||||||
|
|
||||||
|
---
|
||||||
|
tools/debugedit.c | 14 +++++++-------
|
||||||
|
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/debugedit.c b/tools/debugedit.c
|
||||||
|
index 6bea88551..a351adec8 100644
|
||||||
|
--- a/tools/debugedit.c
|
||||||
|
+++ b/tools/debugedit.c
|
||||||
|
@@ -233,7 +233,7 @@ typedef struct
|
||||||
|
int shift = 0; \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
- c = *ptr++; \
|
||||||
|
+ c = *(ptr)++; \
|
||||||
|
ret |= (c & 0x7f) << shift; \
|
||||||
|
shift += 7; \
|
||||||
|
} while (c & 0x80); \
|
||||||
|
@@ -251,7 +251,7 @@ typedef struct
|
||||||
|
valv >>= 7; \
|
||||||
|
if (valv) \
|
||||||
|
c |= 0x80; \
|
||||||
|
- *ptr++ = c; \
|
||||||
|
+ *(ptr)++ = c; \
|
||||||
|
} \
|
||||||
|
while (valv); \
|
||||||
|
})
|
||||||
|
@@ -311,7 +311,7 @@ strptr (DSO *dso, int sec, off_t offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-#define read_8(ptr) *ptr++
|
||||||
|
+#define read_8(ptr) *(ptr)++
|
||||||
|
|
||||||
|
#define read_16(ptr) ({ \
|
||||||
|
uint16_t ret = do_read_16 (ptr); \
|
||||||
|
@@ -328,13 +328,13 @@ strptr (DSO *dso, int sec, off_t offset)
|
||||||
|
REL *relptr, *relend;
|
||||||
|
int reltype;
|
||||||
|
|
||||||
|
-#define do_read_32_relocated(ptr) ({ \
|
||||||
|
- uint32_t dret = do_read_32 (ptr); \
|
||||||
|
+#define do_read_32_relocated(xptr) ({ \
|
||||||
|
+ uint32_t dret = do_read_32 (xptr); \
|
||||||
|
if (relptr) \
|
||||||
|
{ \
|
||||||
|
- while (relptr < relend && relptr->ptr < ptr) \
|
||||||
|
+ while (relptr < relend && relptr->ptr < (xptr)) \
|
||||||
|
++relptr; \
|
||||||
|
- if (relptr < relend && relptr->ptr == ptr) \
|
||||||
|
+ if (relptr < relend && relptr->ptr == (xptr)) \
|
||||||
|
{ \
|
||||||
|
if (reltype == SHT_REL) \
|
||||||
|
dret += relptr->addend; \
|
||||||
|
--
|
||||||
|
2.18.4
|
||||||
|
|
@ -0,0 +1,30 @@
|
|||||||
|
From f2bc669cd0a080792522dd1bb7f50ef7025f16f0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Wielaard <mark@klomp.org>
|
||||||
|
Date: Sat, 21 Jul 2018 10:13:04 +0200
|
||||||
|
Subject: [PATCH] find-debuginfo.sh: decompress DWARF compressed ELF sections
|
||||||
|
|
||||||
|
debugedit and dwz do not support DWARF compressed ELF sections, let's
|
||||||
|
just decompress those before extracting debuginfo.
|
||||||
|
|
||||||
|
Tested-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
|
||||||
|
---
|
||||||
|
scripts/find-debuginfo.sh | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh
|
||||||
|
index 90a44942d..7b01bc036 100755
|
||||||
|
--- a/scripts/find-debuginfo.sh
|
||||||
|
+++ b/scripts/find-debuginfo.sh
|
||||||
|
@@ -357,6 +357,9 @@ do_file()
|
||||||
|
get_debugfn "$f"
|
||||||
|
[ -f "${debugfn}" ] && return
|
||||||
|
|
||||||
|
+ echo "explicitly decompress any DWARF compressed ELF sections in $f"
|
||||||
|
+ eu-elfcompress -q -p -t none "$f"
|
||||||
|
+
|
||||||
|
echo "extracting debug info from $f"
|
||||||
|
# See also cpio SOURCEFILE copy. Directories must match up.
|
||||||
|
debug_base_name="$RPM_BUILD_DIR"
|
||||||
|
--
|
||||||
|
2.18.0
|
||||||
|
|
@ -0,0 +1,753 @@
|
|||||||
|
From de119ea9797f3ccfa3842e3926b6ea8198607207 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
Date: Sat, 1 Aug 2020 10:43:12 +0200
|
||||||
|
Subject: [PATCH 2/6] [NFC] debugedit: Move code from edit_dwarf2() to
|
||||||
|
edit_info().
|
||||||
|
|
||||||
|
---
|
||||||
|
tools/debugedit.c | 672 +++++++++++++++++++++++-----------------------
|
||||||
|
1 file changed, 343 insertions(+), 329 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/debugedit.c b/tools/debugedit.c
|
||||||
|
index a351adec8..cad0cc349 100644
|
||||||
|
--- a/tools/debugedit.c
|
||||||
|
+++ b/tools/debugedit.c
|
||||||
|
@@ -1964,6 +1964,106 @@ line_rel_cmp (const void *a, const void *b)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+edit_info (DSO *dso, int phase)
|
||||||
|
+{
|
||||||
|
+ unsigned char *ptr, *endcu, *endsec;
|
||||||
|
+ uint32_t value;
|
||||||
|
+ htab_t abbrev;
|
||||||
|
+ struct abbrev_tag tag, *t;
|
||||||
|
+
|
||||||
|
+ ptr = debug_sections[DEBUG_INFO].data;
|
||||||
|
+ setup_relbuf(dso, &debug_sections[DEBUG_INFO], &reltype);
|
||||||
|
+ endsec = ptr + debug_sections[DEBUG_INFO].size;
|
||||||
|
+ while (ptr < endsec)
|
||||||
|
+ {
|
||||||
|
+ if (ptr + 11 > endsec)
|
||||||
|
+ {
|
||||||
|
+ error (0, 0, "%s: .debug_info CU header too small",
|
||||||
|
+ dso->filename);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ endcu = ptr + 4;
|
||||||
|
+ endcu += read_32 (ptr);
|
||||||
|
+ if (endcu == ptr + 0xffffffff)
|
||||||
|
+ {
|
||||||
|
+ error (0, 0, "%s: 64-bit DWARF not supported", dso->filename);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (endcu > endsec)
|
||||||
|
+ {
|
||||||
|
+ error (0, 0, "%s: .debug_info too small", dso->filename);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cu_version = read_16 (ptr);
|
||||||
|
+ if (cu_version != 2 && cu_version != 3 && cu_version != 4)
|
||||||
|
+ {
|
||||||
|
+ error (0, 0, "%s: DWARF version %d unhandled", dso->filename,
|
||||||
|
+ cu_version);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ value = read_32_relocated (ptr);
|
||||||
|
+ if (value >= debug_sections[DEBUG_ABBREV].size)
|
||||||
|
+ {
|
||||||
|
+ if (debug_sections[DEBUG_ABBREV].data == NULL)
|
||||||
|
+ error (0, 0, "%s: .debug_abbrev not present", dso->filename);
|
||||||
|
+ else
|
||||||
|
+ error (0, 0, "%s: DWARF CU abbrev offset too large",
|
||||||
|
+ dso->filename);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ptr_size == 0)
|
||||||
|
+ {
|
||||||
|
+ ptr_size = read_8 (ptr);
|
||||||
|
+ if (ptr_size != 4 && ptr_size != 8)
|
||||||
|
+ {
|
||||||
|
+ error (0, 0, "%s: Invalid DWARF pointer size %d",
|
||||||
|
+ dso->filename, ptr_size);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else if (read_8 (ptr) != ptr_size)
|
||||||
|
+ {
|
||||||
|
+ error (0, 0, "%s: DWARF pointer size differs between CUs",
|
||||||
|
+ dso->filename);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ abbrev = read_abbrev (dso,
|
||||||
|
+ debug_sections[DEBUG_ABBREV].data + value);
|
||||||
|
+ if (abbrev == NULL)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ while (ptr < endcu)
|
||||||
|
+ {
|
||||||
|
+ tag.entry = read_uleb128 (ptr);
|
||||||
|
+ if (tag.entry == 0)
|
||||||
|
+ continue;
|
||||||
|
+ t = htab_find_with_hash (abbrev, &tag, tag.entry);
|
||||||
|
+ if (t == NULL)
|
||||||
|
+ {
|
||||||
|
+ error (0, 0, "%s: Could not find DWARF abbreviation %d",
|
||||||
|
+ dso->filename, tag.entry);
|
||||||
|
+ htab_delete (abbrev);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ptr = edit_attributes (dso, ptr, t, phase);
|
||||||
|
+ if (ptr == NULL)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ htab_delete (abbrev);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
edit_dwarf2 (DSO *dso)
|
||||||
|
{
|
||||||
|
@@ -2100,385 +2200,299 @@ edit_dwarf2 (DSO *dso)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (debug_sections[DEBUG_INFO].data != NULL)
|
||||||
|
+ if (debug_sections[DEBUG_INFO].data == NULL)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ unsigned char *ptr, *endcu, *endsec;
|
||||||
|
+ uint32_t value;
|
||||||
|
+ htab_t abbrev;
|
||||||
|
+ struct abbrev_tag tag, *t;
|
||||||
|
+ int phase;
|
||||||
|
+ bool info_rel_updated = false;
|
||||||
|
+ bool macro_rel_updated = false;
|
||||||
|
+
|
||||||
|
+ for (phase = 0; phase < 2; phase++)
|
||||||
|
{
|
||||||
|
- unsigned char *ptr, *endcu, *endsec;
|
||||||
|
- uint32_t value;
|
||||||
|
- htab_t abbrev;
|
||||||
|
- struct abbrev_tag tag, *t;
|
||||||
|
- int phase;
|
||||||
|
- bool info_rel_updated = false;
|
||||||
|
- bool macro_rel_updated = false;
|
||||||
|
+ /* If we don't need to update anyhing, skip phase 1. */
|
||||||
|
+ if (phase == 1
|
||||||
|
+ && !need_strp_update
|
||||||
|
+ && !need_string_replacement
|
||||||
|
+ && !need_stmt_update)
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
- for (phase = 0; phase < 2; phase++)
|
||||||
|
+ rel_updated = false;
|
||||||
|
+ if (edit_info (dso, phase))
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ /* Remember whether any .debug_info relocations might need
|
||||||
|
+ to be updated. */
|
||||||
|
+ info_rel_updated = rel_updated;
|
||||||
|
+
|
||||||
|
+ /* We might have to recalculate/rewrite the debug_line
|
||||||
|
+ section. We need to do that before going into phase one
|
||||||
|
+ so we have all new offsets. We do this separately from
|
||||||
|
+ scanning the dirs/file names because the DW_AT_stmt_lists
|
||||||
|
+ might not be in order or skip some padding we might have
|
||||||
|
+ to (re)move. */
|
||||||
|
+ if (phase == 0 && need_stmt_update)
|
||||||
|
{
|
||||||
|
- /* If we don't need to update anyhing, skip phase 1. */
|
||||||
|
- if (phase == 1
|
||||||
|
- && !need_strp_update
|
||||||
|
- && !need_string_replacement
|
||||||
|
- && !need_stmt_update)
|
||||||
|
- break;
|
||||||
|
+ edit_dwarf2_line (dso);
|
||||||
|
|
||||||
|
- ptr = debug_sections[DEBUG_INFO].data;
|
||||||
|
- setup_relbuf(dso, &debug_sections[DEBUG_INFO], &reltype);
|
||||||
|
- rel_updated = false;
|
||||||
|
- endsec = ptr + debug_sections[DEBUG_INFO].size;
|
||||||
|
- while (ptr < endsec)
|
||||||
|
+ /* The line table programs will be moved
|
||||||
|
+ forward/backwards a bit in the new data. Update the
|
||||||
|
+ debug_line relocations to the new offsets. */
|
||||||
|
+ int rndx = debug_sections[DEBUG_LINE].relsec;
|
||||||
|
+ if (rndx != 0)
|
||||||
|
{
|
||||||
|
- if (ptr + 11 > endsec)
|
||||||
|
- {
|
||||||
|
- error (0, 0, "%s: .debug_info CU header too small",
|
||||||
|
- dso->filename);
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- endcu = ptr + 4;
|
||||||
|
- endcu += read_32 (ptr);
|
||||||
|
- if (endcu == ptr + 0xffffffff)
|
||||||
|
- {
|
||||||
|
- error (0, 0, "%s: 64-bit DWARF not supported", dso->filename);
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (endcu > endsec)
|
||||||
|
- {
|
||||||
|
- error (0, 0, "%s: .debug_info too small", dso->filename);
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- cu_version = read_16 (ptr);
|
||||||
|
- if (cu_version != 2 && cu_version != 3 && cu_version != 4)
|
||||||
|
- {
|
||||||
|
- error (0, 0, "%s: DWARF version %d unhandled", dso->filename,
|
||||||
|
- cu_version);
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- value = read_32_relocated (ptr);
|
||||||
|
- if (value >= debug_sections[DEBUG_ABBREV].size)
|
||||||
|
+ LINE_REL *rbuf;
|
||||||
|
+ size_t rels;
|
||||||
|
+ Elf_Data *rdata = elf_getdata (dso->scn[rndx], NULL);
|
||||||
|
+ int rtype = dso->shdr[rndx].sh_type;
|
||||||
|
+ rels = dso->shdr[rndx].sh_size / dso->shdr[rndx].sh_entsize;
|
||||||
|
+ rbuf = malloc (rels * sizeof (LINE_REL));
|
||||||
|
+ if (rbuf == NULL)
|
||||||
|
+ error (1, errno, "%s: Could not allocate line relocations",
|
||||||
|
+ dso->filename);
|
||||||
|
+
|
||||||
|
+ /* Sort them by offset into section. */
|
||||||
|
+ for (size_t i = 0; i < rels; i++)
|
||||||
|
{
|
||||||
|
- if (debug_sections[DEBUG_ABBREV].data == NULL)
|
||||||
|
- error (0, 0, "%s: .debug_abbrev not present", dso->filename);
|
||||||
|
+ if (rtype == SHT_RELA)
|
||||||
|
+ {
|
||||||
|
+ GElf_Rela rela;
|
||||||
|
+ if (gelf_getrela (rdata, i, &rela) == NULL)
|
||||||
|
+ error (1, 0, "Couldn't get relocation: %s",
|
||||||
|
+ elf_errmsg (-1));
|
||||||
|
+ rbuf[i].r_offset = rela.r_offset;
|
||||||
|
+ rbuf[i].ndx = i;
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
- error (0, 0, "%s: DWARF CU abbrev offset too large",
|
||||||
|
- dso->filename);
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (ptr_size == 0)
|
||||||
|
- {
|
||||||
|
- ptr_size = read_8 (ptr);
|
||||||
|
- if (ptr_size != 4 && ptr_size != 8)
|
||||||
|
{
|
||||||
|
- error (0, 0, "%s: Invalid DWARF pointer size %d",
|
||||||
|
- dso->filename, ptr_size);
|
||||||
|
- return 1;
|
||||||
|
+ GElf_Rel rel;
|
||||||
|
+ if (gelf_getrel (rdata, i, &rel) == NULL)
|
||||||
|
+ error (1, 0, "Couldn't get relocation: %s",
|
||||||
|
+ elf_errmsg (-1));
|
||||||
|
+ rbuf[i].r_offset = rel.r_offset;
|
||||||
|
+ rbuf[i].ndx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- else if (read_8 (ptr) != ptr_size)
|
||||||
|
- {
|
||||||
|
- error (0, 0, "%s: DWARF pointer size differs between CUs",
|
||||||
|
- dso->filename);
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
+ qsort (rbuf, rels, sizeof (LINE_REL), line_rel_cmp);
|
||||||
|
|
||||||
|
- abbrev = read_abbrev (dso,
|
||||||
|
- debug_sections[DEBUG_ABBREV].data + value);
|
||||||
|
- if (abbrev == NULL)
|
||||||
|
- return 1;
|
||||||
|
-
|
||||||
|
- while (ptr < endcu)
|
||||||
|
+ size_t lndx = 0;
|
||||||
|
+ for (size_t i = 0; i < rels; i++)
|
||||||
|
{
|
||||||
|
- tag.entry = read_uleb128 (ptr);
|
||||||
|
- if (tag.entry == 0)
|
||||||
|
- continue;
|
||||||
|
- t = htab_find_with_hash (abbrev, &tag, tag.entry);
|
||||||
|
- if (t == NULL)
|
||||||
|
+ /* These relocations only happen in ET_REL files
|
||||||
|
+ and are section offsets. */
|
||||||
|
+ GElf_Addr r_offset;
|
||||||
|
+ size_t ndx = rbuf[i].ndx;
|
||||||
|
+
|
||||||
|
+ GElf_Rel rel;
|
||||||
|
+ GElf_Rela rela;
|
||||||
|
+ if (rtype == SHT_RELA)
|
||||||
|
{
|
||||||
|
- error (0, 0, "%s: Could not find DWARF abbreviation %d",
|
||||||
|
- dso->filename, tag.entry);
|
||||||
|
- htab_delete (abbrev);
|
||||||
|
- return 1;
|
||||||
|
+ if (gelf_getrela (rdata, ndx, &rela) == NULL)
|
||||||
|
+ error (1, 0, "Couldn't get relocation: %s",
|
||||||
|
+ elf_errmsg (-1));
|
||||||
|
+ r_offset = rela.r_offset;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ if (gelf_getrel (rdata, ndx, &rel) == NULL)
|
||||||
|
+ error (1, 0, "Couldn't get relocation: %s",
|
||||||
|
+ elf_errmsg (-1));
|
||||||
|
+ r_offset = rel.r_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ptr = edit_attributes (dso, ptr, t, phase);
|
||||||
|
- if (ptr == NULL)
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
+ while (lndx < dso->lines.used
|
||||||
|
+ && r_offset > (dso->lines.table[lndx].old_idx
|
||||||
|
+ + 4
|
||||||
|
+ + dso->lines.table[lndx].unit_length))
|
||||||
|
+ lndx++;
|
||||||
|
|
||||||
|
- htab_delete (abbrev);
|
||||||
|
- }
|
||||||
|
+ if (lndx >= dso->lines.used)
|
||||||
|
+ error (1, 0,
|
||||||
|
+ ".debug_line relocation offset out of range");
|
||||||
|
|
||||||
|
- /* Remember whether any .debug_info relocations might need
|
||||||
|
- to be updated. */
|
||||||
|
- info_rel_updated = rel_updated;
|
||||||
|
-
|
||||||
|
- /* We might have to recalculate/rewrite the debug_line
|
||||||
|
- section. We need to do that before going into phase one
|
||||||
|
- so we have all new offsets. We do this separately from
|
||||||
|
- scanning the dirs/file names because the DW_AT_stmt_lists
|
||||||
|
- might not be in order or skip some padding we might have
|
||||||
|
- to (re)move. */
|
||||||
|
- if (phase == 0 && need_stmt_update)
|
||||||
|
- {
|
||||||
|
- edit_dwarf2_line (dso);
|
||||||
|
+ /* Offset (pointing into the line program) moves
|
||||||
|
+ from old to new index including the header
|
||||||
|
+ size diff. */
|
||||||
|
+ r_offset += (ssize_t)((dso->lines.table[lndx].new_idx
|
||||||
|
+ - dso->lines.table[lndx].old_idx)
|
||||||
|
+ + dso->lines.table[lndx].size_diff);
|
||||||
|
|
||||||
|
- /* The line table programs will be moved
|
||||||
|
- forward/backwards a bit in the new data. Update the
|
||||||
|
- debug_line relocations to the new offsets. */
|
||||||
|
- int rndx = debug_sections[DEBUG_LINE].relsec;
|
||||||
|
- if (rndx != 0)
|
||||||
|
- {
|
||||||
|
- LINE_REL *rbuf;
|
||||||
|
- size_t rels;
|
||||||
|
- Elf_Data *rdata = elf_getdata (dso->scn[rndx], NULL);
|
||||||
|
- int rtype = dso->shdr[rndx].sh_type;
|
||||||
|
- rels = dso->shdr[rndx].sh_size / dso->shdr[rndx].sh_entsize;
|
||||||
|
- rbuf = malloc (rels * sizeof (LINE_REL));
|
||||||
|
- if (rbuf == NULL)
|
||||||
|
- error (1, errno, "%s: Could not allocate line relocations",
|
||||||
|
- dso->filename);
|
||||||
|
-
|
||||||
|
- /* Sort them by offset into section. */
|
||||||
|
- for (size_t i = 0; i < rels; i++)
|
||||||
|
+ if (rtype == SHT_RELA)
|
||||||
|
{
|
||||||
|
- if (rtype == SHT_RELA)
|
||||||
|
- {
|
||||||
|
- GElf_Rela rela;
|
||||||
|
- if (gelf_getrela (rdata, i, &rela) == NULL)
|
||||||
|
- error (1, 0, "Couldn't get relocation: %s",
|
||||||
|
- elf_errmsg (-1));
|
||||||
|
- rbuf[i].r_offset = rela.r_offset;
|
||||||
|
- rbuf[i].ndx = i;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- GElf_Rel rel;
|
||||||
|
- if (gelf_getrel (rdata, i, &rel) == NULL)
|
||||||
|
- error (1, 0, "Couldn't get relocation: %s",
|
||||||
|
- elf_errmsg (-1));
|
||||||
|
- rbuf[i].r_offset = rel.r_offset;
|
||||||
|
- rbuf[i].ndx = i;
|
||||||
|
- }
|
||||||
|
+ rela.r_offset = r_offset;
|
||||||
|
+ if (gelf_update_rela (rdata, ndx, &rela) == 0)
|
||||||
|
+ error (1, 0, "Couldn't update relocation: %s",
|
||||||
|
+ elf_errmsg (-1));
|
||||||
|
}
|
||||||
|
- qsort (rbuf, rels, sizeof (LINE_REL), line_rel_cmp);
|
||||||
|
-
|
||||||
|
- size_t lndx = 0;
|
||||||
|
- for (size_t i = 0; i < rels; i++)
|
||||||
|
+ else
|
||||||
|
{
|
||||||
|
- /* These relocations only happen in ET_REL files
|
||||||
|
- and are section offsets. */
|
||||||
|
- GElf_Addr r_offset;
|
||||||
|
- size_t ndx = rbuf[i].ndx;
|
||||||
|
-
|
||||||
|
- GElf_Rel rel;
|
||||||
|
- GElf_Rela rela;
|
||||||
|
- if (rtype == SHT_RELA)
|
||||||
|
- {
|
||||||
|
- if (gelf_getrela (rdata, ndx, &rela) == NULL)
|
||||||
|
- error (1, 0, "Couldn't get relocation: %s",
|
||||||
|
- elf_errmsg (-1));
|
||||||
|
- r_offset = rela.r_offset;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- if (gelf_getrel (rdata, ndx, &rel) == NULL)
|
||||||
|
- error (1, 0, "Couldn't get relocation: %s",
|
||||||
|
- elf_errmsg (-1));
|
||||||
|
- r_offset = rel.r_offset;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- while (lndx < dso->lines.used
|
||||||
|
- && r_offset > (dso->lines.table[lndx].old_idx
|
||||||
|
- + 4
|
||||||
|
- + dso->lines.table[lndx].unit_length))
|
||||||
|
- lndx++;
|
||||||
|
-
|
||||||
|
- if (lndx >= dso->lines.used)
|
||||||
|
- error (1, 0,
|
||||||
|
- ".debug_line relocation offset out of range");
|
||||||
|
-
|
||||||
|
- /* Offset (pointing into the line program) moves
|
||||||
|
- from old to new index including the header
|
||||||
|
- size diff. */
|
||||||
|
- r_offset += (ssize_t)((dso->lines.table[lndx].new_idx
|
||||||
|
- - dso->lines.table[lndx].old_idx)
|
||||||
|
- + dso->lines.table[lndx].size_diff);
|
||||||
|
-
|
||||||
|
- if (rtype == SHT_RELA)
|
||||||
|
- {
|
||||||
|
- rela.r_offset = r_offset;
|
||||||
|
- if (gelf_update_rela (rdata, ndx, &rela) == 0)
|
||||||
|
- error (1, 0, "Couldn't update relocation: %s",
|
||||||
|
- elf_errmsg (-1));
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- rel.r_offset = r_offset;
|
||||||
|
- if (gelf_update_rel (rdata, ndx, &rel) == 0)
|
||||||
|
- error (1, 0, "Couldn't update relocation: %s",
|
||||||
|
- elf_errmsg (-1));
|
||||||
|
- }
|
||||||
|
+ rel.r_offset = r_offset;
|
||||||
|
+ if (gelf_update_rel (rdata, ndx, &rel) == 0)
|
||||||
|
+ error (1, 0, "Couldn't update relocation: %s",
|
||||||
|
+ elf_errmsg (-1));
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- elf_flagdata (rdata, ELF_C_SET, ELF_F_DIRTY);
|
||||||
|
- free (rbuf);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ elf_flagdata (rdata, ELF_C_SET, ELF_F_DIRTY);
|
||||||
|
+ free (rbuf);
|
||||||
|
}
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- /* The .debug_macro section also contains offsets into the
|
||||||
|
- .debug_str section and references to the .debug_line
|
||||||
|
- tables, so we need to update those as well if we update
|
||||||
|
- the strings or the stmts. */
|
||||||
|
- if ((need_strp_update || need_stmt_update)
|
||||||
|
- && debug_sections[DEBUG_MACRO].data)
|
||||||
|
+ /* The .debug_macro section also contains offsets into the
|
||||||
|
+ .debug_str section and references to the .debug_line
|
||||||
|
+ tables, so we need to update those as well if we update
|
||||||
|
+ the strings or the stmts. */
|
||||||
|
+ if ((need_strp_update || need_stmt_update)
|
||||||
|
+ && debug_sections[DEBUG_MACRO].data)
|
||||||
|
+ {
|
||||||
|
+ /* There might be multiple (COMDAT) .debug_macro sections. */
|
||||||
|
+ struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO];
|
||||||
|
+ while (macro_sec != NULL)
|
||||||
|
{
|
||||||
|
- /* There might be multiple (COMDAT) .debug_macro sections. */
|
||||||
|
- struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO];
|
||||||
|
- while (macro_sec != NULL)
|
||||||
|
- {
|
||||||
|
- setup_relbuf(dso, macro_sec, &reltype);
|
||||||
|
- rel_updated = false;
|
||||||
|
+ setup_relbuf(dso, macro_sec, &reltype);
|
||||||
|
+ rel_updated = false;
|
||||||
|
|
||||||
|
- ptr = macro_sec->data;
|
||||||
|
- endsec = ptr + macro_sec->size;
|
||||||
|
- int op = 0, macro_version, macro_flags;
|
||||||
|
- int offset_len = 4, line_offset = 0;
|
||||||
|
+ ptr = macro_sec->data;
|
||||||
|
+ endsec = ptr + macro_sec->size;
|
||||||
|
+ int op = 0, macro_version, macro_flags;
|
||||||
|
+ int offset_len = 4, line_offset = 0;
|
||||||
|
|
||||||
|
- while (ptr < endsec)
|
||||||
|
+ while (ptr < endsec)
|
||||||
|
+ {
|
||||||
|
+ if (!op)
|
||||||
|
{
|
||||||
|
- if (!op)
|
||||||
|
- {
|
||||||
|
- macro_version = read_16 (ptr);
|
||||||
|
- macro_flags = read_8 (ptr);
|
||||||
|
- if (macro_version < 4 || macro_version > 5)
|
||||||
|
- error (1, 0, "unhandled .debug_macro version: %d",
|
||||||
|
- macro_version);
|
||||||
|
- if ((macro_flags & ~2) != 0)
|
||||||
|
- error (1, 0, "unhandled .debug_macro flags: 0x%x",
|
||||||
|
- macro_flags);
|
||||||
|
-
|
||||||
|
- offset_len = (macro_flags & 0x01) ? 8 : 4;
|
||||||
|
- line_offset = (macro_flags & 0x02) ? 1 : 0;
|
||||||
|
-
|
||||||
|
- if (offset_len != 4)
|
||||||
|
- error (0, 1,
|
||||||
|
- "Cannot handle 8 byte macro offsets: %s",
|
||||||
|
- dso->filename);
|
||||||
|
-
|
||||||
|
- /* Update the line_offset if it is there. */
|
||||||
|
- if (line_offset)
|
||||||
|
- {
|
||||||
|
- if (phase == 0)
|
||||||
|
- ptr += offset_len;
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- size_t idx, new_idx;
|
||||||
|
- idx = do_read_32_relocated (ptr);
|
||||||
|
- new_idx = find_new_list_offs (&dso->lines,
|
||||||
|
- idx);
|
||||||
|
- write_32_relocated (ptr, new_idx);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ macro_version = read_16 (ptr);
|
||||||
|
+ macro_flags = read_8 (ptr);
|
||||||
|
+ if (macro_version < 4 || macro_version > 5)
|
||||||
|
+ error (1, 0, "unhandled .debug_macro version: %d",
|
||||||
|
+ macro_version);
|
||||||
|
+ if ((macro_flags & ~2) != 0)
|
||||||
|
+ error (1, 0, "unhandled .debug_macro flags: 0x%x",
|
||||||
|
+ macro_flags);
|
||||||
|
+
|
||||||
|
+ offset_len = (macro_flags & 0x01) ? 8 : 4;
|
||||||
|
+ line_offset = (macro_flags & 0x02) ? 1 : 0;
|
||||||
|
+
|
||||||
|
+ if (offset_len != 4)
|
||||||
|
+ error (0, 1,
|
||||||
|
+ "Cannot handle 8 byte macro offsets: %s",
|
||||||
|
+ dso->filename);
|
||||||
|
|
||||||
|
- op = read_8 (ptr);
|
||||||
|
- if (!op)
|
||||||
|
- continue;
|
||||||
|
- switch(op)
|
||||||
|
+ /* Update the line_offset if it is there. */
|
||||||
|
+ if (line_offset)
|
||||||
|
{
|
||||||
|
- case DW_MACRO_GNU_define:
|
||||||
|
- case DW_MACRO_GNU_undef:
|
||||||
|
- read_uleb128 (ptr);
|
||||||
|
- ptr = ((unsigned char *) strchr ((char *) ptr, '\0')
|
||||||
|
- + 1);
|
||||||
|
- break;
|
||||||
|
- case DW_MACRO_GNU_start_file:
|
||||||
|
- read_uleb128 (ptr);
|
||||||
|
- read_uleb128 (ptr);
|
||||||
|
- break;
|
||||||
|
- case DW_MACRO_GNU_end_file:
|
||||||
|
- break;
|
||||||
|
- case DW_MACRO_GNU_define_indirect:
|
||||||
|
- case DW_MACRO_GNU_undef_indirect:
|
||||||
|
- read_uleb128 (ptr);
|
||||||
|
if (phase == 0)
|
||||||
|
- {
|
||||||
|
- size_t idx = read_32_relocated (ptr);
|
||||||
|
- record_existing_string_entry_idx (&dso->strings,
|
||||||
|
- idx);
|
||||||
|
- }
|
||||||
|
+ ptr += offset_len;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
- struct stridxentry *entry;
|
||||||
|
size_t idx, new_idx;
|
||||||
|
idx = do_read_32_relocated (ptr);
|
||||||
|
- entry = string_find_entry (&dso->strings, idx);
|
||||||
|
- new_idx = strent_offset (entry->entry);
|
||||||
|
+ new_idx = find_new_list_offs (&dso->lines,
|
||||||
|
+ idx);
|
||||||
|
write_32_relocated (ptr, new_idx);
|
||||||
|
}
|
||||||
|
- break;
|
||||||
|
- case DW_MACRO_GNU_transparent_include:
|
||||||
|
- ptr += offset_len;
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- error (1, 0, "Unhandled DW_MACRO op 0x%x", op);
|
||||||
|
- break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (rel_updated)
|
||||||
|
- macro_rel_updated = true;
|
||||||
|
- macro_sec = macro_sec->next;
|
||||||
|
+ op = read_8 (ptr);
|
||||||
|
+ if (!op)
|
||||||
|
+ continue;
|
||||||
|
+ switch(op)
|
||||||
|
+ {
|
||||||
|
+ case DW_MACRO_GNU_define:
|
||||||
|
+ case DW_MACRO_GNU_undef:
|
||||||
|
+ read_uleb128 (ptr);
|
||||||
|
+ ptr = ((unsigned char *) strchr ((char *) ptr, '\0')
|
||||||
|
+ + 1);
|
||||||
|
+ break;
|
||||||
|
+ case DW_MACRO_GNU_start_file:
|
||||||
|
+ read_uleb128 (ptr);
|
||||||
|
+ read_uleb128 (ptr);
|
||||||
|
+ break;
|
||||||
|
+ case DW_MACRO_GNU_end_file:
|
||||||
|
+ break;
|
||||||
|
+ case DW_MACRO_GNU_define_indirect:
|
||||||
|
+ case DW_MACRO_GNU_undef_indirect:
|
||||||
|
+ read_uleb128 (ptr);
|
||||||
|
+ if (phase == 0)
|
||||||
|
+ {
|
||||||
|
+ size_t idx = read_32_relocated (ptr);
|
||||||
|
+ record_existing_string_entry_idx (&dso->strings,
|
||||||
|
+ idx);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ struct stridxentry *entry;
|
||||||
|
+ size_t idx, new_idx;
|
||||||
|
+ idx = do_read_32_relocated (ptr);
|
||||||
|
+ entry = string_find_entry (&dso->strings, idx);
|
||||||
|
+ new_idx = strent_offset (entry->entry);
|
||||||
|
+ write_32_relocated (ptr, new_idx);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case DW_MACRO_GNU_transparent_include:
|
||||||
|
+ ptr += offset_len;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ error (1, 0, "Unhandled DW_MACRO op 0x%x", op);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
|
||||||
|
- /* Same for the debug_str section. Make sure everything is
|
||||||
|
- in place for phase 1 updating of debug_info
|
||||||
|
- references. */
|
||||||
|
- if (phase == 0 && need_strp_update)
|
||||||
|
- {
|
||||||
|
- Strtab *strtab = dso->strings.str_tab;
|
||||||
|
- Elf_Data *strdata = debug_sections[DEBUG_STR].elf_data;
|
||||||
|
- int strndx = debug_sections[DEBUG_STR].sec;
|
||||||
|
- Elf_Scn *strscn = dso->scn[strndx];
|
||||||
|
-
|
||||||
|
- /* Out with the old. */
|
||||||
|
- strdata->d_size = 0;
|
||||||
|
- /* In with the new. */
|
||||||
|
- strdata = elf_newdata (strscn);
|
||||||
|
-
|
||||||
|
- /* We really should check whether we had enough memory,
|
||||||
|
- but the old ebl version will just abort on out of
|
||||||
|
- memory... */
|
||||||
|
- strtab_finalize (strtab, strdata);
|
||||||
|
- debug_sections[DEBUG_STR].size = strdata->d_size;
|
||||||
|
- dso->strings.str_buf = strdata->d_buf;
|
||||||
|
+ if (rel_updated)
|
||||||
|
+ macro_rel_updated = true;
|
||||||
|
+ macro_sec = macro_sec->next;
|
||||||
|
}
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ /* Same for the debug_str section. Make sure everything is
|
||||||
|
+ in place for phase 1 updating of debug_info
|
||||||
|
+ references. */
|
||||||
|
+ if (phase == 0 && need_strp_update)
|
||||||
|
+ {
|
||||||
|
+ Strtab *strtab = dso->strings.str_tab;
|
||||||
|
+ Elf_Data *strdata = debug_sections[DEBUG_STR].elf_data;
|
||||||
|
+ int strndx = debug_sections[DEBUG_STR].sec;
|
||||||
|
+ Elf_Scn *strscn = dso->scn[strndx];
|
||||||
|
+
|
||||||
|
+ /* Out with the old. */
|
||||||
|
+ strdata->d_size = 0;
|
||||||
|
+ /* In with the new. */
|
||||||
|
+ strdata = elf_newdata (strscn);
|
||||||
|
+
|
||||||
|
+ /* We really should check whether we had enough memory,
|
||||||
|
+ but the old ebl version will just abort on out of
|
||||||
|
+ memory... */
|
||||||
|
+ strtab_finalize (strtab, strdata);
|
||||||
|
+ debug_sections[DEBUG_STR].size = strdata->d_size;
|
||||||
|
+ dso->strings.str_buf = strdata->d_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* After phase 1 we might have rewritten the debug_info with
|
||||||
|
- new strp, strings and/or linep offsets. */
|
||||||
|
- if (need_strp_update || need_string_replacement || need_stmt_update)
|
||||||
|
- dirty_section (DEBUG_INFO);
|
||||||
|
- if (need_strp_update || need_stmt_update)
|
||||||
|
- dirty_section (DEBUG_MACRO);
|
||||||
|
- if (need_stmt_update)
|
||||||
|
- dirty_section (DEBUG_LINE);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* After phase 1 we might have rewritten the debug_info with
|
||||||
|
+ new strp, strings and/or linep offsets. */
|
||||||
|
+ if (need_strp_update || need_string_replacement || need_stmt_update)
|
||||||
|
+ dirty_section (DEBUG_INFO);
|
||||||
|
+ if (need_strp_update || need_stmt_update)
|
||||||
|
+ dirty_section (DEBUG_MACRO);
|
||||||
|
+ if (need_stmt_update)
|
||||||
|
+ dirty_section (DEBUG_LINE);
|
||||||
|
|
||||||
|
- /* Update any relocations addends we might have touched. */
|
||||||
|
- if (info_rel_updated)
|
||||||
|
- update_rela_data (dso, &debug_sections[DEBUG_INFO]);
|
||||||
|
+ /* Update any relocations addends we might have touched. */
|
||||||
|
+ if (info_rel_updated)
|
||||||
|
+ update_rela_data (dso, &debug_sections[DEBUG_INFO]);
|
||||||
|
|
||||||
|
- if (macro_rel_updated)
|
||||||
|
+ if (macro_rel_updated)
|
||||||
|
+ {
|
||||||
|
+ struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO];
|
||||||
|
+ while (macro_sec != NULL)
|
||||||
|
{
|
||||||
|
- struct debug_section *macro_sec = &debug_sections[DEBUG_MACRO];
|
||||||
|
- while (macro_sec != NULL)
|
||||||
|
- {
|
||||||
|
- update_rela_data (dso, macro_sec);
|
||||||
|
- macro_sec = macro_sec->next;
|
||||||
|
- }
|
||||||
|
+ update_rela_data (dso, macro_sec);
|
||||||
|
+ macro_sec = macro_sec->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.18.4
|
||||||
|
|
@ -0,0 +1,269 @@
|
|||||||
|
From 8cd4d5046d7cb1bc16f01e77a5ff50eca8d9da3d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
Date: Sat, 1 Aug 2020 10:45:47 +0200
|
||||||
|
Subject: [PATCH 3/6] debugedit: Fix missing relocation of .debug_types
|
||||||
|
section.
|
||||||
|
|
||||||
|
---
|
||||||
|
tools/debugedit.c | 123 ++++++++++++++++++++++++++++++----------------
|
||||||
|
1 file changed, 80 insertions(+), 43 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/debugedit.c b/tools/debugedit.c
|
||||||
|
index cad0cc349..87c1cd622 100644
|
||||||
|
--- a/tools/debugedit.c
|
||||||
|
+++ b/tools/debugedit.c
|
||||||
|
@@ -433,7 +433,8 @@ typedef struct debug_section
|
||||||
|
int sec, relsec;
|
||||||
|
REL *relbuf;
|
||||||
|
REL *relend;
|
||||||
|
- struct debug_section *next; /* Only happens for COMDAT .debug_macro. */
|
||||||
|
+ /* Only happens for COMDAT .debug_macro and .debug_types. */
|
||||||
|
+ struct debug_section *next;
|
||||||
|
} debug_section;
|
||||||
|
|
||||||
|
static debug_section debug_sections[] =
|
||||||
|
@@ -1269,7 +1270,9 @@ static int dirty_elf;
|
||||||
|
static void
|
||||||
|
dirty_section (unsigned int sec)
|
||||||
|
{
|
||||||
|
- elf_flagdata (debug_sections[sec].elf_data, ELF_C_SET, ELF_F_DIRTY);
|
||||||
|
+ for (struct debug_section *secp = &debug_sections[sec]; secp != NULL;
|
||||||
|
+ secp = secp->next)
|
||||||
|
+ elf_flagdata (secp->elf_data, ELF_C_SET, ELF_F_DIRTY);
|
||||||
|
dirty_elf = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1469,12 +1472,7 @@ read_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir)
|
||||||
|
|
||||||
|
if (get_line_table (dso, off, &table) == false
|
||||||
|
|| table == NULL)
|
||||||
|
- {
|
||||||
|
- if (table != NULL)
|
||||||
|
- error (0, 0, ".debug_line offset 0x%x referenced multiple times",
|
||||||
|
- off);
|
||||||
|
- return false;
|
||||||
|
- }
|
||||||
|
+ return false;
|
||||||
|
|
||||||
|
/* Skip to the directory table. The rest of the header has already
|
||||||
|
been read and checked by get_line_table. */
|
||||||
|
@@ -1965,22 +1963,25 @@ line_rel_cmp (const void *a, const void *b)
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-edit_info (DSO *dso, int phase)
|
||||||
|
+edit_info (DSO *dso, int phase, struct debug_section *sec)
|
||||||
|
{
|
||||||
|
unsigned char *ptr, *endcu, *endsec;
|
||||||
|
uint32_t value;
|
||||||
|
htab_t abbrev;
|
||||||
|
struct abbrev_tag tag, *t;
|
||||||
|
|
||||||
|
- ptr = debug_sections[DEBUG_INFO].data;
|
||||||
|
- setup_relbuf(dso, &debug_sections[DEBUG_INFO], &reltype);
|
||||||
|
- endsec = ptr + debug_sections[DEBUG_INFO].size;
|
||||||
|
+ ptr = sec->data;
|
||||||
|
+ if (ptr == NULL)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ setup_relbuf(dso, sec, &reltype);
|
||||||
|
+ endsec = ptr + sec->size;
|
||||||
|
while (ptr < endsec)
|
||||||
|
{
|
||||||
|
- if (ptr + 11 > endsec)
|
||||||
|
+ if (ptr + (sec == &debug_sections[DEBUG_INFO] ? 11 : 23) > endsec)
|
||||||
|
{
|
||||||
|
- error (0, 0, "%s: .debug_info CU header too small",
|
||||||
|
- dso->filename);
|
||||||
|
+ error (0, 0, "%s: %s CU header too small",
|
||||||
|
+ dso->filename, sec->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1994,7 +1995,7 @@ edit_info (DSO *dso, int phase)
|
||||||
|
|
||||||
|
if (endcu > endsec)
|
||||||
|
{
|
||||||
|
- error (0, 0, "%s: .debug_info too small", dso->filename);
|
||||||
|
+ error (0, 0, "%s: %s too small", dso->filename, sec->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2034,6 +2035,9 @@ edit_info (DSO *dso, int phase)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (sec != &debug_sections[DEBUG_INFO])
|
||||||
|
+ ptr += 12; /* Skip type_signature and type_offset. */
|
||||||
|
+
|
||||||
|
abbrev = read_abbrev (dso,
|
||||||
|
debug_sections[DEBUG_ABBREV].data + value);
|
||||||
|
if (abbrev == NULL)
|
||||||
|
@@ -2095,7 +2099,7 @@ edit_dwarf2 (DSO *dso)
|
||||||
|
struct debug_section *debug_sec = &debug_sections[j];
|
||||||
|
if (debug_sections[j].data)
|
||||||
|
{
|
||||||
|
- if (j != DEBUG_MACRO)
|
||||||
|
+ if (j != DEBUG_MACRO && j != DEBUG_TYPES)
|
||||||
|
{
|
||||||
|
error (0, 0, "%s: Found two copies of %s section",
|
||||||
|
dso->filename, name);
|
||||||
|
@@ -2103,22 +2107,21 @@ edit_dwarf2 (DSO *dso)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
- /* In relocatable files .debug_macro might
|
||||||
|
- appear multiple times as COMDAT
|
||||||
|
- section. */
|
||||||
|
+ /* In relocatable files .debug_macro and .debug_types
|
||||||
|
+ might appear multiple times as COMDAT section. */
|
||||||
|
struct debug_section *sec;
|
||||||
|
sec = calloc (sizeof (struct debug_section), 1);
|
||||||
|
if (sec == NULL)
|
||||||
|
error (1, errno,
|
||||||
|
- "%s: Could not allocate more macro sections",
|
||||||
|
- dso->filename);
|
||||||
|
- sec->name = ".debug_macro";
|
||||||
|
+ "%s: Could not allocate more %s sections",
|
||||||
|
+ dso->filename, name);
|
||||||
|
+ sec->name = name;
|
||||||
|
|
||||||
|
- struct debug_section *macro_sec = debug_sec;
|
||||||
|
- while (macro_sec->next != NULL)
|
||||||
|
- macro_sec = macro_sec->next;
|
||||||
|
+ struct debug_section *multi_sec = debug_sec;
|
||||||
|
+ while (multi_sec->next != NULL)
|
||||||
|
+ multi_sec = multi_sec->next;
|
||||||
|
|
||||||
|
- macro_sec->next = sec;
|
||||||
|
+ multi_sec->next = sec;
|
||||||
|
debug_sec = sec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -2155,23 +2158,23 @@ edit_dwarf2 (DSO *dso)
|
||||||
|
+ (dso->shdr[i].sh_type == SHT_RELA),
|
||||||
|
debug_sections[j].name) == 0)
|
||||||
|
{
|
||||||
|
- if (j == DEBUG_MACRO)
|
||||||
|
+ if (j == DEBUG_MACRO || j == DEBUG_TYPES)
|
||||||
|
{
|
||||||
|
/* Pick the correct one. */
|
||||||
|
int rel_target = dso->shdr[i].sh_info;
|
||||||
|
- struct debug_section *macro_sec = &debug_sections[j];
|
||||||
|
- while (macro_sec != NULL)
|
||||||
|
+ struct debug_section *multi_sec = &debug_sections[j];
|
||||||
|
+ while (multi_sec != NULL)
|
||||||
|
{
|
||||||
|
- if (macro_sec->sec == rel_target)
|
||||||
|
+ if (multi_sec->sec == rel_target)
|
||||||
|
{
|
||||||
|
- macro_sec->relsec = i;
|
||||||
|
+ multi_sec->relsec = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- macro_sec = macro_sec->next;
|
||||||
|
+ multi_sec = multi_sec->next;
|
||||||
|
}
|
||||||
|
- if (macro_sec == NULL)
|
||||||
|
- error (0, 1, "No .debug_macro reloc section: %s",
|
||||||
|
- dso->filename);
|
||||||
|
+ if (multi_sec == NULL)
|
||||||
|
+ error (0, 1, "No %s reloc section: %s",
|
||||||
|
+ debug_sections[j].name, dso->filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
debug_sections[j].relsec = i;
|
||||||
|
@@ -2203,12 +2206,10 @@ edit_dwarf2 (DSO *dso)
|
||||||
|
if (debug_sections[DEBUG_INFO].data == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- unsigned char *ptr, *endcu, *endsec;
|
||||||
|
- uint32_t value;
|
||||||
|
- htab_t abbrev;
|
||||||
|
- struct abbrev_tag tag, *t;
|
||||||
|
+ unsigned char *ptr, *endsec;
|
||||||
|
int phase;
|
||||||
|
bool info_rel_updated = false;
|
||||||
|
+ bool types_rel_updated = false;
|
||||||
|
bool macro_rel_updated = false;
|
||||||
|
|
||||||
|
for (phase = 0; phase < 2; phase++)
|
||||||
|
@@ -2221,13 +2222,26 @@ edit_dwarf2 (DSO *dso)
|
||||||
|
break;
|
||||||
|
|
||||||
|
rel_updated = false;
|
||||||
|
- if (edit_info (dso, phase))
|
||||||
|
- return 1;
|
||||||
|
+ if (edit_info (dso, phase, &debug_sections[DEBUG_INFO]))
|
||||||
|
+ return 1;
|
||||||
|
|
||||||
|
/* Remember whether any .debug_info relocations might need
|
||||||
|
to be updated. */
|
||||||
|
info_rel_updated = rel_updated;
|
||||||
|
|
||||||
|
+ rel_updated = false;
|
||||||
|
+ struct debug_section *types_sec = &debug_sections[DEBUG_TYPES];
|
||||||
|
+ while (types_sec != NULL)
|
||||||
|
+ {
|
||||||
|
+ if (edit_info (dso, phase, types_sec))
|
||||||
|
+ return 1;
|
||||||
|
+ types_sec = types_sec->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Remember whether any .debug_types relocations might need
|
||||||
|
+ to be updated. */
|
||||||
|
+ types_rel_updated = rel_updated;
|
||||||
|
+
|
||||||
|
/* We might have to recalculate/rewrite the debug_line
|
||||||
|
section. We need to do that before going into phase one
|
||||||
|
so we have all new offsets. We do this separately from
|
||||||
|
@@ -2475,8 +2489,11 @@ edit_dwarf2 (DSO *dso)
|
||||||
|
|
||||||
|
/* After phase 1 we might have rewritten the debug_info with
|
||||||
|
new strp, strings and/or linep offsets. */
|
||||||
|
- if (need_strp_update || need_string_replacement || need_stmt_update)
|
||||||
|
+ if (need_strp_update || need_string_replacement || need_stmt_update) {
|
||||||
|
dirty_section (DEBUG_INFO);
|
||||||
|
+ if (debug_sections[DEBUG_TYPES].data != NULL)
|
||||||
|
+ dirty_section (DEBUG_TYPES);
|
||||||
|
+ }
|
||||||
|
if (need_strp_update || need_stmt_update)
|
||||||
|
dirty_section (DEBUG_MACRO);
|
||||||
|
if (need_stmt_update)
|
||||||
|
@@ -2485,6 +2502,15 @@ edit_dwarf2 (DSO *dso)
|
||||||
|
/* Update any relocations addends we might have touched. */
|
||||||
|
if (info_rel_updated)
|
||||||
|
update_rela_data (dso, &debug_sections[DEBUG_INFO]);
|
||||||
|
+ if (types_rel_updated)
|
||||||
|
+ {
|
||||||
|
+ struct debug_section *types_sec = &debug_sections[DEBUG_TYPES];
|
||||||
|
+ while (types_sec != NULL)
|
||||||
|
+ {
|
||||||
|
+ update_rela_data (dso, types_sec);
|
||||||
|
+ types_sec = types_sec->next;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (macro_rel_updated)
|
||||||
|
{
|
||||||
|
@@ -3037,6 +3063,17 @@ main (int argc, char *argv[])
|
||||||
|
macro_sec = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* In case there were multiple (COMDAT) .debug_types sections,
|
||||||
|
+ free them. */
|
||||||
|
+ struct debug_section *types_sec = &debug_sections[DEBUG_TYPES];
|
||||||
|
+ types_sec = types_sec->next;
|
||||||
|
+ while (types_sec != NULL)
|
||||||
|
+ {
|
||||||
|
+ struct debug_section *next = types_sec->next;
|
||||||
|
+ free (types_sec);
|
||||||
|
+ types_sec = next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
poptFreeContext (optCon);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
--
|
||||||
|
2.18.4
|
||||||
|
|
@ -0,0 +1,455 @@
|
|||||||
|
From bab443ab4f756ef80f814af0353143f41e90e6a6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
Date: Mon, 17 Aug 2020 21:58:19 +0200
|
||||||
|
Subject: [PATCH 4/6] [NFC] debugedit: Move code to separate functions.
|
||||||
|
|
||||||
|
New functions edit_strp, skip_form and edit_attributes_str_comp_dir
|
||||||
|
called by edit_attributes.
|
||||||
|
Split part of read_dwarf2_line into a read_dwarf4_line function.
|
||||||
|
New function edit_dwarf2_any_str called by edit_dwarf2 at the end of
|
||||||
|
phase 0 to rebuild .debug_str.
|
||||||
|
---
|
||||||
|
tools/debugedit.c | 367 ++++++++++++++++++++++++++--------------------
|
||||||
|
1 file changed, 212 insertions(+), 155 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/debugedit.c b/tools/debugedit.c
|
||||||
|
index 87c1cd622..7464883c5 100644
|
||||||
|
--- a/tools/debugedit.c
|
||||||
|
+++ b/tools/debugedit.c
|
||||||
|
@@ -1457,37 +1457,128 @@ edit_dwarf2_line (DSO *dso)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Called during phase zero for each debug_line table referenced from
|
||||||
|
- .debug_info. Outputs all source files seen and records any
|
||||||
|
- adjustments needed in the debug_list data structures. Returns true
|
||||||
|
- if line_table needs to be rewrite either the dir or file paths. */
|
||||||
|
+/* Record or adjust (according to phase) DW_FORM_strp. */
|
||||||
|
+static void
|
||||||
|
+edit_strp (DSO *dso, unsigned char *ptr, int phase, bool handled_strp)
|
||||||
|
+{
|
||||||
|
+ unsigned char *ptr_orig = ptr;
|
||||||
|
+
|
||||||
|
+ /* In the first pass we collect all strings, in the
|
||||||
|
+ second we put the new references back (if there are
|
||||||
|
+ any changes). */
|
||||||
|
+ if (phase == 0)
|
||||||
|
+ {
|
||||||
|
+ /* handled_strp is set for attributes referring to
|
||||||
|
+ files. If it is set the string is already
|
||||||
|
+ recorded. */
|
||||||
|
+ if (! handled_strp)
|
||||||
|
+ {
|
||||||
|
+ size_t idx = do_read_32_relocated (ptr);
|
||||||
|
+ record_existing_string_entry_idx (&dso->strings, idx);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else if (need_strp_update) /* && phase == 1 */
|
||||||
|
+ {
|
||||||
|
+ struct stridxentry *entry;
|
||||||
|
+ size_t idx, new_idx;
|
||||||
|
+ idx = do_read_32_relocated (ptr);
|
||||||
|
+ entry = string_find_entry (&dso->strings, idx);
|
||||||
|
+ new_idx = strent_offset (entry->entry);
|
||||||
|
+ do_write_32_relocated (ptr, new_idx);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ assert (ptr == ptr_orig);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Adjust *PTRP after the current *FORMP, update *FORMP for FORM_INDIRECT. */
|
||||||
|
+static enum { FORM_OK, FORM_ERROR, FORM_INDIRECT }
|
||||||
|
+skip_form (DSO *dso, uint32_t *formp, unsigned char **ptrp)
|
||||||
|
+{
|
||||||
|
+ size_t len = 0;
|
||||||
|
+
|
||||||
|
+ switch (*formp)
|
||||||
|
+ {
|
||||||
|
+ case DW_FORM_ref_addr:
|
||||||
|
+ if (cu_version == 2)
|
||||||
|
+ *ptrp += ptr_size;
|
||||||
|
+ else
|
||||||
|
+ *ptrp += 4;
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_flag_present:
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_addr:
|
||||||
|
+ *ptrp += ptr_size;
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_ref1:
|
||||||
|
+ case DW_FORM_flag:
|
||||||
|
+ case DW_FORM_data1:
|
||||||
|
+ ++*ptrp;
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_ref2:
|
||||||
|
+ case DW_FORM_data2:
|
||||||
|
+ *ptrp += 2;
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_ref4:
|
||||||
|
+ case DW_FORM_data4:
|
||||||
|
+ case DW_FORM_sec_offset:
|
||||||
|
+ *ptrp += 4;
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_ref8:
|
||||||
|
+ case DW_FORM_data8:
|
||||||
|
+ case DW_FORM_ref_sig8:
|
||||||
|
+ *ptrp += 8;
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_sdata:
|
||||||
|
+ case DW_FORM_ref_udata:
|
||||||
|
+ case DW_FORM_udata:
|
||||||
|
+ read_uleb128 (*ptrp);
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_strp:
|
||||||
|
+ *ptrp += 4;
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_string:
|
||||||
|
+ *ptrp = (unsigned char *) strchr ((char *)*ptrp, '\0') + 1;
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_indirect:
|
||||||
|
+ *formp = read_uleb128 (*ptrp);
|
||||||
|
+ return FORM_INDIRECT;
|
||||||
|
+ case DW_FORM_block1:
|
||||||
|
+ len = *(*ptrp)++;
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_block2:
|
||||||
|
+ len = read_16 (*ptrp);
|
||||||
|
+ *formp = DW_FORM_block1;
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_block4:
|
||||||
|
+ len = read_32 (*ptrp);
|
||||||
|
+ *formp = DW_FORM_block1;
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_block:
|
||||||
|
+ case DW_FORM_exprloc:
|
||||||
|
+ len = read_uleb128 (*ptrp);
|
||||||
|
+ *formp = DW_FORM_block1;
|
||||||
|
+ assert (len < UINT_MAX);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename, *formp);
|
||||||
|
+ return FORM_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (*formp == DW_FORM_block1)
|
||||||
|
+ *ptrp += len;
|
||||||
|
+
|
||||||
|
+ return FORM_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Part of read_dwarf2_line processing DWARF-4. */
|
||||||
|
static bool
|
||||||
|
-read_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir)
|
||||||
|
+read_dwarf4_line (DSO *dso, unsigned char *ptr, char *comp_dir,
|
||||||
|
+ struct line_table *table)
|
||||||
|
{
|
||||||
|
- unsigned char *ptr, *dir;
|
||||||
|
unsigned char **dirt;
|
||||||
|
uint32_t value, dirt_cnt;
|
||||||
|
size_t comp_dir_len = !comp_dir ? 0 : strlen (comp_dir);
|
||||||
|
- struct line_table *table;
|
||||||
|
-
|
||||||
|
- if (get_line_table (dso, off, &table) == false
|
||||||
|
- || table == NULL)
|
||||||
|
- return false;
|
||||||
|
-
|
||||||
|
- /* Skip to the directory table. The rest of the header has already
|
||||||
|
- been read and checked by get_line_table. */
|
||||||
|
- ptr = debug_sections[DEBUG_LINE].data + off;
|
||||||
|
- ptr += (4 /* unit len */
|
||||||
|
- + 2 /* version */
|
||||||
|
- + 4 /* header len */
|
||||||
|
- + 1 /* min instr len */
|
||||||
|
- + (table->version >= 4) /* max op per instr, if version >= 4 */
|
||||||
|
- + 1 /* default is stmt */
|
||||||
|
- + 1 /* line base */
|
||||||
|
- + 1 /* line range */
|
||||||
|
- + 1 /* opcode base */
|
||||||
|
- + table->opcode_base - 1); /* opcode len table */
|
||||||
|
- dir = ptr;
|
||||||
|
+ unsigned char *dir = ptr;
|
||||||
|
|
||||||
|
/* dir table: */
|
||||||
|
value = 1;
|
||||||
|
@@ -1620,6 +1711,40 @@ read_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir)
|
||||||
|
read_uleb128 (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Called during phase zero for each debug_line table referenced from
|
||||||
|
+ .debug_info. Outputs all source files seen and records any
|
||||||
|
+ adjustments needed in the debug_list data structures. Returns true
|
||||||
|
+ if line_table needs to be rewrite either the dir or file paths. */
|
||||||
|
+static bool
|
||||||
|
+read_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir)
|
||||||
|
+{
|
||||||
|
+ unsigned char *ptr;
|
||||||
|
+ struct line_table *table;
|
||||||
|
+
|
||||||
|
+ if (get_line_table (dso, off, &table) == false
|
||||||
|
+ || table == NULL)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ /* Skip to the directory table. The rest of the header has already
|
||||||
|
+ been read and checked by get_line_table. */
|
||||||
|
+ ptr = debug_sections[DEBUG_LINE].data + off;
|
||||||
|
+ ptr += (4 /* unit len */
|
||||||
|
+ + 2 /* version */
|
||||||
|
+ + 4 /* header len */
|
||||||
|
+ + 1 /* min instr len */
|
||||||
|
+ + (table->version >= 4) /* max op per instr, if version >= 4 */
|
||||||
|
+ + 1 /* default is stmt */
|
||||||
|
+ + 1 /* line base */
|
||||||
|
+ + 1 /* line range */
|
||||||
|
+ + 1 /* opcode base */
|
||||||
|
+ + table->opcode_base - 1); /* opcode len table */
|
||||||
|
+
|
||||||
|
+ if (! read_dwarf4_line (dso, ptr, comp_dir, table))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
dso->lines.debug_lines_len += 4 + table->unit_length + table->size_diff;
|
||||||
|
return table->replace_dirs || table->replace_files;
|
||||||
|
}
|
||||||
|
@@ -1637,6 +1762,33 @@ find_new_list_offs (struct debug_lines *lines, size_t idx)
|
||||||
|
return table->new_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Read DW_FORM_strp collecting compilation directory. */
|
||||||
|
+static void
|
||||||
|
+edit_attributes_str_comp_dir (DSO *dso, unsigned char **ptrp, int phase,
|
||||||
|
+ char **comp_dirp, bool *handled_strpp)
|
||||||
|
+{
|
||||||
|
+ const char *dir;
|
||||||
|
+ size_t idx = do_read_32_relocated (*ptrp);
|
||||||
|
+ /* In phase zero we collect the comp_dir. */
|
||||||
|
+ if (phase == 0)
|
||||||
|
+ {
|
||||||
|
+ if (idx >= debug_sections[DEBUG_STR].size)
|
||||||
|
+ error (1, 0, "%s: Bad string pointer index %zd for comp_dir",
|
||||||
|
+ dso->filename, idx);
|
||||||
|
+ dir = (char *) debug_sections[DEBUG_STR].data + idx;
|
||||||
|
+
|
||||||
|
+ free (*comp_dirp);
|
||||||
|
+ *comp_dirp = strdup (dir);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (dest_dir != NULL && phase == 0)
|
||||||
|
+ {
|
||||||
|
+ if (record_file_string_entry_idx (&dso->strings, idx))
|
||||||
|
+ need_strp_update = true;
|
||||||
|
+ *handled_strpp = true;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* This scans the attributes of one DIE described by the given abbrev_tag.
|
||||||
|
PTR points to the data in the debug_info. It will be advanced till all
|
||||||
|
abbrev data is consumed. In phase zero data is collected, in phase one
|
||||||
|
@@ -1655,7 +1807,6 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
|
||||||
|
for (i = 0; i < t->nattr; ++i)
|
||||||
|
{
|
||||||
|
uint32_t form = t->attr[i].form;
|
||||||
|
- size_t len = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* Whether we already handled a string as file for this
|
||||||
|
@@ -1743,29 +1894,8 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
|
||||||
|
}
|
||||||
|
else if (form == DW_FORM_strp &&
|
||||||
|
debug_sections[DEBUG_STR].data)
|
||||||
|
- {
|
||||||
|
- const char *dir;
|
||||||
|
- size_t idx = do_read_32_relocated (ptr);
|
||||||
|
- /* In phase zero we collect the comp_dir. */
|
||||||
|
- if (phase == 0)
|
||||||
|
- {
|
||||||
|
- if (idx >= debug_sections[DEBUG_STR].size)
|
||||||
|
- error (1, 0,
|
||||||
|
- "%s: Bad string pointer index %zd for comp_dir",
|
||||||
|
- dso->filename, idx);
|
||||||
|
- dir = (char *) debug_sections[DEBUG_STR].data + idx;
|
||||||
|
-
|
||||||
|
- free (comp_dir);
|
||||||
|
- comp_dir = strdup (dir);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (dest_dir != NULL && phase == 0)
|
||||||
|
- {
|
||||||
|
- if (record_file_string_entry_idx (&dso->strings, idx))
|
||||||
|
- need_strp_update = true;
|
||||||
|
- handled_strp = true;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ edit_attributes_str_comp_dir (dso, &ptr, phase, &comp_dir,
|
||||||
|
+ &handled_strp);
|
||||||
|
}
|
||||||
|
else if ((t->tag == DW_TAG_compile_unit
|
||||||
|
|| t->tag == DW_TAG_partial_unit)
|
||||||
|
@@ -1815,99 +1945,21 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
|
||||||
|
|
||||||
|
switch (form)
|
||||||
|
{
|
||||||
|
- case DW_FORM_ref_addr:
|
||||||
|
- if (cu_version == 2)
|
||||||
|
- ptr += ptr_size;
|
||||||
|
- else
|
||||||
|
- ptr += 4;
|
||||||
|
- break;
|
||||||
|
- case DW_FORM_flag_present:
|
||||||
|
- break;
|
||||||
|
- case DW_FORM_addr:
|
||||||
|
- ptr += ptr_size;
|
||||||
|
- break;
|
||||||
|
- case DW_FORM_ref1:
|
||||||
|
- case DW_FORM_flag:
|
||||||
|
- case DW_FORM_data1:
|
||||||
|
- ++ptr;
|
||||||
|
- break;
|
||||||
|
- case DW_FORM_ref2:
|
||||||
|
- case DW_FORM_data2:
|
||||||
|
- ptr += 2;
|
||||||
|
- break;
|
||||||
|
- case DW_FORM_ref4:
|
||||||
|
- case DW_FORM_data4:
|
||||||
|
- case DW_FORM_sec_offset:
|
||||||
|
- ptr += 4;
|
||||||
|
- break;
|
||||||
|
- case DW_FORM_ref8:
|
||||||
|
- case DW_FORM_data8:
|
||||||
|
- case DW_FORM_ref_sig8:
|
||||||
|
- ptr += 8;
|
||||||
|
- break;
|
||||||
|
- case DW_FORM_sdata:
|
||||||
|
- case DW_FORM_ref_udata:
|
||||||
|
- case DW_FORM_udata:
|
||||||
|
- read_uleb128 (ptr);
|
||||||
|
- break;
|
||||||
|
case DW_FORM_strp:
|
||||||
|
- /* In the first pass we collect all strings, in the
|
||||||
|
- second we put the new references back (if there are
|
||||||
|
- any changes). */
|
||||||
|
- if (phase == 0)
|
||||||
|
- {
|
||||||
|
- /* handled_strp is set for attributes referring to
|
||||||
|
- files. If it is set the string is already
|
||||||
|
- recorded. */
|
||||||
|
- if (! handled_strp)
|
||||||
|
- {
|
||||||
|
- size_t idx = do_read_32_relocated (ptr);
|
||||||
|
- record_existing_string_entry_idx (&dso->strings, idx);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- else if (need_strp_update) /* && phase == 1 */
|
||||||
|
- {
|
||||||
|
- struct stridxentry *entry;
|
||||||
|
- size_t idx, new_idx;
|
||||||
|
- idx = do_read_32_relocated (ptr);
|
||||||
|
- entry = string_find_entry (&dso->strings, idx);
|
||||||
|
- new_idx = strent_offset (entry->entry);
|
||||||
|
- do_write_32_relocated (ptr, new_idx);
|
||||||
|
- }
|
||||||
|
- ptr += 4;
|
||||||
|
- break;
|
||||||
|
- case DW_FORM_string:
|
||||||
|
- ptr = (unsigned char *) strchr ((char *)ptr, '\0') + 1;
|
||||||
|
- break;
|
||||||
|
- case DW_FORM_indirect:
|
||||||
|
- form = read_uleb128 (ptr);
|
||||||
|
- continue;
|
||||||
|
- case DW_FORM_block1:
|
||||||
|
- len = *ptr++;
|
||||||
|
- break;
|
||||||
|
- case DW_FORM_block2:
|
||||||
|
- len = read_16 (ptr);
|
||||||
|
- form = DW_FORM_block1;
|
||||||
|
+ edit_strp (dso, ptr, phase, handled_strp);
|
||||||
|
break;
|
||||||
|
- case DW_FORM_block4:
|
||||||
|
- len = read_32 (ptr);
|
||||||
|
- form = DW_FORM_block1;
|
||||||
|
- break;
|
||||||
|
- case DW_FORM_block:
|
||||||
|
- case DW_FORM_exprloc:
|
||||||
|
- len = read_uleb128 (ptr);
|
||||||
|
- form = DW_FORM_block1;
|
||||||
|
- assert (len < UINT_MAX);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (skip_form (dso, &form, &ptr))
|
||||||
|
+ {
|
||||||
|
+ case FORM_OK:
|
||||||
|
break;
|
||||||
|
- default:
|
||||||
|
- error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename,
|
||||||
|
- form);
|
||||||
|
+ case FORM_ERROR:
|
||||||
|
return NULL;
|
||||||
|
+ case FORM_INDIRECT:
|
||||||
|
+ continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (form == DW_FORM_block1)
|
||||||
|
- ptr += len;
|
||||||
|
-
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -2068,6 +2120,28 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Rebuild .debug_str. */
|
||||||
|
+static void
|
||||||
|
+edit_dwarf2_any_str (DSO *dso)
|
||||||
|
+{
|
||||||
|
+ Strtab *strtab = dso->strings.str_tab;
|
||||||
|
+ Elf_Data *strdata = debug_sections[DEBUG_STR].elf_data;
|
||||||
|
+ int strndx = debug_sections[DEBUG_STR].sec;
|
||||||
|
+ Elf_Scn *strscn = dso->scn[strndx];
|
||||||
|
+
|
||||||
|
+ /* Out with the old. */
|
||||||
|
+ strdata->d_size = 0;
|
||||||
|
+ /* In with the new. */
|
||||||
|
+ strdata = elf_newdata (strscn);
|
||||||
|
+
|
||||||
|
+ /* We really should check whether we had enough memory,
|
||||||
|
+ but the old ebl version will just abort on out of
|
||||||
|
+ memory... */
|
||||||
|
+ strtab_finalize (strtab, strdata);
|
||||||
|
+ debug_sections[DEBUG_STR].size = strdata->d_size;
|
||||||
|
+ dso->strings.str_buf = strdata->d_buf;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
edit_dwarf2 (DSO *dso)
|
||||||
|
{
|
||||||
|
@@ -2466,24 +2540,7 @@ edit_dwarf2 (DSO *dso)
|
||||||
|
in place for phase 1 updating of debug_info
|
||||||
|
references. */
|
||||||
|
if (phase == 0 && need_strp_update)
|
||||||
|
- {
|
||||||
|
- Strtab *strtab = dso->strings.str_tab;
|
||||||
|
- Elf_Data *strdata = debug_sections[DEBUG_STR].elf_data;
|
||||||
|
- int strndx = debug_sections[DEBUG_STR].sec;
|
||||||
|
- Elf_Scn *strscn = dso->scn[strndx];
|
||||||
|
-
|
||||||
|
- /* Out with the old. */
|
||||||
|
- strdata->d_size = 0;
|
||||||
|
- /* In with the new. */
|
||||||
|
- strdata = elf_newdata (strscn);
|
||||||
|
-
|
||||||
|
- /* We really should check whether we had enough memory,
|
||||||
|
- but the old ebl version will just abort on out of
|
||||||
|
- memory... */
|
||||||
|
- strtab_finalize (strtab, strdata);
|
||||||
|
- debug_sections[DEBUG_STR].size = strdata->d_size;
|
||||||
|
- dso->strings.str_buf = strdata->d_buf;
|
||||||
|
- }
|
||||||
|
+ edit_dwarf2_any_str (dso);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.18.4
|
||||||
|
|
@ -0,0 +1,217 @@
|
|||||||
|
From 8b5dcb4c2175ac706a4e1c34ce83301213800689 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
Date: Mon, 18 Jan 2021 22:56:53 +0100
|
||||||
|
Subject: [PATCH 5/6] debugedit: Implement DWARF-5 unit header and new forms
|
||||||
|
parsing.
|
||||||
|
|
||||||
|
Recognize the various new DWARF5 .debug sections.
|
||||||
|
Parse and skip new DWARF5 forms in read_abbrev and skip_form.
|
||||||
|
Read DWARF5 unit headers for compile and partial units in edit_info.
|
||||||
|
|
||||||
|
This is enough to be able to process gcc -gdwarf-5 produced binaries
|
||||||
|
without the new DWARF5 .debug_line format (which isn't produced with
|
||||||
|
binutils < 2.36).
|
||||||
|
|
||||||
|
Patches slightly edited/merged by Mark Wielaard <mark@klomp.org>
|
||||||
|
---
|
||||||
|
tools/debugedit.c | 88 +++++++++++++++++++++++++++++++++++++++++++----
|
||||||
|
1 file changed, 81 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/debugedit.c b/tools/debugedit.c
|
||||||
|
index 7464883c5..be5fee85b 100644
|
||||||
|
--- a/tools/debugedit.c
|
||||||
|
+++ b/tools/debugedit.c
|
||||||
|
@@ -453,6 +453,11 @@ static debug_section debug_sections[] =
|
||||||
|
#define DEBUG_TYPES 11
|
||||||
|
#define DEBUG_MACRO 12
|
||||||
|
#define DEBUG_GDB_SCRIPT 13
|
||||||
|
+#define DEBUG_RNGLISTS 14
|
||||||
|
+#define DEBUG_LINE_STR 15
|
||||||
|
+#define DEBUG_ADDR 16
|
||||||
|
+#define DEBUG_STR_OFFSETS 17
|
||||||
|
+#define DEBUG_LOCLISTS 18
|
||||||
|
{ ".debug_info", NULL, NULL, 0, 0, 0 },
|
||||||
|
{ ".debug_abbrev", NULL, NULL, 0, 0, 0 },
|
||||||
|
{ ".debug_line", NULL, NULL, 0, 0, 0 },
|
||||||
|
@@ -467,6 +472,11 @@ static debug_section debug_sections[] =
|
||||||
|
{ ".debug_types", NULL, NULL, 0, 0, 0 },
|
||||||
|
{ ".debug_macro", NULL, NULL, 0, 0, 0 },
|
||||||
|
{ ".debug_gdb_scripts", NULL, NULL, 0, 0, 0 },
|
||||||
|
+ { ".debug_rnglists", NULL, NULL, 0, 0, 0 },
|
||||||
|
+ { ".debug_line_str", NULL, NULL, 0, 0, 0 },
|
||||||
|
+ { ".debug_addr", NULL, NULL, 0, 0, 0 },
|
||||||
|
+ { ".debug_str_offsets", NULL, NULL, 0, 0, 0 },
|
||||||
|
+ { ".debug_loclists", NULL, NULL, 0, 0, 0 },
|
||||||
|
{ NULL, NULL, NULL, 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -755,12 +765,28 @@ no_memory:
|
||||||
|
}
|
||||||
|
form = read_uleb128 (ptr);
|
||||||
|
if (form == 2
|
||||||
|
- || (form > DW_FORM_flag_present && form != DW_FORM_ref_sig8))
|
||||||
|
+ || (form > DW_FORM_flag_present
|
||||||
|
+ && !(form == DW_FORM_ref_sig8
|
||||||
|
+ || form == DW_FORM_data16
|
||||||
|
+ || form == DW_FORM_implicit_const
|
||||||
|
+ || form == DW_FORM_addrx
|
||||||
|
+ || form == DW_FORM_loclistx
|
||||||
|
+ || form == DW_FORM_rnglistx
|
||||||
|
+ || form == DW_FORM_addrx1
|
||||||
|
+ || form == DW_FORM_addrx2
|
||||||
|
+ || form == DW_FORM_addrx3
|
||||||
|
+ || form == DW_FORM_addrx4)))
|
||||||
|
{
|
||||||
|
- error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename, form);
|
||||||
|
+ error (0, 0, "%s: Unknown DWARF DW_FORM_0x%x", dso->filename,
|
||||||
|
+ form);
|
||||||
|
htab_delete (h);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
+ if (form == DW_FORM_implicit_const)
|
||||||
|
+ {
|
||||||
|
+ /* It is SLEB128 but the value is dropped anyway. */
|
||||||
|
+ read_uleb128 (ptr);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
t->attr[t->nattr].attr = attr;
|
||||||
|
t->attr[t->nattr++].form = form;
|
||||||
|
@@ -1505,6 +1531,7 @@ skip_form (DSO *dso, uint32_t *formp, unsigned char **ptrp)
|
||||||
|
*ptrp += 4;
|
||||||
|
break;
|
||||||
|
case DW_FORM_flag_present:
|
||||||
|
+ case DW_FORM_implicit_const:
|
||||||
|
break;
|
||||||
|
case DW_FORM_addr:
|
||||||
|
*ptrp += ptr_size;
|
||||||
|
@@ -1512,14 +1539,24 @@ skip_form (DSO *dso, uint32_t *formp, unsigned char **ptrp)
|
||||||
|
case DW_FORM_ref1:
|
||||||
|
case DW_FORM_flag:
|
||||||
|
case DW_FORM_data1:
|
||||||
|
+ case DW_FORM_strx1:
|
||||||
|
+ case DW_FORM_addrx1:
|
||||||
|
++*ptrp;
|
||||||
|
break;
|
||||||
|
case DW_FORM_ref2:
|
||||||
|
case DW_FORM_data2:
|
||||||
|
+ case DW_FORM_strx2:
|
||||||
|
+ case DW_FORM_addrx2:
|
||||||
|
*ptrp += 2;
|
||||||
|
break;
|
||||||
|
+ case DW_FORM_strx3:
|
||||||
|
+ case DW_FORM_addrx3:
|
||||||
|
+ *ptrp += 3;
|
||||||
|
+ break;
|
||||||
|
case DW_FORM_ref4:
|
||||||
|
case DW_FORM_data4:
|
||||||
|
+ case DW_FORM_strx4:
|
||||||
|
+ case DW_FORM_addrx4:
|
||||||
|
case DW_FORM_sec_offset:
|
||||||
|
*ptrp += 4;
|
||||||
|
break;
|
||||||
|
@@ -1528,12 +1565,20 @@ skip_form (DSO *dso, uint32_t *formp, unsigned char **ptrp)
|
||||||
|
case DW_FORM_ref_sig8:
|
||||||
|
*ptrp += 8;
|
||||||
|
break;
|
||||||
|
+ case DW_FORM_data16:
|
||||||
|
+ *ptrp += 16;
|
||||||
|
+ break;
|
||||||
|
case DW_FORM_sdata:
|
||||||
|
case DW_FORM_ref_udata:
|
||||||
|
case DW_FORM_udata:
|
||||||
|
+ case DW_FORM_strx:
|
||||||
|
+ case DW_FORM_loclistx:
|
||||||
|
+ case DW_FORM_rnglistx:
|
||||||
|
+ case DW_FORM_addrx:
|
||||||
|
read_uleb128 (*ptrp);
|
||||||
|
break;
|
||||||
|
case DW_FORM_strp:
|
||||||
|
+ case DW_FORM_line_strp:
|
||||||
|
*ptrp += 4;
|
||||||
|
break;
|
||||||
|
case DW_FORM_string:
|
||||||
|
@@ -1560,7 +1605,7 @@ skip_form (DSO *dso, uint32_t *formp, unsigned char **ptrp)
|
||||||
|
assert (len < UINT_MAX);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
- error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename, *formp);
|
||||||
|
+ error (0, 0, "%s: Unknown DWARF DW_FORM_0x%x", dso->filename, *formp);
|
||||||
|
return FORM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2030,7 +2075,10 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
|
||||||
|
endsec = ptr + sec->size;
|
||||||
|
while (ptr < endsec)
|
||||||
|
{
|
||||||
|
- if (ptr + (sec == &debug_sections[DEBUG_INFO] ? 11 : 23) > endsec)
|
||||||
|
+ unsigned char *cu_start = ptr;
|
||||||
|
+
|
||||||
|
+ /* header size, version, unit_type, ptr_size. */
|
||||||
|
+ if (ptr + 4 + 2 + 1 + 1 > endsec)
|
||||||
|
{
|
||||||
|
error (0, 0, "%s: %s CU header too small",
|
||||||
|
dso->filename, sec->name);
|
||||||
|
@@ -2052,13 +2100,36 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
|
||||||
|
}
|
||||||
|
|
||||||
|
cu_version = read_16 (ptr);
|
||||||
|
- if (cu_version != 2 && cu_version != 3 && cu_version != 4)
|
||||||
|
+ if (cu_version != 2 && cu_version != 3 && cu_version != 4
|
||||||
|
+ && cu_version != 5)
|
||||||
|
{
|
||||||
|
error (0, 0, "%s: DWARF version %d unhandled", dso->filename,
|
||||||
|
cu_version);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ int cu_ptr_size = 0;
|
||||||
|
+
|
||||||
|
+ if (cu_version >= 5)
|
||||||
|
+ {
|
||||||
|
+ uint8_t unit_type = read_8 (ptr);
|
||||||
|
+ if (unit_type != DW_UT_compile && unit_type != DW_UT_partial)
|
||||||
|
+ {
|
||||||
|
+ error (0, 0, "%s: Unit type %u unhandled", dso->filename,
|
||||||
|
+ unit_type);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cu_ptr_size = read_8 (ptr);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ unsigned char *header_end = (cu_start + 23 + (cu_version < 5 ? 0 : 1));
|
||||||
|
+ if (header_end > endsec)
|
||||||
|
+ {
|
||||||
|
+ error (0, 0, "%s: %s CU header too small", dso->filename, sec->name);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
value = read_32_relocated (ptr);
|
||||||
|
if (value >= debug_sections[DEBUG_ABBREV].size)
|
||||||
|
{
|
||||||
|
@@ -2070,9 +2141,12 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (cu_version < 5)
|
||||||
|
+ cu_ptr_size = read_8 (ptr);
|
||||||
|
+
|
||||||
|
if (ptr_size == 0)
|
||||||
|
{
|
||||||
|
- ptr_size = read_8 (ptr);
|
||||||
|
+ ptr_size = cu_ptr_size;
|
||||||
|
if (ptr_size != 4 && ptr_size != 8)
|
||||||
|
{
|
||||||
|
error (0, 0, "%s: Invalid DWARF pointer size %d",
|
||||||
|
@@ -2080,7 +2154,7 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- else if (read_8 (ptr) != ptr_size)
|
||||||
|
+ else if (cu_ptr_size != ptr_size)
|
||||||
|
{
|
||||||
|
error (0, 0, "%s: DWARF pointer size differs between CUs",
|
||||||
|
dso->filename);
|
||||||
|
--
|
||||||
|
2.18.4
|
||||||
|
|
@ -0,0 +1,772 @@
|
|||||||
|
From d9947f2dc0c2cd812f8e64380d5f6f53705a5280 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Wielaard <mark@klomp.org>
|
||||||
|
Date: Tue, 19 Jan 2021 04:12:33 +0100
|
||||||
|
Subject: [PATCH 6/6] debugedit: Handle DWARF-5 debug_line and debug_line_str.
|
||||||
|
|
||||||
|
Handle the new DWARF5 .debug_line tables and the new DW_FORM_line_strp.
|
||||||
|
DWARF5 tables are handled separately from the earlier tables. They
|
||||||
|
will never change size, but they do need updates to the .debug_str
|
||||||
|
or .debug_line_str references.
|
||||||
|
|
||||||
|
Based on a patch from Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
---
|
||||||
|
tools/debugedit.c | 471 ++++++++++++++++++++++++++++++++++++++++------
|
||||||
|
1 file changed, 410 insertions(+), 61 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/debugedit.c b/tools/debugedit.c
|
||||||
|
index be5fee85b..d6a0058e9 100644
|
||||||
|
--- a/tools/debugedit.c
|
||||||
|
+++ b/tools/debugedit.c
|
||||||
|
@@ -103,6 +103,8 @@ static bool need_string_replacement = false;
|
||||||
|
/* Whether we need to do any updates of the string indexes (DW_FORM_strp)
|
||||||
|
in debug_info for string indexes. */
|
||||||
|
static bool need_strp_update = false;
|
||||||
|
+/* Likewise for DW_FORM_line_strp. */
|
||||||
|
+static bool need_line_strp_update = false;
|
||||||
|
/* If the debug_line changes size we will need to update the
|
||||||
|
DW_AT_stmt_list attributes indexes in the debug_info. */
|
||||||
|
static bool need_stmt_update = false;
|
||||||
|
@@ -192,7 +194,7 @@ typedef struct
|
||||||
|
const char *filename;
|
||||||
|
int lastscn;
|
||||||
|
size_t phnum;
|
||||||
|
- struct strings strings;
|
||||||
|
+ struct strings debug_str, debug_line_str;
|
||||||
|
struct debug_lines lines;
|
||||||
|
GElf_Shdr shdr[0];
|
||||||
|
} DSO;
|
||||||
|
@@ -553,10 +555,11 @@ setup_relbuf (DSO *dso, debug_section *sec, int *reltype)
|
||||||
|
/* Relocations against section symbols are uninteresting in REL. */
|
||||||
|
if (dso->shdr[i].sh_type == SHT_REL && sym.st_value == 0)
|
||||||
|
continue;
|
||||||
|
- /* Only consider relocations against .debug_str, .debug_line
|
||||||
|
- and .debug_abbrev. */
|
||||||
|
+ /* Only consider relocations against .debug_str, .debug_line,
|
||||||
|
+ .debug_line_str, and .debug_abbrev. */
|
||||||
|
if (sym.st_shndx != debug_sections[DEBUG_STR].sec
|
||||||
|
&& sym.st_shndx != debug_sections[DEBUG_LINE].sec
|
||||||
|
+ && sym.st_shndx != debug_sections[DEBUG_LINE_STR].sec
|
||||||
|
&& sym.st_shndx != debug_sections[DEBUG_ABBREV].sec)
|
||||||
|
continue;
|
||||||
|
rela.r_addend += sym.st_value;
|
||||||
|
@@ -768,6 +771,7 @@ no_memory:
|
||||||
|
|| (form > DW_FORM_flag_present
|
||||||
|
&& !(form == DW_FORM_ref_sig8
|
||||||
|
|| form == DW_FORM_data16
|
||||||
|
+ || form == DW_FORM_line_strp
|
||||||
|
|| form == DW_FORM_implicit_const
|
||||||
|
|| form == DW_FORM_addrx
|
||||||
|
|| form == DW_FORM_loclistx
|
||||||
|
@@ -1049,17 +1053,20 @@ string_find_entry (struct strings *strings, size_t old_idx)
|
||||||
|
a replacement file string has been recorded for it, otherwise
|
||||||
|
returns false. */
|
||||||
|
static bool
|
||||||
|
-record_file_string_entry_idx (struct strings *strings, size_t old_idx)
|
||||||
|
+record_file_string_entry_idx (bool line_strp, DSO *dso, size_t old_idx)
|
||||||
|
{
|
||||||
|
+ struct strings *strings = line_strp ? &dso->debug_line_str : &dso->debug_str;
|
||||||
|
bool ret = false;
|
||||||
|
struct stridxentry *entry = string_find_new_entry (strings, old_idx);
|
||||||
|
if (entry != NULL)
|
||||||
|
{
|
||||||
|
- if (old_idx >= debug_sections[DEBUG_STR].size)
|
||||||
|
- error (1, 0, "Bad string pointer index %zd", old_idx);
|
||||||
|
+ debug_section *sec = &debug_sections[line_strp
|
||||||
|
+ ? DEBUG_LINE_STR : DEBUG_STR];
|
||||||
|
+ if (old_idx >= sec->size)
|
||||||
|
+ error (1, 0, "Bad string pointer index %zd (%s)", old_idx, sec->name);
|
||||||
|
|
||||||
|
Strent *strent;
|
||||||
|
- const char *old_str = (char *)debug_sections[DEBUG_STR].data + old_idx;
|
||||||
|
+ const char *old_str = (char *)sec->data + old_idx;
|
||||||
|
const char *file = skip_dir_prefix (old_str, base_dir);
|
||||||
|
if (file == NULL)
|
||||||
|
{
|
||||||
|
@@ -1103,15 +1110,18 @@ record_file_string_entry_idx (struct strings *strings, size_t old_idx)
|
||||||
|
base_dir with dest_dir, just records the existing string associated
|
||||||
|
with the index. */
|
||||||
|
static void
|
||||||
|
-record_existing_string_entry_idx (struct strings *strings, size_t old_idx)
|
||||||
|
+record_existing_string_entry_idx (bool line_strp, DSO *dso, size_t old_idx)
|
||||||
|
{
|
||||||
|
+ struct strings *strings = line_strp ? &dso->debug_line_str : &dso->debug_str;
|
||||||
|
struct stridxentry *entry = string_find_new_entry (strings, old_idx);
|
||||||
|
if (entry != NULL)
|
||||||
|
{
|
||||||
|
- if (old_idx >= debug_sections[DEBUG_STR].size)
|
||||||
|
- error (1, 0, "Bad string pointer index %zd", old_idx);
|
||||||
|
+ debug_section *sec = &debug_sections[line_strp
|
||||||
|
+ ? DEBUG_LINE_STR : DEBUG_STR];
|
||||||
|
+ if (old_idx >= sec->size)
|
||||||
|
+ error (1, 0, "Bad string pointer index %zd (%s)", old_idx, sec->name);
|
||||||
|
|
||||||
|
- const char *str = (char *)debug_sections[DEBUG_STR].data + old_idx;
|
||||||
|
+ const char *str = (char *)sec->data + old_idx;
|
||||||
|
Strent *strent = strtab_add_len (strings->str_tab,
|
||||||
|
str, strlen (str) + 1);
|
||||||
|
if (strent == NULL)
|
||||||
|
@@ -1244,13 +1254,28 @@ get_line_table (DSO *dso, size_t off, struct line_table **table)
|
||||||
|
|
||||||
|
/* version */
|
||||||
|
t->version = read_16 (ptr);
|
||||||
|
- if (t->version != 2 && t->version != 3 && t->version != 4)
|
||||||
|
+ if (t->version != 2 && t->version != 3 && t->version != 4 && t->version != 5)
|
||||||
|
{
|
||||||
|
error (0, 0, "%s: DWARF version %d unhandled", dso->filename,
|
||||||
|
t->version);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (t->version >= 5)
|
||||||
|
+ {
|
||||||
|
+ /* address_size */
|
||||||
|
+ assert (ptr_size != 0);
|
||||||
|
+ if (ptr_size != read_8 (ptr))
|
||||||
|
+ {
|
||||||
|
+ error (0, 0, "%s: .debug_line address size differs from .debug_info",
|
||||||
|
+ dso->filename);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* segment_selector_size */
|
||||||
|
+ (void) read_8 (ptr);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* header_length */
|
||||||
|
unsigned char *endprol = ptr + 4;
|
||||||
|
t->header_length = read_32 (ptr);
|
||||||
|
@@ -1343,7 +1368,9 @@ edit_dwarf2_line (DSO *dso)
|
||||||
|
|
||||||
|
linedata->d_size = dso->lines.debug_lines_len;
|
||||||
|
linedata->d_buf = dso->lines.line_buf;
|
||||||
|
+ debug_sections[DEBUG_LINE].data = linedata->d_buf;
|
||||||
|
debug_sections[DEBUG_LINE].size = linedata->d_size;
|
||||||
|
+ debug_sections[DEBUG_LINE].elf_data = linedata;
|
||||||
|
|
||||||
|
/* Make sure the line tables are sorted on the old index. */
|
||||||
|
qsort (dso->lines.table, dso->lines.used, sizeof (struct line_table),
|
||||||
|
@@ -1483,9 +1510,10 @@ edit_dwarf2_line (DSO *dso)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Record or adjust (according to phase) DW_FORM_strp. */
|
||||||
|
+/* Record or adjust (according to phase) DW_FORM_strp or DW_FORM_line_strp. */
|
||||||
|
static void
|
||||||
|
-edit_strp (DSO *dso, unsigned char *ptr, int phase, bool handled_strp)
|
||||||
|
+edit_strp (DSO *dso, bool line_strp, unsigned char *ptr, int phase,
|
||||||
|
+ bool handled_strp)
|
||||||
|
{
|
||||||
|
unsigned char *ptr_orig = ptr;
|
||||||
|
|
||||||
|
@@ -1500,15 +1528,18 @@ edit_strp (DSO *dso, unsigned char *ptr, int phase, bool handled_strp)
|
||||||
|
if (! handled_strp)
|
||||||
|
{
|
||||||
|
size_t idx = do_read_32_relocated (ptr);
|
||||||
|
- record_existing_string_entry_idx (&dso->strings, idx);
|
||||||
|
+ record_existing_string_entry_idx (line_strp, dso, idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- else if (need_strp_update) /* && phase == 1 */
|
||||||
|
+ else if (line_strp
|
||||||
|
+ ? need_line_strp_update : need_strp_update) /* && phase == 1 */
|
||||||
|
{
|
||||||
|
struct stridxentry *entry;
|
||||||
|
size_t idx, new_idx;
|
||||||
|
+ struct strings *strings = (line_strp
|
||||||
|
+ ? &dso->debug_line_str : &dso->debug_str);
|
||||||
|
idx = do_read_32_relocated (ptr);
|
||||||
|
- entry = string_find_entry (&dso->strings, idx);
|
||||||
|
+ entry = string_find_entry (strings, idx);
|
||||||
|
new_idx = strent_offset (entry->entry);
|
||||||
|
do_write_32_relocated (ptr, new_idx);
|
||||||
|
}
|
||||||
|
@@ -1759,6 +1790,254 @@ read_dwarf4_line (DSO *dso, unsigned char *ptr, char *comp_dir,
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Called by read_dwarf5_line first for directories and then file
|
||||||
|
+ names as they both have the same format. */
|
||||||
|
+static bool
|
||||||
|
+read_dwarf5_line_entries (DSO *dso, unsigned char **ptrp,
|
||||||
|
+ struct line_table *table, int phase,
|
||||||
|
+ char ***dirs, int *ndir,
|
||||||
|
+ const char *entry_name)
|
||||||
|
+{
|
||||||
|
+ /* directory_entry_format_count */
|
||||||
|
+ /* file_name_entry_format_count */
|
||||||
|
+ unsigned format_count = read_8 (*ptrp);
|
||||||
|
+
|
||||||
|
+ unsigned char *formats = *ptrp;
|
||||||
|
+
|
||||||
|
+ /* directory_entry_format */
|
||||||
|
+ /* file_name_entry_format */
|
||||||
|
+ for (unsigned formati = 0; formati < format_count; ++formati)
|
||||||
|
+ {
|
||||||
|
+ read_uleb128 (*ptrp);
|
||||||
|
+ read_uleb128 (*ptrp);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* directories_count */
|
||||||
|
+ /* file_names_count */
|
||||||
|
+ unsigned entry_count = read_uleb128 (*ptrp);
|
||||||
|
+
|
||||||
|
+ bool collecting_dirs = dest_dir && phase == 0 && *dirs == NULL;
|
||||||
|
+ bool writing_files = dest_dir && phase == 0 && *dirs != NULL;
|
||||||
|
+ if (collecting_dirs)
|
||||||
|
+ {
|
||||||
|
+ *ndir = entry_count;
|
||||||
|
+ *dirs = malloc (entry_count * sizeof (char *));
|
||||||
|
+ if (*dirs == NULL)
|
||||||
|
+ error (1, errno, "%s: Could not allocate debug_line dirs",
|
||||||
|
+ dso->filename);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* directories */
|
||||||
|
+ /* file_names */
|
||||||
|
+ for (unsigned entryi = 0; entryi < entry_count; ++entryi)
|
||||||
|
+ {
|
||||||
|
+ char *dir = NULL;
|
||||||
|
+ char *file = NULL;;
|
||||||
|
+ unsigned char *format_ptr = formats;
|
||||||
|
+ for (unsigned formati = 0; formati < format_count; ++formati)
|
||||||
|
+ {
|
||||||
|
+ unsigned lnct = read_uleb128 (format_ptr);
|
||||||
|
+ unsigned form = read_uleb128 (format_ptr);
|
||||||
|
+ bool handled_form = false;
|
||||||
|
+ bool handled_strp = false;
|
||||||
|
+ bool line_strp = form == DW_FORM_line_strp;
|
||||||
|
+ if (lnct == DW_LNCT_path)
|
||||||
|
+ {
|
||||||
|
+ switch (form)
|
||||||
|
+ {
|
||||||
|
+ case DW_FORM_strp:
|
||||||
|
+ case DW_FORM_line_strp:
|
||||||
|
+ if (dest_dir && phase == 0)
|
||||||
|
+ {
|
||||||
|
+ size_t idx = do_read_32_relocated (*ptrp);
|
||||||
|
+ if (record_file_string_entry_idx (line_strp, dso, idx))
|
||||||
|
+ {
|
||||||
|
+ if (line_strp)
|
||||||
|
+ need_line_strp_update = true;
|
||||||
|
+ else
|
||||||
|
+ need_strp_update = true;
|
||||||
|
+ }
|
||||||
|
+ handled_strp = true;
|
||||||
|
+ if (collecting_dirs || writing_files)
|
||||||
|
+ {
|
||||||
|
+ debug_section *sec = &debug_sections[line_strp
|
||||||
|
+ ? DEBUG_LINE_STR : DEBUG_STR];
|
||||||
|
+ if (collecting_dirs)
|
||||||
|
+ dir = (char *)sec->data + idx;
|
||||||
|
+ if (writing_files)
|
||||||
|
+ file = (char *)sec->data + idx;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ error (0, 0, "%s: Unsupported "
|
||||||
|
+ ".debug_line %s %u path DW_FORM_0x%x",
|
||||||
|
+ dso->filename, entry_name, entryi, form);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (writing_files && lnct == DW_LNCT_directory_index)
|
||||||
|
+ {
|
||||||
|
+ int dirndx;
|
||||||
|
+ switch (form)
|
||||||
|
+ {
|
||||||
|
+ case DW_FORM_udata:
|
||||||
|
+ handled_form = true;
|
||||||
|
+ dirndx = read_uleb128 (*ptrp);
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_data1:
|
||||||
|
+ dirndx = **ptrp;
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_data2:
|
||||||
|
+ dirndx = do_read_16 (*ptrp);
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_data4:
|
||||||
|
+ dirndx = do_read_32 (*ptrp);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ error (0, 0, "%s: Unsupported "
|
||||||
|
+ ".debug_line %s %u dirndx DW_FORM_0x%x",
|
||||||
|
+ dso->filename, entry_name, entryi, form);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (dirndx > *ndir)
|
||||||
|
+ {
|
||||||
|
+ error (0, 0, "%s: Bad dir number %u in .debug_line %s",
|
||||||
|
+ dso->filename, entryi, entry_name);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ dir = (*dirs)[dirndx];
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ switch (form)
|
||||||
|
+ {
|
||||||
|
+ case DW_FORM_strp:
|
||||||
|
+ case DW_FORM_line_strp:
|
||||||
|
+ edit_strp (dso, line_strp, *ptrp, phase, handled_strp);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!handled_form)
|
||||||
|
+ {
|
||||||
|
+ switch (skip_form (dso, &form, ptrp))
|
||||||
|
+ {
|
||||||
|
+ case FORM_OK:
|
||||||
|
+ break;
|
||||||
|
+ case FORM_ERROR:
|
||||||
|
+ return false;
|
||||||
|
+ case FORM_INDIRECT:
|
||||||
|
+ error (0, 0, "%s: Unsupported "
|
||||||
|
+ ".debug_line %s %u DW_FORM_indirect",
|
||||||
|
+ dso->filename, entry_name, entryi);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (collecting_dirs)
|
||||||
|
+ (*dirs)[entryi] = dir;
|
||||||
|
+
|
||||||
|
+ if (writing_files)
|
||||||
|
+ {
|
||||||
|
+ char *comp_dir = (*dirs)[0];
|
||||||
|
+ size_t comp_dir_len = strlen(comp_dir);
|
||||||
|
+ size_t file_len = strlen (file);
|
||||||
|
+ size_t dir_len = strlen (dir);
|
||||||
|
+
|
||||||
|
+ char *s = malloc (comp_dir_len + 1 + file_len + 1 + dir_len + 1);
|
||||||
|
+ if (s == NULL)
|
||||||
|
+ {
|
||||||
|
+ error (0, ENOMEM, "%s: Reading file table", dso->filename);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ if (file[0] == '/')
|
||||||
|
+ {
|
||||||
|
+ memcpy (s, file, file_len + 1);
|
||||||
|
+ }
|
||||||
|
+ else if (dir[0] == '/')
|
||||||
|
+ {
|
||||||
|
+ memcpy (s, dir, dir_len);
|
||||||
|
+ s[dir_len] = '/';
|
||||||
|
+ memcpy (s + dir_len + 1, file, file_len + 1);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ char *p = s;
|
||||||
|
+ if (comp_dir_len != 0)
|
||||||
|
+ {
|
||||||
|
+ memcpy (s, comp_dir, comp_dir_len);
|
||||||
|
+ s[comp_dir_len] = '/';
|
||||||
|
+ p += comp_dir_len + 1;
|
||||||
|
+ }
|
||||||
|
+ memcpy (p, dir, dir_len);
|
||||||
|
+ p[dir_len] = '/';
|
||||||
|
+ memcpy (p + dir_len + 1, file, file_len + 1);
|
||||||
|
+ }
|
||||||
|
+ canonicalize_path (s, s);
|
||||||
|
+ if (list_file_fd != -1)
|
||||||
|
+ {
|
||||||
|
+ const char *p = NULL;
|
||||||
|
+ if (base_dir == NULL)
|
||||||
|
+ p = s;
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ p = skip_dir_prefix (s, base_dir);
|
||||||
|
+ if (p == NULL && dest_dir != NULL)
|
||||||
|
+ p = skip_dir_prefix (s, dest_dir);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (p)
|
||||||
|
+ {
|
||||||
|
+ size_t size = strlen (p) + 1;
|
||||||
|
+ while (size > 0)
|
||||||
|
+ {
|
||||||
|
+ ssize_t ret = write (list_file_fd, p, size);
|
||||||
|
+ if (ret == -1)
|
||||||
|
+ break;
|
||||||
|
+ size -= ret;
|
||||||
|
+ p += ret;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ free (s);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Part of read_dwarf2_line processing DWARF-5. */
|
||||||
|
+static bool
|
||||||
|
+read_dwarf5_line (DSO *dso, unsigned char *ptr, struct line_table *table,
|
||||||
|
+ int phase)
|
||||||
|
+{
|
||||||
|
+ char **dirs = NULL;
|
||||||
|
+ int ndir;
|
||||||
|
+ /* Skip header. */
|
||||||
|
+ ptr += (4 /* unit len */
|
||||||
|
+ + 2 /* version */
|
||||||
|
+ + (table->version < 5 ? 0 : 0
|
||||||
|
+ + 1 /* address_size */
|
||||||
|
+ + 1 /* segment_selector*/)
|
||||||
|
+ + 4 /* header len */
|
||||||
|
+ + 1 /* min instr len */
|
||||||
|
+ + (table->version >= 4) /* max op per instr, if version >= 4 */
|
||||||
|
+ + 1 /* default is stmt */
|
||||||
|
+ + 1 /* line base */
|
||||||
|
+ + 1 /* line range */
|
||||||
|
+ + 1 /* opcode base */
|
||||||
|
+ + table->opcode_base - 1); /* opcode len table */
|
||||||
|
+
|
||||||
|
+ bool retval = (read_dwarf5_line_entries (dso, &ptr, table, phase,
|
||||||
|
+ &dirs, &ndir, "directory")
|
||||||
|
+ && read_dwarf5_line_entries (dso, &ptr, table, phase,
|
||||||
|
+ &dirs, &ndir, "file name"));
|
||||||
|
+ free (dirs);
|
||||||
|
+ return retval;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Called during phase zero for each debug_line table referenced from
|
||||||
|
.debug_info. Outputs all source files seen and records any
|
||||||
|
adjustments needed in the debug_list data structures. Returns true
|
||||||
|
@@ -1778,6 +2057,9 @@ read_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir)
|
||||||
|
ptr = debug_sections[DEBUG_LINE].data + off;
|
||||||
|
ptr += (4 /* unit len */
|
||||||
|
+ 2 /* version */
|
||||||
|
+ + (table->version < 5 ? 0 : 0
|
||||||
|
+ + 1 /* address_size */
|
||||||
|
+ + 1 /* segment_selector*/)
|
||||||
|
+ 4 /* header len */
|
||||||
|
+ 1 /* min instr len */
|
||||||
|
+ (table->version >= 4) /* max op per instr, if version >= 4 */
|
||||||
|
@@ -1787,8 +2069,13 @@ read_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir)
|
||||||
|
+ 1 /* opcode base */
|
||||||
|
+ table->opcode_base - 1); /* opcode len table */
|
||||||
|
|
||||||
|
- if (! read_dwarf4_line (dso, ptr, comp_dir, table))
|
||||||
|
- return false;
|
||||||
|
+ /* DWARF version 5 line tables won't change size. But they might need
|
||||||
|
+ [line]strp recording/updates. Handle that part later. */
|
||||||
|
+ if (table->version < 5)
|
||||||
|
+ {
|
||||||
|
+ if (! read_dwarf4_line (dso, ptr, comp_dir, table))
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
dso->lines.debug_lines_len += 4 + table->unit_length + table->size_diff;
|
||||||
|
return table->replace_dirs || table->replace_files;
|
||||||
|
@@ -1807,20 +2094,22 @@ find_new_list_offs (struct debug_lines *lines, size_t idx)
|
||||||
|
return table->new_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Read DW_FORM_strp collecting compilation directory. */
|
||||||
|
+/* Read DW_FORM_strp or DW_FORM_line_strp collecting compilation directory. */
|
||||||
|
static void
|
||||||
|
-edit_attributes_str_comp_dir (DSO *dso, unsigned char **ptrp, int phase,
|
||||||
|
- char **comp_dirp, bool *handled_strpp)
|
||||||
|
+edit_attributes_str_comp_dir (bool line_strp, DSO *dso, unsigned char **ptrp,
|
||||||
|
+ int phase, char **comp_dirp, bool *handled_strpp)
|
||||||
|
{
|
||||||
|
const char *dir;
|
||||||
|
size_t idx = do_read_32_relocated (*ptrp);
|
||||||
|
/* In phase zero we collect the comp_dir. */
|
||||||
|
if (phase == 0)
|
||||||
|
{
|
||||||
|
- if (idx >= debug_sections[DEBUG_STR].size)
|
||||||
|
- error (1, 0, "%s: Bad string pointer index %zd for comp_dir",
|
||||||
|
- dso->filename, idx);
|
||||||
|
- dir = (char *) debug_sections[DEBUG_STR].data + idx;
|
||||||
|
+ debug_section *sec = &debug_sections[line_strp
|
||||||
|
+ ? DEBUG_LINE_STR : DEBUG_STR];
|
||||||
|
+ if (sec->data == NULL || idx >= sec->size)
|
||||||
|
+ error (1, 0, "%s: Bad string pointer index %zd for comp_dir (%s)",
|
||||||
|
+ dso->filename, idx, sec->name);
|
||||||
|
+ dir = (char *) sec->data + idx;
|
||||||
|
|
||||||
|
free (*comp_dirp);
|
||||||
|
*comp_dirp = strdup (dir);
|
||||||
|
@@ -1828,8 +2117,13 @@ edit_attributes_str_comp_dir (DSO *dso, unsigned char **ptrp, int phase,
|
||||||
|
|
||||||
|
if (dest_dir != NULL && phase == 0)
|
||||||
|
{
|
||||||
|
- if (record_file_string_entry_idx (&dso->strings, idx))
|
||||||
|
- need_strp_update = true;
|
||||||
|
+ if (record_file_string_entry_idx (line_strp, dso, idx))
|
||||||
|
+ {
|
||||||
|
+ if (line_strp)
|
||||||
|
+ need_line_strp_update = true;
|
||||||
|
+ else
|
||||||
|
+ need_strp_update = true;
|
||||||
|
+ }
|
||||||
|
*handled_strpp = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1937,17 +2231,24 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- else if (form == DW_FORM_strp &&
|
||||||
|
- debug_sections[DEBUG_STR].data)
|
||||||
|
- edit_attributes_str_comp_dir (dso, &ptr, phase, &comp_dir,
|
||||||
|
+ else if (form == DW_FORM_strp)
|
||||||
|
+ edit_attributes_str_comp_dir (false /* line_strp */, dso,
|
||||||
|
+ &ptr, phase, &comp_dir,
|
||||||
|
&handled_strp);
|
||||||
|
+ else if (form == DW_FORM_line_strp)
|
||||||
|
+ edit_attributes_str_comp_dir (true /* line_strp */, dso, &ptr,
|
||||||
|
+ phase, &comp_dir, &handled_strp);
|
||||||
|
}
|
||||||
|
else if ((t->tag == DW_TAG_compile_unit
|
||||||
|
|| t->tag == DW_TAG_partial_unit)
|
||||||
|
- && t->attr[i].attr == DW_AT_name
|
||||||
|
- && form == DW_FORM_strp
|
||||||
|
- && debug_sections[DEBUG_STR].data)
|
||||||
|
+ && ((form == DW_FORM_strp
|
||||||
|
+ && debug_sections[DEBUG_STR].data)
|
||||||
|
+ || (form == DW_FORM_line_strp
|
||||||
|
+ && debug_sections[DEBUG_LINE_STR].data))
|
||||||
|
+ && t->attr[i].attr == DW_AT_name)
|
||||||
|
{
|
||||||
|
+ bool line_strp = form == DW_FORM_line_strp;
|
||||||
|
+
|
||||||
|
/* DW_AT_name is the primary file for this compile
|
||||||
|
unit. If starting with / it is a full path name.
|
||||||
|
Note that we don't handle DW_FORM_string in this
|
||||||
|
@@ -1957,11 +2258,14 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
|
||||||
|
/* In phase zero we will look for a comp_dir to use. */
|
||||||
|
if (phase == 0)
|
||||||
|
{
|
||||||
|
- if (idx >= debug_sections[DEBUG_STR].size)
|
||||||
|
+ debug_section *sec = &debug_sections[line_strp
|
||||||
|
+ ? DEBUG_LINE_STR
|
||||||
|
+ : DEBUG_STR];
|
||||||
|
+ if (idx >= sec->size)
|
||||||
|
error (1, 0,
|
||||||
|
- "%s: Bad string pointer index %zd for unit name",
|
||||||
|
- dso->filename, idx);
|
||||||
|
- char *name = (char *) debug_sections[DEBUG_STR].data + idx;
|
||||||
|
+ "%s: Bad string pointer index %zd for unit name (%s)",
|
||||||
|
+ dso->filename, idx, sec->name);
|
||||||
|
+ char *name = (char *) sec->data + idx;
|
||||||
|
if (*name == '/' && comp_dir == NULL)
|
||||||
|
{
|
||||||
|
char *enddir = strrchr (name, '/');
|
||||||
|
@@ -1982,8 +2286,13 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
|
||||||
|
pass (1) stores it (the new index). */
|
||||||
|
if (dest_dir && phase == 0)
|
||||||
|
{
|
||||||
|
- if (record_file_string_entry_idx (&dso->strings, idx))
|
||||||
|
- need_strp_update = true;
|
||||||
|
+ if (record_file_string_entry_idx (line_strp, dso, idx))
|
||||||
|
+ {
|
||||||
|
+ if (line_strp)
|
||||||
|
+ need_line_strp_update = true;
|
||||||
|
+ else
|
||||||
|
+ need_strp_update = true;
|
||||||
|
+ }
|
||||||
|
handled_strp = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1991,7 +2300,10 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
|
||||||
|
switch (form)
|
||||||
|
{
|
||||||
|
case DW_FORM_strp:
|
||||||
|
- edit_strp (dso, ptr, phase, handled_strp);
|
||||||
|
+ edit_strp (dso, false /* line_strp */, ptr, phase, handled_strp);
|
||||||
|
+ break;
|
||||||
|
+ case DW_FORM_line_strp:
|
||||||
|
+ edit_strp (dso, true /* line_strp */, ptr, phase, handled_strp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2196,11 +2508,11 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
|
||||||
|
|
||||||
|
/* Rebuild .debug_str. */
|
||||||
|
static void
|
||||||
|
-edit_dwarf2_any_str (DSO *dso)
|
||||||
|
+edit_dwarf2_any_str (DSO *dso, struct strings *strings, debug_section *secp)
|
||||||
|
{
|
||||||
|
- Strtab *strtab = dso->strings.str_tab;
|
||||||
|
- Elf_Data *strdata = debug_sections[DEBUG_STR].elf_data;
|
||||||
|
- int strndx = debug_sections[DEBUG_STR].sec;
|
||||||
|
+ Strtab *strtab = strings->str_tab;
|
||||||
|
+ Elf_Data *strdata = secp->elf_data;
|
||||||
|
+ int strndx = secp->sec;
|
||||||
|
Elf_Scn *strscn = dso->scn[strndx];
|
||||||
|
|
||||||
|
/* Out with the old. */
|
||||||
|
@@ -2212,8 +2524,8 @@ edit_dwarf2_any_str (DSO *dso)
|
||||||
|
but the old ebl version will just abort on out of
|
||||||
|
memory... */
|
||||||
|
strtab_finalize (strtab, strdata);
|
||||||
|
- debug_sections[DEBUG_STR].size = strdata->d_size;
|
||||||
|
- dso->strings.str_buf = strdata->d_buf;
|
||||||
|
+ secp->size = strdata->d_size;
|
||||||
|
+ strings->str_buf = strdata->d_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
@@ -2359,12 +2671,14 @@ edit_dwarf2 (DSO *dso)
|
||||||
|
bool info_rel_updated = false;
|
||||||
|
bool types_rel_updated = false;
|
||||||
|
bool macro_rel_updated = false;
|
||||||
|
+ bool line_rel_updated = false;
|
||||||
|
|
||||||
|
for (phase = 0; phase < 2; phase++)
|
||||||
|
{
|
||||||
|
/* If we don't need to update anyhing, skip phase 1. */
|
||||||
|
if (phase == 1
|
||||||
|
&& !need_strp_update
|
||||||
|
+ && !need_line_strp_update
|
||||||
|
&& !need_string_replacement
|
||||||
|
&& !need_stmt_update)
|
||||||
|
break;
|
||||||
|
@@ -2582,15 +2896,14 @@ edit_dwarf2 (DSO *dso)
|
||||||
|
if (phase == 0)
|
||||||
|
{
|
||||||
|
size_t idx = read_32_relocated (ptr);
|
||||||
|
- record_existing_string_entry_idx (&dso->strings,
|
||||||
|
- idx);
|
||||||
|
+ record_existing_string_entry_idx (false, dso, idx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct stridxentry *entry;
|
||||||
|
size_t idx, new_idx;
|
||||||
|
idx = do_read_32_relocated (ptr);
|
||||||
|
- entry = string_find_entry (&dso->strings, idx);
|
||||||
|
+ entry = string_find_entry (&dso->debug_str, idx);
|
||||||
|
new_idx = strent_offset (entry->entry);
|
||||||
|
write_32_relocated (ptr, new_idx);
|
||||||
|
}
|
||||||
|
@@ -2610,24 +2923,50 @@ edit_dwarf2 (DSO *dso)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Same for the debug_str section. Make sure everything is
|
||||||
|
- in place for phase 1 updating of debug_info
|
||||||
|
+
|
||||||
|
+ /* Now handle all the DWARF5 line tables, they contain strp
|
||||||
|
+ and/or line_strp entries that need to be registered/rewritten. */
|
||||||
|
+ setup_relbuf(dso, &debug_sections[DEBUG_LINE], &reltype);
|
||||||
|
+ rel_updated = false;
|
||||||
|
+
|
||||||
|
+ /* edit_dwarf2_line will have set this up, unless there are no
|
||||||
|
+ moved/resized (DWARF4) lines. In which case we can just use
|
||||||
|
+ the original section data. new_idx will have been setup
|
||||||
|
+ correctly, even if it is the same as old_idx. */
|
||||||
|
+ unsigned char *line_buf = (unsigned char *)dso->lines.line_buf;
|
||||||
|
+ if (line_buf == NULL)
|
||||||
|
+ line_buf = debug_sections[DEBUG_LINE].data;
|
||||||
|
+ for (int ldx = 0; ldx < dso->lines.used; ldx++)
|
||||||
|
+ {
|
||||||
|
+ struct line_table *t = &dso->lines.table[ldx];
|
||||||
|
+ if (t->version >= 5)
|
||||||
|
+ read_dwarf5_line (dso, line_buf + t->new_idx, t, phase);
|
||||||
|
+ }
|
||||||
|
+ if (rel_updated)
|
||||||
|
+ line_rel_updated = true;
|
||||||
|
+
|
||||||
|
+ /* Same for the debug_str and debug_line_str sections.
|
||||||
|
+ Make sure everything is in place for phase 1 updating of debug_info
|
||||||
|
references. */
|
||||||
|
if (phase == 0 && need_strp_update)
|
||||||
|
- edit_dwarf2_any_str (dso);
|
||||||
|
-
|
||||||
|
+ edit_dwarf2_any_str (dso, &dso->debug_str,
|
||||||
|
+ &debug_sections[DEBUG_STR]);
|
||||||
|
+ if (phase == 0 && need_line_strp_update)
|
||||||
|
+ edit_dwarf2_any_str (dso, &dso->debug_line_str,
|
||||||
|
+ &debug_sections[DEBUG_LINE_STR]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* After phase 1 we might have rewritten the debug_info with
|
||||||
|
new strp, strings and/or linep offsets. */
|
||||||
|
- if (need_strp_update || need_string_replacement || need_stmt_update) {
|
||||||
|
+ if (need_strp_update || need_line_strp_update
|
||||||
|
+ || need_string_replacement || need_stmt_update) {
|
||||||
|
dirty_section (DEBUG_INFO);
|
||||||
|
if (debug_sections[DEBUG_TYPES].data != NULL)
|
||||||
|
dirty_section (DEBUG_TYPES);
|
||||||
|
}
|
||||||
|
if (need_strp_update || need_stmt_update)
|
||||||
|
dirty_section (DEBUG_MACRO);
|
||||||
|
- if (need_stmt_update)
|
||||||
|
+ if (need_stmt_update || need_line_strp_update)
|
||||||
|
dirty_section (DEBUG_LINE);
|
||||||
|
|
||||||
|
/* Update any relocations addends we might have touched. */
|
||||||
|
@@ -2653,6 +2992,9 @@ edit_dwarf2 (DSO *dso)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (line_rel_updated)
|
||||||
|
+ update_rela_data (dso, &debug_sections[DEBUG_LINE]);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2745,7 +3087,8 @@ fdopen_dso (int fd, const char *name)
|
||||||
|
}
|
||||||
|
|
||||||
|
dso->filename = (const char *) strdup (name);
|
||||||
|
- setup_strings (&dso->strings);
|
||||||
|
+ setup_strings (&dso->debug_str);
|
||||||
|
+ setup_strings (&dso->debug_line_str);
|
||||||
|
setup_lines (&dso->lines);
|
||||||
|
return dso;
|
||||||
|
|
||||||
|
@@ -2753,7 +3096,8 @@ error_out:
|
||||||
|
if (dso)
|
||||||
|
{
|
||||||
|
free ((char *) dso->filename);
|
||||||
|
- destroy_strings (&dso->strings);
|
||||||
|
+ destroy_strings (&dso->debug_str);
|
||||||
|
+ destroy_strings (&dso->debug_line_str);
|
||||||
|
destroy_lines (&dso->lines);
|
||||||
|
free (dso);
|
||||||
|
}
|
||||||
|
@@ -3034,7 +3378,9 @@ main (int argc, char *argv[])
|
||||||
|
in elfutils before 0.169 we will have to update and write out all
|
||||||
|
section data if any data has changed (when ELF_F_LAYOUT was
|
||||||
|
set). https://sourceware.org/bugzilla/show_bug.cgi?id=21199 */
|
||||||
|
- bool need_update = need_strp_update || need_stmt_update;
|
||||||
|
+ bool need_update = (need_strp_update
|
||||||
|
+ || need_line_strp_update
|
||||||
|
+ || need_stmt_update);
|
||||||
|
|
||||||
|
#if !_ELFUTILS_PREREQ (0, 169)
|
||||||
|
/* string replacements or build_id updates don't change section size. */
|
||||||
|
@@ -3106,10 +3452,12 @@ main (int argc, char *argv[])
|
||||||
|
GElf_Xword sec_size = shdr->sh_size;
|
||||||
|
|
||||||
|
/* We might have changed the size (and content) of the
|
||||||
|
- debug_str or debug_line section. */
|
||||||
|
+ debug_str, debug_line_str or debug_line section. */
|
||||||
|
size_t secnum = elf_ndxscn (scn);
|
||||||
|
if (secnum == debug_sections[DEBUG_STR].sec)
|
||||||
|
sec_size = debug_sections[DEBUG_STR].size;
|
||||||
|
+ if (secnum == debug_sections[DEBUG_LINE_STR].sec)
|
||||||
|
+ sec_size = debug_sections[DEBUG_LINE_STR].size;
|
||||||
|
if (secnum == debug_sections[DEBUG_LINE].sec)
|
||||||
|
sec_size = debug_sections[DEBUG_LINE].size;
|
||||||
|
|
||||||
|
@@ -3179,7 +3527,8 @@ main (int argc, char *argv[])
|
||||||
|
chmod (file, stat_buf.st_mode);
|
||||||
|
|
||||||
|
free ((char *) dso->filename);
|
||||||
|
- destroy_strings (&dso->strings);
|
||||||
|
+ destroy_strings (&dso->debug_str);
|
||||||
|
+ destroy_strings (&dso->debug_line_str);
|
||||||
|
destroy_lines (&dso->lines);
|
||||||
|
free (dso);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.18.4
|
||||||
|
|
@ -0,0 +1,18 @@
|
|||||||
|
diff --git a/rpm2cpio.c b/rpm2cpio.c
|
||||||
|
index 89ebdfa..ae999ff 100644
|
||||||
|
--- a/rpm2cpio.c
|
||||||
|
+++ b/rpm2cpio.c
|
||||||
|
@@ -84,7 +84,12 @@ int main(int argc, char *argv[])
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
- rc = (ufdCopy(gzdi, fdo) == payload_size) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
+ /*
|
||||||
|
+ * XXX HACK for #1142949: should be equality test, but archive size
|
||||||
|
+ * short by cpio trailer size in packages built with rpm 4.12.0
|
||||||
|
+ * and its pre-releases.
|
||||||
|
+ */
|
||||||
|
+ rc = (ufdCopy(gzdi, fdo) >= payload_size) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
|
||||||
|
Fclose(fdo);
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
From fe274b8f965582fdf97e6c46f90b9e7c124b0b8b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Festi <ffesti@redhat.com>
|
||||||
|
Date: Fri, 16 Dec 2022 15:50:12 +0100
|
||||||
|
Subject: [PATCH] rpm2archive: Don't print usage on no arguments
|
||||||
|
|
||||||
|
given as we want to default to reading from stdin and writing to stdout in
|
||||||
|
that case.
|
||||||
|
---
|
||||||
|
rpm2archive.c | 4 ----
|
||||||
|
1 file changed, 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/rpm2archive.c b/rpm2archive.c
|
||||||
|
index 09da8d16b..53f047f58 100644
|
||||||
|
--- a/rpm2archive.c
|
||||||
|
+++ b/rpm2archive.c
|
||||||
|
@@ -241,10 +241,6 @@ int main(int argc, const char *argv[])
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- if (argc < 2 || poptGetNextOpt(optCon) == 0) {
|
||||||
|
- poptPrintUsage(optCon, stderr, 0);
|
||||||
|
- exit(EXIT_FAILURE);
|
||||||
|
- }
|
||||||
|
|
||||||
|
rpmts ts = rpmtsCreate();
|
||||||
|
rpmVSFlags vsflags = 0;
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From 8f416b275a365426b07c75adfc017e0b18a85450 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Festi <ffesti@redhat.com>
|
||||||
|
Date: Fri, 16 Dec 2022 15:45:20 +0100
|
||||||
|
Subject: [PATCH] rpm2archive: Properly parse popt options
|
||||||
|
|
||||||
|
and issue an error message for unknown options. Before unknown options
|
||||||
|
could mess up the argument parsing leading to reading and writing from
|
||||||
|
stdin/stdout.
|
||||||
|
|
||||||
|
Thanks to Eva Mrakova and the Red Hat QE team for spotting this!
|
||||||
|
---
|
||||||
|
rpm2archive.c | 8 ++++++++
|
||||||
|
1 file changed, 8 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/rpm2archive.c b/rpm2archive.c
|
||||||
|
index de1a17d2b..09da8d16b 100644
|
||||||
|
--- a/rpm2archive.c
|
||||||
|
+++ b/rpm2archive.c
|
||||||
|
@@ -233,6 +233,14 @@ int main(int argc, const char *argv[])
|
||||||
|
|
||||||
|
optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
|
||||||
|
poptSetOtherOptionHelp(optCon, "[OPTIONS]* <FILES>");
|
||||||
|
+ while ((rc = poptGetNextOpt(optCon)) != -1) {
|
||||||
|
+ if (rc < 0) {
|
||||||
|
+ fprintf(stderr, "%s: %s\n",
|
||||||
|
+ poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
|
||||||
|
+ poptStrerror(rc));
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
if (argc < 2 || poptGetNextOpt(optCon) == 0) {
|
||||||
|
poptPrintUsage(optCon, stderr, 0);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,15 @@
|
|||||||
|
diff -up rpm-4.9.1.1/macros.in.jx rpm-4.9.1.1/macros.in
|
||||||
|
--- rpm-4.9.1.1/macros.in.jx 2011-08-03 16:19:05.000000000 -0400
|
||||||
|
+++ rpm-4.9.1.1/macros.in 2011-08-08 09:41:52.981064316 -0400
|
||||||
|
@@ -674,9 +674,10 @@ print (t)\
|
||||||
|
RPM_BUILD_DIR=\"%{u2p:%{_builddir}}\"\
|
||||||
|
RPM_OPT_FLAGS=\"%{optflags}\"\
|
||||||
|
+ RPM_LD_FLAGS=\"%{?build_ldflags}\"\
|
||||||
|
RPM_ARCH=\"%{_arch}\"\
|
||||||
|
RPM_OS=\"%{_os}\"\
|
||||||
|
RPM_BUILD_NCPUS=\"%{_smp_build_ncpus}\"\
|
||||||
|
- export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS RPM_BUILD_NCPUS\
|
||||||
|
+ export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_LD_FLAGS RPM_ARCH RPM_OS RPM_BUILD_NCPUS RPM_LD_FLAGS\
|
||||||
|
RPM_DOC_DIR=\"%{_docdir}\"\
|
||||||
|
export RPM_DOC_DIR\
|
||||||
|
RPM_PACKAGE_NAME=\"%{NAME}\"\
|
@ -0,0 +1,12 @@
|
|||||||
|
diff -up rpm-4.11.1-rc1/macros.in.siteconfig rpm-4.11.1-rc1/macros.in
|
||||||
|
--- rpm-4.11.1-rc1/macros.in.siteconfig 2013-06-07 13:19:21.000000000 +0300
|
||||||
|
+++ rpm-4.11.1-rc1/macros.in 2013-06-11 15:06:59.525747503 +0300
|
||||||
|
@@ -647,6 +647,8 @@ package or when debugging this package.\
|
||||||
|
export CLASSPATH}\
|
||||||
|
PKG_CONFIG_PATH=\"${PKG_CONFIG_PATH}:%{_libdir}/pkgconfig:%{_datadir}/pkgconfig\"\
|
||||||
|
export PKG_CONFIG_PATH\
|
||||||
|
+ CONFIG_SITE=${CONFIG_SITE:-NONE}\
|
||||||
|
+ export CONFIG_SITE\
|
||||||
|
\
|
||||||
|
%{verbose:set -x}\
|
||||||
|
umask 022\
|
@ -0,0 +1,36 @@
|
|||||||
|
From 7f0b7217fb1c20ec6ce0c0e0bfee0349f27a2511 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Panu Matilainen <pmatilai@redhat.com>
|
||||||
|
Date: Fri, 8 Jan 2021 13:59:59 +0200
|
||||||
|
Subject: [PATCH] Ensure ELF files get stripped when debuginfo is disabled
|
||||||
|
|
||||||
|
Depending on libmagic version, PIE executables can be reported as
|
||||||
|
"shared object" avoiding the strip. And so will any libraries because
|
||||||
|
we're explicitly skipping them for whatever historical reason - perhaps
|
||||||
|
because there's a separate script for stripping the libraries, but that
|
||||||
|
has been never enabled in rpm, and relying on "file" strings to do this
|
||||||
|
is hopelessly unreliable.
|
||||||
|
|
||||||
|
Also drop file permissions checks: making shared libraries executable
|
||||||
|
just to have them stripped is not sensical, especially in the light of
|
||||||
|
commit 80818e4f902ba3cf85e4cfcd8a7a4c71c601f3cf
|
||||||
|
|
||||||
|
Reported once upon time as RhBug:988812 and later RhBug:1634084
|
||||||
|
---
|
||||||
|
scripts/brp-strip | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/scripts/brp-strip b/scripts/brp-strip
|
||||||
|
index c3484fe3c..35fbb593a 100755
|
||||||
|
--- a/scripts/brp-strip
|
||||||
|
+++ b/scripts/brp-strip
|
||||||
|
@@ -13,5 +13,5 @@ Darwin*) exit 0 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Strip ELF binaries
|
||||||
|
-find "$RPM_BUILD_ROOT" -type f \( -perm -0100 -or -perm -0010 -or -perm -0001 \) \! -regex "${RPM_BUILD_ROOT}/*usr/lib/debug.*" -print0 | \
|
||||||
|
- xargs -0 -r -P$NCPUS -n32 sh -c "file \"\$@\" | grep -v ' shared object,' | sed -n -e 's/^\(.*\):[ ]*ELF.*, not stripped.*/\1/p' | xargs -I\{\} $STRIP -g \{\}" ARG0
|
||||||
|
+find "$RPM_BUILD_ROOT" -type f \! -regex "${RPM_BUILD_ROOT}/*usr/lib/debug.*" -print0 | \
|
||||||
|
+ xargs -0 -r -P$NCPUS -n32 sh -c "file \"\$@\" | sed -n -e 's/^\(.*\):[ ]*ELF.*, not stripped.*/\1/p' | xargs -I\{\} $STRIP -g \{\}" ARG0
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,57 @@
|
|||||||
|
diff --git a/scripts/rpm2cpio.sh b/scripts/rpm2cpio.sh
|
||||||
|
index 4531271cc..74aeed851 100755
|
||||||
|
--- a/scripts/rpm2cpio.sh
|
||||||
|
+++ b/scripts/rpm2cpio.sh
|
||||||
|
@@ -15,13 +15,23 @@ _dd() {
|
||||||
|
}
|
||||||
|
|
||||||
|
calcsize() {
|
||||||
|
+
|
||||||
|
+ case "$(_dd $1 bs=4 count=1 | tr -d '\0')" in
|
||||||
|
+ "$(printf '\216\255\350')"*) ;; # '\x8e\xad\xe8'
|
||||||
|
+ *) fatal "File doesn't look like rpm: $pkg" ;;
|
||||||
|
+ esac
|
||||||
|
+
|
||||||
|
offset=$(($1 + 8))
|
||||||
|
|
||||||
|
local i b b0 b1 b2 b3 b4 b5 b6 b7
|
||||||
|
|
||||||
|
i=0
|
||||||
|
while [ $i -lt 8 ]; do
|
||||||
|
- b="$(_dd $(($offset + $i)) bs=1 count=1)"
|
||||||
|
+ # add . to not loose \n
|
||||||
|
+ # strip \0 as it gets dropped with warning otherwise
|
||||||
|
+ b="$(_dd $(($offset + $i)) bs=1 count=1 | tr -d '\0' ; echo .)"
|
||||||
|
+ b=${b%.} # strip . again
|
||||||
|
+
|
||||||
|
[ -z "$b" ] &&
|
||||||
|
b="0" ||
|
||||||
|
b="$(exec printf '%u\n' "'$b")"
|
||||||
|
@@ -33,7 +43,7 @@ calcsize() {
|
||||||
|
offset=$(($offset + $rsize))
|
||||||
|
}
|
||||||
|
|
||||||
|
-case "$(_dd 0 bs=8 count=1)" in
|
||||||
|
+case "$(_dd 0 bs=4 count=1 | tr -d '\0')" in
|
||||||
|
"$(printf '\355\253\356\333')"*) ;; # '\xed\xab\xee\xdb'
|
||||||
|
*) fatal "File doesn't look like rpm: $pkg" ;;
|
||||||
|
esac
|
||||||
|
@@ -44,11 +54,11 @@ sigsize=$rsize
|
||||||
|
calcsize $(($offset + (8 - ($sigsize % 8)) % 8))
|
||||||
|
hdrsize=$rsize
|
||||||
|
|
||||||
|
-case "$(_dd $offset bs=3 count=1)" in
|
||||||
|
- "$(printf '\102\132')"*) _dd $offset | bunzip2 ;; # '\x42\x5a'
|
||||||
|
- "$(printf '\037\213')"*) _dd $offset | gunzip ;; # '\x1f\x8b'
|
||||||
|
- "$(printf '\375\067')"*) _dd $offset | xzcat ;; # '\xfd\x37'
|
||||||
|
- "$(printf '\135\000')"*) _dd $offset | unlzma ;; # '\x5d\x00'
|
||||||
|
- "$(printf '\050\265')"*) _dd $offset | unzstd ;; # '\x28\xb5'
|
||||||
|
- *) fatal "Unrecognized rpm file: $pkg" ;;
|
||||||
|
+case "$(_dd $offset bs=2 count=1 | tr -d '\0')" in
|
||||||
|
+ "$(printf '\102\132')") _dd $offset | bunzip2 ;; # '\x42\x5a'
|
||||||
|
+ "$(printf '\037\213')") _dd $offset | gunzip ;; # '\x1f\x8b'
|
||||||
|
+ "$(printf '\375\067')") _dd $offset | xzcat ;; # '\xfd\x37'
|
||||||
|
+ "$(printf '\135')") _dd $offset | unlzma ;; # '\x5d\x00'
|
||||||
|
+ "$(printf '\050\265')") _dd $offset | unzstd ;; # '\x28\xb5'
|
||||||
|
+ *) fatal "Unrecognized payload compression format in rpm file: $pkg" ;;
|
||||||
|
esac
|
@ -0,0 +1,40 @@
|
|||||||
|
From 35739c2a2298e61caacb45157706bf342ffcd20e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Festi <ffesti@redhat.com>
|
||||||
|
Date: Tue, 27 Apr 2021 10:09:41 +0200
|
||||||
|
Subject: [PATCH] find-lang.sh: Support long languages names for QT
|
||||||
|
|
||||||
|
Most language abbreviations are just two characters but some are longer.
|
||||||
|
Allow an arbiraty number of character instead of exactly two in the names
|
||||||
|
of .qm files (QT translations). This brings the handling of .qm files in
|
||||||
|
line with all other file types.
|
||||||
|
|
||||||
|
Resolves: #1642
|
||||||
|
---
|
||||||
|
scripts/find-lang.sh | 14 +++++++-------
|
||||||
|
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/scripts/find-lang.sh b/scripts/find-lang.sh
|
||||||
|
index f2aa7d8951..b97210b117 100755
|
||||||
|
--- a/scripts/find-lang.sh
|
||||||
|
+++ b/scripts/find-lang.sh
|
||||||
|
@@ -249,13 +249,13 @@ s:%lang(C) ::
|
||||||
|
|
||||||
|
find "$TOP_DIR" -type f -o -type l|sed '
|
||||||
|
s:'"$TOP_DIR"'::
|
||||||
|
-'"$NO_ALL_NAME$QT"'s:\(.*/'"$NAME"'_\([a-zA-Z]\{2\}\([_@].*\)\?\)\.qm$\):%lang(\2) \1:
|
||||||
|
-'"$ALL_NAME$QT"'s:^\([^%].*/\([a-zA-Z]\{2\}[_@].*\)\.qm$\):%lang(\2) \1:
|
||||||
|
-'"$ALL_NAME$QT"'s:^\([^%].*/\([a-zA-Z]\{2\}\)\.qm$\):%lang(\2) \1:
|
||||||
|
-'"$ALL_NAME$QT"'s:^\([^%].*/[^/_]\+_\([a-zA-Z]\{2\}[_@].*\)\.qm$\):%lang(\2) \1:
|
||||||
|
-'"$ALL_NAME$QT"'s:^\([^%].*/[^/_]\+_\([a-zA-Z]\{2\}\)\.qm$\):%lang(\2) \1:
|
||||||
|
-'"$ALL_NAME$QT"'s:^\([^%].*/[^/]\+_\([a-zA-Z]\{2\}[_@].*\)\.qm$\):%lang(\2) \1:
|
||||||
|
-'"$ALL_NAME$QT"'s:^\([^%].*/[^/]\+_\([a-zA-Z]\{2\}\)\.qm$\):%lang(\2) \1:
|
||||||
|
+'"$NO_ALL_NAME$QT"'s:\(.*/'"$NAME"'_\([a-zA-Z]\+\([_@].*\)\?\)\.qm$\):%lang(\2) \1:
|
||||||
|
+'"$ALL_NAME$QT"'s:^\([^%].*/\([a-zA-Z]\+[_@].*\)\.qm$\):%lang(\2) \1:
|
||||||
|
+'"$ALL_NAME$QT"'s:^\([^%].*/\([a-zA-Z]\+\)\.qm$\):%lang(\2) \1:
|
||||||
|
+'"$ALL_NAME$QT"'s:^\([^%].*/[^/_]\+_\([a-zA-Z]\+[_@].*\)\.qm$\):%lang(\2) \1:
|
||||||
|
+'"$ALL_NAME$QT"'s:^\([^%].*/[^/_]\+_\([a-zA-Z]\+\)\.qm$\):%lang(\2) \1:
|
||||||
|
+'"$ALL_NAME$QT"'s:^\([^%].*/[^/]\+_\([a-zA-Z]\+[_@].*\)\.qm$\):%lang(\2) \1:
|
||||||
|
+'"$ALL_NAME$QT"'s:^\([^%].*/[^/]\+_\([a-zA-Z]\+\)\.qm$\):%lang(\2) \1:
|
||||||
|
s:^[^%].*::
|
||||||
|
s:%lang(C) ::
|
||||||
|
/^$/d' >> $MO_NAME
|
@ -0,0 +1,334 @@
|
|||||||
|
commit 39595ccee321497dc3b08c7cab8a10304345429c
|
||||||
|
Author: Radovan Sroka <rsroka@redhat.com>
|
||||||
|
Date: Tue Oct 27 16:18:04 2020 +0100
|
||||||
|
|
||||||
|
Added fapolicyd rpm plugin
|
||||||
|
|
||||||
|
Fapolicyd (File Access Policy Daemon) implements application whitelisting
|
||||||
|
to decide file access rights. Applications that are known via a reputation
|
||||||
|
source are allowed access while unknown applications are not.
|
||||||
|
|
||||||
|
The rpm plugin allows us to use rpm database as a source of trust.
|
||||||
|
We used dnf plugin since the beggining but it only provides notification
|
||||||
|
when transaction ends. With "integrity checking" requirement we need
|
||||||
|
a continual addition of files which are installed during the system
|
||||||
|
update. With fapolicyd rpm plugin we can allow using of recently
|
||||||
|
added/updated files in scriptlets during rpm transaction.
|
||||||
|
|
||||||
|
The fapolicyd plugin gathers metadata of currently installed files.
|
||||||
|
It sends the information about files and about ongoing rpm transaction
|
||||||
|
to the fapolicyd daemon. The information is written to Linux pipe which
|
||||||
|
is placed in /var/run/fapolicyd/fapolicyd.fifo.
|
||||||
|
|
||||||
|
The data format is "%s %lu %64s\n". [path, size, sha256]
|
||||||
|
|
||||||
|
The fapolicyd rpm plugin can be enabled with "--with-fapolicyd"
|
||||||
|
configure option.
|
||||||
|
|
||||||
|
Related PRs:
|
||||||
|
https://github.com/linux-application-whitelisting/fapolicyd/pull/105
|
||||||
|
https://github.com/linux-application-whitelisting/fapolicyd/pull/106
|
||||||
|
|
||||||
|
Signed-off-by: Radovan Sroka <rsroka@redhat.com>
|
||||||
|
|
||||||
|
Backported into 4.16.1.3, together with commit
|
||||||
|
6d61b7118adcc14631b7ee5163a481472af940b8 (covscan fix)
|
||||||
|
|
||||||
|
diff -up rpm-4.16.1.3/configure.ac.orig rpm-4.16.1.3/configure.ac
|
||||||
|
--- rpm-4.16.1.3/configure.ac.orig 2021-03-22 11:05:07.311635968 +0100
|
||||||
|
+++ rpm-4.16.1.3/configure.ac 2021-07-22 16:18:29.352006782 +0200
|
||||||
|
@@ -891,6 +891,14 @@ AS_IF([test "$enable_plugins" != no],[
|
||||||
|
AM_CONDITIONAL(IMA, [test "x$ac_cv_func_lsetxattr" = xyes])
|
||||||
|
|
||||||
|
#=================
|
||||||
|
+# Check for fapolicyd support
|
||||||
|
+AC_ARG_WITH(fapolicyd,
|
||||||
|
+AS_HELP_STRING([--with-fapolicyd],[build with File Access Policy Daemon support]),
|
||||||
|
+with_fapolicyd=$withval,
|
||||||
|
+with_fapolicyd=auto)
|
||||||
|
+AM_CONDITIONAL(FAPOLICYD,[test "$with_fapolicyd" = yes])
|
||||||
|
+
|
||||||
|
+#=================
|
||||||
|
# Check for audit library.
|
||||||
|
AC_ARG_WITH(audit,
|
||||||
|
AS_HELP_STRING([--with-audit],[Linux audit plugin]),
|
||||||
|
diff -up rpm-4.16.1.3/doc/Makefile.am.orig rpm-4.16.1.3/doc/Makefile.am
|
||||||
|
--- rpm-4.16.1.3/doc/Makefile.am.orig 2020-06-23 14:13:01.895628382 +0200
|
||||||
|
+++ rpm-4.16.1.3/doc/Makefile.am 2021-07-22 16:18:29.352006782 +0200
|
||||||
|
@@ -25,6 +25,9 @@ endif
|
||||||
|
if IMA
|
||||||
|
man_man8_DATA += rpm-plugin-ima.8
|
||||||
|
endif
|
||||||
|
+if FAPOLICYD
|
||||||
|
+man_man8_DATA += rpm-plugin-fapolicyd.8
|
||||||
|
+endif
|
||||||
|
if SELINUX
|
||||||
|
man_man8_DATA += rpm-plugin-selinux.8
|
||||||
|
endif
|
||||||
|
@@ -37,6 +40,8 @@ endif
|
||||||
|
EXTRA_DIST += rpm-plugins.8 rpm-plugin-prioreset.8 rpm-plugin-syslog.8
|
||||||
|
EXTRA_DIST += rpm-plugin-audit.8 rpm-plugin-systemd-inhibit.8
|
||||||
|
EXTRA_DIST += rpm-plugin-ima.8 rpm-plugin-selinux.8 rpm2archive.8
|
||||||
|
+EXTRA_DIST += rpm-plugin-fapolicyd.8
|
||||||
|
+
|
||||||
|
|
||||||
|
man_fr_man8dir = $(mandir)/fr/man8
|
||||||
|
man_fr_man8_DATA = fr/rpm.8
|
||||||
|
diff -up rpm-4.16.1.3/doc/rpm-plugin-fapolicyd.8.orig rpm-4.16.1.3/doc/rpm-plugin-fapolicyd.8
|
||||||
|
--- rpm-4.16.1.3/doc/rpm-plugin-fapolicyd.8.orig 2021-07-22 16:18:29.353006800 +0200
|
||||||
|
+++ rpm-4.16.1.3/doc/rpm-plugin-fapolicyd.8 2021-07-22 16:18:29.353006800 +0200
|
||||||
|
@@ -0,0 +1,21 @@
|
||||||
|
+'\" t
|
||||||
|
+.TH "RPM-FAPOLICYD" "8" "28 Jan 2021" "Red Hat, Inc."
|
||||||
|
+.SH NAME
|
||||||
|
+rpm-plugin-fapolicyd \- Fapolicyd plugin for the RPM Package Manager
|
||||||
|
+
|
||||||
|
+.SH Description
|
||||||
|
+
|
||||||
|
+The plugin gathers metadata of currently installed files. It sends the
|
||||||
|
+information about files and about ongoing rpm transaction to the fapolicyd daemon.
|
||||||
|
+The information is written to Linux pipe which is placed in
|
||||||
|
+/var/run/fapolicyd/fapolicyd.fifo.
|
||||||
|
+
|
||||||
|
+.SH Configuration
|
||||||
|
+
|
||||||
|
+There are currently no options for this plugin in particular. See
|
||||||
|
+.BR rpm-plugins (8)
|
||||||
|
+on how to control plugins in general.
|
||||||
|
+
|
||||||
|
+.SH SEE ALSO
|
||||||
|
+.IR fapolicyd (8)
|
||||||
|
+.IR rpm-plugins (8)
|
||||||
|
diff -up rpm-4.16.1.3/macros.in.orig rpm-4.16.1.3/macros.in
|
||||||
|
--- rpm-4.16.1.3/macros.in.orig 2021-07-22 16:18:20.525844141 +0200
|
||||||
|
+++ rpm-4.16.1.3/macros.in 2021-07-22 16:19:36.196238525 +0200
|
||||||
|
@@ -1208,6 +1208,7 @@ package or when debugging this package.\
|
||||||
|
%__transaction_selinux %{__plugindir}/selinux.so
|
||||||
|
%__transaction_syslog %{__plugindir}/syslog.so
|
||||||
|
%__transaction_ima %{__plugindir}/ima.so
|
||||||
|
+%__transaction_fapolicyd %{__plugindir}/fapolicyd.so
|
||||||
|
%__transaction_prioreset %{__plugindir}/prioreset.so
|
||||||
|
%__transaction_audit %{__plugindir}/audit.so
|
||||||
|
|
||||||
|
diff -up rpm-4.16.1.3/Makefile.am.orig rpm-4.16.1.3/Makefile.am
|
||||||
|
--- rpm-4.16.1.3/Makefile.am.orig 2021-07-22 16:18:29.350006745 +0200
|
||||||
|
+++ rpm-4.16.1.3/Makefile.am 2021-07-22 16:19:18.223907346 +0200
|
||||||
|
@@ -14,6 +14,7 @@ DISTCHECK_CONFIGURE_FLAGS = \
|
||||||
|
--with-audit \
|
||||||
|
--with-selinux \
|
||||||
|
--with-imaevm \
|
||||||
|
+ --with-fapolicyd \
|
||||||
|
--disable-dependency-tracking
|
||||||
|
|
||||||
|
include $(top_srcdir)/rpm.am
|
||||||
|
diff -up rpm-4.16.1.3/plugins/fapolicyd.c.orig rpm-4.16.1.3/plugins/fapolicyd.c
|
||||||
|
--- rpm-4.16.1.3/plugins/fapolicyd.c.orig 2021-07-22 16:18:29.356006855 +0200
|
||||||
|
+++ rpm-4.16.1.3/plugins/fapolicyd.c 2021-07-22 16:18:35.380117862 +0200
|
||||||
|
@@ -0,0 +1,191 @@
|
||||||
|
+#include "system.h"
|
||||||
|
+
|
||||||
|
+#include <rpm/rpmts.h>
|
||||||
|
+#include <rpm/rpmlog.h>
|
||||||
|
+#include "lib/rpmplugin.h"
|
||||||
|
+
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+
|
||||||
|
+struct fapolicyd_data {
|
||||||
|
+ int fd;
|
||||||
|
+ long changed_files;
|
||||||
|
+ const char * fifo_path;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static struct fapolicyd_data fapolicyd_state = {
|
||||||
|
+ .fd = -1,
|
||||||
|
+ .changed_files = 0,
|
||||||
|
+ .fifo_path = "/run/fapolicyd/fapolicyd.fifo",
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static rpmRC open_fifo(struct fapolicyd_data* state)
|
||||||
|
+{
|
||||||
|
+ int fd = -1;
|
||||||
|
+ struct stat s;
|
||||||
|
+
|
||||||
|
+ fd = open(state->fifo_path, O_RDWR);
|
||||||
|
+ if (fd == -1) {
|
||||||
|
+ rpmlog(RPMLOG_DEBUG, "Open: %s -> %s\n", state->fifo_path, strerror(errno));
|
||||||
|
+ goto bad;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (stat(state->fifo_path, &s) == -1) {
|
||||||
|
+ rpmlog(RPMLOG_DEBUG, "Stat: %s -> %s\n", state->fifo_path, strerror(errno));
|
||||||
|
+ goto bad;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!S_ISFIFO(s.st_mode)) {
|
||||||
|
+ rpmlog(RPMLOG_DEBUG, "File: %s exists but it is not a pipe!\n", state->fifo_path);
|
||||||
|
+ goto bad;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* keep only file's permition bits */
|
||||||
|
+ mode_t mode = s.st_mode & ~S_IFMT;
|
||||||
|
+
|
||||||
|
+ /* we require pipe to have 0660 permission */
|
||||||
|
+ if (mode != 0660) {
|
||||||
|
+ rpmlog(RPMLOG_ERR, "File: %s has %o instead of 0660 \n",
|
||||||
|
+ state->fifo_path,
|
||||||
|
+ mode );
|
||||||
|
+ goto bad;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ state->fd = fd;
|
||||||
|
+ /* considering success */
|
||||||
|
+ return RPMRC_OK;
|
||||||
|
+
|
||||||
|
+ bad:
|
||||||
|
+ if (fd >= 0)
|
||||||
|
+ close(fd);
|
||||||
|
+ return RPMRC_FAIL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static rpmRC write_fifo(struct fapolicyd_data* state, const char * str)
|
||||||
|
+{
|
||||||
|
+ ssize_t len = strlen(str);
|
||||||
|
+ ssize_t written = 0;
|
||||||
|
+ ssize_t n = 0;
|
||||||
|
+
|
||||||
|
+ while (written < len) {
|
||||||
|
+ if ((n = write(state->fd, str + written, len - written)) < 0) {
|
||||||
|
+ if (errno == EINTR || errno == EAGAIN)
|
||||||
|
+ continue;
|
||||||
|
+ rpmlog(RPMLOG_DEBUG, "Write: %s -> %s\n", state->fifo_path, strerror(errno));
|
||||||
|
+ goto bad;
|
||||||
|
+ }
|
||||||
|
+ written += n;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return RPMRC_OK;
|
||||||
|
+
|
||||||
|
+ bad:
|
||||||
|
+ return RPMRC_FAIL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static rpmRC fapolicyd_init(rpmPlugin plugin, rpmts ts)
|
||||||
|
+{
|
||||||
|
+ if (rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ if (!rstreq(rpmtsRootDir(ts), "/"))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ (void) open_fifo(&fapolicyd_state);
|
||||||
|
+
|
||||||
|
+ end:
|
||||||
|
+ return RPMRC_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void fapolicyd_cleanup(rpmPlugin plugin)
|
||||||
|
+{
|
||||||
|
+ if (fapolicyd_state.fd > 0)
|
||||||
|
+ (void) close(fapolicyd_state.fd);
|
||||||
|
+
|
||||||
|
+ fapolicyd_state.fd = -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static rpmRC fapolicyd_tsm_post(rpmPlugin plugin, rpmts ts, int res)
|
||||||
|
+{
|
||||||
|
+ if (rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ /* we are ready */
|
||||||
|
+ if (fapolicyd_state.fd > 0) {
|
||||||
|
+ /* send a signal that transaction is over */
|
||||||
|
+ (void) write_fifo(&fapolicyd_state, "1\n");
|
||||||
|
+ /* flush cache */
|
||||||
|
+ (void) write_fifo(&fapolicyd_state, "2\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ end:
|
||||||
|
+ return RPMRC_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static rpmRC fapolicyd_scriptlet_pre(rpmPlugin plugin, const char *s_name,
|
||||||
|
+ int type)
|
||||||
|
+{
|
||||||
|
+ if (fapolicyd_state.fd == -1)
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ if (fapolicyd_state.changed_files > 0) {
|
||||||
|
+ /* send signal to flush cache */
|
||||||
|
+ (void) write_fifo(&fapolicyd_state, "2\n");
|
||||||
|
+
|
||||||
|
+ /* optimize flushing */
|
||||||
|
+ /* flush only when there was an actual change */
|
||||||
|
+ fapolicyd_state.changed_files = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ end:
|
||||||
|
+ return RPMRC_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static rpmRC fapolicyd_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,
|
||||||
|
+ const char *path, const char *dest,
|
||||||
|
+ mode_t file_mode, rpmFsmOp op)
|
||||||
|
+{
|
||||||
|
+ /* not ready */
|
||||||
|
+ if (fapolicyd_state.fd == -1)
|
||||||
|
+ goto end;
|
||||||
|
+
|
||||||
|
+ rpmFileAction action = XFO_ACTION(op);
|
||||||
|
+
|
||||||
|
+ /* Ignore skipped files and unowned directories */
|
||||||
|
+ if (XFA_SKIPPING(action) || (op & FAF_UNOWNED)) {
|
||||||
|
+ rpmlog(RPMLOG_DEBUG, "fapolicyd skipping early: path %s dest %s\n",
|
||||||
|
+ path, dest);
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!S_ISREG(rpmfiFMode(fi))) {
|
||||||
|
+ rpmlog(RPMLOG_DEBUG, "fapolicyd skipping non regular: path %s dest %s\n",
|
||||||
|
+ path, dest);
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fapolicyd_state.changed_files++;
|
||||||
|
+
|
||||||
|
+ char buffer[4096];
|
||||||
|
+
|
||||||
|
+ rpm_loff_t size = rpmfiFSize(fi);
|
||||||
|
+ char * sha = rpmfiFDigestHex(fi, NULL);
|
||||||
|
+
|
||||||
|
+ snprintf(buffer, 4096, "%s %lu %64s\n", dest, size, sha);
|
||||||
|
+ (void) write_fifo(&fapolicyd_state, buffer);
|
||||||
|
+
|
||||||
|
+ free(sha);
|
||||||
|
+
|
||||||
|
+ end:
|
||||||
|
+ return RPMRC_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct rpmPluginHooks_s fapolicyd_hooks = {
|
||||||
|
+ .init = fapolicyd_init,
|
||||||
|
+ .cleanup = fapolicyd_cleanup,
|
||||||
|
+ .scriptlet_pre = fapolicyd_scriptlet_pre,
|
||||||
|
+ .tsm_post = fapolicyd_tsm_post,
|
||||||
|
+ .fsm_file_prepare = fapolicyd_fsm_file_prepare,
|
||||||
|
+};
|
||||||
|
diff -up rpm-4.16.1.3/plugins/Makefile.am.orig rpm-4.16.1.3/plugins/Makefile.am
|
||||||
|
--- rpm-4.16.1.3/plugins/Makefile.am.orig 2021-07-22 16:18:23.022890155 +0200
|
||||||
|
+++ rpm-4.16.1.3/plugins/Makefile.am 2021-07-22 16:18:55.797494098 +0200
|
||||||
|
@@ -43,6 +43,12 @@ ima_la_LIBADD = $(top_builddir)/lib/libr
|
||||||
|
plugins_LTLIBRARIES += ima.la
|
||||||
|
endif
|
||||||
|
|
||||||
|
+if FAPOLICYD
|
||||||
|
+fapolicyd_la_sources = fapolicyd.c
|
||||||
|
+fapolicyd_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la
|
||||||
|
+plugins_LTLIBRARIES += fapolicyd.la
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
if AUDIT
|
||||||
|
audit_la_sources = audit.c
|
||||||
|
audit_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la @WITH_AUDIT_LIB@
|
@ -0,0 +1,197 @@
|
|||||||
|
From ba659220886c1a315f50fb91b9af4615b1a8757e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Domonkos <mdomonko@redhat.com>
|
||||||
|
Date: Mon, 16 Aug 2021 18:21:02 +0200
|
||||||
|
Subject: [PATCH] Add support for RPMDBI_BASENAMES on file queries
|
||||||
|
|
||||||
|
There are legitimate reasons (such as rhbz#1940895 or the included test)
|
||||||
|
for wanting the former behavior where all file states were considered in
|
||||||
|
file queries prior to commit 9ad57bda4a82b9847826daa766b4421d877bb3d9,
|
||||||
|
so celebrate the tenth anniversary of that commit by adding a CLI switch
|
||||||
|
(a new package selector --path), as contemplated back then.
|
||||||
|
|
||||||
|
Update the man page for --file to reflect it's current behavior and make
|
||||||
|
--path that more obvious.
|
||||||
|
|
||||||
|
Resolves: rhbz#1940895
|
||||||
|
|
||||||
|
Combined with:
|
||||||
|
d1aebda01033bc8ba0d748b49f6fad9a5c0caa3f
|
||||||
|
f62b6d27cd741406a52a7e9c5b1d6f581dbd3af8
|
||||||
|
|
||||||
|
Backported for 4.16.1.3.
|
||||||
|
---
|
||||||
|
doc/rpm.8 | 9 ++++++--
|
||||||
|
lib/poptQV.c | 6 +++++-
|
||||||
|
lib/query.c | 7 +++++--
|
||||||
|
lib/rpmcli.h | 1 +
|
||||||
|
tests/rpmquery.at | 52 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
5 files changed, 70 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/doc/rpm.8 b/doc/rpm.8
|
||||||
|
index 80055b675..ab7364cf6 100644
|
||||||
|
--- a/doc/rpm.8
|
||||||
|
+++ b/doc/rpm.8
|
||||||
|
@@ -57,7 +57,7 @@ rpm \- RPM Package Manager
|
||||||
|
.PP
|
||||||
|
|
||||||
|
[\fB\fIPACKAGE_NAME\fB\fR]
|
||||||
|
- [\fB-a,--all [\fISELECTOR\fR]\fR] [\fB-f,--file \fIFILE\fB\fR]
|
||||||
|
+ [\fB-a,--all [\fISELECTOR\fR]\fR] [\fB-f,--file \fIFILE\fB\fR] [\fB--path \fIPATH\fB\fR]
|
||||||
|
[\fB-g,--group \fIGROUP\fB\fR] [\fB-p,--package \fIPACKAGE_FILE\fB\fR]
|
||||||
|
[\fB--hdrid \fISHA1\fB\fR] [\fB--pkgid \fIMD5\fB\fR] [\fB--tid \fITID\fB\fR]
|
||||||
|
[\fB--querybynumber \fIHDRNUM\fB\fR] [\fB--triggeredby \fIPACKAGE_NAME\fB\fR]
|
||||||
|
@@ -569,7 +569,7 @@ starts with "b".
|
||||||
|
List duplicated packages.
|
||||||
|
.TP
|
||||||
|
\fB-f, --file \fIFILE\fB\fR
|
||||||
|
-Query package owning \fIFILE\fR.
|
||||||
|
+Query package owning installed \fIFILE\fR.
|
||||||
|
.TP
|
||||||
|
\fB--filecaps\fR
|
||||||
|
List file names with POSIX1.e capabilities.
|
||||||
|
@@ -612,6 +612,11 @@ that will be expanded to paths that are substituted in place of
|
||||||
|
the package manifest as additional \fIPACKAGE_FILE\fR
|
||||||
|
arguments to the query.
|
||||||
|
.TP
|
||||||
|
+\fB--path \fIPATH\fB\fR
|
||||||
|
+Query package(s) owning \fIPATH\fR, whether the file is installed or not.
|
||||||
|
+Multiple packages may own a \fIPATH\fR, but the file is only owned by the
|
||||||
|
+package installed last.
|
||||||
|
+.TP
|
||||||
|
\fB--pkgid \fIMD5\fB\fR
|
||||||
|
Query package that contains a given package identifier, i.e. the
|
||||||
|
\fIMD5\fR digest of the combined header and
|
||||||
|
diff --git a/lib/poptQV.c b/lib/poptQV.c
|
||||||
|
index d9d1fad75..9b6101009 100644
|
||||||
|
--- a/lib/poptQV.c
|
||||||
|
+++ b/lib/poptQV.c
|
||||||
|
@@ -27,6 +27,7 @@ struct rpmQVKArguments_s rpmQVKArgs;
|
||||||
|
#define POPT_WHATENHANCES -1014
|
||||||
|
#define POPT_WHATOBSOLETES -1015
|
||||||
|
#define POPT_WHATCONFLICTS -1016
|
||||||
|
+#define POPT_QUERYBYPATH -1017
|
||||||
|
|
||||||
|
/* ========== Query/Verify/Signature source args */
|
||||||
|
static void rpmQVSourceArgCallback( poptContext con,
|
||||||
|
@@ -58,6 +59,7 @@ static void rpmQVSourceArgCallback( poptContext con,
|
||||||
|
case POPT_WHATSUPPLEMENTS: qva->qva_source |= RPMQV_WHATSUPPLEMENTS; break;
|
||||||
|
case POPT_WHATENHANCES: qva->qva_source |= RPMQV_WHATENHANCES; break;
|
||||||
|
case POPT_TRIGGEREDBY: qva->qva_source |= RPMQV_TRIGGEREDBY; break;
|
||||||
|
+ case POPT_QUERYBYPATH: qva->qva_source |= RPMQV_PATH_ALL; break;
|
||||||
|
case POPT_QUERYBYPKGID: qva->qva_source |= RPMQV_PKGID; break;
|
||||||
|
case POPT_QUERYBYHDRID: qva->qva_source |= RPMQV_HDRID; break;
|
||||||
|
case POPT_QUERYBYTID: qva->qva_source |= RPMQV_TID; break;
|
||||||
|
@@ -80,7 +82,9 @@ struct poptOption rpmQVSourcePoptTable[] = {
|
||||||
|
{ "checksig", 'K', POPT_ARGFLAG_DOC_HIDDEN, NULL, 'K',
|
||||||
|
N_("rpm checksig mode"), NULL },
|
||||||
|
{ "file", 'f', 0, 0, 'f',
|
||||||
|
- N_("query/verify package(s) owning file"), "FILE" },
|
||||||
|
+ N_("query/verify package(s) owning installed file"), "FILE" },
|
||||||
|
+ { "path", '\0', 0, 0, POPT_QUERYBYPATH,
|
||||||
|
+ N_("query/verify package(s) owning path, installed or not"), "PATH" },
|
||||||
|
{ "group", 'g', 0, 0, 'g',
|
||||||
|
N_("query/verify package(s) in group"), "GROUP" },
|
||||||
|
{ "package", 'p', 0, 0, 'p',
|
||||||
|
diff --git a/lib/query.c b/lib/query.c
|
||||||
|
index fdabe6e52..9a71f0dc5 100644
|
||||||
|
--- a/lib/query.c
|
||||||
|
+++ b/lib/query.c
|
||||||
|
@@ -445,6 +445,7 @@ static rpmdbMatchIterator initQueryIterator(QVA_t qva, rpmts ts, const char * ar
|
||||||
|
}
|
||||||
|
/* fallthrough on absolute and relative paths */
|
||||||
|
case RPMQV_PATH:
|
||||||
|
+ case RPMQV_PATH_ALL:
|
||||||
|
{ char * fn;
|
||||||
|
|
||||||
|
for (s = arg; *s != '\0'; s++)
|
||||||
|
@@ -463,8 +464,10 @@ static rpmdbMatchIterator initQueryIterator(QVA_t qva, rpmts ts, const char * ar
|
||||||
|
fn = xstrdup(arg);
|
||||||
|
(void) rpmCleanPath(fn);
|
||||||
|
|
||||||
|
- /* XXX Add a switch to enable former BASENAMES behavior? */
|
||||||
|
- mi = rpmtsInitIterator(ts, RPMDBI_INSTFILENAMES, fn, 0);
|
||||||
|
+ rpmDbiTagVal tag = RPMDBI_INSTFILENAMES;
|
||||||
|
+ if (qva->qva_source == RPMQV_PATH_ALL)
|
||||||
|
+ tag = RPMDBI_BASENAMES;
|
||||||
|
+ mi = rpmtsInitIterator(ts, tag, fn, 0);
|
||||||
|
if (mi == NULL)
|
||||||
|
mi = rpmtsInitIterator(ts, RPMDBI_PROVIDENAME, fn, 0);
|
||||||
|
|
||||||
|
diff --git a/lib/rpmcli.h b/lib/rpmcli.h
|
||||||
|
index 4886c2453..3961418e7 100644
|
||||||
|
--- a/lib/rpmcli.h
|
||||||
|
+++ b/lib/rpmcli.h
|
||||||
|
@@ -101,6 +101,7 @@ enum rpmQVSources_e {
|
||||||
|
RPMQV_SPECBUILTRPMS, /*!< ... from pkgs which would be built from spec */
|
||||||
|
RPMQV_WHATOBSOLETES, /*!< ... from obsoletes db search. */
|
||||||
|
RPMQV_WHATCONFLICTS, /*!< ... from conflicts db search. */
|
||||||
|
+ RPMQV_PATH_ALL, /*!< ... from file path db search (all states). */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef rpmFlags rpmQVSources;
|
||||||
|
diff --git a/tests/rpmquery.at b/tests/rpmquery.at
|
||||||
|
index 9a4f1cb76..335d5ee0d 100644
|
||||||
|
--- a/tests/rpmquery.at
|
||||||
|
+++ b/tests/rpmquery.at
|
||||||
|
@@ -201,6 +201,58 @@ runroot rpm \
|
||||||
|
|
||||||
|
AT_CLEANUP
|
||||||
|
|
||||||
|
+# ------------------------------
|
||||||
|
+# query a package by a file
|
||||||
|
+AT_SETUP([rpm -qf])
|
||||||
|
+AT_KEYWORDS([query])
|
||||||
|
+AT_CHECK([
|
||||||
|
+RPMDB_INIT
|
||||||
|
+runroot rpm \
|
||||||
|
+ --nodeps \
|
||||||
|
+ -i /data/RPMS/hello-1.0-1.i386.rpm
|
||||||
|
+runroot rpm \
|
||||||
|
+ -qf /usr/local/bin/hello
|
||||||
|
+],
|
||||||
|
+[0],
|
||||||
|
+[hello-1.0-1.i386
|
||||||
|
+],
|
||||||
|
+[])
|
||||||
|
+AT_CLEANUP
|
||||||
|
+
|
||||||
|
+AT_SETUP([rpm -qf on non-installed file])
|
||||||
|
+AT_KEYWORDS([query])
|
||||||
|
+AT_CHECK([
|
||||||
|
+RPMDB_INIT
|
||||||
|
+runroot rpm \
|
||||||
|
+ --nodeps \
|
||||||
|
+ --excludedocs \
|
||||||
|
+ -i /data/RPMS/hello-1.0-1.i386.rpm
|
||||||
|
+runroot rpm \
|
||||||
|
+ -qf /usr/share/doc/hello-1.0/FAQ
|
||||||
|
+],
|
||||||
|
+[1],
|
||||||
|
+[],
|
||||||
|
+[error: file /usr/share/doc/hello-1.0/FAQ: No such file or directory
|
||||||
|
+])
|
||||||
|
+AT_CLEANUP
|
||||||
|
+
|
||||||
|
+AT_SETUP([rpm -q --path on non-installed file])
|
||||||
|
+AT_KEYWORDS([query])
|
||||||
|
+AT_CHECK([
|
||||||
|
+RPMDB_INIT
|
||||||
|
+runroot rpm \
|
||||||
|
+ --nodeps \
|
||||||
|
+ --excludedocs \
|
||||||
|
+ -i /data/RPMS/hello-1.0-1.i386.rpm
|
||||||
|
+runroot rpm \
|
||||||
|
+ -q --path /usr/share/doc/hello-1.0/FAQ
|
||||||
|
+],
|
||||||
|
+[0],
|
||||||
|
+[hello-1.0-1.i386
|
||||||
|
+],
|
||||||
|
+[])
|
||||||
|
+AT_CLEANUP
|
||||||
|
+
|
||||||
|
# ------------------------------
|
||||||
|
AT_SETUP([integer array query])
|
||||||
|
AT_KEYWORDS([query])
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
@ -0,0 +1,217 @@
|
|||||||
|
From 7b1fc619a5c828828dad7c1f61f525d957b9e2c5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Viktorin <pviktori@redhat.com>
|
||||||
|
Date: Wed, 27 Jan 2021 17:32:51 +0100
|
||||||
|
Subject: [PATCH] Add %bcond macro for defining build conditionals
|
||||||
|
|
||||||
|
Move documentation from comments to reference manual
|
||||||
|
Fixes: https://github.com/rpm-software-management/rpm/issues/941
|
||||||
|
|
||||||
|
(cherry picked from commit a99b6373af0774f4bef62aa89defc84cfcacc078)
|
||||||
|
---
|
||||||
|
macros.in | 54 +++++++----------------
|
||||||
|
tests/Makefile.am | 1 +
|
||||||
|
tests/data/SPECS/bcondtest.spec | 33 +++++++++++++++
|
||||||
|
tests/rpmbuild.at | 73 ++++++++++++++++++++++++++++++++
|
||||||
|
5 files changed, 157 insertions(+), 42 deletions(-)
|
||||||
|
create mode 100644 tests/data/SPECS/bcondtest.spec
|
||||||
|
|
||||||
|
diff --git a/macros.in b/macros.in
|
||||||
|
index 7c458f5d8a..35462c933c 100644
|
||||||
|
--- a/macros.in
|
||||||
|
+++ b/macros.in
|
||||||
|
@@ -78,47 +78,25 @@
|
||||||
|
%defined() %{expand:%%{?%{1}:1}%%{!?%{1}:0}}
|
||||||
|
%undefined() %{expand:%%{?%{1}:0}%%{!?%{1}:1}}
|
||||||
|
|
||||||
|
-# Shorthand for %{defined with_...}
|
||||||
|
+# Handle conditional builds.
|
||||||
|
+# (see 'conditionalbuilds' in the manual)
|
||||||
|
+#
|
||||||
|
+# Internally, the `--with foo` option defines the macro `_with_foo` and the
|
||||||
|
+# `--without foo` option defines the macro `_without_foo`.
|
||||||
|
+# Based on those and a default (used when neither is given), bcond macros
|
||||||
|
+# define the macro `with_foo`, which should later be checked:
|
||||||
|
+
|
||||||
|
+%bcond() %[ (%2)\
|
||||||
|
+ ? "%{expand:%%{!?_without_%{1}:%%global with_%{1} 1}}"\
|
||||||
|
+ : "%{expand:%%{?_with_%{1}:%%global with_%{1} 1}}"\
|
||||||
|
+]
|
||||||
|
+%bcond_with() %bcond %{1} 0
|
||||||
|
+%bcond_without() %bcond %{1} 1
|
||||||
|
+
|
||||||
|
+# Shorthands for %{defined with_...}:
|
||||||
|
%with() %{expand:%%{?with_%{1}:1}%%{!?with_%{1}:0}}
|
||||||
|
%without() %{expand:%%{?with_%{1}:0}%%{!?with_%{1}:1}}
|
||||||
|
|
||||||
|
-# Handle conditional builds. %bcond_with is for case when feature is
|
||||||
|
-# default off and needs to be activated with --with ... command line
|
||||||
|
-# switch. %bcond_without is for the dual case.
|
||||||
|
-#
|
||||||
|
-# %bcond_with foo defines symbol with_foo if --with foo was specified on
|
||||||
|
-# command line.
|
||||||
|
-# %bcond_without foo defines symbol with_foo if --without foo was *not*
|
||||||
|
-# specified on command line.
|
||||||
|
-#
|
||||||
|
-# For example (spec file):
|
||||||
|
-#
|
||||||
|
-# (at the beginning)
|
||||||
|
-# %bcond_with extra_fonts
|
||||||
|
-# %bcond_without static
|
||||||
|
-# (and later)
|
||||||
|
-# %if %{with extra_fonts}
|
||||||
|
-# ...
|
||||||
|
-# %else
|
||||||
|
-# ...
|
||||||
|
-# %endif
|
||||||
|
-# %if ! %{with static}
|
||||||
|
-# ...
|
||||||
|
-# %endif
|
||||||
|
-# %if %{with static}
|
||||||
|
-# ...
|
||||||
|
-# %endif
|
||||||
|
-# %{?with_static: ... }
|
||||||
|
-# %{!?with_static: ... }
|
||||||
|
-# %{?with_extra_fonts: ... }
|
||||||
|
-# %{!?with_extra_fonts: ... }
|
||||||
|
-
|
||||||
|
-#
|
||||||
|
-# The bottom line: never use without_foo, _with_foo nor _without_foo, only
|
||||||
|
-# with_foo. This way changing default set of bconds for given spec is just
|
||||||
|
-# a matter of changing single line in it and syntax is more readable.
|
||||||
|
-%bcond_with() %{expand:%%{?_with_%{1}:%%global with_%{1} 1}}
|
||||||
|
-%bcond_without() %{expand:%%{!?_without_%{1}:%%global with_%{1} 1}}
|
||||||
|
#
|
||||||
|
#==============================================================================
|
||||||
|
# ---- Required rpmrc macros.
|
||||||
|
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||||
|
index 66cee3273b..6d41ef93c5 100644
|
||||||
|
--- a/tests/Makefile.am
|
||||||
|
+++ b/tests/Makefile.am
|
||||||
|
@@ -40,6 +40,7 @@ EXTRA_DIST += $(TESTSUITE_AT)
|
||||||
|
|
||||||
|
## testsuite data
|
||||||
|
EXTRA_DIST += data/SPECS/attrtest.spec
|
||||||
|
+EXTRA_DIST += data/SPECS/bcondtest.spec
|
||||||
|
EXTRA_DIST += data/SPECS/buildrequires.spec
|
||||||
|
EXTRA_DIST += data/SPECS/docmiss.spec
|
||||||
|
EXTRA_DIST += data/SPECS/hello.spec
|
||||||
|
diff --git a/tests/data/SPECS/bcondtest.spec b/tests/data/SPECS/bcondtest.spec
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..7172a31d29
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/data/SPECS/bcondtest.spec
|
||||||
|
@@ -0,0 +1,33 @@
|
||||||
|
+Name: bcondtest
|
||||||
|
+Version: 1.0
|
||||||
|
+Release: 1
|
||||||
|
+Group: Testing
|
||||||
|
+License: CC0
|
||||||
|
+BuildArch: noarch
|
||||||
|
+Summary: Test package for the bcond macro
|
||||||
|
+
|
||||||
|
+%bcond normally_on 1
|
||||||
|
+%bcond normally_off 0
|
||||||
|
+%bcond both_features %[%{with normally_on} && %{with normally_off}]
|
||||||
|
+
|
||||||
|
+%if %{with normally_on}
|
||||||
|
+Provides: has_bcond(normally_on)
|
||||||
|
+%endif
|
||||||
|
+%if %{with normally_off}
|
||||||
|
+Provides: has_bcond(normally_off)
|
||||||
|
+%endif
|
||||||
|
+%if %{with both_features}
|
||||||
|
+Provides: has_bcond(both_features)
|
||||||
|
+%endif
|
||||||
|
+
|
||||||
|
+%description
|
||||||
|
+%{summary}
|
||||||
|
+
|
||||||
|
+%install
|
||||||
|
+mkdir -p %{buildroot}/opt
|
||||||
|
+touch %{buildroot}/opt/file
|
||||||
|
+
|
||||||
|
+%files
|
||||||
|
+/opt/file
|
||||||
|
+
|
||||||
|
+%changelog
|
||||||
|
diff --git a/tests/rpmbuild.at b/tests/rpmbuild.at
|
||||||
|
index 30d8e6895d..f378a4af2a 100644
|
||||||
|
--- a/tests/rpmbuild.at
|
||||||
|
+++ b/tests/rpmbuild.at
|
||||||
|
@@ -1801,3 +1801,76 @@ runroot rpmbuild -ba --quiet \
|
||||||
|
[],
|
||||||
|
[])
|
||||||
|
AT_CLEANUP
|
||||||
|
+
|
||||||
|
+AT_SETUP([bcond macro])
|
||||||
|
+AT_KEYWORDS([bcond build])
|
||||||
|
+RPMDB_INIT
|
||||||
|
+
|
||||||
|
+# basic bcond behavior with --eval
|
||||||
|
+AT_CHECK([
|
||||||
|
+runroot rpm \
|
||||||
|
+ --eval "%bcond normally_on 1" \
|
||||||
|
+ --eval "%bcond normally_off 0" \
|
||||||
|
+ --eval "%bcond both_features %[[%{with normally_on} && %{with normally_off}]]" \
|
||||||
|
+ --eval "%{with normally_on}" \
|
||||||
|
+ --eval "%{with normally_off}" \
|
||||||
|
+ --eval "%{with both_features}"
|
||||||
|
+],
|
||||||
|
+[0],
|
||||||
|
+[
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+1
|
||||||
|
+0
|
||||||
|
+0
|
||||||
|
+],
|
||||||
|
+[])
|
||||||
|
+
|
||||||
|
+# bcond behavior, without CLI options
|
||||||
|
+AT_CHECK([
|
||||||
|
+runroot rpmbuild -bb --quiet /data/SPECS/bcondtest.spec
|
||||||
|
+runroot rpm -q --provides -p /build/RPMS/noarch/bcondtest-1.0-1.noarch.rpm |
|
||||||
|
+ grep has_bcond | sort
|
||||||
|
+],
|
||||||
|
+[0],
|
||||||
|
+[has_bcond(normally_on)
|
||||||
|
+],
|
||||||
|
+[])
|
||||||
|
+
|
||||||
|
+# bcond behavior, --with
|
||||||
|
+AT_CHECK([
|
||||||
|
+runroot rpmbuild -bb --quiet --with normally_on --with normally_off \
|
||||||
|
+ /data/SPECS/bcondtest.spec
|
||||||
|
+runroot rpm -q --provides -p /build/RPMS/noarch/bcondtest-1.0-1.noarch.rpm |
|
||||||
|
+ grep has_bcond | sort
|
||||||
|
+],
|
||||||
|
+[0],
|
||||||
|
+[has_bcond(both_features)
|
||||||
|
+has_bcond(normally_off)
|
||||||
|
+has_bcond(normally_on)
|
||||||
|
+],
|
||||||
|
+[])
|
||||||
|
+
|
||||||
|
+# bcond behavior, --without
|
||||||
|
+AT_CHECK([
|
||||||
|
+runroot rpmbuild -bb --quiet --without normally_on --without normally_off \
|
||||||
|
+ /data/SPECS/bcondtest.spec
|
||||||
|
+runroot rpm -q --provides -p /build/RPMS/noarch/bcondtest-1.0-1.noarch.rpm |
|
||||||
|
+ grep has_bcond | sort
|
||||||
|
+],
|
||||||
|
+[0],
|
||||||
|
+[],
|
||||||
|
+[])
|
||||||
|
+
|
||||||
|
+# bcond behavior, CLI overriding a complex defailt
|
||||||
|
+AT_CHECK([
|
||||||
|
+runroot rpmbuild -bb --quiet --with both_features /data/SPECS/bcondtest.spec
|
||||||
|
+runroot rpm -q --provides -p /build/RPMS/noarch/bcondtest-1.0-1.noarch.rpm |
|
||||||
|
+ grep has_bcond | sort
|
||||||
|
+],
|
||||||
|
+[0],
|
||||||
|
+[has_bcond(both_features)
|
||||||
|
+has_bcond(normally_on)
|
||||||
|
+],
|
||||||
|
+[])
|
||||||
|
+AT_CLEANUP
|
@ -0,0 +1,32 @@
|
|||||||
|
From a26f6655546158153807017e7ded2aff5e4e10e4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Panu Matilainen <pmatilai@redhat.com>
|
||||||
|
Date: Mon, 31 Jan 2022 11:13:35 +0200
|
||||||
|
Subject: [PATCH] Bump hash for rpmdb cookie to SHA256 to appease FIPS
|
||||||
|
|
||||||
|
The rpmdb cookie is not a security feature, but as these existing
|
||||||
|
hashes are more convenient than coming up with our own... we then
|
||||||
|
run into the great big wall of FIPS which in its current incarnation
|
||||||
|
disallows use of SHA1. And so rpmdbCookie() fails under current FIPS.
|
||||||
|
|
||||||
|
Just bumping the algorithm to SHA256 seems the path of lowest
|
||||||
|
resistance, whether that algo makes sense for this purpose or not.
|
||||||
|
---
|
||||||
|
lib/rpmdb.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
|
||||||
|
index 01d49a641..00bd4236f 100644
|
||||||
|
--- a/lib/rpmdb.c
|
||||||
|
+++ b/lib/rpmdb.c
|
||||||
|
@@ -2642,7 +2642,7 @@ char *rpmdbCookie(rpmdb db)
|
||||||
|
rpmdbIndexIterator ii = rpmdbIndexIteratorInit(db, RPMDBI_NAME);
|
||||||
|
|
||||||
|
if (ii) {
|
||||||
|
- DIGEST_CTX ctx = rpmDigestInit(PGPHASHALGO_SHA1, RPMDIGEST_NONE);
|
||||||
|
+ DIGEST_CTX ctx = rpmDigestInit(PGPHASHALGO_SHA256, RPMDIGEST_NONE);
|
||||||
|
const void *key = 0;
|
||||||
|
size_t keylen = 0;
|
||||||
|
while ((rpmdbIndexIteratorNext(ii, &key, &keylen)) == 0) {
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
@ -0,0 +1,24 @@
|
|||||||
|
From 4420c78beb86cc67392274bf351478a3375626a2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: yangchenguang <89123114+yangchenguang94@users.noreply.github.com>
|
||||||
|
Date: Wed, 13 Jul 2022 16:52:07 +0800
|
||||||
|
Subject: [PATCH] Fix query arguments with ^ not working
|
||||||
|
|
||||||
|
when querying packages in the RPM database.
|
||||||
|
|
||||||
|
Rersolves: #2104
|
||||||
|
---
|
||||||
|
lib/rpmdb.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
|
||||||
|
index fa8f3c9b9c..fd2b0671ae 100644
|
||||||
|
--- a/lib/rpmdb.c
|
||||||
|
+++ b/lib/rpmdb.c
|
||||||
|
@@ -1133,6 +1133,7 @@ static char * mireDup(rpmTagVal tag, rpmMireMode *modep,
|
||||||
|
switch (*s) {
|
||||||
|
case '.':
|
||||||
|
case '+':
|
||||||
|
+ case '^':
|
||||||
|
if (!brackets) *t++ = '\\';
|
||||||
|
break;
|
||||||
|
case '*':
|
@ -0,0 +1,24 @@
|
|||||||
|
From 19d73f67883c011cc74326a5dc34f7009efa60e1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Panu Matilainen <pmatilai@redhat.com>
|
||||||
|
Date: Tue, 6 Sep 2022 13:15:44 +0300
|
||||||
|
Subject: [PATCH] Fix buffer overrun from commit
|
||||||
|
4420c78beb86cc67392274bf351478a3375626a2
|
||||||
|
|
||||||
|
The newly handled ^ needs to be accounted for when allocating memory.
|
||||||
|
Found when testing #1936, goes to show what a useful thing that is.
|
||||||
|
---
|
||||||
|
lib/rpmdb.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
|
||||||
|
index fd2b0671ae..b3c5da62d5 100644
|
||||||
|
--- a/lib/rpmdb.c
|
||||||
|
+++ b/lib/rpmdb.c
|
||||||
|
@@ -1107,6 +1107,7 @@ static char * mireDup(rpmTagVal tag, rpmMireMode *modep,
|
||||||
|
case '.':
|
||||||
|
case '+':
|
||||||
|
case '*':
|
||||||
|
+ case '^':
|
||||||
|
if (!brackets) nb++;
|
||||||
|
break;
|
||||||
|
case '\\':
|
@ -0,0 +1,167 @@
|
|||||||
|
From 534fd1f0c84b12ba6080a46e07c57ef913c77cba Mon Sep 17 00:00:00 2001
|
||||||
|
From: Radovan Sroka <rsroka@redhat.com>
|
||||||
|
Date: Thu, 25 Aug 2022 15:38:01 +0200
|
||||||
|
Subject: [PATCH] fapolicyd: Make write() nonblocking
|
||||||
|
|
||||||
|
- switch to read only and non blocking mode for pipe
|
||||||
|
- add 1 minute loop to wait for pipe to reappear
|
||||||
|
|
||||||
|
Sometimes during the system update/upgrade fapolicyd
|
||||||
|
get restarted e.g. when systemd gets updated.
|
||||||
|
That can lead to the situation where fapolicyd pipe
|
||||||
|
has been removed and created again.
|
||||||
|
In such cases rpm-plugin-fapolicyd gets stuck on
|
||||||
|
write() to the pipe which does not exist anymore.
|
||||||
|
After switching to non blocking file descriptor
|
||||||
|
we can try to reopen the pipe if there is an error
|
||||||
|
from write(). Assuming that a new pipe should appear
|
||||||
|
when fapolicyd daemon starts again.
|
||||||
|
If not then after 1 minute of waiting we expect
|
||||||
|
fapolicyd daemon to be not active and we let the
|
||||||
|
transaction continue.
|
||||||
|
|
||||||
|
Signed-off-by: Radovan Sroka <rsroka@redhat.com>
|
||||||
|
---
|
||||||
|
plugins/fapolicyd.c | 74 +++++++++++++++++++++++++++++++++++++++------
|
||||||
|
1 file changed, 65 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/plugins/fapolicyd.c b/plugins/fapolicyd.c
|
||||||
|
index 1ff50c30f..6c6322941 100644
|
||||||
|
--- a/plugins/fapolicyd.c
|
||||||
|
+++ b/plugins/fapolicyd.c
|
||||||
|
@@ -27,7 +27,7 @@ static rpmRC open_fifo(struct fapolicyd_data* state)
|
||||||
|
int fd = -1;
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
- fd = open(state->fifo_path, O_RDWR);
|
||||||
|
+ fd = open(state->fifo_path, O_WRONLY|O_NONBLOCK);
|
||||||
|
if (fd == -1) {
|
||||||
|
rpmlog(RPMLOG_DEBUG, "Open: %s -> %s\n", state->fifo_path, strerror(errno));
|
||||||
|
goto bad;
|
||||||
|
@@ -55,15 +55,26 @@ static rpmRC open_fifo(struct fapolicyd_data* state)
|
||||||
|
}
|
||||||
|
|
||||||
|
state->fd = fd;
|
||||||
|
+
|
||||||
|
/* considering success */
|
||||||
|
return RPMRC_OK;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
if (fd >= 0)
|
||||||
|
close(fd);
|
||||||
|
+
|
||||||
|
+ state->fd = -1;
|
||||||
|
return RPMRC_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void close_fifo(struct fapolicyd_data* state)
|
||||||
|
+{
|
||||||
|
+ if (state->fd > 0)
|
||||||
|
+ (void) close(state->fd);
|
||||||
|
+
|
||||||
|
+ state->fd = -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static rpmRC write_fifo(struct fapolicyd_data* state, const char * str)
|
||||||
|
{
|
||||||
|
ssize_t len = strlen(str);
|
||||||
|
@@ -86,6 +97,54 @@ static rpmRC write_fifo(struct fapolicyd_data* state, const char * str)
|
||||||
|
return RPMRC_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void try_to_write_to_fifo(struct fapolicyd_data* state, const char * str)
|
||||||
|
+{
|
||||||
|
+ int reload = 0;
|
||||||
|
+ int printed = 0;
|
||||||
|
+
|
||||||
|
+ /* 1min/60s */
|
||||||
|
+ const int timeout = 60;
|
||||||
|
+
|
||||||
|
+ /* wait up to X seconds */
|
||||||
|
+ for (int i = 0; i < timeout; i++) {
|
||||||
|
+
|
||||||
|
+ if (reload) {
|
||||||
|
+ if (!printed) {
|
||||||
|
+ rpmlog(RPMLOG_WARNING, "rpm-plugin-fapolicyd: waiting for the service connection to resume, it can take up to %d seconds\n", timeout);
|
||||||
|
+ printed = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ (void) close_fifo(state);
|
||||||
|
+ (void) open_fifo(state);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (state->fd >= 0) {
|
||||||
|
+ if (write_fifo(state, str) == RPMRC_OK) {
|
||||||
|
+
|
||||||
|
+ /* write was successful after few reopens */
|
||||||
|
+ if (reload)
|
||||||
|
+ rpmlog(RPMLOG_WARNING, "rpm-plugin-fapolicyd: the service connection has resumed\n");
|
||||||
|
+
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* failed write or reopen */
|
||||||
|
+ reload = 1;
|
||||||
|
+ sleep(1);
|
||||||
|
+
|
||||||
|
+ /* the last iteration */
|
||||||
|
+ /* consider failure */
|
||||||
|
+ if (i == timeout-1) {
|
||||||
|
+ rpmlog(RPMLOG_WARNING, "rpm-plugin-fapolicyd: the service connection has not resumed\n");
|
||||||
|
+ rpmlog(RPMLOG_WARNING, "rpm-plugin-fapolicyd: continuing without the service\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
static rpmRC fapolicyd_init(rpmPlugin plugin, rpmts ts)
|
||||||
|
{
|
||||||
|
if (rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))
|
||||||
|
@@ -102,10 +161,7 @@ static rpmRC fapolicyd_init(rpmPlugin plugin, rpmts ts)
|
||||||
|
|
||||||
|
static void fapolicyd_cleanup(rpmPlugin plugin)
|
||||||
|
{
|
||||||
|
- if (fapolicyd_state.fd > 0)
|
||||||
|
- (void) close(fapolicyd_state.fd);
|
||||||
|
-
|
||||||
|
- fapolicyd_state.fd = -1;
|
||||||
|
+ (void) close_fifo(&fapolicyd_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rpmRC fapolicyd_tsm_post(rpmPlugin plugin, rpmts ts, int res)
|
||||||
|
@@ -116,9 +172,9 @@ static rpmRC fapolicyd_tsm_post(rpmPlugin plugin, rpmts ts, int res)
|
||||||
|
/* we are ready */
|
||||||
|
if (fapolicyd_state.fd > 0) {
|
||||||
|
/* send a signal that transaction is over */
|
||||||
|
- (void) write_fifo(&fapolicyd_state, "1\n");
|
||||||
|
+ (void) try_to_write_to_fifo(&fapolicyd_state, "1\n");
|
||||||
|
/* flush cache */
|
||||||
|
- (void) write_fifo(&fapolicyd_state, "2\n");
|
||||||
|
+ (void) try_to_write_to_fifo(&fapolicyd_state, "2\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
@@ -133,7 +189,7 @@ static rpmRC fapolicyd_scriptlet_pre(rpmPlugin plugin, const char *s_name,
|
||||||
|
|
||||||
|
if (fapolicyd_state.changed_files > 0) {
|
||||||
|
/* send signal to flush cache */
|
||||||
|
- (void) write_fifo(&fapolicyd_state, "2\n");
|
||||||
|
+ (void) try_to_write_to_fifo(&fapolicyd_state, "2\n");
|
||||||
|
|
||||||
|
/* optimize flushing */
|
||||||
|
/* flush only when there was an actual change */
|
||||||
|
@@ -176,7 +232,7 @@ static rpmRC fapolicyd_fsm_file_prepare(rpmPlugin plugin, rpmfi fi,
|
||||||
|
char * sha = rpmfiFDigestHex(fi, NULL);
|
||||||
|
|
||||||
|
snprintf(buffer, 4096, "%s %lu %64s\n", dest, size, sha);
|
||||||
|
- (void) write_fifo(&fapolicyd_state, buffer);
|
||||||
|
+ (void) try_to_write_to_fifo(&fapolicyd_state, buffer);
|
||||||
|
|
||||||
|
free(sha);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.37.3
|
||||||
|
|
@ -0,0 +1,20 @@
|
|||||||
|
--- rpm.orig/macros.in 2022-06-30 11:37:18.975312592 +0100
|
||||||
|
+++ rpm-4.16.1.3/macros.in 2022-06-30 11:37:43.145158323 +0100
|
||||||
|
@@ -167,6 +167,9 @@
|
||||||
|
# A spec file can %%define _find_debuginfo_opts to pass options to
|
||||||
|
# the script. See the script for details.
|
||||||
|
#
|
||||||
|
+# Vendor spec files (eg redhat-rpm-config:macros) can %%define
|
||||||
|
+# _find_debuginfo_vendor_opts to pass options to the script.
|
||||||
|
+#
|
||||||
|
%__debug_install_post \
|
||||||
|
%{_rpmconfigdir}/find-debuginfo.sh \\\
|
||||||
|
%{?_smp_build_ncpus:-j%{_smp_build_ncpus}} \\\
|
||||||
|
@@ -179,6 +182,7 @@
|
||||||
|
%{?_unique_debug_srcs:--unique-debug-src-base "%{name}-%{VERSION}-%{RELEASE}.%{_arch}"} \\\
|
||||||
|
%{?_find_debuginfo_dwz_opts} \\\
|
||||||
|
%{?_find_debuginfo_opts} \\\
|
||||||
|
+ %{?_find_debuginfo_vendor_opts} \\\
|
||||||
|
%{?_debugsource_packages:-S debugsourcefiles.list} \\\
|
||||||
|
"%{_builddir}/%{?buildsubdir}"\
|
||||||
|
%{nil}
|
@ -0,0 +1,288 @@
|
|||||||
|
From b66422161d68ed7f7b1cb30e4db900bf42bed146 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Panu Matilainen <pmatilai@redhat.com>
|
||||||
|
Date: Mon, 29 Nov 2021 14:01:39 +0200
|
||||||
|
Subject: [PATCH 1/4] Add Python bindings for rpmfilesFSignature()
|
||||||
|
|
||||||
|
Only, use more descriptive names than the C-side counterparts.
|
||||||
|
Python has nice facilities for dealing with binary data so return it
|
||||||
|
as such rather than converting to hex.
|
||||||
|
|
||||||
|
Backported for 4.16.1.3 (removed rpmfilesVSignature()).
|
||||||
|
---
|
||||||
|
python/rpmfiles-py.c | 18 ++++++++++++++++++
|
||||||
|
1 file changed, 18 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/python/rpmfiles-py.c b/python/rpmfiles-py.c
|
||||||
|
index 27666021d..48189a0ac 100644
|
||||||
|
--- a/python/rpmfiles-py.c
|
||||||
|
+++ b/python/rpmfiles-py.c
|
||||||
|
@@ -152,6 +152,22 @@ static PyObject *rpmfile_digest(rpmfileObject *s)
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static PyObject *bytebuf(const unsigned char *buf, size_t len)
|
||||||
|
+{
|
||||||
|
+ if (buf) {
|
||||||
|
+ PyObject *o = PyBytes_FromStringAndSize((const char *)buf, len);
|
||||||
|
+ return o;
|
||||||
|
+ }
|
||||||
|
+ Py_RETURN_NONE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static PyObject *rpmfile_imasig(rpmfileObject *s)
|
||||||
|
+{
|
||||||
|
+ size_t len = 0;
|
||||||
|
+ const unsigned char *sig = rpmfilesFSignature(s->files, s->ix, &len);
|
||||||
|
+ return bytebuf(sig, len);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static PyObject *rpmfile_class(rpmfileObject *s)
|
||||||
|
{
|
||||||
|
return utf8FromString(rpmfilesFClass(s->files, s->ix));
|
||||||
|
@@ -278,6 +294,8 @@ static PyGetSetDef rpmfile_getseters[] = {
|
||||||
|
"language the file provides (typically for doc files)" },
|
||||||
|
{ "caps", (getter) rpmfile_caps, NULL,
|
||||||
|
"file capabilities" },
|
||||||
|
+ { "imasig", (getter) rpmfile_imasig, NULL,
|
||||||
|
+ "IMA signature" },
|
||||||
|
{ NULL, NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
||||||
|
From 9c4622998d3d0666edbea3ed1ae518502c3ed987 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Panu Matilainen <pmatilai@redhat.com>
|
||||||
|
Date: Mon, 7 Feb 2022 11:52:55 +0200
|
||||||
|
Subject: [PATCH 2/4] Add a testcase for --dump query
|
||||||
|
|
||||||
|
---
|
||||||
|
tests/rpmquery.at | 18 ++++++++++++++++++
|
||||||
|
1 file changed, 18 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/tests/rpmquery.at b/tests/rpmquery.at
|
||||||
|
index 9a4f1cb76..9bd391ac5 100644
|
||||||
|
--- a/tests/rpmquery.at
|
||||||
|
+++ b/tests/rpmquery.at
|
||||||
|
@@ -83,6 +83,24 @@ hello.spec
|
||||||
|
[ignore])
|
||||||
|
AT_CLEANUP
|
||||||
|
|
||||||
|
+AT_SETUP([rpm -qp --dump])
|
||||||
|
+AT_KEYWORDS([query])
|
||||||
|
+AT_CHECK([
|
||||||
|
+RPMDB_INIT
|
||||||
|
+runroot rpm \
|
||||||
|
+ -qp --dump \
|
||||||
|
+ /data/RPMS/hello-2.0-1.x86_64.rpm
|
||||||
|
+],
|
||||||
|
+[0],
|
||||||
|
+[/usr/bin/hello 7120 1489670606 c89fa87aeb1143969c0b6be9334b21d932f77f74e8f60120b5de316406369cf0 0100751 root root 0 0 0 X
|
||||||
|
+/usr/share/doc/hello-2.0 4096 1489670606 0000000000000000000000000000000000000000000000000000000000000000 040755 root root 0 0 0 X
|
||||||
|
+/usr/share/doc/hello-2.0/COPYING 48 908894882 fac3b28492ecdc16da172a6f1a432ceed356ca4d9248157b2a962b395e37b3b0 0100644 root root 0 1 0 X
|
||||||
|
+/usr/share/doc/hello-2.0/FAQ 36 908895030 678b87e217a415f05e43460e2c7b668245b412e2b4f18a75aa7399d9774ed0b4 0100644 root root 0 1 0 X
|
||||||
|
+/usr/share/doc/hello-2.0/README 39 908884468 d63fdc6c986106f57230f217d36b2395d83ecf491d2b7187af714dc8db9629e9 0100644 root root 0 1 0 X
|
||||||
|
+],
|
||||||
|
+[])
|
||||||
|
+AT_CLEANUP
|
||||||
|
+
|
||||||
|
# ------------------------------
|
||||||
|
AT_SETUP([rpmspec -q])
|
||||||
|
AT_KEYWORDS([query])
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
||||||
|
From 9b2bc10881db7691439005fd74ea53d75b15ac76 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Panu Matilainen <pmatilai@redhat.com>
|
||||||
|
Date: Thu, 10 Feb 2022 11:15:04 +0200
|
||||||
|
Subject: [PATCH 3/4] Ensure sane string lengths for file digests from header
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/rpmfi.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/lib/rpmfi.c b/lib/rpmfi.c
|
||||||
|
index af428468c..2dffab3aa 100644
|
||||||
|
--- a/lib/rpmfi.c
|
||||||
|
+++ b/lib/rpmfi.c
|
||||||
|
@@ -1501,6 +1501,10 @@ static uint8_t *hex2bin(Header h, rpmTagVal tag, rpm_count_t num, size_t len)
|
||||||
|
t += len;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
+ if (strlen(s) != len * 2) {
|
||||||
|
+ bin = rfree(bin);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
for (int j = 0; j < len; j++, t++, s += 2)
|
||||||
|
*t = (rnibble(s[0]) << 4) | rnibble(s[1]);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
||||||
|
From ddfed9e1842a1b60a8c40de3a18add6f6d68c515 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Panu Matilainen <pmatilai@redhat.com>
|
||||||
|
Date: Mon, 29 Nov 2021 14:01:39 +0200
|
||||||
|
Subject: [PATCH 4/4] Fix IMA signature fubar, take III (#1833, RhBug:2018937)
|
||||||
|
|
||||||
|
At least ECDSA and RSA signatures can vary in length, but the IMA code
|
||||||
|
assumes constant lengths and thus may either place invalid signatures on
|
||||||
|
disk from either truncating or overshooting, and segfault if the stars are
|
||||||
|
just so.
|
||||||
|
|
||||||
|
As we can't assume static lengths and attempts to use maximum length
|
||||||
|
have proven problematic for other reasons, use a data structure that
|
||||||
|
can actually handle variable length data properly: store offsets into
|
||||||
|
the decoded binary blob and use them to calculate lengths when needed,
|
||||||
|
empty data is simply consequtive identical offsets. This avoids a whole
|
||||||
|
class of silly overflow issues with multiplying, makes zero-length data
|
||||||
|
actually presentable in the data structure and saves memory too.
|
||||||
|
|
||||||
|
Add tests to show behavior with variable length signatures and missing
|
||||||
|
signatures.
|
||||||
|
|
||||||
|
Additionally update the signing code to store the largest IMA signature
|
||||||
|
length rather than what happened to be last to be on the safe side.
|
||||||
|
We can't rely on this value due to invalid packages being out there,
|
||||||
|
but then we need to calculate the lengths on rpmfiles populate so there's
|
||||||
|
not a lot to gain anyhow.
|
||||||
|
|
||||||
|
Fixes: #1833
|
||||||
|
|
||||||
|
Backported for 4.16.1.3. Note that the test case has been removed due
|
||||||
|
to it including a binary file (test package) for which we'd have to use
|
||||||
|
-Sgit with %autopatch and thus depend on git-core at build time.
|
||||||
|
Nevertheless, we do have this BZ covered in our internal test suite, so
|
||||||
|
no need for it anyway.
|
||||||
|
---
|
||||||
|
lib/rpmfi.c | 61 +++++++++++++++++++++++++++++++++++++++------
|
||||||
|
sign/rpmsignfiles.c | 5 +++-
|
||||||
|
2 files changed, 58 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/rpmfi.c b/lib/rpmfi.c
|
||||||
|
index 2dffab3aa..77e73442c 100644
|
||||||
|
--- a/lib/rpmfi.c
|
||||||
|
+++ b/lib/rpmfi.c
|
||||||
|
@@ -115,7 +115,7 @@ struct rpmfiles_s {
|
||||||
|
struct fingerPrint_s * fps; /*!< File fingerprint(s). */
|
||||||
|
|
||||||
|
int digestalgo; /*!< File digest algorithm */
|
||||||
|
- int signaturelength; /*!< File signature length */
|
||||||
|
+ uint32_t *signatureoffs; /*!< File signature offsets */
|
||||||
|
unsigned char * digests; /*!< File digests in binary. */
|
||||||
|
unsigned char * signatures; /*!< File signatures in binary. */
|
||||||
|
|
||||||
|
@@ -574,10 +574,15 @@ const unsigned char * rpmfilesFSignature(rpmfiles fi, int ix, size_t *len)
|
||||||
|
const unsigned char *signature = NULL;
|
||||||
|
|
||||||
|
if (fi != NULL && ix >= 0 && ix < rpmfilesFC(fi)) {
|
||||||
|
- if (fi->signatures != NULL)
|
||||||
|
- signature = fi->signatures + (fi->signaturelength * ix);
|
||||||
|
+ size_t slen = 0;
|
||||||
|
+ if (fi->signatures != NULL && fi->signatureoffs != NULL) {
|
||||||
|
+ uint32_t off = fi->signatureoffs[ix];
|
||||||
|
+ slen = fi->signatureoffs[ix+1] - off;
|
||||||
|
+ if (slen > 0)
|
||||||
|
+ signature = fi->signatures + off;
|
||||||
|
+ }
|
||||||
|
if (len)
|
||||||
|
- *len = fi->signaturelength;
|
||||||
|
+ *len = slen;
|
||||||
|
}
|
||||||
|
return signature;
|
||||||
|
}
|
||||||
|
@@ -1257,6 +1262,7 @@ rpmfiles rpmfilesFree(rpmfiles fi)
|
||||||
|
fi->flangs = _free(fi->flangs);
|
||||||
|
fi->digests = _free(fi->digests);
|
||||||
|
fi->signatures = _free(fi->signatures);
|
||||||
|
+ fi->signatureoffs = _free(fi->signatureoffs);
|
||||||
|
fi->fcaps = _free(fi->fcaps);
|
||||||
|
|
||||||
|
fi->cdict = _free(fi->cdict);
|
||||||
|
@@ -1485,6 +1491,48 @@ err:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Convert a tag of variable len hex strings to binary presentation,
|
||||||
|
+ * accessed via offsets to a contiguous binary blob. Empty values
|
||||||
|
+ * are represented by identical consequtive offsets. The offsets array
|
||||||
|
+ * always has one extra element to allow calculating the size of the
|
||||||
|
+ * last element.
|
||||||
|
+ */
|
||||||
|
+static uint8_t *hex2binv(Header h, rpmTagVal tag, rpm_count_t num,
|
||||||
|
+ uint32_t **offsetp)
|
||||||
|
+{
|
||||||
|
+ struct rpmtd_s td;
|
||||||
|
+ uint8_t *bin = NULL;
|
||||||
|
+ uint32_t *offs = NULL;
|
||||||
|
+
|
||||||
|
+ if (headerGet(h, tag, &td, HEADERGET_MINMEM) && rpmtdCount(&td) == num) {
|
||||||
|
+ const char *s;
|
||||||
|
+ int i = 0;
|
||||||
|
+ uint8_t *t = bin = xmalloc(((rpmtdSize(&td) / 2) + 1));
|
||||||
|
+ offs = xmalloc((num + 1) * sizeof(*offs));
|
||||||
|
+
|
||||||
|
+ while ((s = rpmtdNextString(&td))) {
|
||||||
|
+ uint32_t slen = strlen(s);
|
||||||
|
+ uint32_t len = slen / 2;
|
||||||
|
+ if (slen % 2) {
|
||||||
|
+ bin = rfree(bin);
|
||||||
|
+ offs = rfree(offs);
|
||||||
|
+ goto exit;
|
||||||
|
+ }
|
||||||
|
+ offs[i] = t - bin;
|
||||||
|
+ for (int j = 0; j < len; j++, t++, s += 2)
|
||||||
|
+ *t = (rnibble(s[0]) << 4) | rnibble(s[1]);
|
||||||
|
+ i++;
|
||||||
|
+ }
|
||||||
|
+ offs[i] = t - bin;
|
||||||
|
+ *offsetp = offs;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+exit:
|
||||||
|
+ rpmtdFreeData(&td);
|
||||||
|
+ return bin;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Convert a tag of hex strings to binary presentation */
|
||||||
|
static uint8_t *hex2bin(Header h, rpmTagVal tag, rpm_count_t num, size_t len)
|
||||||
|
{
|
||||||
|
@@ -1580,9 +1628,8 @@ static int rpmfilesPopulate(rpmfiles fi, Header h, rpmfiFlags flags)
|
||||||
|
fi->signatures = NULL;
|
||||||
|
/* grab hex signatures from header and store in binary format */
|
||||||
|
if (!(flags & RPMFI_NOFILESIGNATURES)) {
|
||||||
|
- fi->signaturelength = headerGetNumber(h, RPMTAG_FILESIGNATURELENGTH);
|
||||||
|
- fi->signatures = hex2bin(h, RPMTAG_FILESIGNATURES,
|
||||||
|
- totalfc, fi->signaturelength);
|
||||||
|
+ fi->signatures = hex2binv(h, RPMTAG_FILESIGNATURES,
|
||||||
|
+ totalfc, &fi->signatureoffs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX TR_REMOVED doesn;t need fmtimes, frdevs, finodes */
|
||||||
|
diff --git a/sign/rpmsignfiles.c b/sign/rpmsignfiles.c
|
||||||
|
index b143c5b9b..372ba634c 100644
|
||||||
|
--- a/sign/rpmsignfiles.c
|
||||||
|
+++ b/sign/rpmsignfiles.c
|
||||||
|
@@ -98,8 +98,9 @@ rpmRC rpmSignFiles(Header sigh, Header h, const char *key, char *keypass)
|
||||||
|
td.count = 1;
|
||||||
|
|
||||||
|
while (rpmfiNext(fi) >= 0) {
|
||||||
|
+ uint32_t slen = 0;
|
||||||
|
digest = rpmfiFDigest(fi, NULL, NULL);
|
||||||
|
- signature = signFile(algoname, digest, diglen, key, keypass, &siglen);
|
||||||
|
+ signature = signFile(algoname, digest, diglen, key, keypass, &slen);
|
||||||
|
if (!signature) {
|
||||||
|
rpmlog(RPMLOG_ERR, _("signFile failed\n"));
|
||||||
|
goto exit;
|
||||||
|
@@ -110,6 +111,8 @@ rpmRC rpmSignFiles(Header sigh, Header h, const char *key, char *keypass)
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
signature = _free(signature);
|
||||||
|
+ if (slen > siglen)
|
||||||
|
+ siglen = slen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (siglen > 0) {
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
@ -0,0 +1,88 @@
|
|||||||
|
From f5695d04f56e27d9cf947c0502eb549c28aa817e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Panu Matilainen <pmatilai@redhat.com>
|
||||||
|
Date: Tue, 25 May 2021 14:07:18 +0300
|
||||||
|
Subject: [PATCH] Fix regression reading rpm v3 and other rare packages (#1635)
|
||||||
|
|
||||||
|
Commit d6a86b5e69e46cc283b1e06c92343319beb42e21 introduced far stricter
|
||||||
|
checks on what tags are allowed in signature and main headers than rpm
|
||||||
|
had previously seen, and unsurprisingly this introduced some regressions
|
||||||
|
on less common cases:
|
||||||
|
|
||||||
|
- On rpm v3 packages and some newer 3rd party created packages (such as
|
||||||
|
install4j < 9.0.2), RPMTAG_ARCHIVESIZE resides in the main header
|
||||||
|
to begin with
|
||||||
|
- In rpm 4.13 - 4.14, file IMA signatures were incorrectly placed in
|
||||||
|
the main header.
|
||||||
|
|
||||||
|
As a quirk, permit the existence of RPMTAG_ARCHIVESIZE,
|
||||||
|
RPMTAG_FILESIGNATURES and RPMTAG_FILESIGNATURELENGTH in the main header
|
||||||
|
too provided that the corresponding signature tag is not there (so
|
||||||
|
they can reside in either but not both headers).
|
||||||
|
|
||||||
|
Initial workaround patch by Demi Marie Obenour.
|
||||||
|
|
||||||
|
Fixes: #1635
|
||||||
|
|
||||||
|
Backported for 4.16.1.3.
|
||||||
|
---
|
||||||
|
lib/package.c | 35 ++++++++++++++++++++---------------
|
||||||
|
1 file changed, 20 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/package.c b/lib/package.c
|
||||||
|
index 36ed5abc6..8c2b66b0b 100644
|
||||||
|
--- a/lib/package.c
|
||||||
|
+++ b/lib/package.c
|
||||||
|
@@ -35,21 +35,22 @@ struct taglate_s {
|
||||||
|
rpmTagVal stag;
|
||||||
|
rpmTagVal xtag;
|
||||||
|
rpm_count_t count;
|
||||||
|
+ int quirk;
|
||||||
|
} const xlateTags[] = {
|
||||||
|
- { RPMSIGTAG_SIZE, RPMTAG_SIGSIZE, 1 },
|
||||||
|
- { RPMSIGTAG_PGP, RPMTAG_SIGPGP, 0 },
|
||||||
|
- { RPMSIGTAG_MD5, RPMTAG_SIGMD5, 16 },
|
||||||
|
- { RPMSIGTAG_GPG, RPMTAG_SIGGPG, 0 },
|
||||||
|
- /* { RPMSIGTAG_PGP5, RPMTAG_SIGPGP5, 0 }, */ /* long obsolete, dont use */
|
||||||
|
- { RPMSIGTAG_PAYLOADSIZE, RPMTAG_ARCHIVESIZE, 1 },
|
||||||
|
- { RPMSIGTAG_FILESIGNATURES, RPMTAG_FILESIGNATURES, 0 },
|
||||||
|
- { RPMSIGTAG_FILESIGNATURELENGTH, RPMTAG_FILESIGNATURELENGTH, 1 },
|
||||||
|
- { RPMSIGTAG_SHA1, RPMTAG_SHA1HEADER, 1 },
|
||||||
|
- { RPMSIGTAG_SHA256, RPMTAG_SHA256HEADER, 1 },
|
||||||
|
- { RPMSIGTAG_DSA, RPMTAG_DSAHEADER, 0 },
|
||||||
|
- { RPMSIGTAG_RSA, RPMTAG_RSAHEADER, 0 },
|
||||||
|
- { RPMSIGTAG_LONGSIZE, RPMTAG_LONGSIGSIZE, 1 },
|
||||||
|
- { RPMSIGTAG_LONGARCHIVESIZE, RPMTAG_LONGARCHIVESIZE, 1 },
|
||||||
|
+ { RPMSIGTAG_SIZE, RPMTAG_SIGSIZE, 1, 0 },
|
||||||
|
+ { RPMSIGTAG_PGP, RPMTAG_SIGPGP, 0, 0 },
|
||||||
|
+ { RPMSIGTAG_MD5, RPMTAG_SIGMD5, 16, 0 },
|
||||||
|
+ { RPMSIGTAG_GPG, RPMTAG_SIGGPG, 0, 0 },
|
||||||
|
+ /* { RPMSIGTAG_PGP5, RPMTAG_SIGPGP5, 0, 0 }, */ /* long obsolete, dont use */
|
||||||
|
+ { RPMSIGTAG_PAYLOADSIZE, RPMTAG_ARCHIVESIZE, 1, 1 },
|
||||||
|
+ { RPMSIGTAG_FILESIGNATURES, RPMTAG_FILESIGNATURES, 0, 1 },
|
||||||
|
+ { RPMSIGTAG_FILESIGNATURELENGTH, RPMTAG_FILESIGNATURELENGTH, 1, 1 },
|
||||||
|
+ { RPMSIGTAG_SHA1, RPMTAG_SHA1HEADER, 1, 0 },
|
||||||
|
+ { RPMSIGTAG_SHA256, RPMTAG_SHA256HEADER, 1, 0 },
|
||||||
|
+ { RPMSIGTAG_DSA, RPMTAG_DSAHEADER, 0, 0 },
|
||||||
|
+ { RPMSIGTAG_RSA, RPMTAG_RSAHEADER, 0, 0 },
|
||||||
|
+ { RPMSIGTAG_LONGSIZE, RPMTAG_LONGSIGSIZE, 1, 0 },
|
||||||
|
+ { RPMSIGTAG_LONGARCHIVESIZE, RPMTAG_LONGARCHIVESIZE, 1, 0 },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -67,8 +68,12 @@ rpmTagVal headerMergeLegacySigs(Header h, Header sigh, char **msg)
|
||||||
|
|
||||||
|
for (xl = xlateTags; xl->stag; xl++) {
|
||||||
|
/* There mustn't be one in the main header */
|
||||||
|
- if (headerIsEntry(h, xl->xtag))
|
||||||
|
+ if (headerIsEntry(h, xl->xtag)) {
|
||||||
|
+ /* Some tags may exist in either header, but never both */
|
||||||
|
+ if (xl->quirk && !headerIsEntry(sigh, xl->stag))
|
||||||
|
+ continue;
|
||||||
|
goto exit;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
rpmtdReset(&td);
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
@ -0,0 +1,123 @@
|
|||||||
|
From 8c37dff4ce9c887eda5ad61f78001e87473002ed Mon Sep 17 00:00:00 2001
|
||||||
|
From: Panu Matilainen <pmatilai@redhat.com>
|
||||||
|
Date: Tue, 16 Nov 2021 11:49:18 +0200
|
||||||
|
Subject: [PATCH] Fix spurious %transfiletriggerpostun execution
|
||||||
|
(RhBug:2023311)
|
||||||
|
|
||||||
|
If a package has multiple %transfiletriggerpostun triggers, any one
|
||||||
|
of them matching would cause all of them to run, due to disconnect
|
||||||
|
in the intel gathering stage: we'd gather all the headers with matching
|
||||||
|
files into a lump, and then add any postun triggers found in them,
|
||||||
|
but this loses the triggering file information and causes all postuns
|
||||||
|
to run.
|
||||||
|
|
||||||
|
The triggers need to be added while looping over the file matches,
|
||||||
|
like runFileTriggers() does. Doing so actually simplifies the code.
|
||||||
|
These should really be unified to use the same code, but leaving
|
||||||
|
that exercise to another rainy day.
|
||||||
|
|
||||||
|
Combined with 0988ccb53abf426587d228df5c60c4042da71999 (fix-up).
|
||||||
|
---
|
||||||
|
lib/rpmtriggers.c | 65 ++++++++++++++++++++++++-----------------------
|
||||||
|
1 file changed, 33 insertions(+), 32 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/rpmtriggers.c b/lib/rpmtriggers.c
|
||||||
|
index fc809a65e..8d8f57450 100644
|
||||||
|
--- a/lib/rpmtriggers.c
|
||||||
|
+++ b/lib/rpmtriggers.c
|
||||||
|
@@ -97,19 +97,39 @@ static void rpmtriggersSortAndUniq(rpmtriggers trigs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void addTriggers(rpmts ts, Header trigH, rpmsenseFlags filter,
|
||||||
|
+ const char *prefix)
|
||||||
|
+{
|
||||||
|
+ int tix = 0;
|
||||||
|
+ rpmds ds;
|
||||||
|
+ rpmds triggers = rpmdsNew(trigH, RPMTAG_TRANSFILETRIGGERNAME, 0);
|
||||||
|
+
|
||||||
|
+ while ((ds = rpmdsFilterTi(triggers, tix))) {
|
||||||
|
+ if ((rpmdsNext(ds) >= 0) && (rpmdsFlags(ds) & filter) &&
|
||||||
|
+ strcmp(prefix, rpmdsN(ds)) == 0) {
|
||||||
|
+ struct rpmtd_s priorities;
|
||||||
|
+
|
||||||
|
+ if (headerGet(trigH, RPMTAG_TRANSFILETRIGGERPRIORITIES,
|
||||||
|
+ &priorities, HEADERGET_MINMEM)) {
|
||||||
|
+ rpmtdSetIndex(&priorities, tix);
|
||||||
|
+ rpmtriggersAdd(ts->trigs2run, headerGetInstance(trigH),
|
||||||
|
+ tix, *rpmtdGetUint32(&priorities));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ rpmdsFree(ds);
|
||||||
|
+ tix++;
|
||||||
|
+ }
|
||||||
|
+ rpmdsFree(triggers);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void rpmtriggersPrepPostUnTransFileTrigs(rpmts ts, rpmte te)
|
||||||
|
{
|
||||||
|
- rpmdbMatchIterator mi;
|
||||||
|
rpmdbIndexIterator ii;
|
||||||
|
- Header trigH;
|
||||||
|
const void *key;
|
||||||
|
size_t keylen;
|
||||||
|
rpmfiles files;
|
||||||
|
- rpmds rpmdsTriggers;
|
||||||
|
- rpmds rpmdsTrigger;
|
||||||
|
|
||||||
|
ii = rpmdbIndexIteratorInit(rpmtsGetRdb(ts), RPMDBI_TRANSFILETRIGGERNAME);
|
||||||
|
- mi = rpmdbNewIterator(rpmtsGetRdb(ts), RPMDBI_PACKAGES);
|
||||||
|
files = rpmteFiles(te);
|
||||||
|
|
||||||
|
/* Iterate over file triggers in rpmdb */
|
||||||
|
@@ -121,39 +141,20 @@ void rpmtriggersPrepPostUnTransFileTrigs(rpmts ts, rpmte te)
|
||||||
|
rpmfi fi = rpmfilesFindPrefix(files, pfx);
|
||||||
|
while (rpmfiNext(fi) >= 0) {
|
||||||
|
if (RPMFILE_IS_INSTALLED(rpmfiFState(fi))) {
|
||||||
|
- /* If yes then store it */
|
||||||
|
- rpmdbAppendIterator(mi, rpmdbIndexIteratorPkgOffsets(ii),
|
||||||
|
- rpmdbIndexIteratorNumPkgs(ii));
|
||||||
|
+ unsigned int npkg = rpmdbIndexIteratorNumPkgs(ii);
|
||||||
|
+ const unsigned int *offs = rpmdbIndexIteratorPkgOffsets(ii);
|
||||||
|
+ /* Save any postun triggers matching this prefix */
|
||||||
|
+ for (int i = 0; i < npkg; i++) {
|
||||||
|
+ Header h = rpmdbGetHeaderAt(rpmtsGetRdb(ts), offs[i]);
|
||||||
|
+ addTriggers(ts, h, RPMSENSE_TRIGGERPOSTUN, pfx);
|
||||||
|
+ headerFree(h);
|
||||||
|
+ }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rpmfiFree(fi);
|
||||||
|
}
|
||||||
|
rpmdbIndexIteratorFree(ii);
|
||||||
|
-
|
||||||
|
- if (rpmdbGetIteratorCount(mi)) {
|
||||||
|
- /* Filter triggers and save only trans postun triggers into ts */
|
||||||
|
- while ((trigH = rpmdbNextIterator(mi)) != NULL) {
|
||||||
|
- int tix = 0;
|
||||||
|
- rpmdsTriggers = rpmdsNew(trigH, RPMTAG_TRANSFILETRIGGERNAME, 0);
|
||||||
|
- while ((rpmdsTrigger = rpmdsFilterTi(rpmdsTriggers, tix))) {
|
||||||
|
- if ((rpmdsNext(rpmdsTrigger) >= 0) &&
|
||||||
|
- (rpmdsFlags(rpmdsTrigger) & RPMSENSE_TRIGGERPOSTUN)) {
|
||||||
|
- struct rpmtd_s priorities;
|
||||||
|
-
|
||||||
|
- headerGet(trigH, RPMTAG_TRANSFILETRIGGERPRIORITIES,
|
||||||
|
- &priorities, HEADERGET_MINMEM);
|
||||||
|
- rpmtdSetIndex(&priorities, tix);
|
||||||
|
- rpmtriggersAdd(ts->trigs2run, rpmdbGetIteratorOffset(mi),
|
||||||
|
- tix, *rpmtdGetUint32(&priorities));
|
||||||
|
- }
|
||||||
|
- rpmdsFree(rpmdsTrigger);
|
||||||
|
- tix++;
|
||||||
|
- }
|
||||||
|
- rpmdsFree(rpmdsTriggers);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- rpmdbFreeIterator(mi);
|
||||||
|
rpmfilesFree(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.35.1
|
||||||
|
|
@ -0,0 +1,13 @@
|
|||||||
|
diff -up rpm-4.16.1.3/tools/hashtab.c.orig rpm-4.16.1.3/tools/hashtab.c
|
||||||
|
--- rpm-4.16.1.3/tools/hashtab.c.orig 2021-07-01 14:51:24.576237269 +0200
|
||||||
|
+++ rpm-4.16.1.3/tools/hashtab.c 2021-07-01 15:02:42.005754968 +0200
|
||||||
|
@@ -292,7 +292,8 @@ htab_expand (htab)
|
||||||
|
}
|
||||||
|
while (p < olimit);
|
||||||
|
|
||||||
|
- free (oentries);
|
||||||
|
+ if (oentries != htab->entries)
|
||||||
|
+ free(oentries);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,286 @@
|
|||||||
|
commit c7d7c5acd0c14d0450016887cba1d86483086794
|
||||||
|
Author: Michal Domonkos <mdomonko@redhat.com>
|
||||||
|
Date: Mon Jun 21 10:05:10 2021 +0200
|
||||||
|
|
||||||
|
Add quoting to literal curly brackets
|
||||||
|
|
||||||
|
These curly brackets are already treated as literals by the shell, so
|
||||||
|
let's make that explicit for clarity, and silence a ShellCheck warning
|
||||||
|
at the same time.
|
||||||
|
|
||||||
|
More info: https://github.com/koalaman/shellcheck/wiki/SC1083
|
||||||
|
|
||||||
|
Found by ShellCheck.
|
||||||
|
|
||||||
|
Adjusted for 4.16.1.3
|
||||||
|
|
||||||
|
diff -up rpm-4.16.1.3/scripts/check-rpaths-worker.orig rpm-4.16.1.3/scripts/check-rpaths-worker
|
||||||
|
--- rpm-4.16.1.3/scripts/check-rpaths-worker.orig 2021-06-29 15:34:31.671003589 +0200
|
||||||
|
+++ rpm-4.16.1.3/scripts/check-rpaths-worker 2021-06-29 15:34:51.993414093 +0200
|
||||||
|
@@ -120,13 +120,13 @@ for i; do
|
||||||
|
(/lib64/*|/usr/lib64/*|/usr/X11R6/lib64/*|/usr/local/lib64/*)
|
||||||
|
badness=0;;
|
||||||
|
|
||||||
|
- (\$ORIGIN|\${ORIGINX}|\$ORIGIN/*|\${ORIGINX}/*)
|
||||||
|
+ (\$ORIGIN|\$\{ORIGINX\}|\$ORIGIN/*|\$\{ORIGINX\}/*)
|
||||||
|
test $allow_ORIGIN -eq 0 && badness=8 || {
|
||||||
|
badness=0
|
||||||
|
new_allow_ORIGIN=1
|
||||||
|
}
|
||||||
|
;;
|
||||||
|
- (/*\$PLATFORM*|/*\${PLATFORM}*|/*\$LIB*|/*\${LIB}*)
|
||||||
|
+ (/*\$PLATFORM*|/*\$\{PLATFORM\}*|/*\$LIB*|/*\$\{LIB\}*)
|
||||||
|
badness=0;;
|
||||||
|
|
||||||
|
(/lib|/usr/lib|/usr/X11R6/lib)
|
||||||
|
From d8dc4fd37b1d90cd97de7fcf484d449ec132c9b3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Domonkos <mdomonko@redhat.com>
|
||||||
|
Date: Wed, 9 Jun 2021 21:31:40 +0200
|
||||||
|
Subject: [PATCH 1/7] Fix memory leak in sqlexec()
|
||||||
|
|
||||||
|
Callers are supposed to free the error strings themselves:
|
||||||
|
https://www.sqlite.org/capi3ref.html#sqlite3_exec
|
||||||
|
|
||||||
|
Found by Coverity.
|
||||||
|
---
|
||||||
|
lib/backend/sqlite.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/lib/backend/sqlite.c b/lib/backend/sqlite.c
|
||||||
|
index 7c2de45aa..dbefeb163 100644
|
||||||
|
--- a/lib/backend/sqlite.c
|
||||||
|
+++ b/lib/backend/sqlite.c
|
||||||
|
@@ -233,6 +233,7 @@ static int sqlexec(sqlite3 *sdb, const char *fmt, ...)
|
||||||
|
rpmlog(RPMLOG_DEBUG, "%s: %d\n", cmd, rc);
|
||||||
|
|
||||||
|
sqlite3_free(cmd);
|
||||||
|
+ sqlite3_free(err);
|
||||||
|
|
||||||
|
return rc ? RPMRC_FAIL : RPMRC_OK;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
|
From 5baf73feb4951cc3b3f553a4b18d3b3599cbf87c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Domonkos <mdomonko@redhat.com>
|
||||||
|
Date: Fri, 25 Jun 2021 11:21:46 +0200
|
||||||
|
Subject: [PATCH 2/7] Always free the arg list passed to rpmGlob()
|
||||||
|
|
||||||
|
Even though the actual implementation of rpmGlob() does not allocate the
|
||||||
|
passed arg list (av) if the return code (rc) is non-zero or arg count
|
||||||
|
(ac) is 0, it's the responsibility of the caller (rpmInstall() here) to
|
||||||
|
free that memory, so make sure we do that irrespectively of the above
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
Found by Coverity.
|
||||||
|
---
|
||||||
|
lib/rpminstall.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/lib/rpminstall.c b/lib/rpminstall.c
|
||||||
|
index 724126e94..302ec0ba1 100644
|
||||||
|
--- a/lib/rpminstall.c
|
||||||
|
+++ b/lib/rpminstall.c
|
||||||
|
@@ -461,6 +461,7 @@ int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv)
|
||||||
|
rpmlog(RPMLOG_ERR, _("File not found by glob: %s\n"), *eiu->fnp);
|
||||||
|
}
|
||||||
|
eiu->numFailed++;
|
||||||
|
+ argvFree(av);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
|
From 3c8b01b67ec907afaaffe71691fa41b878578527 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Domonkos <mdomonko@redhat.com>
|
||||||
|
Date: Mon, 14 Jun 2021 10:21:25 +0200
|
||||||
|
Subject: [PATCH 3/7] Fix resource leak in Fts_children()
|
||||||
|
|
||||||
|
This function is not used anywhere within our codebase (and neither is
|
||||||
|
it part of the public API) so it's basically a no-op... Still, rather
|
||||||
|
than yanking it completely, let's just silence the Coverity error here.
|
||||||
|
|
||||||
|
Found by Coverity.
|
||||||
|
---
|
||||||
|
misc/fts.c | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/misc/fts.c b/misc/fts.c
|
||||||
|
index d3ebb2946..caf27495d 100644
|
||||||
|
--- a/misc/fts.c
|
||||||
|
+++ b/misc/fts.c
|
||||||
|
@@ -585,8 +585,10 @@ Fts_children(FTS * sp, int instr)
|
||||||
|
if ((fd = __open(".", O_RDONLY, 0)) < 0)
|
||||||
|
return (NULL);
|
||||||
|
sp->fts_child = fts_build(sp, instr);
|
||||||
|
- if (__fchdir(fd))
|
||||||
|
+ if (__fchdir(fd)) {
|
||||||
|
+ (void)__close(fd);
|
||||||
|
return (NULL);
|
||||||
|
+ }
|
||||||
|
(void)__close(fd);
|
||||||
|
return (sp->fts_child);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
|
From 39b7bf8579e0522cf16347b3a7e332d3b6d742c6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Domonkos <mdomonko@redhat.com>
|
||||||
|
Date: Mon, 14 Jun 2021 12:34:23 +0200
|
||||||
|
Subject: [PATCH 4/7] Fix memory leak in fts_build()
|
||||||
|
|
||||||
|
Turns out this leak is already fixed in glibc's current version of fts.c
|
||||||
|
(where our copy originates from), so let's just backport that.
|
||||||
|
|
||||||
|
Original commit in glibc:
|
||||||
|
https://sourceware.org/git/?p=glibc.git;\
|
||||||
|
a=commit;h=db67c2c98b89a5723af44df54f38b779de8d4a65
|
||||||
|
|
||||||
|
Found by Coverity.
|
||||||
|
---
|
||||||
|
misc/fts.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/misc/fts.c b/misc/fts.c
|
||||||
|
index caf27495d..f7fce0eaa 100644
|
||||||
|
--- a/misc/fts.c
|
||||||
|
+++ b/misc/fts.c
|
||||||
|
@@ -855,6 +855,7 @@ mem1: saved_errno = errno;
|
||||||
|
fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
|
||||||
|
cur->fts_info = FTS_ERR;
|
||||||
|
SET(FTS_STOP);
|
||||||
|
+ fts_lfree(head);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -862,6 +863,7 @@ mem1: saved_errno = errno;
|
||||||
|
if (!nitems) {
|
||||||
|
if (type == BREAD)
|
||||||
|
cur->fts_info = FTS_DP;
|
||||||
|
+ fts_lfree(head);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
|
From 9c093c4f092dd6bd1e0c8d2b852a72b74db076c2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Domonkos <mdomonko@redhat.com>
|
||||||
|
Date: Tue, 15 Jun 2021 13:34:21 +0200
|
||||||
|
Subject: [PATCH 5/7] Fix memory leak in decodePkts()
|
||||||
|
|
||||||
|
Found by Coverity.
|
||||||
|
---
|
||||||
|
rpmio/rpmpgp.c | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
|
||||||
|
index c59185dce..ee5c81e24 100644
|
||||||
|
--- a/rpmio/rpmpgp.c
|
||||||
|
+++ b/rpmio/rpmpgp.c
|
||||||
|
@@ -1371,9 +1371,13 @@ static pgpArmor decodePkts(uint8_t *b, uint8_t **pkt, size_t *pktlen)
|
||||||
|
crc = pgpCRC(dec, declen);
|
||||||
|
if (crcpkt != crc) {
|
||||||
|
ec = PGPARMOR_ERR_CRC_CHECK;
|
||||||
|
+ _free(dec);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
- if (pkt) *pkt = dec;
|
||||||
|
+ if (pkt)
|
||||||
|
+ *pkt = dec;
|
||||||
|
+ else
|
||||||
|
+ _free(dec);
|
||||||
|
if (pktlen) *pktlen = declen;
|
||||||
|
ec = PGPARMOR_PUBKEY; /* XXX ASCII Pubkeys only, please. */
|
||||||
|
goto exit;
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
|
From 590b2fc06252567eb7d57197dc361a8b459d62a3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Domonkos <mdomonko@redhat.com>
|
||||||
|
Date: Mon, 21 Jun 2021 17:51:14 +0200
|
||||||
|
Subject: [PATCH 6/7] Fix memory leak with multiple %lang-s in one line
|
||||||
|
|
||||||
|
We permit two equivalent forms of specifying a list of languages per
|
||||||
|
file:
|
||||||
|
|
||||||
|
%lang(xx,yy,zz) /path/to/file
|
||||||
|
%lang(xx) %lang(yy) %lang(zz) /path/to/file
|
||||||
|
|
||||||
|
The leak was when parsing the second form.
|
||||||
|
|
||||||
|
Found by Coverity.
|
||||||
|
---
|
||||||
|
build/files.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/build/files.c b/build/files.c
|
||||||
|
index f8153ad2b..0c8859f6c 100644
|
||||||
|
--- a/build/files.c
|
||||||
|
+++ b/build/files.c
|
||||||
|
@@ -777,6 +777,8 @@ static rpmRC parseForLang(char * buf, FileEntry cur)
|
||||||
|
|
||||||
|
if (*pe == ',') pe++; /* skip , if present */
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ q = _free(q);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = RPMRC_OK;
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
||||||
|
From b7a1e996326ee29a163d67ceb1e6127fdc251c14 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Domonkos <mdomonko@redhat.com>
|
||||||
|
Date: Fri, 25 Jun 2021 15:15:08 +0200
|
||||||
|
Subject: [PATCH 7/7] Fix memory leaks in Lua rex extension
|
||||||
|
|
||||||
|
This covers the following usage:
|
||||||
|
|
||||||
|
expr = rex.newPOSIX(<regex>)
|
||||||
|
expr:match(<string>) # A leak occurred here
|
||||||
|
expr:gmatch(<string>, <func>) # A leak occurred here
|
||||||
|
|
||||||
|
Found by Coverity.
|
||||||
|
---
|
||||||
|
luaext/lrexlib.c | 9 ++++++---
|
||||||
|
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/luaext/lrexlib.c b/luaext/lrexlib.c
|
||||||
|
index 09c5a6454..0f29b6371 100644
|
||||||
|
--- a/luaext/lrexlib.c
|
||||||
|
+++ b/luaext/lrexlib.c
|
||||||
|
@@ -80,6 +80,7 @@ static void rex_push_matches(lua_State *L, const char *text, regmatch_t *match,
|
||||||
|
|
||||||
|
static int rex_match(lua_State *L)
|
||||||
|
{
|
||||||
|
+ int rc = 0;
|
||||||
|
int res;
|
||||||
|
#ifdef REG_BASIC
|
||||||
|
size_t len;
|
||||||
|
@@ -109,9 +110,10 @@ static int rex_match(lua_State *L)
|
||||||
|
lua_pushstring(L, "n");
|
||||||
|
lua_pushnumber(L, ncapt);
|
||||||
|
lua_rawset(L, -3);
|
||||||
|
- return 3;
|
||||||
|
- } else
|
||||||
|
- return 0;
|
||||||
|
+ rc = 3;
|
||||||
|
+ }
|
||||||
|
+ free(match);
|
||||||
|
+ return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rex_gmatch(lua_State *L)
|
||||||
|
@@ -158,6 +160,7 @@ static int rex_gmatch(lua_State *L)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lua_pushnumber(L, nmatch);
|
||||||
|
+ free(match);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,51 @@
|
|||||||
|
From f1634250587479d664b34b6de1a6546b2c2b9de5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Festi <ffesti@redhat.com>
|
||||||
|
Date: Mon, 18 Jan 2021 15:02:34 +0100
|
||||||
|
Subject: [PATCH] rpm2archive: Add more error handling
|
||||||
|
|
||||||
|
Cleanly error out if file can't be written instead of segfaulting
|
||||||
|
|
||||||
|
Resolves: #1091
|
||||||
|
---
|
||||||
|
rpm2archive.c | 17 ++++++++++++-----
|
||||||
|
1 file changed, 12 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/rpm2archive.c b/rpm2archive.c
|
||||||
|
index 646f1663d..15c5da016 100644
|
||||||
|
--- a/rpm2archive.c
|
||||||
|
+++ b/rpm2archive.c
|
||||||
|
@@ -119,9 +119,14 @@ static int process_package(rpmts ts, char * filename)
|
||||||
|
|
||||||
|
/* create archive */
|
||||||
|
a = archive_write_new();
|
||||||
|
- archive_write_add_filter_gzip(a);
|
||||||
|
- archive_write_set_format_pax_restricted(a);
|
||||||
|
-
|
||||||
|
+ if (archive_write_add_filter_gzip(a) != ARCHIVE_OK) {
|
||||||
|
+ fprintf(stderr, "Error: Could not create gzip output filter\n");
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
+ }
|
||||||
|
+ if (archive_write_set_format_pax_restricted(a) != ARCHIVE_OK) {
|
||||||
|
+ fprintf(stderr, "Error: Format pax restricted is not supported\n");
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
+ }
|
||||||
|
if (!strcmp(filename, "-")) {
|
||||||
|
if (isatty(STDOUT_FILENO)) {
|
||||||
|
fprintf(stderr, "Error: refusing to output archive data to a terminal.\n");
|
||||||
|
@@ -130,9 +135,11 @@ static int process_package(rpmts ts, char * filename)
|
||||||
|
archive_write_open_fd(a, STDOUT_FILENO);
|
||||||
|
} else {
|
||||||
|
char * outname = rstrscat(NULL, filename, ".tgz", NULL);
|
||||||
|
- archive_write_open_filename(a, outname);
|
||||||
|
+ if (archive_write_open_filename(a, outname) != ARCHIVE_OK) {
|
||||||
|
+ fprintf(stderr, "Error: Can't open output file: %s\n", outname);
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
+ }
|
||||||
|
_free(outname);
|
||||||
|
- // XXX error handling
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = archive_entry_new();
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,173 @@
|
|||||||
|
From d8a169164cf40fc1cf6448792c1fa991f19bb375 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Florian Festi <ffesti@redhat.com>
|
||||||
|
Date: Thu, 22 Apr 2021 14:50:34 +0200
|
||||||
|
Subject: [PATCH] Add --nocompression option to rpm2archive
|
||||||
|
|
||||||
|
Also use popt for the command line handling. As we are using librpm
|
||||||
|
anyway there is no reason to keep the dependencies low (as with
|
||||||
|
rpm2cpio).
|
||||||
|
|
||||||
|
Resolves: #1530
|
||||||
|
---
|
||||||
|
doc/rpm2archive.8 | 16 ++++++++++---
|
||||||
|
rpm2archive.c | 60 ++++++++++++++++++++++++++++++++++-------------
|
||||||
|
2 files changed, 57 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/doc/rpm2archive.8 b/doc/rpm2archive.8
|
||||||
|
index 8bd6d4ed9d..3895d01981 100644
|
||||||
|
--- a/doc/rpm2archive.8
|
||||||
|
+++ b/doc/rpm2archive.8
|
||||||
|
@@ -3,10 +3,10 @@
|
||||||
|
.SH NAME
|
||||||
|
rpm2archive \- Create tar archive from RPM Package Manager (RPM) package.
|
||||||
|
.SH SYNOPSIS
|
||||||
|
-\fBrpm2archive\fP [filename]
|
||||||
|
+\fBrpm2archive\fP \fB{-n|--nocompression}\fR \fB\fIFILES\fB\fR
|
||||||
|
.SH DESCRIPTION
|
||||||
|
-\fBrpm2archive\fP converts the .rpm files specified as arguments to gz
|
||||||
|
-compressed tar files with suffix ".tgz".
|
||||||
|
+\fBrpm2archive\fP converts the .rpm files specified as arguments to
|
||||||
|
+tar files. By default they are gzip compressed and saved with postfix ".tgz".
|
||||||
|
|
||||||
|
If '-' is given as argument, an rpm stream is read from standard in and
|
||||||
|
written to standard out.
|
||||||
|
@@ -16,6 +16,16 @@ containing files greater than 4GB which are not supported by cpio. Unless
|
||||||
|
\fBrpm2cpio\fP \fBrpm2archive\fP needs a working rpm installation which limits
|
||||||
|
its usefulness for some disaster recovery scenarios.
|
||||||
|
|
||||||
|
+.SH "OPTIONS"
|
||||||
|
+.TP
|
||||||
|
+\fB\-n, --nocompression\fR
|
||||||
|
+Generate uncompressed tar archive and use ".tar" as postfix of the
|
||||||
|
+file name.
|
||||||
|
+.PP
|
||||||
|
+
|
||||||
|
+.SH EXAMPLES
|
||||||
|
+.PP
|
||||||
|
+
|
||||||
|
.br
|
||||||
|
.I "\fBrpm2archive glint-1.0-1.i386.rpm ; tar -xvz glint-1.0-1.i386.rpm.tgz\fP"
|
||||||
|
.br
|
||||||
|
diff --git a/rpm2archive.c b/rpm2archive.c
|
||||||
|
index d96db006ea..cb39c7a712 100644
|
||||||
|
--- a/rpm2archive.c
|
||||||
|
+++ b/rpm2archive.c
|
||||||
|
@@ -10,6 +10,8 @@
|
||||||
|
|
||||||
|
#include <rpm/rpmts.h>
|
||||||
|
|
||||||
|
+#include <popt.h>
|
||||||
|
+
|
||||||
|
#include <archive.h>
|
||||||
|
#include <archive_entry.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
@@ -18,6 +20,16 @@
|
||||||
|
|
||||||
|
#define BUFSIZE (128*1024)
|
||||||
|
|
||||||
|
+int compress = 1;
|
||||||
|
+
|
||||||
|
+static struct poptOption optionsTable[] = {
|
||||||
|
+ { "nocompression", 'n', POPT_ARG_VAL, &compress, 0,
|
||||||
|
+ N_("create uncompressed tar file"),
|
||||||
|
+ NULL },
|
||||||
|
+ POPT_AUTOHELP
|
||||||
|
+ POPT_TABLEEND
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static void fill_archive_entry(struct archive * a, struct archive_entry * entry, rpmfi fi)
|
||||||
|
{
|
||||||
|
archive_entry_clear(entry);
|
||||||
|
@@ -60,7 +72,7 @@ static void write_file_content(struct archive * a, char * buf, rpmfi fi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int process_package(rpmts ts, char * filename)
|
||||||
|
+static int process_package(rpmts ts, const char * filename)
|
||||||
|
{
|
||||||
|
FD_t fdi;
|
||||||
|
FD_t gzdi;
|
||||||
|
@@ -119,9 +131,11 @@ static int process_package(rpmts ts, char * filename)
|
||||||
|
|
||||||
|
/* create archive */
|
||||||
|
a = archive_write_new();
|
||||||
|
- if (archive_write_add_filter_gzip(a) != ARCHIVE_OK) {
|
||||||
|
- fprintf(stderr, "Error: Could not create gzip output filter\n");
|
||||||
|
- exit(EXIT_FAILURE);
|
||||||
|
+ if (compress) {
|
||||||
|
+ if (archive_write_add_filter_gzip(a) != ARCHIVE_OK) {
|
||||||
|
+ fprintf(stderr, "%s\n", archive_error_string(a));
|
||||||
|
+ exit(EXIT_FAILURE);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
if (archive_write_set_format_pax_restricted(a) != ARCHIVE_OK) {
|
||||||
|
fprintf(stderr, "Error: Format pax restricted is not supported\n");
|
||||||
|
@@ -142,7 +156,12 @@ static int process_package(rpmts ts, char * filename)
|
||||||
|
}
|
||||||
|
archive_write_open_fd(a, STDOUT_FILENO);
|
||||||
|
} else {
|
||||||
|
- char * outname = rstrscat(NULL, filename, ".tgz", NULL);
|
||||||
|
+ char * outname = rstrscat(NULL, filename, NULL);
|
||||||
|
+ if (compress) {
|
||||||
|
+ outname = rstrscat(&outname, ".tgz", NULL);
|
||||||
|
+ } else {
|
||||||
|
+ outname = rstrscat(&outname, ".tar", NULL);
|
||||||
|
+ }
|
||||||
|
if (archive_write_open_filename(a, outname) != ARCHIVE_OK) {
|
||||||
|
fprintf(stderr, "Error: Can't open output file: %s\n", outname);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
@@ -203,21 +222,22 @@ static int process_package(rpmts ts, char * filename)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int main(int argc, char *argv[])
|
||||||
|
+int main(int argc, const char *argv[])
|
||||||
|
{
|
||||||
|
- int rc = 0, i;
|
||||||
|
+ int rc = 0;
|
||||||
|
+ poptContext optCon;
|
||||||
|
+ const char *fn;
|
||||||
|
|
||||||
|
xsetprogname(argv[0]); /* Portability call -- see system.h */
|
||||||
|
rpmReadConfigFiles(NULL, NULL);
|
||||||
|
|
||||||
|
- if (argc > 1 && (rstreq(argv[1], "-h") || rstreq(argv[1], "--help"))) {
|
||||||
|
- fprintf(stderr, "Usage: %s [file.rpm ...]\n", argv[0]);
|
||||||
|
+ optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
|
||||||
|
+ poptSetOtherOptionHelp(optCon, "[OPTIONS]* <FILES>");
|
||||||
|
+ if (argc < 2 || poptGetNextOpt(optCon) == 0) {
|
||||||
|
+ poptPrintUsage(optCon, stderr, 0);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (argc == 1)
|
||||||
|
- argv[argc++] = "-"; /* abuse NULL pointer at the end of argv */
|
||||||
|
-
|
||||||
|
rpmts ts = rpmtsCreate();
|
||||||
|
rpmVSFlags vsflags = 0;
|
||||||
|
|
||||||
|
@@ -227,13 +247,21 @@ int main(int argc, char *argv[])
|
||||||
|
vsflags |= RPMVSF_NOHDRCHK;
|
||||||
|
(void) rpmtsSetVSFlags(ts, vsflags);
|
||||||
|
|
||||||
|
- for (i = 1; i < argc; i++) {
|
||||||
|
+ /* if no file name is given use stdin/stdout */
|
||||||
|
+ if (!poptPeekArg(optCon)) {
|
||||||
|
+ rc = process_package(ts, "-");
|
||||||
|
+ if (rc != 0)
|
||||||
|
+ goto exit;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- rc = process_package(ts, argv[i]);
|
||||||
|
+ while ((fn = poptGetArg(optCon)) != NULL) {
|
||||||
|
+ rc = process_package(ts, fn);
|
||||||
|
if (rc != 0)
|
||||||
|
- return rc;
|
||||||
|
+ goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ exit:
|
||||||
|
+ poptFreeContext(optCon);
|
||||||
|
(void) rpmtsFree(ts);
|
||||||
|
return rc;
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
commit 23770e1a4f28c56a31fe600cae332c77333b60b6
|
||||||
|
Author: Demi Marie Obenour <athena@invisiblethingslab.com>
|
||||||
|
Date: Sat Mar 6 03:23:41 2021 -0500
|
||||||
|
|
||||||
|
rpmsign: support EdDSA signatures
|
||||||
|
|
||||||
|
They were previously rejected
|
||||||
|
|
||||||
|
diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c
|
||||||
|
index 28cd91576..d8c84e937 100644
|
||||||
|
--- a/sign/rpmgensig.c
|
||||||
|
+++ b/sign/rpmgensig.c
|
||||||
|
@@ -155,6 +155,7 @@ static rpmtd makeSigTag(Header sigh, int ishdr, uint8_t *pkt, size_t pktlen)
|
||||||
|
pubkey_algo = pgpDigParamsAlgo(sigp, PGPVAL_PUBKEYALGO);
|
||||||
|
switch (pubkey_algo) {
|
||||||
|
case PGPPUBKEYALGO_DSA:
|
||||||
|
+ case PGPPUBKEYALGO_EDDSA:
|
||||||
|
sigtag = ishdr ? RPMSIGTAG_DSA : RPMSIGTAG_GPG;
|
||||||
|
break;
|
||||||
|
case PGPPUBKEYALGO_RSA:
|
@ -0,0 +1,40 @@
|
|||||||
|
From 6cdcdd8770d1f0b9ba706dcc1e6392a59dbe3fe5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Domonkos <mdomonko@redhat.com>
|
||||||
|
Date: Tue, 7 Dec 2021 08:08:37 +0100
|
||||||
|
Subject: [PATCH] Skip recorded symlinks in --setperms (RhBug:1900662)
|
||||||
|
|
||||||
|
If a package contains a symlink in the buildroot which is declared as a
|
||||||
|
ghost or config file but is a regular file or directory on the system
|
||||||
|
where it's installed, a --setperms call will reset its permissions to
|
||||||
|
those of a symlink (777 on Linux), which almost certainly is not the
|
||||||
|
correct thing to do.
|
||||||
|
|
||||||
|
To fix that, just skip files that were recorded as symlinks.
|
||||||
|
|
||||||
|
This is a special case of a general issue in --setperms; since file
|
||||||
|
permission semantics may change depending on the file type, to stay on
|
||||||
|
the safe side, any (ghost or config) file whose type changes after
|
||||||
|
installation should probably be skipped. However, symlinks are the most
|
||||||
|
prominent case here, so let's just focus on that now and avoid adding
|
||||||
|
too much cleverness to a popt alias (this got us into trouble not too
|
||||||
|
long ago, see commits 38c2f6e and 0d83637). We may revisit this in the
|
||||||
|
eventual C implementation.
|
||||||
|
---
|
||||||
|
rpmpopt.in | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/rpmpopt.in b/rpmpopt.in
|
||||||
|
index 27d298651..d5a6b140b 100644
|
||||||
|
--- a/rpmpopt.in
|
||||||
|
+++ b/rpmpopt.in
|
||||||
|
@@ -44,6 +44,7 @@ rpm alias --scripts --qf '\
|
||||||
|
--POPTdesc=$"list install/erase scriptlets from package(s)"
|
||||||
|
|
||||||
|
rpm alias --setperms -q --qf '[\[ -L %{FILENAMES:shescape} \] || \
|
||||||
|
+ \[ -n %{FILELINKTOS:shescape} \] || \
|
||||||
|
( \[ $((%{FILEFLAGS} & 2#1001000)) != 0 \] && \[ ! -e %{FILENAMES:shescape} \] ) || \
|
||||||
|
chmod %7{FILEMODES:octal} %{FILENAMES:shescape}\n]' \
|
||||||
|
--pipe "grep -v \(none\) | grep '^. -L ' | sed 's/chmod .../chmod /' | sh" \
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
@ -0,0 +1,39 @@
|
|||||||
|
From c771ae28e28b2971869b7801ffc7961f4dcb6544 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Panu Matilainen <pmatilai@redhat.com>
|
||||||
|
Date: Thu, 10 Jun 2021 10:32:12 +0300
|
||||||
|
Subject: [PATCH] Support hash v8 databases from BDB < 4.6 in bdb_ro
|
||||||
|
|
||||||
|
In Hash v8 databases page type differs from newer ones to denote
|
||||||
|
the difference between sorted and unsorted pages.
|
||||||
|
|
||||||
|
Fixes reading rpm databases from older distros like SLES 11 and RHEL 5
|
||||||
|
(RhBug:1965147)
|
||||||
|
---
|
||||||
|
lib/backend/bdb_ro.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/backend/bdb_ro.c b/lib/backend/bdb_ro.c
|
||||||
|
index 2667ec845..695ef78e3 100644
|
||||||
|
--- a/lib/backend/bdb_ro.c
|
||||||
|
+++ b/lib/backend/bdb_ro.c
|
||||||
|
@@ -276,7 +276,7 @@ static int hash_lookup(struct bdb_cur *cur, const unsigned char *key, unsigned i
|
||||||
|
pg = hash_bucket_to_page(cur->db, bucket);
|
||||||
|
if (bdb_getpage(cur->db, cur->page, pg))
|
||||||
|
return -1;
|
||||||
|
- if (cur->page[25] != 8 && cur->page[25] != 13)
|
||||||
|
+ if (cur->page[25] != 8 && cur->page[25] != 13 && cur->page[25] != 2)
|
||||||
|
return -1;
|
||||||
|
cur->idx = (unsigned int)-2;
|
||||||
|
cur->numidx = *(uint16_t *)(cur->page + 20);
|
||||||
|
@@ -323,7 +323,7 @@ static int hash_next(struct bdb_cur *cur)
|
||||||
|
}
|
||||||
|
if (bdb_getpage(cur->db, cur->page, pg))
|
||||||
|
return -1;
|
||||||
|
- if (cur->page[25] != 8 && cur->page[25] != 13)
|
||||||
|
+ if (cur->page[25] != 8 && cur->page[25] != 13 && cur->page[25] != 2)
|
||||||
|
return -1;
|
||||||
|
cur->numidx = *(uint16_t *)(cur->page + 20);
|
||||||
|
continue;
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
commit cb6aa82dbc10d554f8d234e934ae7c77e39a3ce2
|
||||||
|
Author: Panu Matilainen <pmatilai@redhat.com>
|
||||||
|
Date: Tue Jan 12 13:35:23 2021 +0200
|
||||||
|
|
||||||
|
Unblock signals in forked scriptlets
|
||||||
|
|
||||||
|
Since commit c5f82d3f6223ebd0c5cc0a07ea60393ae7284929 we've blocked
|
||||||
|
most signals during transactions, which makes sense to rpm itself but
|
||||||
|
the signal mask is inherited to childs and carried even across exec(),
|
||||||
|
so all scriptlets are executing with those signals blocked as well.
|
||||||
|
Which in turn does not make sense, the scriptlets could run stuff that
|
||||||
|
actually depends on signal delivery (such as SIGALARM in RhBug:1913765).
|
||||||
|
|
||||||
|
Unblock all signals for forked scriptlet execution (Lua scriptlets are
|
||||||
|
totally different as they execute in-process for now)
|
||||||
|
|
||||||
|
diff --git a/lib/rpmscript.c b/lib/rpmscript.c
|
||||||
|
index 2ae3378f7..c69d29554 100644
|
||||||
|
--- a/lib/rpmscript.c
|
||||||
|
+++ b/lib/rpmscript.c
|
||||||
|
@@ -152,6 +152,11 @@ static void doScriptExec(ARGV_const_t argv, ARGV_const_t prefixes,
|
||||||
|
FD_t scriptFd, FD_t out)
|
||||||
|
{
|
||||||
|
int xx;
|
||||||
|
+ sigset_t set;
|
||||||
|
+
|
||||||
|
+ /* Unmask all signals, the scripts may need them */
|
||||||
|
+ sigfillset(&set);
|
||||||
|
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
|
||||||
|
|
||||||
|
/* SIGPIPE is ignored in rpm, reset to default for the scriptlet */
|
||||||
|
(void) signal(SIGPIPE, SIG_DFL);
|
@ -0,0 +1,144 @@
|
|||||||
|
From 137ecc2e1841c2b27b99d4db9006253dd1c73dde Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
Date: Fri, 4 Jun 2021 23:30:49 +0200
|
||||||
|
Subject: [PATCH] Unbreak checking of installed rich dependencies
|
||||||
|
|
||||||
|
Commit ddb32b9187e9ce85819a84ca8d202131fd9f8b9f added an
|
||||||
|
extra check that tests if the provide we are checking really
|
||||||
|
intersects the dependency from rpmdb. Unfortunately the
|
||||||
|
rpmdsCompare() call does not understand rich dependencies and
|
||||||
|
will consider them as not intersecting.
|
||||||
|
|
||||||
|
Unbreak the check by not doing the intersection test for
|
||||||
|
rich dependencies. We'll improve this in a later commit.
|
||||||
|
|
||||||
|
Also add test cases for dependency problems with installed
|
||||||
|
rich dependencies.
|
||||||
|
---
|
||||||
|
lib/depends.c | 2 +-
|
||||||
|
tests/rpmdeps.at | 99 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 100 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/lib/depends.c b/lib/depends.c
|
||||||
|
index c10ba4bda..fecbd9675 100644
|
||||||
|
--- a/lib/depends.c
|
||||||
|
+++ b/lib/depends.c
|
||||||
|
@@ -846,7 +846,7 @@ static void checkInstDeps(rpmts ts, depCache dcache, rpmte te,
|
||||||
|
rpmdsSetIx(ds, rpmdbGetIteratorFileNum(mi));
|
||||||
|
|
||||||
|
/* Is it in our range at all? (but file deps have no range) */
|
||||||
|
- if (depds)
|
||||||
|
+ if (depds && !rpmdsIsRich(ds))
|
||||||
|
match = rpmdsCompare(ds, depds);
|
||||||
|
|
||||||
|
if (match && unsatisfiedDepend(ts, dcache, ds) == is_problem) {
|
||||||
|
diff --git a/tests/rpmdeps.at b/tests/rpmdeps.at
|
||||||
|
index 67bde1dc8..8357af9df 100644
|
||||||
|
--- a/tests/rpmdeps.at
|
||||||
|
+++ b/tests/rpmdeps.at
|
||||||
|
@@ -732,3 +732,102 @@ runroot rpm -U /build/RPMS/noarch/deptest-one-1.0-1.noarch.rpm /build/RPMS/noarc
|
||||||
|
[],
|
||||||
|
[])
|
||||||
|
AT_CLEANUP
|
||||||
|
+
|
||||||
|
+# ------------------------------
|
||||||
|
+#
|
||||||
|
+AT_SETUP([install to break installed rich dependency])
|
||||||
|
+AT_KEYWORDS([install, boolean])
|
||||||
|
+RPMDB_INIT
|
||||||
|
+
|
||||||
|
+runroot rpmbuild --quiet -bb \
|
||||||
|
+ --define "pkg one" \
|
||||||
|
+ --define "cfls (deptest-three or deptest-five)" \
|
||||||
|
+ /data/SPECS/deptest.spec
|
||||||
|
+runroot rpmbuild --quiet -bb \
|
||||||
|
+ --define "pkg two" \
|
||||||
|
+ --define "reqs (deptest-five if deptest-four)" \
|
||||||
|
+ /data/SPECS/deptest.spec
|
||||||
|
+runroot rpmbuild --quiet -bb \
|
||||||
|
+ --define "pkg three" \
|
||||||
|
+ /data/SPECS/deptest.spec
|
||||||
|
+runroot rpmbuild --quiet -bb \
|
||||||
|
+ --define "pkg four" \
|
||||||
|
+ /data/SPECS/deptest.spec
|
||||||
|
+
|
||||||
|
+# installed conflict with "or" clause
|
||||||
|
+AT_CHECK([
|
||||||
|
+RPMDB_INIT
|
||||||
|
+
|
||||||
|
+runroot rpm -U /build/RPMS/noarch/deptest-one-1.0-1.noarch.rpm
|
||||||
|
+runroot rpm -U /build/RPMS/noarch/deptest-three-1.0-1.noarch.rpm
|
||||||
|
+],
|
||||||
|
+[1],
|
||||||
|
+[],
|
||||||
|
+[error: Failed dependencies:
|
||||||
|
+ (deptest-three or deptest-five) conflicts with (installed) deptest-one-1.0-1.noarch
|
||||||
|
+])
|
||||||
|
+
|
||||||
|
+# installed requires with "if" clause
|
||||||
|
+AT_CHECK([
|
||||||
|
+RPMDB_INIT
|
||||||
|
+
|
||||||
|
+runroot rpm -U /build/RPMS/noarch/deptest-two-1.0-1.noarch.rpm
|
||||||
|
+runroot rpm -U /build/RPMS/noarch/deptest-four-1.0-1.noarch.rpm
|
||||||
|
+],
|
||||||
|
+[1],
|
||||||
|
+[],
|
||||||
|
+[error: Failed dependencies:
|
||||||
|
+ (deptest-five if deptest-four) is needed by (installed) deptest-two-1.0-1.noarch
|
||||||
|
+])
|
||||||
|
+AT_CLEANUP
|
||||||
|
+
|
||||||
|
+# ------------------------------
|
||||||
|
+#
|
||||||
|
+AT_SETUP([erase to break installed rich dependency])
|
||||||
|
+AT_KEYWORDS([install, boolean])
|
||||||
|
+RPMDB_INIT
|
||||||
|
+
|
||||||
|
+runroot rpmbuild --quiet -bb \
|
||||||
|
+ --define "pkg one" \
|
||||||
|
+ --define "reqs (deptest-three or deptest-five)" \
|
||||||
|
+ /data/SPECS/deptest.spec
|
||||||
|
+runroot rpmbuild --quiet -bb \
|
||||||
|
+ --define "pkg two" \
|
||||||
|
+ --define "cfls (deptest-five unless deptest-four)" \
|
||||||
|
+ /data/SPECS/deptest.spec
|
||||||
|
+runroot rpmbuild --quiet -bb \
|
||||||
|
+ --define "pkg three" \
|
||||||
|
+ /data/SPECS/deptest.spec
|
||||||
|
+runroot rpmbuild --quiet -bb \
|
||||||
|
+ --define "pkg four" \
|
||||||
|
+ /data/SPECS/deptest.spec
|
||||||
|
+runroot rpmbuild --quiet -bb \
|
||||||
|
+ --define "pkg five" \
|
||||||
|
+ /data/SPECS/deptest.spec
|
||||||
|
+
|
||||||
|
+# installed requires with "or" clause
|
||||||
|
+AT_CHECK([
|
||||||
|
+RPMDB_INIT
|
||||||
|
+
|
||||||
|
+runroot rpm -U /build/RPMS/noarch/deptest-one-1.0-1.noarch.rpm /build/RPMS/noarch/deptest-three-1.0-1.noarch.rpm
|
||||||
|
+runroot rpm -e deptest-three
|
||||||
|
+],
|
||||||
|
+[1],
|
||||||
|
+[],
|
||||||
|
+[error: Failed dependencies:
|
||||||
|
+ (deptest-three or deptest-five) is needed by (installed) deptest-one-1.0-1.noarch
|
||||||
|
+])
|
||||||
|
+
|
||||||
|
+# installed conflicts with "unless" clause
|
||||||
|
+AT_CHECK([
|
||||||
|
+RPMDB_INIT
|
||||||
|
+
|
||||||
|
+runroot rpm -U /build/RPMS/noarch/deptest-two-1.0-1.noarch.rpm /build/RPMS/noarch/deptest-four-1.0-1.noarch.rpm /build/RPMS/noarch/deptest-five-1.0-1.noarch.rpm
|
||||||
|
+runroot rpm -e deptest-four
|
||||||
|
+],
|
||||||
|
+[1],
|
||||||
|
+[],
|
||||||
|
+[error: Failed dependencies:
|
||||||
|
+ (deptest-five unless deptest-four) conflicts with (installed) deptest-two-1.0-1.noarch
|
||||||
|
+])
|
||||||
|
+AT_CLEANUP
|
||||||
|
--
|
||||||
|
2.33.1
|
||||||
|
|
@ -0,0 +1,401 @@
|
|||||||
|
From 32b21da4bae5b8fbe0f42c31b723c4963b4b2512 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Demi Marie Obenour <demi@invisiblethingslab.com>
|
||||||
|
Date: Thu, 6 May 2021 18:34:45 -0400
|
||||||
|
Subject: [PATCH] Validate and require subkey binding signatures on PGP public
|
||||||
|
keys
|
||||||
|
|
||||||
|
All subkeys must be followed by a binding signature by the primary key
|
||||||
|
as per the OpenPGP RFC, enforce the presence and validity in the parser.
|
||||||
|
|
||||||
|
The implementation is as kludgey as they come to work around our
|
||||||
|
simple-minded parser structure without touching API, to maximise
|
||||||
|
backportability. Store all the raw packets internally as we decode them
|
||||||
|
to be able to access previous elements at will, needed to validate ordering
|
||||||
|
and access the actual data. Add testcases for manipulated keys whose
|
||||||
|
import previously would succeed.
|
||||||
|
|
||||||
|
Combined with:
|
||||||
|
5ff86764b17f31535cb247543a90dd739076ec38
|
||||||
|
b5e8bc74b2b05aa557f663fe227b94d2bc64fbd8
|
||||||
|
9f03f42e2614a68f589f9db8fe76287146522c0c
|
||||||
|
b6dffb6dc5ffa2ddc389743f0507876cab341315 (mem-leak fix)
|
||||||
|
ae3d2d234ae47ff85229d3fce97a266fa1aa5a61 (use-after-free fix)
|
||||||
|
|
||||||
|
Fixes CVE-2021-3521.
|
||||||
|
---
|
||||||
|
rpmio/rpmpgp.c | 122 +++++++++++++++---
|
||||||
|
sign/rpmgensig.c | 2 +-
|
||||||
|
tests/Makefile.am | 3 +
|
||||||
|
tests/data/keys/CVE-2021-3521-badbind.asc | 25 ++++
|
||||||
|
.../data/keys/CVE-2021-3521-nosubsig-last.asc | 25 ++++
|
||||||
|
tests/data/keys/CVE-2021-3521-nosubsig.asc | 37 ++++++
|
||||||
|
tests/rpmsigdig.at | 28 ++++
|
||||||
|
7 files changed, 224 insertions(+), 18 deletions(-)
|
||||||
|
create mode 100644 tests/data/keys/CVE-2021-3521-badbind.asc
|
||||||
|
create mode 100644 tests/data/keys/CVE-2021-3521-nosubsig-last.asc
|
||||||
|
create mode 100644 tests/data/keys/CVE-2021-3521-nosubsig.asc
|
||||||
|
|
||||||
|
diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
|
||||||
|
index d0688ebe9..3372d577d 100644
|
||||||
|
--- a/rpmio/rpmpgp.c
|
||||||
|
+++ b/rpmio/rpmpgp.c
|
||||||
|
@@ -515,7 +515,7 @@ pgpDigAlg pgpDigAlgFree(pgpDigAlg alg)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo, uint8_t sigtype,
|
||||||
|
+static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo,
|
||||||
|
const uint8_t *p, const uint8_t *h, size_t hlen,
|
||||||
|
pgpDigParams sigp)
|
||||||
|
{
|
||||||
|
@@ -528,10 +528,8 @@ static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo, uint8_t sigtype,
|
||||||
|
int mpil = pgpMpiLen(p);
|
||||||
|
if (p + mpil > pend)
|
||||||
|
break;
|
||||||
|
- if (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT) {
|
||||||
|
- if (sigalg->setmpi(sigalg, i, p))
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
+ if (sigalg->setmpi(sigalg, i, p))
|
||||||
|
+ break;
|
||||||
|
p += mpil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -604,7 +602,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
|
||||||
|
}
|
||||||
|
|
||||||
|
p = ((uint8_t *)v) + sizeof(*v);
|
||||||
|
- rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp);
|
||||||
|
+ rc = pgpPrtSigParams(tag, v->pubkey_algo, p, h, hlen, _digp);
|
||||||
|
} break;
|
||||||
|
case 4:
|
||||||
|
{ pgpPktSigV4 v = (pgpPktSigV4)h;
|
||||||
|
@@ -662,7 +660,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
|
||||||
|
if (p > (h + hlen))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
- rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp);
|
||||||
|
+ rc = pgpPrtSigParams(tag, v->pubkey_algo, p, h, hlen, _digp);
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
rpmlog(RPMLOG_WARNING, _("Unsupported version of key: V%d\n"), version);
|
||||||
|
@@ -1041,36 +1039,127 @@ unsigned int pgpDigParamsAlgo(pgpDigParams digp, unsigned int algotype)
|
||||||
|
return algo;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static pgpDigParams pgpDigParamsNew(uint8_t tag)
|
||||||
|
+{
|
||||||
|
+ pgpDigParams digp = xcalloc(1, sizeof(*digp));
|
||||||
|
+ digp->tag = tag;
|
||||||
|
+ return digp;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int hashKey(DIGEST_CTX hash, const struct pgpPkt *pkt, int exptag)
|
||||||
|
+{
|
||||||
|
+ int rc = -1;
|
||||||
|
+ if (pkt->tag == exptag) {
|
||||||
|
+ uint8_t head[] = {
|
||||||
|
+ 0x99,
|
||||||
|
+ (pkt->blen >> 8),
|
||||||
|
+ (pkt->blen ),
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ rpmDigestUpdate(hash, head, 3);
|
||||||
|
+ rpmDigestUpdate(hash, pkt->body, pkt->blen);
|
||||||
|
+ rc = 0;
|
||||||
|
+ }
|
||||||
|
+ return rc;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int pgpVerifySelf(pgpDigParams key, pgpDigParams selfsig,
|
||||||
|
+ const struct pgpPkt *all, int i)
|
||||||
|
+{
|
||||||
|
+ int rc = -1;
|
||||||
|
+ DIGEST_CTX hash = NULL;
|
||||||
|
+
|
||||||
|
+ switch (selfsig->sigtype) {
|
||||||
|
+ case PGPSIGTYPE_SUBKEY_BINDING:
|
||||||
|
+ hash = rpmDigestInit(selfsig->hash_algo, 0);
|
||||||
|
+ if (hash) {
|
||||||
|
+ rc = hashKey(hash, &all[0], PGPTAG_PUBLIC_KEY);
|
||||||
|
+ if (!rc)
|
||||||
|
+ rc = hashKey(hash, &all[i-1], PGPTAG_PUBLIC_SUBKEY);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ /* ignore types we can't handle */
|
||||||
|
+ rc = 0;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (hash && rc == 0)
|
||||||
|
+ rc = pgpVerifySignature(key, selfsig, hash);
|
||||||
|
+
|
||||||
|
+ rpmDigestFinal(hash, NULL, NULL, 0);
|
||||||
|
+
|
||||||
|
+ return rc;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype,
|
||||||
|
pgpDigParams * ret)
|
||||||
|
{
|
||||||
|
const uint8_t *p = pkts;
|
||||||
|
const uint8_t *pend = pkts + pktlen;
|
||||||
|
pgpDigParams digp = NULL;
|
||||||
|
- struct pgpPkt pkt;
|
||||||
|
+ pgpDigParams selfsig = NULL;
|
||||||
|
+ int i = 0;
|
||||||
|
+ int alloced = 16; /* plenty for normal cases */
|
||||||
|
+ struct pgpPkt *all = xmalloc(alloced * sizeof(*all));
|
||||||
|
int rc = -1; /* assume failure */
|
||||||
|
+ int expect = 0;
|
||||||
|
+ int prevtag = 0;
|
||||||
|
|
||||||
|
while (p < pend) {
|
||||||
|
- if (decodePkt(p, (pend - p), &pkt))
|
||||||
|
+ struct pgpPkt *pkt = &all[i];
|
||||||
|
+ if (decodePkt(p, (pend - p), pkt))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (digp == NULL) {
|
||||||
|
- if (pkttype && pkt.tag != pkttype) {
|
||||||
|
+ if (pkttype && pkt->tag != pkttype) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
- digp = xcalloc(1, sizeof(*digp));
|
||||||
|
- digp->tag = pkt.tag;
|
||||||
|
+ digp = pgpDigParamsNew(pkt->tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (pgpPrtPkt(&pkt, digp))
|
||||||
|
+ if (expect) {
|
||||||
|
+ if (pkt->tag != expect)
|
||||||
|
+ break;
|
||||||
|
+ selfsig = pgpDigParamsNew(pkt->tag);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (pgpPrtPkt(pkt, selfsig ? selfsig : digp))
|
||||||
|
break;
|
||||||
|
|
||||||
|
- p += (pkt.body - pkt.head) + pkt.blen;
|
||||||
|
+ if (selfsig) {
|
||||||
|
+ /* subkeys must be followed by binding signature */
|
||||||
|
+ int xx = 1; /* assume failure */
|
||||||
|
+
|
||||||
|
+ if (!(prevtag == PGPTAG_PUBLIC_SUBKEY &&
|
||||||
|
+ selfsig->sigtype != PGPSIGTYPE_SUBKEY_BINDING))
|
||||||
|
+ xx = pgpVerifySelf(digp, selfsig, all, i);
|
||||||
|
+
|
||||||
|
+ selfsig = pgpDigParamsFree(selfsig);
|
||||||
|
+ if (xx)
|
||||||
|
+ break;
|
||||||
|
+ expect = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (pkt->tag == PGPTAG_PUBLIC_SUBKEY)
|
||||||
|
+ expect = PGPTAG_SIGNATURE;
|
||||||
|
+ prevtag = pkt->tag;
|
||||||
|
+
|
||||||
|
+ i++;
|
||||||
|
+ p += (pkt->body - pkt->head) + pkt->blen;
|
||||||
|
+ if (pkttype == PGPTAG_SIGNATURE)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (alloced <= i) {
|
||||||
|
+ alloced *= 2;
|
||||||
|
+ all = xrealloc(all, alloced * sizeof(*all));
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
- rc = (digp && (p == pend)) ? 0 : -1;
|
||||||
|
+ rc = (digp && (p == pend) && expect == 0) ? 0 : -1;
|
||||||
|
|
||||||
|
+ free(all);
|
||||||
|
if (ret && rc == 0) {
|
||||||
|
*ret = digp;
|
||||||
|
} else {
|
||||||
|
@@ -1105,8 +1194,7 @@ int pgpPrtParamsSubkeys(const uint8_t *pkts, size_t pktlen,
|
||||||
|
digps = xrealloc(digps, alloced * sizeof(*digps));
|
||||||
|
}
|
||||||
|
|
||||||
|
- digps[count] = xcalloc(1, sizeof(**digps));
|
||||||
|
- digps[count]->tag = PGPTAG_PUBLIC_SUBKEY;
|
||||||
|
+ digps[count] = pgpDigParamsNew(PGPTAG_PUBLIC_SUBKEY);
|
||||||
|
/* Copy UID from main key to subkey */
|
||||||
|
digps[count]->userid = xstrdup(mainkey->userid);
|
||||||
|
|
||||||
|
diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c
|
||||||
|
index e5d191cc0..988a0f611 100644
|
||||||
|
--- a/sign/rpmgensig.c
|
||||||
|
+++ b/sign/rpmgensig.c
|
||||||
|
@@ -351,7 +351,7 @@ static int haveSignature(rpmtd sigtd, Header h)
|
||||||
|
pgpPrtParams(oldtd.data, oldtd.count, PGPTAG_SIGNATURE, &sig2);
|
||||||
|
if (pgpDigParamsCmp(sig1, sig2) == 0)
|
||||||
|
rc = 1;
|
||||||
|
- pgpDigParamsFree(sig2);
|
||||||
|
+ sig2 = pgpDigParamsFree(sig2);
|
||||||
|
}
|
||||||
|
pgpDigParamsFree(sig1);
|
||||||
|
rpmtdFreeData(&oldtd);
|
||||||
|
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||||
|
index f742a9e1d..328234278 100644
|
||||||
|
--- a/tests/Makefile.am
|
||||||
|
+++ b/tests/Makefile.am
|
||||||
|
@@ -107,6 +107,9 @@ EXTRA_DIST += data/SPECS/hello-config-buildid.spec
|
||||||
|
EXTRA_DIST += data/SPECS/hello-cd.spec
|
||||||
|
EXTRA_DIST += data/keys/rpm.org-rsa-2048-test.pub
|
||||||
|
EXTRA_DIST += data/keys/rpm.org-rsa-2048-test.secret
|
||||||
|
+EXTRA_DIST += data/keys/CVE-2021-3521-badbind.asc
|
||||||
|
+EXTRA_DIST += data/keys/CVE-2021-3521-nosubsig.asc
|
||||||
|
+EXTRA_DIST += data/keys/CVE-2021-3521-nosubsig-last.asc
|
||||||
|
EXTRA_DIST += data/macros.testfile
|
||||||
|
EXTRA_DIST += data/macros.debug
|
||||||
|
EXTRA_DIST += data/SOURCES/foo.c
|
||||||
|
diff --git a/tests/data/keys/CVE-2021-3521-badbind.asc b/tests/data/keys/CVE-2021-3521-badbind.asc
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..aea00f9d7
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/data/keys/CVE-2021-3521-badbind.asc
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
+Version: rpm-4.17.90 (NSS-3)
|
||||||
|
+
|
||||||
|
+mQENBFjmORgBCAC7TMEk6wnjSs8Dr4yqSScWdU2pjcqrkTxuzdWvowcIUPZI0w/g
|
||||||
|
+HkRqGd4apjvY2V15kjL10gk3QhFP3pZ/9p7zh8o8NHX7aGdSGDK7NOq1eFaErPRY
|
||||||
|
+91LW9RiZ0lbOjXEzIL0KHxUiTQEmdXJT43DJMFPyW9fkCWg0OltiX618FUdWWfI8
|
||||||
|
+eySdLur1utnqBvdEbCUvWK2RX3vQZQdvEBODnNk2pxqTyV0w6VPQ96W++lF/5Aas
|
||||||
|
+7rUv3HIyIXxIggc8FRrnH+y9XvvHDonhTIlGnYZN4ubm9i4y3gOkrZlGTrEw7elQ
|
||||||
|
+1QeMyG2QQEbze8YjpTm4iLABCBrRfPRaQpwrABEBAAG0IXJwbS5vcmcgUlNBIHRl
|
||||||
|
+c3RrZXkgPHJzYUBycG0ub3JnPokBNwQTAQgAIQUCWOY5GAIbAwULCQgHAgYVCAkK
|
||||||
|
+CwIEFgIDAQIeAQIXgAAKCRBDRFkeGWTF/MxxCACnjqFL+MmPh9W9JQKT2DcLbBzf
|
||||||
|
+Cqo6wcEBoCOcwgRSk8dSikhARoteoa55JRJhuMyeKhhEAogE9HRmCPFdjezFTwgB
|
||||||
|
+BDVBpO2dZ023mLXDVCYX3S8pShOgCP6Tn4wqCnYeAdLcGg106N4xcmgtcssJE+Pr
|
||||||
|
+XzTZksbZsrTVEmL/Ym+R5w5jBfFnGk7Yw7ndwfQsfNXQb5AZynClFxnX546lcyZX
|
||||||
|
+fEx3/e6ezw57WNOUK6WT+8b+EGovPkbetK/rGxNXuWaP6X4A/QUm8O98nCuHYFQq
|
||||||
|
++mvNdsCBqGf7mhaRGtpHk/JgCn5rFvArMDqLVrR9hX0LdCSsH7EGE+bR3r7wuQEN
|
||||||
|
+BFjmORgBCACk+vDZrIXQuFXEYToZVwb2attzbbJJCqD71vmZTLsW0QxuPKRgbcYY
|
||||||
|
+zp4K4lVBnHhFrF8MOUOxJ7kQWIJZMZFt+BDcptCYurbD2H4W2xvnWViiC+LzCMzz
|
||||||
|
+iMJT6165uefL4JHTDPxC2fFiM9yrc72LmylJNkM/vepT128J5Qv0gRUaQbHiQuS6
|
||||||
|
+Dm/+WRnUfx3i89SV4mnBxb/Ta93GVqoOciWwzWSnwEnWYAvOb95JL4U7c5J5f/+c
|
||||||
|
+KnQDHsW7sIiIdscsWzvgf6qs2Ra1Zrt7Fdk4+ZS2f/adagLhDO1C24sXf5XfMk5m
|
||||||
|
+L0OGwZSr9m5s17VXxfspgU5ugc8kBJfzABEBAAE=
|
||||||
|
+=WCfs
|
||||||
|
+-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
+
|
||||||
|
diff --git a/tests/data/keys/CVE-2021-3521-nosubsig-last.asc b/tests/data/keys/CVE-2021-3521-nosubsig-last.asc
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..aea00f9d7
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/data/keys/CVE-2021-3521-nosubsig-last.asc
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
+Version: rpm-4.17.90 (NSS-3)
|
||||||
|
+
|
||||||
|
+mQENBFjmORgBCAC7TMEk6wnjSs8Dr4yqSScWdU2pjcqrkTxuzdWvowcIUPZI0w/g
|
||||||
|
+HkRqGd4apjvY2V15kjL10gk3QhFP3pZ/9p7zh8o8NHX7aGdSGDK7NOq1eFaErPRY
|
||||||
|
+91LW9RiZ0lbOjXEzIL0KHxUiTQEmdXJT43DJMFPyW9fkCWg0OltiX618FUdWWfI8
|
||||||
|
+eySdLur1utnqBvdEbCUvWK2RX3vQZQdvEBODnNk2pxqTyV0w6VPQ96W++lF/5Aas
|
||||||
|
+7rUv3HIyIXxIggc8FRrnH+y9XvvHDonhTIlGnYZN4ubm9i4y3gOkrZlGTrEw7elQ
|
||||||
|
+1QeMyG2QQEbze8YjpTm4iLABCBrRfPRaQpwrABEBAAG0IXJwbS5vcmcgUlNBIHRl
|
||||||
|
+c3RrZXkgPHJzYUBycG0ub3JnPokBNwQTAQgAIQUCWOY5GAIbAwULCQgHAgYVCAkK
|
||||||
|
+CwIEFgIDAQIeAQIXgAAKCRBDRFkeGWTF/MxxCACnjqFL+MmPh9W9JQKT2DcLbBzf
|
||||||
|
+Cqo6wcEBoCOcwgRSk8dSikhARoteoa55JRJhuMyeKhhEAogE9HRmCPFdjezFTwgB
|
||||||
|
+BDVBpO2dZ023mLXDVCYX3S8pShOgCP6Tn4wqCnYeAdLcGg106N4xcmgtcssJE+Pr
|
||||||
|
+XzTZksbZsrTVEmL/Ym+R5w5jBfFnGk7Yw7ndwfQsfNXQb5AZynClFxnX546lcyZX
|
||||||
|
+fEx3/e6ezw57WNOUK6WT+8b+EGovPkbetK/rGxNXuWaP6X4A/QUm8O98nCuHYFQq
|
||||||
|
++mvNdsCBqGf7mhaRGtpHk/JgCn5rFvArMDqLVrR9hX0LdCSsH7EGE+bR3r7wuQEN
|
||||||
|
+BFjmORgBCACk+vDZrIXQuFXEYToZVwb2attzbbJJCqD71vmZTLsW0QxuPKRgbcYY
|
||||||
|
+zp4K4lVBnHhFrF8MOUOxJ7kQWIJZMZFt+BDcptCYurbD2H4W2xvnWViiC+LzCMzz
|
||||||
|
+iMJT6165uefL4JHTDPxC2fFiM9yrc72LmylJNkM/vepT128J5Qv0gRUaQbHiQuS6
|
||||||
|
+Dm/+WRnUfx3i89SV4mnBxb/Ta93GVqoOciWwzWSnwEnWYAvOb95JL4U7c5J5f/+c
|
||||||
|
+KnQDHsW7sIiIdscsWzvgf6qs2Ra1Zrt7Fdk4+ZS2f/adagLhDO1C24sXf5XfMk5m
|
||||||
|
+L0OGwZSr9m5s17VXxfspgU5ugc8kBJfzABEBAAE=
|
||||||
|
+=WCfs
|
||||||
|
+-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
+
|
||||||
|
diff --git a/tests/data/keys/CVE-2021-3521-nosubsig.asc b/tests/data/keys/CVE-2021-3521-nosubsig.asc
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..3a2e7417f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tests/data/keys/CVE-2021-3521-nosubsig.asc
|
||||||
|
@@ -0,0 +1,37 @@
|
||||||
|
+-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
+Version: rpm-4.17.90 (NSS-3)
|
||||||
|
+
|
||||||
|
+mQENBFjmORgBCAC7TMEk6wnjSs8Dr4yqSScWdU2pjcqrkTxuzdWvowcIUPZI0w/g
|
||||||
|
+HkRqGd4apjvY2V15kjL10gk3QhFP3pZ/9p7zh8o8NHX7aGdSGDK7NOq1eFaErPRY
|
||||||
|
+91LW9RiZ0lbOjXEzIL0KHxUiTQEmdXJT43DJMFPyW9fkCWg0OltiX618FUdWWfI8
|
||||||
|
+eySdLur1utnqBvdEbCUvWK2RX3vQZQdvEBODnNk2pxqTyV0w6VPQ96W++lF/5Aas
|
||||||
|
+7rUv3HIyIXxIggc8FRrnH+y9XvvHDonhTIlGnYZN4ubm9i4y3gOkrZlGTrEw7elQ
|
||||||
|
+1QeMyG2QQEbze8YjpTm4iLABCBrRfPRaQpwrABEBAAG0IXJwbS5vcmcgUlNBIHRl
|
||||||
|
+c3RrZXkgPHJzYUBycG0ub3JnPokBNwQTAQgAIQUCWOY5GAIbAwULCQgHAgYVCAkK
|
||||||
|
+CwIEFgIDAQIeAQIXgAAKCRBDRFkeGWTF/MxxCACnjqFL+MmPh9W9JQKT2DcLbBzf
|
||||||
|
+Cqo6wcEBoCOcwgRSk8dSikhARoteoa55JRJhuMyeKhhEAogE9HRmCPFdjezFTwgB
|
||||||
|
+BDVBpO2dZ023mLXDVCYX3S8pShOgCP6Tn4wqCnYeAdLcGg106N4xcmgtcssJE+Pr
|
||||||
|
+XzTZksbZsrTVEmL/Ym+R5w5jBfFnGk7Yw7ndwfQsfNXQb5AZynClFxnX546lcyZX
|
||||||
|
+fEx3/e6ezw57WNOUK6WT+8b+EGovPkbetK/rGxNXuWaP6X4A/QUm8O98nCuHYFQq
|
||||||
|
++mvNdsCBqGf7mhaRGtpHk/JgCn5rFvArMDqLVrR9hX0LdCSsH7EGE+bR3r7wuQEN
|
||||||
|
+BFjmORgBCACk+vDZrIXQuFXEYToZVwb2attzbbJJCqD71vmZTLsW0QxuPKRgbcYY
|
||||||
|
+zp4K4lVBnHhFrF8MOUOxJ7kQWIJZMZFt+BDcptCYurbD2H4W2xvnWViiC+LzCMzz
|
||||||
|
+iMJT6165uefL4JHTDPxC2fFiM9yrc72LmylJNkM/vepT128J5Qv0gRUaQbHiQuS6
|
||||||
|
+Dm/+WRnUfx3i89SV4mnBxb/Ta93GVqoOciWwzWSnwEnWYAvOb95JL4U7c5J5f/+c
|
||||||
|
+KnQDHsW7sIiIdscsWzvgf6qs2Ra1Zrt7Fdk4+ZS2f/adagLhDO1C24sXf5XfMk5m
|
||||||
|
+L0OGwZSr9m5s17VXxfspgU5ugc8kBJfzABEBAAG5AQ0EWOY5GAEIAKT68NmshdC4
|
||||||
|
+VcRhOhlXBvZq23NtskkKoPvW+ZlMuxbRDG48pGBtxhjOngriVUGceEWsXww5Q7En
|
||||||
|
+uRBYglkxkW34ENym0Ji6tsPYfhbbG+dZWKIL4vMIzPOIwlPrXrm558vgkdMM/ELZ
|
||||||
|
+8WIz3KtzvYubKUk2Qz+96lPXbwnlC/SBFRpBseJC5LoOb/5ZGdR/HeLz1JXiacHF
|
||||||
|
+v9Nr3cZWqg5yJbDNZKfASdZgC85v3kkvhTtzknl//5wqdAMexbuwiIh2xyxbO+B/
|
||||||
|
+qqzZFrVmu3sV2Tj5lLZ/9p1qAuEM7ULbixd/ld8yTmYvQ4bBlKv2bmzXtVfF+ymB
|
||||||
|
+Tm6BzyQEl/MAEQEAAYkBHwQYAQgACQUCWOY5GAIbDAAKCRBDRFkeGWTF/PANB/9j
|
||||||
|
+mifmj6z/EPe0PJFhrpISt9PjiUQCt0IPtiL5zKAkWjHePIzyi+0kCTBF6DDLFxos
|
||||||
|
+3vN4bWnVKT1kBhZAQlPqpJTg+m74JUYeDGCdNx9SK7oRllATqyu+5rncgxjWVPnQ
|
||||||
|
+zu/HRPlWJwcVFYEVXYL8xzfantwQTqefjmcRmBRdA2XJITK+hGWwAmrqAWx+q5xX
|
||||||
|
+Pa8wkNMxVzNS2rUKO9SoVuJ/wlUvfoShkJ/VJ5HDp3qzUqncADfdGN35TDzscngQ
|
||||||
|
+gHvnMwVBfYfSCABV1hNByoZcc/kxkrWMmsd/EnIyLd1Q1baKqc3cEDuC6E6/o4yJ
|
||||||
|
+E4XX4jtDmdZPreZALsiB
|
||||||
|
+=rRop
|
||||||
|
+-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
+
|
||||||
|
diff --git a/tests/rpmsigdig.at b/tests/rpmsigdig.at
|
||||||
|
index e1a3ab062..705fc5870 100644
|
||||||
|
--- a/tests/rpmsigdig.at
|
||||||
|
+++ b/tests/rpmsigdig.at
|
||||||
|
@@ -240,6 +240,34 @@ gpg(185e6146f00650f8) = 4:185e6146f00650f8-58e63918
|
||||||
|
[])
|
||||||
|
AT_CLEANUP
|
||||||
|
|
||||||
|
+AT_SETUP([rpmkeys --import invalid keys])
|
||||||
|
+AT_KEYWORDS([rpmkeys import])
|
||||||
|
+RPMDB_INIT
|
||||||
|
+
|
||||||
|
+AT_CHECK([
|
||||||
|
+runroot rpmkeys --import /data/keys/CVE-2021-3521-badbind.asc
|
||||||
|
+],
|
||||||
|
+[1],
|
||||||
|
+[],
|
||||||
|
+[error: /data/keys/CVE-2021-3521-badbind.asc: key 1 import failed.]
|
||||||
|
+)
|
||||||
|
+AT_CHECK([
|
||||||
|
+runroot rpmkeys --import /data/keys/CVE-2021-3521-nosubsig.asc
|
||||||
|
+],
|
||||||
|
+[1],
|
||||||
|
+[],
|
||||||
|
+[error: /data/keys/CVE-2021-3521-nosubsig.asc: key 1 import failed.]
|
||||||
|
+)
|
||||||
|
+
|
||||||
|
+AT_CHECK([
|
||||||
|
+runroot rpmkeys --import /data/keys/CVE-2021-3521-nosubsig-last.asc
|
||||||
|
+],
|
||||||
|
+[1],
|
||||||
|
+[],
|
||||||
|
+[error: /data/keys/CVE-2021-3521-nosubsig-last.asc: key 1 import failed.]
|
||||||
|
+)
|
||||||
|
+AT_CLEANUP
|
||||||
|
+
|
||||||
|
# ------------------------------
|
||||||
|
# Test pre-built package verification
|
||||||
|
AT_SETUP([rpmkeys -K <signed> 1])
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
@ -0,0 +1,78 @@
|
|||||||
|
From 96888e99c5103d9dea5230c917b946732de2d302 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Panu Matilainen <pmatilai@redhat.com>
|
||||||
|
Date: Thu, 22 Sep 2022 11:54:47 +0300
|
||||||
|
Subject: [PATCH] Add a handler for libselinux log messages (RhBug:2123719,
|
||||||
|
RhBug:2050774)
|
||||||
|
|
||||||
|
libselinux logs to stderr by default, which up to now has been just fine
|
||||||
|
with us. However somewhere around libselinux 3.2 it begun issuing
|
||||||
|
log messages for events discovered in selinux_status_updated().
|
||||||
|
We only call that to see whether the status *was* updated behind our
|
||||||
|
back and are not interested in these audit-style messages for our
|
||||||
|
functionality, but to suppress them while preserving actually relevant
|
||||||
|
errors and warnings, we need to have a log callback of our own. Might as
|
||||||
|
well forward them to rpmlog then.
|
||||||
|
|
||||||
|
SELINUX_ERROR and SELINUX_WARNING are pretty obvious, of SELINUX_AVC
|
||||||
|
selinux_set_callback(3) says it should be treated as SELINUX_ERROR if
|
||||||
|
not audited. The rest we suppress to debug messages, they may be handy
|
||||||
|
for diagnostics some day.
|
||||||
|
|
||||||
|
Note that this intentionally avoids explicit SELINUX_POLICYLOAD and
|
||||||
|
SELINUX_SETENFORCE cases in the switch: we don't want to introduce
|
||||||
|
libselinux >= 3.2 dependency just because of this silly thing.
|
||||||
|
---
|
||||||
|
plugins/selinux.c | 30 ++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 30 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/plugins/selinux.c b/plugins/selinux.c
|
||||||
|
index 747f62d05..0f10331f0 100644
|
||||||
|
--- a/plugins/selinux.c
|
||||||
|
+++ b/plugins/selinux.c
|
||||||
|
@@ -18,6 +18,35 @@ static inline rpmlogLvl loglvl(int iserror)
|
||||||
|
return iserror ? RPMLOG_ERR : RPMLOG_DEBUG;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int logcb(int type, const char *fmt, ...)
|
||||||
|
+{
|
||||||
|
+ char *buf = NULL;
|
||||||
|
+ va_list ap;
|
||||||
|
+ int lvl;
|
||||||
|
+
|
||||||
|
+ switch (type) {
|
||||||
|
+ case SELINUX_ERROR:
|
||||||
|
+ case SELINUX_AVC:
|
||||||
|
+ lvl = RPMLOG_ERR;
|
||||||
|
+ break;
|
||||||
|
+ case SELINUX_WARNING:
|
||||||
|
+ lvl = RPMLOG_WARNING;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ lvl = RPMLOG_DEBUG;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ va_start(ap, fmt);
|
||||||
|
+ rvasprintf(&buf, fmt, ap);
|
||||||
|
+ va_end(ap);
|
||||||
|
+
|
||||||
|
+ rpmlog(lvl, "libselinux: type %d: %s", type, buf);
|
||||||
|
+ free(buf);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void sehandle_fini(int close_status)
|
||||||
|
{
|
||||||
|
if (sehandle) {
|
||||||
|
@@ -44,6 +73,7 @@ static rpmRC sehandle_init(int open_status)
|
||||||
|
if (selinux_status_open(0) < 0) {
|
||||||
|
return RPMRC_FAIL;
|
||||||
|
}
|
||||||
|
+ selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) &logcb);
|
||||||
|
} else if (!selinux_status_updated() && sehandle) {
|
||||||
|
return RPMRC_OK;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,14 @@
|
|||||||
|
diff --git a/rpmrc.in b/rpmrc.in
|
||||||
|
index 4a6cca9..d62ddaf 100644
|
||||||
|
--- a/rpmrc.in
|
||||||
|
+++ b/rpmrc.in
|
||||||
|
@@ -281,7 +281,7 @@ arch_compat: alphaev5: alpha
|
||||||
|
arch_compat: alpha: axp noarch
|
||||||
|
|
||||||
|
arch_compat: athlon: i686
|
||||||
|
-arch_compat: geode: i586
|
||||||
|
+arch_compat: geode: i686
|
||||||
|
arch_compat: pentium4: pentium3
|
||||||
|
arch_compat: pentium3: i686
|
||||||
|
arch_compat: i686: i586
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
diff -up rpm-4.9.90.git11486/scripts/find-lang.sh.no-man-dirs rpm-4.9.90.git11486/scripts/find-lang.sh
|
||||||
|
--- rpm-4.9.90.git11486/scripts/find-lang.sh.no-man-dirs 2012-03-07 11:31:10.000000000 +0200
|
||||||
|
+++ rpm-4.9.90.git11486/scripts/find-lang.sh 2012-03-07 15:11:57.465801075 +0200
|
||||||
|
@@ -181,7 +181,7 @@ s:%lang(C) ::
|
||||||
|
find "$TOP_DIR" -type d|sed '
|
||||||
|
s:'"$TOP_DIR"'::
|
||||||
|
'"$ALL_NAME$MAN"'s:\(.*/man/\([^/_]\+\).*/man[a-z0-9]\+/\)::
|
||||||
|
-'"$ALL_NAME$MAN"'s:\(.*/man/\([^/_]\+\).*/man[a-z0-9]\+$\):%lang(\2) \1*:
|
||||||
|
+'"$ALL_NAME$MAN"'s:\(.*/man/\([^/_]\+\).*/man[a-z0-9]\+$\):%lang(\2) \1/*:
|
||||||
|
s:^\([^%].*\)::
|
||||||
|
s:%lang(C) ::
|
||||||
|
/^$/d' >> $MO_NAME
|
@ -0,0 +1,19 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=RPM database rebuild
|
||||||
|
ConditionPathExists=/var/lib/rpm/.rebuilddb
|
||||||
|
|
||||||
|
# This should run before any daemons that may open the rpmdb
|
||||||
|
DefaultDependencies=no
|
||||||
|
After=sysinit.target
|
||||||
|
Before=basic.target shutdown.target
|
||||||
|
Conflicts=shutdown.target
|
||||||
|
# In case /var is remote-mounted
|
||||||
|
RequiresMountsFor=/var
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/bin/rpmdb --rebuilddb
|
||||||
|
ExecStartPost=rm -f /var/lib/rpm/.rebuilddb
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=basic.target
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue