public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ardb+git@google.com>
To: linux-kernel@vger.kernel.org
Cc: llvm@lists.linux.dev, keescook@chromium.org,
	 linux-hardening@vger.kernel.org, nathan@kernel.org,
	 Ard Biesheuvel <ardb@kernel.org>,
	Josh Poimboeuf <jpoimboe@kernel.org>,
	 Peter Zijlstra <peterz@infradead.org>,
	Jan Beulich <jbeulich@suse.com>,
	 "Jose E. Marchesi" <jemarch@gnu.org>,
	Kees Cook <kees@kernel.org>
Subject: [PATCH v2 3/5] objtool: Add support for annotated jump tables
Date: Thu, 10 Oct 2024 14:28:05 +0200	[thread overview]
Message-ID: <20241010122801.1321976-10-ardb+git@google.com> (raw)
In-Reply-To: <20241010122801.1321976-7-ardb+git@google.com>

From: Ard Biesheuvel <ardb@kernel.org>

Add logic to follow R_X86_64_NONE relocations attached to indirect
jumps, which are emitted to annotate jump tables, which are otherwise
difficult to spot reliably.

If an ELF symbol is associated with the jump table, its size is taken as
the size of the jump table, and subsequently used to limit the traversal
of the table and validate its jump destinations.

One complicating factor is that indirect jumps may actually be direct
jumps to retpoline thunks, and therefore already have a relocation
associated with it. Accommodate these by ignoring R_*_NONE relocations
in insn_reloc(), so that the existing code does not get confused by
them.

E.g.,

  8c:   48 63 7c 85 00          movslq 0x0(%rbp,%rax,4),%rdi
  91:   48 01 ef                add    %rbp,%rdi
  94:   e9 00 00 00 00          jmp    99 <crc_pcl+0x89>
            94: R_X86_64_NONE       .rodata+0x400
            95: R_X86_64_PLT32      __x86_indirect_thunk_rdi-0x4

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 tools/objtool/arch/x86/special.c | 33 ++++++++++++++++----
 tools/objtool/check.c            | 10 ++++--
 2 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/special.c
index f8fb67636384..67c20623d7f7 100644
--- a/tools/objtool/arch/x86/special.c
+++ b/tools/objtool/arch/x86/special.c
@@ -115,30 +115,51 @@ struct reloc *arch_find_switch_table(struct objtool_file *file,
 	struct reloc  *text_reloc, *rodata_reloc;
 	struct section *table_sec;
 	unsigned long table_offset;
+	struct symbol *sym;
 
 	/* look for a relocation which references .rodata */
 	text_reloc = find_reloc_by_dest_range(file->elf, insn->sec,
 					      insn->offset, insn->len);
-	if (!text_reloc || text_reloc->sym->type != STT_SECTION ||
-	    !text_reloc->sym->sec->rodata)
+	if (!text_reloc || !text_reloc->sym->sec->rodata)
 		return NULL;
 
-	table_offset = reloc_addend(text_reloc);
+	/*
+	 * If the indirect jump instruction itself is annotated with a
+	 * R_X86_64_NONE relocation, it should point to the jump table
+	 * in .rodata. In this case, the ELF symbol will give us the
+	 * size of the table. Ignore other occurrences of R_X86_64_NONE.
+	 */
+	if (reloc_type(text_reloc) == R_X86_64_NONE &&
+	    insn->type != INSN_JUMP_DYNAMIC)
+		return NULL;
+
+	table_offset = text_reloc->sym->offset + reloc_addend(text_reloc);
 	table_sec = text_reloc->sym->sec;
 
 	if (reloc_type(text_reloc) == R_X86_64_PC32)
 		table_offset += 4;
 
+	switch (text_reloc->sym->type) {
+	case STT_OBJECT:
+		sym = text_reloc->sym;
+		break;
+	case  STT_SECTION:
+		sym = find_symbol_containing(table_sec, table_offset);
+		break;
+	default:
+		return NULL;
+	}
+
 	/*
 	 * Make sure the .rodata address isn't associated with a
-	 * symbol.  GCC jump tables are anonymous data.
+	 * symbol. Unannotated GCC jump tables are anonymous data.
 	 *
 	 * Also support C jump tables which are in the same format as
 	 * switch jump tables.  For objtool to recognize them, they
 	 * need to be placed in the C_JUMP_TABLE_SECTION section.  They
 	 * have symbols associated with them.
 	 */
-	if (find_symbol_containing(table_sec, table_offset) &&
+	if (reloc_type(text_reloc) != R_X86_64_NONE && sym &&
 	    strcmp(table_sec->name, C_JUMP_TABLE_SECTION))
 		return NULL;
 
@@ -151,6 +172,6 @@ struct reloc *arch_find_switch_table(struct objtool_file *file,
 	if (!rodata_reloc)
 		return NULL;
 
-	*table_size = 0;
+	*table_size = sym ? sym->len : 0;
 	return rodata_reloc;
 }
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 5f711ac5b43d..6521c82880f0 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1386,6 +1386,8 @@ __weak const char *arch_nop_fentry_call(int len)
 
 static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *insn)
 {
+	unsigned long offset = insn->offset;
+	unsigned int len = insn->len;
 	struct reloc *reloc;
 
 	if (insn->no_reloc)
@@ -1394,8 +1396,12 @@ static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *i
 	if (!file)
 		return NULL;
 
-	reloc = find_reloc_by_dest_range(file->elf, insn->sec,
-					 insn->offset, insn->len);
+	do {
+		/* Skip any R_*_NONE relocations */
+		reloc = find_reloc_by_dest_range(file->elf, insn->sec,
+						 offset++, len--);
+	} while (len && reloc && reloc_type(reloc) == 0);
+
 	if (!reloc) {
 		insn->no_reloc = 1;
 		return NULL;
-- 
2.47.0.rc0.187.ge670bccf7e-goog


  parent reply	other threads:[~2024-10-10 12:28 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-10 12:28 [PATCH v2 0/5] Improve objtool jump table handling Ard Biesheuvel
2024-10-10 12:28 ` [PATCH v2 1/5] objtool: Deal with relative jump tables correctly Ard Biesheuvel
2024-10-10 13:26   ` Peter Zijlstra
2024-10-10 13:59     ` Ard Biesheuvel
2024-10-10 14:07       ` Peter Zijlstra
2024-10-10 15:32         ` Josh Poimboeuf
2024-10-10 12:28 ` [PATCH v2 2/5] objtool: Allow arch code to discover jump table size Ard Biesheuvel
2024-10-10 19:52   ` Josh Poimboeuf
2024-10-11 16:50     ` Ard Biesheuvel
2024-10-10 12:28 ` Ard Biesheuvel [this message]
2024-10-10 20:12   ` [PATCH v2 3/5] objtool: Add support for annotated jump tables Josh Poimboeuf
2024-10-10 20:15   ` Josh Poimboeuf
2024-10-11  6:29     ` Ard Biesheuvel
2024-10-11 15:56       ` Josh Poimboeuf
2024-10-10 12:28 ` [PATCH v2 4/5] crypto: x86/crc32c - Use idiomatic relative jump table Ard Biesheuvel
2024-10-10 12:28 ` [PATCH v2 5/5] crypto: x86/crc32c - Tweak jump table to validate objtool logic Ard Biesheuvel
2024-10-10 20:34   ` Josh Poimboeuf
2024-10-11  6:32     ` Ard Biesheuvel
2024-10-11 16:04       ` Josh Poimboeuf
2024-10-11 16:22         ` Ard Biesheuvel
2024-10-10 17:50 ` [PATCH v2 0/5] Improve objtool jump table handling Ard Biesheuvel
2024-10-10 20:36   ` Josh Poimboeuf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241010122801.1321976-10-ardb+git@google.com \
    --to=ardb+git@google.com \
    --cc=ardb@kernel.org \
    --cc=jbeulich@suse.com \
    --cc=jemarch@gnu.org \
    --cc=jpoimboe@kernel.org \
    --cc=kees@kernel.org \
    --cc=keescook@chromium.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=llvm@lists.linux.dev \
    --cc=nathan@kernel.org \
    --cc=peterz@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox