lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon,  1 Mar 2021 09:47:43 -0800
From:   Stephen Boyd <swboyd@...omium.org>
To:     Andrew Morton <akpm@...ux-foundation.org>
Cc:     linux-kernel@...r.kernel.org, Jiri Olsa <jolsa@...nel.org>,
        Alexei Starovoitov <ast@...nel.org>,
        Jessica Yu <jeyu@...nel.org>,
        Evan Green <evgreen@...omium.org>,
        Hsin-Yi Wang <hsinyi@...omium.org>
Subject: [PATCH 1/7] buildid: Add method to get running kernel's build ID

Add vmlinux_build_id() so that callers can get a hex format string
representation of the running kernel's build ID. This will be used in
the kdump and dump_stack code so that developers can easily locate the
vmlinux for a stacktrace.

Cc: Jiri Olsa <jolsa@...nel.org>
Cc: Alexei Starovoitov <ast@...nel.org>
Cc: Jessica Yu <jeyu@...nel.org>
Cc: Evan Green <evgreen@...omium.org>
Cc: Hsin-Yi Wang <hsinyi@...omium.org>
Signed-off-by: Stephen Boyd <swboyd@...omium.org>
---
 include/linux/buildid.h |  3 ++
 lib/buildid.c           | 65 ++++++++++++++++++++++++++++++++---------
 2 files changed, 55 insertions(+), 13 deletions(-)

diff --git a/include/linux/buildid.h b/include/linux/buildid.h
index 40232f90db6e..dd134a96a87c 100644
--- a/include/linux/buildid.h
+++ b/include/linux/buildid.h
@@ -5,8 +5,11 @@
 #include <linux/mm_types.h>
 
 #define BUILD_ID_SIZE_MAX 20
+#define BUILD_ID_STR_SIZE_MAX (BUILD_ID_SIZE_MAX * 2 + 1)
 
 int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id,
 		   __u32 *size);
 
+const char *vmlinux_build_id(void);
+
 #endif
diff --git a/lib/buildid.c b/lib/buildid.c
index 6156997c3895..57daf928b133 100644
--- a/lib/buildid.c
+++ b/lib/buildid.c
@@ -2,30 +2,23 @@
 
 #include <linux/buildid.h>
 #include <linux/elf.h>
+#include <linux/kernel.h>
 #include <linux/pagemap.h>
 
 #define BUILD_ID 3
+
 /*
  * Parse build id from the note segment. This logic can be shared between
  * 32-bit and 64-bit system, because Elf32_Nhdr and Elf64_Nhdr are
  * identical.
  */
-static inline int parse_build_id(void *page_addr,
-				 unsigned char *build_id,
-				 __u32 *size,
-				 void *note_start,
-				 Elf32_Word note_size)
+static int parse_build_id_buf(unsigned char *build_id,
+			      __u32 *size,
+			      const void *note_start,
+			      Elf32_Word note_size)
 {
 	Elf32_Word note_offs = 0, new_offs;
 
-	/* check for overflow */
-	if (note_start < page_addr || note_start + note_size < note_start)
-		return -EINVAL;
-
-	/* only supports note that fits in the first page */
-	if (note_start + note_size > page_addr + PAGE_SIZE)
-		return -EINVAL;
-
 	while (note_offs + sizeof(Elf32_Nhdr) < note_size) {
 		Elf32_Nhdr *nhdr = (Elf32_Nhdr *)(note_start + note_offs);
 
@@ -49,9 +42,27 @@ static inline int parse_build_id(void *page_addr,
 			break;
 		note_offs = new_offs;
 	}
+
 	return -EINVAL;
 }
 
+static inline int parse_build_id(void *page_addr,
+				 unsigned char *build_id,
+				 __u32 *size,
+				 void *note_start,
+				 Elf32_Word note_size)
+{
+	/* check for overflow */
+	if (note_start < page_addr || note_start + note_size < note_start)
+		return -EINVAL;
+
+	/* only supports note that fits in the first page */
+	if (note_start + note_size > page_addr + PAGE_SIZE)
+		return -EINVAL;
+
+	return parse_build_id_buf(build_id, size, note_start, note_size);
+}
+
 /* Parse build ID from 32-bit ELF */
 static int get_build_id_32(void *page_addr, unsigned char *build_id,
 			   __u32 *size)
@@ -147,3 +158,31 @@ int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id,
 	put_page(page);
 	return ret;
 }
+
+static void build_id2hex(char *dst, const unsigned char *src, __u32 size)
+{
+	bin2hex(dst, src, size);
+	dst[2 * size] = '\0';
+}
+
+/**
+ * vmlinux_build_id - Get the running kernel's build-id in hex string format
+ *
+ * Return: Running kernel's build-id in hex string format
+ */
+const char *vmlinux_build_id(void)
+{
+	extern const void __start_notes __weak;
+	extern const void __stop_notes __weak;
+	unsigned int notes_size = &__stop_notes - &__start_notes;
+	unsigned char build_id[BUILD_ID_SIZE_MAX];
+	__u32 size;
+	static char vmlinux_build_id_buf[BUILD_ID_STR_SIZE_MAX];
+
+	if (vmlinux_build_id_buf[0] == '\0') {
+		if (!parse_build_id_buf(build_id, &size, &__start_notes, notes_size))
+			build_id2hex(vmlinux_build_id_buf, build_id, size);
+	}
+
+	return vmlinux_build_id_buf;
+}
-- 
https://chromeos.dev

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ