d2ca5d
From 948d0e24f33c3b411b5ec1e320acec889e6781b8 Mon Sep 17 00:00:00 2001
d2ca5d
From: Vincent Mihalkovic <vmihalko@redhat.com>
d2ca5d
Date: Mon, 6 Feb 2023 15:04:33 +0100
d2ca5d
Subject: [PATCH] Improve detection of static-pie binaries, and don't call them
d2ca5d
 "dynamically linked", but call them "static-pie" linked.
d2ca5d
d2ca5d
363d7fcf703ad3ebf37b45693b2c9e43eb8b4176
d2ca5d
---
d2ca5d
 src/readelf.c | 35 +++++++++++++++++++++++++----------
d2ca5d
 1 file changed, 25 insertions(+), 10 deletions(-)
d2ca5d
d2ca5d
diff --git a/src/readelf.c b/src/readelf.c
d2ca5d
index 9c75c0a..0011659 100644
d2ca5d
--- a/src/readelf.c
d2ca5d
+++ b/src/readelf.c
d2ca5d
@@ -1040,7 +1040,7 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
d2ca5d
 
d2ca5d
 private size_t
d2ca5d
 dodynamic(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
d2ca5d
-    int clazz, int swap)
d2ca5d
+    int clazz, int swap, int *pie, size_t *need)
d2ca5d
 {
d2ca5d
 	Elf32_Dyn dh32;
d2ca5d
 	Elf64_Dyn dh64;
d2ca5d
@@ -1058,11 +1058,15 @@ dodynamic(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
d2ca5d
 
d2ca5d
 	switch (xdh_tag) {
d2ca5d
 	case DT_FLAGS_1:
d2ca5d
+                *pie = 1;
d2ca5d
 		if (xdh_val & DF_1_PIE)
d2ca5d
 			ms->mode |= 0111;
d2ca5d
 		else
d2ca5d
 			ms->mode &= ~0111;
d2ca5d
 		break;
d2ca5d
+        case DT_NEEDED:
d2ca5d
+                (*need)++;
d2ca5d
+                break;
d2ca5d
 	default:
d2ca5d
 		break;
d2ca5d
 	}
d2ca5d
@@ -1529,9 +1533,10 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
d2ca5d
 }
d2ca5d
 
d2ca5d
 /*
d2ca5d
- * Look through the program headers of an executable image, searching
d2ca5d
- * for a PT_INTERP section; if one is found, it's dynamically linked,
d2ca5d
- * otherwise it's statically linked.
d2ca5d
+ * Look through the program headers of an executable image, to determine
d2ca5d
+ * if it is statically or dynamically linked. If it has a dynamic section,
d2ca5d
+ * it is pie, and does not have an interpreter or needed libraries, we
d2ca5d
+ * call it static pie.
d2ca5d
  */
d2ca5d
 private int
d2ca5d
 dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
d2ca5d
@@ -1540,12 +1545,13 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
d2ca5d
 {
d2ca5d
 	Elf32_Phdr ph32;
d2ca5d
 	Elf64_Phdr ph64;
d2ca5d
-	const char *linking_style = "statically";
d2ca5d
+	const char *linking_style;
d2ca5d
 	unsigned char nbuf[BUFSIZ];
d2ca5d
 	char ibuf[BUFSIZ];
d2ca5d
 	char interp[BUFSIZ];
d2ca5d
 	ssize_t bufsize;
d2ca5d
-	size_t offset, align, len;
d2ca5d
+	size_t offset, align, len, need = 0;
d2ca5d
+        int pie = 0, dynamic = 0;
d2ca5d
 	
d2ca5d
 	if (size != xph_sizeof) {
d2ca5d
 		if (file_printf(ms, ", corrupted program header size") == -1)
d2ca5d
@@ -1569,7 +1575,6 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
d2ca5d
 		/* Things we can determine before we seek */
d2ca5d
 		switch (xph_type) {
d2ca5d
 		case PT_DYNAMIC:
d2ca5d
-			linking_style = "dynamically";
d2ca5d
 			doread = 1;
d2ca5d
 			break;
d2ca5d
 		case PT_NOTE:
d2ca5d
@@ -1610,6 +1615,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
d2ca5d
 		/* Things we can determine when we seek */
d2ca5d
 		switch (xph_type) {
d2ca5d
 		case PT_DYNAMIC:
d2ca5d
+			dynamic = 1;
d2ca5d
 			offset = 0;
d2ca5d
                         // Let DF_1 determine if we are PIE or not.
d2ca5d
                         ms->mode &= ~0111;
d2ca5d
@@ -1617,7 +1623,8 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
d2ca5d
 				if (offset >= (size_t)bufsize)
d2ca5d
 					break;
d2ca5d
 				offset = dodynamic(ms, nbuf, offset,
d2ca5d
-				    CAST(size_t, bufsize), clazz, swap);
d2ca5d
+				    CAST(size_t, bufsize), clazz, swap,
d2ca5d
+				    &pie, &need);
d2ca5d
 				if (offset == 0)
d2ca5d
 					break;
d2ca5d
 			}
d2ca5d
@@ -1626,6 +1633,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
d2ca5d
 			break;
d2ca5d
 
d2ca5d
 		case PT_INTERP:
d2ca5d
+                        need++;
d2ca5d
                         if (ms->flags & MAGIC_MIME)
d2ca5d
                                 continue;
d2ca5d
 			if (bufsize && nbuf[0]) {
d2ca5d
@@ -1660,8 +1668,15 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
d2ca5d
 	}
d2ca5d
 	if (ms->flags & MAGIC_MIME)
d2ca5d
 		return 0;
d2ca5d
-	if (file_printf(ms, ", %s linked", linking_style)
d2ca5d
-	    == -1)
d2ca5d
+	if (dynamic) {
d2ca5d
+		if (pie && need == 0)
d2ca5d
+			linking_style = "static-pie";
d2ca5d
+		else
d2ca5d
+			linking_style = "dynamically";
d2ca5d
+	} else {
d2ca5d
+		linking_style = "statically";
d2ca5d
+	}
d2ca5d
+	if (file_printf(ms, ", %s linked", linking_style) == -1)
d2ca5d
 		return -1;
d2ca5d
 	if (interp[0])
d2ca5d
 		if (file_printf(ms, ", interpreter %s",
d2ca5d
-- 
d2ca5d
2.39.1
d2ca5d