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: <alpine.LRH.2.02.2205180813200.22292@file01.intranet.prod.int.rdu2.redhat.com>
Date:   Wed, 18 May 2022 09:28:57 -0400 (EDT)
From:   Mikulas Patocka <mpatocka@...hat.com>
To:     Peter Zijlstra <peterz@...radead.org>
cc:     Linus Torvalds <torvalds@...ux-foundation.org>,
        Josh Poimboeuf <jpoimboe@...hat.com>,
        linux-kernel@...r.kernel.org
Subject: [PATCH v2] objtool: fix objtool regression on x32 systems



On Mon, 16 May 2022, Peter Zijlstra wrote:

> On Mon, May 16, 2022 at 11:56:21AM -0400, Mikulas Patocka wrote:
> > 
> > With this patch, the compiled kernel works. With kernels 5.17 or older, it 
> > also works. I bisected it and the breakage is caused by the commit 
> > 4abff6d48dbc.
> 
> Sure; but it works doesn't mean there aren't more latent issues. ILP32
> hosted (cross) builds just aren't a thing I've ever considered. If we
> really want to go support that then we should at least audit the whole
> thing.
> 
> A quick look seems to suggest at least all the 'offset' fields should be
> u64 or something. The only reason that works is because -mcmodel=kernel
> keeps everything in the 2G range to make s32 immediates work. But it
> isn't right.

There are many 'offset' variables and its hard to determine which should 
be 64-bit. Would it be possible to commit this patch, so that kernel 5.18 
can be compiled on x32 distributions? And you can do code refactoring in 
the next merge window.

Mikulas


From: Mikulas Patocka <mpatocka@...hat.com>

The patch 4abff6d48dbc ("objtool: Fix code relocs vs weak symbols") makes
the kernel unbootable.  The patch c087c6e7b551 ("objtool: Fix type of
reloc::addend") attempts to fix it by replacing 'int' with 'long'.

However, we may be running on a system with x32 ABI and 'long' on x32 is
32-bit, thus the patch c087c6e7b551 doesn't really change anything and we
still end up with miscompiled kernel.  This patch replaces 'long' with
's64', so that the 64-bit kernel is correctly compiled on a x32 system.

Signed-off-by: Mikulas Patocka <mpatocka@...hat.com>
Fixes: 4abff6d48dbc ("objtool: Fix code relocs vs weak symbols")
Fixes: c087c6e7b551 ("objtool: Fix type of reloc::addend")

---
 tools/objtool/check.c               |    9 +++++----
 tools/objtool/elf.c                 |    2 +-
 tools/objtool/include/objtool/elf.h |    4 ++--
 3 files changed, 8 insertions(+), 7 deletions(-)

Index: linux-2.6/tools/objtool/check.c
===================================================================
--- linux-2.6.orig/tools/objtool/check.c	2022-05-18 13:51:22.000000000 +0200
+++ linux-2.6/tools/objtool/check.c	2022-05-18 13:52:37.000000000 +0200
@@ -6,6 +6,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <sys/mman.h>
+#include <inttypes.h>
 
 #include <arch/elf.h>
 #include <objtool/builtin.h>
@@ -560,12 +561,12 @@ static int add_dead_ends(struct objtool_
 		else if (reloc->addend == reloc->sym->sec->sh.sh_size) {
 			insn = find_last_insn(file, reloc->sym->sec);
 			if (!insn) {
-				WARN("can't find unreachable insn at %s+0x%lx",
+				WARN("can't find unreachable insn at %s+0x%"PRIx64,
 				     reloc->sym->sec->name, reloc->addend);
 				return -1;
 			}
 		} else {
-			WARN("can't find unreachable insn at %s+0x%lx",
+			WARN("can't find unreachable insn at %s+0x%"PRIx64,
 			     reloc->sym->sec->name, reloc->addend);
 			return -1;
 		}
@@ -595,12 +596,12 @@ reachable:
 		else if (reloc->addend == reloc->sym->sec->sh.sh_size) {
 			insn = find_last_insn(file, reloc->sym->sec);
 			if (!insn) {
-				WARN("can't find reachable insn at %s+0x%lx",
+				WARN("can't find reachable insn at %s+0x%"PRIx64,
 				     reloc->sym->sec->name, reloc->addend);
 				return -1;
 			}
 		} else {
-			WARN("can't find reachable insn at %s+0x%lx",
+			WARN("can't find reachable insn at %s+0x%"PRIx64,
 			     reloc->sym->sec->name, reloc->addend);
 			return -1;
 		}
Index: linux-2.6/tools/objtool/elf.c
===================================================================
--- linux-2.6.orig/tools/objtool/elf.c	2022-05-18 13:51:22.000000000 +0200
+++ linux-2.6/tools/objtool/elf.c	2022-05-18 13:51:22.000000000 +0200
@@ -546,7 +546,7 @@ static struct section *elf_create_reloc_
 						int reltype);
 
 int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
-		  unsigned int type, struct symbol *sym, long addend)
+		  unsigned int type, struct symbol *sym, s64 addend)
 {
 	struct reloc *reloc;
 
Index: linux-2.6/tools/objtool/include/objtool/elf.h
===================================================================
--- linux-2.6.orig/tools/objtool/include/objtool/elf.h	2022-05-18 13:51:22.000000000 +0200
+++ linux-2.6/tools/objtool/include/objtool/elf.h	2022-05-18 13:51:22.000000000 +0200
@@ -73,7 +73,7 @@ struct reloc {
 	struct symbol *sym;
 	unsigned long offset;
 	unsigned int type;
-	long addend;
+	s64 addend;
 	int idx;
 	bool jump_table_start;
 };
@@ -135,7 +135,7 @@ struct elf *elf_open_read(const char *na
 struct section *elf_create_section(struct elf *elf, const char *name, unsigned int sh_flags, size_t entsize, int nr);
 
 int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
-		  unsigned int type, struct symbol *sym, long addend);
+		  unsigned int type, struct symbol *sym, s64 addend);
 int elf_add_reloc_to_insn(struct elf *elf, struct section *sec,
 			  unsigned long offset, unsigned int type,
 			  struct section *insn_sec, unsigned long insn_off);

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ