I couldn't work out how to get gcc to actually produce such a thing, but
/bin/dbxtool on my debian box right now has them.

The big mistake here is that GNU property notes' data is always 8-byte
aligned, so we needed to skip that. That lets us get rid of the existing
loop termination hack to skip padding.

While I'm here -- since the symptom was running off the end of the file --
I've also added a bounds check in the property dumping loop.

I wish I had fuzzing infrastructure to run AFL++ against this every time
it changes... In lieu of that I do wonder whether we should add `readelf
-aW /bin/* > /dev/null` as a smoke test that "at least it works for all
the _valid_ binaries on the system you're testing on". That would have
caught this sooner.
---
 toys/other/readelf.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)
From 51d643245b4f95a911d2eeaa7855447da69119ba Mon Sep 17 00:00:00 2001
From: Elliott Hughes <e...@google.com>
Date: Thu, 14 Mar 2024 17:03:51 -0700
Subject: [PATCH] readelf: fix -n for x86-64 ibt/shstk notes.

I couldn't work out how to get gcc to actually produce such a thing, but
/bin/dbxtool on my debian box right now has them.

The big mistake here is that GNU property notes' data is always 8-byte
aligned, so we needed to skip that. That lets us get rid of the existing
loop termination hack to skip padding.

While I'm here -- since the symptom was running off the end of the file --
I've also added a bounds check in the property dumping loop.

I wish I had fuzzing infrastructure to run AFL++ against this every time
it changes... In lieu of that I do wonder whether we should add `readelf
-aW /bin/* > /dev/null` as a smoke test that "at least it works for all
the _valid_ binaries on the system you're testing on". That would have
caught this sooner.
---
 toys/other/readelf.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/toys/other/readelf.c b/toys/other/readelf.c
index 19387360..c1fbba60 100644
--- a/toys/other/readelf.c
+++ b/toys/other/readelf.c
@@ -370,14 +370,14 @@ static void show_attributes(unsigned long offset, unsigned long size)
 
 static void show_notes(unsigned long offset, unsigned long size)
 {
-  char *note = TT.elf + offset;
+  char *note = TT.elf + offset, *end = TT.elf + offset + size;
 
   if (!fits("note", -1, offset, size)) return;
 
   printf("  %-20s%11s\tDescription\n", "Owner", "Data size");
-  while (note < TT.elf+offset+size) {
+  while (note < end) {
     char *p = note, *desc;
-    unsigned namesz=elf_int(&p), descsz=elf_int(&p), type=elf_int(&p), j=0;
+    unsigned namesz=elf_int(&p),descsz=elf_int(&p),type=elf_int(&p),j=0;
 
     if (namesz > size || descsz > size)
       return error_msg("%s: bad note @%lu", TT.f, offset);
@@ -392,13 +392,13 @@ static void show_notes(unsigned long offset, unsigned long size)
       } else if (type == 4) {
         printf("NT_GNU_GOLD_VERSION\t%.*s", descsz, p), j=1;
       } else if (type == 5) {
-        printf("NT_GNU_PROPERTY_TYPE_0\t");
-        while (descsz-j > 8) { // Ignore 0-padding at the end.
+        printf("NT_GNU_PROPERTY_TYPE_0\n    Properties:");
+        while (descsz - j > 0) {
           int pr_type = elf_int(&p);
           int pr_size = elf_int(&p), k, pr_data;
 
           j += 8;
-          printf("\n    Properties:    ");
+          if (p > end) return error_msg("%s: bad property @%lu", TT.f, offset);
           if (pr_size != 4) {
             // Just hex dump anything we aren't familiar with.
             for (k=0;k<pr_size;k++) printf("%02x", *p++);
@@ -406,16 +406,22 @@ static void show_notes(unsigned long offset, unsigned long size)
             j += pr_size;
           } else {
             pr_data = elf_int(&p);
-            j += 4;
+            elf_int(&p); // Skip padding.
+            j += 8;
             if (pr_type == 0xc0000000) {
-              printf("arm64 features:");
+              printf("\tarm64 features:");
               if (pr_data & 1) printf(" bti");
               if (pr_data & 2) printf(" pac");
               xputc('\n');
+            } else if (pr_type == 0xc0000002) {
+              printf("\tx86 feature:");
+              if (pr_data & 1) printf(" ibt");
+              if (pr_data & 2) printf(" shstk");
+              xputc('\n');
             } else if (pr_type == 0xc0008002) {
-              printf("x86 isa needed: x86-64v%d", ffs(pr_data));
+              printf("\tx86 isa needed: x86-64v%d", ffs(pr_data));
             } else {
-              printf("other (%#x): %#x", pr_type, pr_data);
+              printf("\tother (%#x): %#x", pr_type, pr_data);
             }
           }
         }
-- 
2.44.0.291.gc1ea87d7ee-goog

_______________________________________________
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to