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]
Message-ID: <20240727074526.1771247-3-masahiroy@kernel.org>
Date: Sat, 27 Jul 2024 16:42:02 +0900
From: Masahiro Yamada <masahiroy@...nel.org>
To: linux-kbuild@...r.kernel.org
Cc: linux-kernel@...r.kernel.org,
	Kees Cook <kees@...nel.org>,
	Nathan Chancellor <nathan@...nel.org>,
	Nicolas Schier <nicolas@...sle.eu>,
	Ben Hutchings <ben@...adent.org.uk>,
	Masahiro Yamada <masahiroy@...nel.org>
Subject: [PATCH 2/4] modpost: detect endianness on run-time

Endianness is currently detected on compile-time, but we can defer this
until run-time. This change avoids re-executing scripts/mod/mk_elfconfig
even if modpost in the linux-headers package needs to be rebuilt for a
foreign architecture.

Signed-off-by: Masahiro Yamada <masahiroy@...nel.org>
---

 scripts/mod/mk_elfconfig.c | 19 -------------------
 scripts/mod/modpost.c      | 36 ++++++++++++++++++++++++++++++++++++
 scripts/mod/modpost.h      | 13 ++++---------
 3 files changed, 40 insertions(+), 28 deletions(-)

diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c
index aca96b3aada0..e8cee4e4bc73 100644
--- a/scripts/mod/mk_elfconfig.c
+++ b/scripts/mod/mk_elfconfig.c
@@ -8,7 +8,6 @@ int
 main(int argc, char **argv)
 {
 	unsigned char ei[EI_NIDENT];
-	union { short s; char c[2]; } endian_test;
 
 	if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) {
 		fprintf(stderr, "Error: input truncated\n");
@@ -28,24 +27,6 @@ main(int argc, char **argv)
 	default:
 		exit(1);
 	}
-	switch (ei[EI_DATA]) {
-	case ELFDATA2LSB:
-		printf("#define KERNEL_ELFDATA ELFDATA2LSB\n");
-		break;
-	case ELFDATA2MSB:
-		printf("#define KERNEL_ELFDATA ELFDATA2MSB\n");
-		break;
-	default:
-		exit(1);
-	}
-
-	endian_test.s = 0x0102;
-	if (memcmp(endian_test.c, "\x01\x02", 2) == 0)
-		printf("#define HOST_ELFDATA ELFDATA2MSB\n");
-	else if (memcmp(endian_test.c, "\x02\x01", 2) == 0)
-		printf("#define HOST_ELFDATA ELFDATA2LSB\n");
-	else
-		exit(1);
 
 	return 0;
 }
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index d16d0ace2775..f492fbeed300 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -50,6 +50,9 @@ static bool error_occurred;
 
 static bool extra_warn;
 
+bool target_is_big_endian;
+bool host_is_big_endian;
+
 /*
  * Cut off the warnings when there are too many. This typically occurs when
  * vmlinux is missing. ('make modules' without building vmlinux.)
@@ -438,6 +441,18 @@ static int parse_elf(struct elf_info *info, const char *filename)
 		/* Not an ELF file - silently ignore it */
 		return 0;
 	}
+
+	switch (hdr->e_ident[EI_DATA]) {
+	case ELFDATA2LSB:
+		target_is_big_endian = false;
+		break;
+	case ELFDATA2MSB:
+		target_is_big_endian = true;
+		break;
+	default:
+		fatal("kernel endian is unknown\n");
+	}
+
 	/* Fix endianness in ELF header */
 	hdr->e_type      = TO_NATIVE(hdr->e_type);
 	hdr->e_machine   = TO_NATIVE(hdr->e_machine);
@@ -2117,6 +2132,25 @@ struct dump_list {
 	const char *file;
 };
 
+static void check_host_endian(void)
+{
+	static const union {
+		short s;
+		char c[2];
+	} endian_test = { .c = {0x01, 0x02} };
+
+	switch (endian_test.s) {
+	case 0x0102:
+		host_is_big_endian = true;
+		break;
+	case 0x0201:
+		host_is_big_endian = false;
+		break;
+	default:
+		fatal("Unknown host endian\n");
+	}
+}
+
 int main(int argc, char **argv)
 {
 	struct module *mod;
@@ -2181,6 +2215,8 @@ int main(int argc, char **argv)
 		}
 	}
 
+	check_host_endian();
+
 	list_for_each_entry_safe(dl, dl2, &dump_lists, list) {
 		read_dump(dl->file);
 		list_del(&dl->list);
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 58197b34a3c8..54ba9431713f 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -62,15 +62,8 @@
 		    x); \
 })
 
-#if KERNEL_ELFDATA != HOST_ELFDATA
-
-#define TO_NATIVE(x) (bswap(x))
-
-#else /* endianness matches */
-
-#define TO_NATIVE(x) (x)
-
-#endif
+#define TO_NATIVE(x)	\
+	(target_is_big_endian == host_is_big_endian ? x : bswap(x))
 
 #define NOFAIL(ptr)   do_nofail((ptr), #ptr)
 
@@ -187,6 +180,8 @@ void add_moddevtable(struct buffer *buf, struct module *mod);
 void get_src_version(const char *modname, char sum[], unsigned sumlen);
 
 /* from modpost.c */
+extern bool target_is_big_endian;
+extern bool host_is_big_endian;
 char *read_text_file(const char *filename);
 char *get_line(char **stringp);
 void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym);
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ