Panu Matilainen 3abc97
From 68d383c39cef8d58b80940b13dd132d3f41a03f0 Mon Sep 17 00:00:00 2001
Panu Matilainen 3abc97
Message-Id: <68d383c39cef8d58b80940b13dd132d3f41a03f0.1558430547.git.pmatilai@redhat.com>
Panu Matilainen 3abc97
From: Panu Matilainen <pmatilai@redhat.com>
Panu Matilainen 3abc97
Date: Tue, 2 Apr 2019 15:22:07 +0300
Panu Matilainen 3abc97
Subject: [PATCH 1/2] Detect kernel modules by .modinfo section presence for
Panu Matilainen 3abc97
 build-id generation
Panu Matilainen 3abc97
Panu Matilainen 3abc97
File extension based heuristics only work so far at best, and break
Panu Matilainen 3abc97
completely on compressed files with arbitrary .gz/.xz etc extension.
Panu Matilainen 3abc97
This isn't supposed to change any behavior as such, only provide more
Panu Matilainen 3abc97
reliable detection of kernel modules.
Panu Matilainen 3abc97
---
Panu Matilainen 3abc97
 build/files.c | 27 ++++++++++++++++++++++++---
Panu Matilainen 3abc97
 1 file changed, 24 insertions(+), 3 deletions(-)
Panu Matilainen 3abc97
Panu Matilainen 3abc97
diff --git a/build/files.c b/build/files.c
Panu Matilainen 3abc97
index dbad9a7f3..3822be3d3 100644
Panu Matilainen 3abc97
--- a/build/files.c
Panu Matilainen 3abc97
+++ b/build/files.c
Panu Matilainen 3abc97
@@ -1739,6 +1739,28 @@ static int addNewIDSymlink(ARGV_t *files,
Panu Matilainen 3abc97
     return rc;
Panu Matilainen 3abc97
 }
Panu Matilainen 3abc97
 
Panu Matilainen 3abc97
+static int haveModinfo(Elf *elf)
Panu Matilainen 3abc97
+{
Panu Matilainen 3abc97
+    Elf_Scn * scn = NULL;
Panu Matilainen 3abc97
+    size_t shstrndx;
Panu Matilainen 3abc97
+    int have_modinfo = 0;
Panu Matilainen 3abc97
+    const char *sname;
Panu Matilainen 3abc97
+
Panu Matilainen 3abc97
+    if (elf_getshdrstrndx(elf, &shstrndx) == 0) {
Panu Matilainen 3abc97
+	while ((scn = elf_nextscn(elf, scn)) != NULL) {
Panu Matilainen 3abc97
+	    GElf_Shdr shdr_mem, *shdr = gelf_getshdr(scn, &shdr_mem);
Panu Matilainen 3abc97
+	    if (shdr == NULL)
Panu Matilainen 3abc97
+		continue;
Panu Matilainen 3abc97
+	    sname = elf_strptr(elf, shstrndx, shdr->sh_name);
Panu Matilainen 3abc97
+	    if (sname && rstreq(sname, ".modinfo")) {
Panu Matilainen 3abc97
+		have_modinfo = 1;
Panu Matilainen 3abc97
+		break;
Panu Matilainen 3abc97
+	    }
Panu Matilainen 3abc97
+	}
Panu Matilainen 3abc97
+    }
Panu Matilainen 3abc97
+    return have_modinfo;
Panu Matilainen 3abc97
+}
Panu Matilainen 3abc97
+
Panu Matilainen 3abc97
 static int generateBuildIDs(FileList fl, ARGV_t *files)
Panu Matilainen 3abc97
 {
Panu Matilainen 3abc97
     int rc = 0;
Panu Matilainen 3abc97
@@ -1803,15 +1825,14 @@ static int generateBuildIDs(FileList fl, ARGV_t *files)
Panu Matilainen 3abc97
 	    int fd = open (flp->diskPath, O_RDONLY);
Panu Matilainen 3abc97
 	    if (fd >= 0) {
Panu Matilainen 3abc97
 		/* Only real ELF files, that are ET_EXEC, ET_DYN or
Panu Matilainen 3abc97
-		   kernel modules (ET_REL files with names ending in .ko)
Panu Matilainen 3abc97
+		   kernel modules (ET_REL files with .modinfo section)
Panu Matilainen 3abc97
 		   should have build-ids. */
Panu Matilainen 3abc97
 		GElf_Ehdr ehdr;
Panu Matilainen 3abc97
 		Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
Panu Matilainen 3abc97
 		if (elf != NULL && elf_kind(elf) == ELF_K_ELF
Panu Matilainen 3abc97
 		    && gelf_getehdr(elf, &ehdr) != NULL
Panu Matilainen 3abc97
 		    && (ehdr.e_type == ET_EXEC || ehdr.e_type == ET_DYN
Panu Matilainen 3abc97
-			|| (ehdr.e_type == ET_REL
Panu Matilainen 3abc97
-			    && rpmFileHasSuffix (flp->diskPath, ".ko")))) {
Panu Matilainen 3abc97
+			|| (ehdr.e_type == ET_REL && haveModinfo(elf)))) {
Panu Matilainen 3abc97
 		    const void *build_id;
Panu Matilainen 3abc97
 		    ssize_t len = dwelf_elf_gnu_build_id (elf, &build_id);
Panu Matilainen 3abc97
 		    /* len == -1 means error. Zero means no
Panu Matilainen 3abc97
-- 
Panu Matilainen 3abc97
2.21.0
Panu Matilainen 3abc97