diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2019-04-02 15:22:07 +0300 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2020-03-26 11:57:58 +0200 |
commit | 1a60222fb9ac7341ad6d5019d97dd546e50df136 (patch) | |
tree | d3978b4799f9af9e82db3d64fe79a6f67cb58d5c | |
parent | 9ea421d347e22c3f53ebe9c0f60badcb94409b24 (diff) | |
download | rpm-1a60222fb9ac7341ad6d5019d97dd546e50df136.tar.gz |
Detect kernel modules by .modinfo section presence for build-id generation
File extension based heuristics only work so far at best, and break
completely on compressed files with arbitrary .gz/.xz etc extension.
This isn't supposed to change any behavior as such, only provide more
reliable detection of kernel modules.
(cherry picked from commit 68d383c39cef8d58b80940b13dd132d3f41a03f0)
-rw-r--r-- | build/files.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/build/files.c b/build/files.c index 190801516..711dc38e7 100644 --- a/build/files.c +++ b/build/files.c @@ -1737,6 +1737,28 @@ static int addNewIDSymlink(ARGV_t *files, return rc; } +static int haveModinfo(Elf *elf) +{ + Elf_Scn * scn = NULL; + size_t shstrndx; + int have_modinfo = 0; + const char *sname; + + if (elf_getshdrstrndx(elf, &shstrndx) == 0) { + while ((scn = elf_nextscn(elf, scn)) != NULL) { + GElf_Shdr shdr_mem, *shdr = gelf_getshdr(scn, &shdr_mem); + if (shdr == NULL) + continue; + sname = elf_strptr(elf, shstrndx, shdr->sh_name); + if (sname && rstreq(sname, ".modinfo")) { + have_modinfo = 1; + break; + } + } + } + return have_modinfo; +} + static int generateBuildIDs(FileList fl, ARGV_t *files) { int rc = 0; @@ -1801,15 +1823,14 @@ static int generateBuildIDs(FileList fl, ARGV_t *files) int fd = open (flp->diskPath, O_RDONLY); if (fd >= 0) { /* Only real ELF files, that are ET_EXEC, ET_DYN or - kernel modules (ET_REL files with names ending in .ko) + kernel modules (ET_REL files with .modinfo section) should have build-ids. */ GElf_Ehdr ehdr; Elf *elf = elf_begin (fd, ELF_C_READ, NULL); if (elf != NULL && elf_kind(elf) == ELF_K_ELF && gelf_getehdr(elf, &ehdr) != NULL && (ehdr.e_type == ET_EXEC || ehdr.e_type == ET_DYN - || (ehdr.e_type == ET_REL - && rpmFileHasSuffix (flp->diskPath, ".ko")))) { + || (ehdr.e_type == ET_REL && haveModinfo(elf)))) { const void *build_id; ssize_t len = dwelf_elf_gnu_build_id (elf, &build_id); /* len == -1 means error. Zero means no |