From nobody Wed Nov 27 09:45:15 2024 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E8D7A1C4610 for ; Fri, 11 Oct 2024 17:09:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728666552; cv=none; b=SG18wJJyHeMa07orZ6Ev3AGGe0CslDQnhtdAiVHlOAacIfaSO6YBUuVBQWN86ZGwCE8UiYqgwiGflCnWPWmA5opdku0RmzVUruZxnqL47/5lfZhqMPAlEf919x5QPsXdQc8Um7R9r5JIpRGTLqrvhLg/Ht5mdwIh5Om/53S9hto= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728666552; c=relaxed/simple; bh=VUujYBiQvSszgV0qs3fJK1Hvr5k7z7tzS0djEyuvxZs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=lJXm1IvJQm5RrVP3WYRyEMJ5Y54G9bfoej2Le3STEpvwFwSHFlZoQoJVKS7XXyYTPvx5R3FD4ngiz0GqPutaQYCr7AaUg/pnSLGOzGegO/h1FEf+D64eqXfs9DLFaVICopM7Ko5nT4IR6q3YK/f++XhmATTq+MaPK8oRj7r098E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--ardb.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=vIFY2t62; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--ardb.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="vIFY2t62" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-431207426e3so3512685e9.1 for ; Fri, 11 Oct 2024 10:09:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1728666549; x=1729271349; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=bfj0B3nnHjUxcCyCalhugd5ngmM/JrZzfePhPsFLeh4=; b=vIFY2t62Kfu9sD1TJtD3E5c4RPwLlZA/U+7yY5NfJhMwZlWqcT9jQRfMBnfpb+pjGg voO+yx8Em89gfalkzcJRLCWQC3WsUHGzLxLod9w0Tm1GEOyBxjP2Nk2TPwLlMaE2ZQo2 X/4si/pDbdI4gzEm2rpjSO0c2MyLMhmmwZluMD7TRqJ3Ia6kncF4Ciu2sTl52sBV0dYz Zn8diq3+bald2w7c/7SMa501mLH0rZUd9w4n+ttrZoLNLNtSpeuXyyOdqaRPa6P+e9lq eXQ4HfLGNXWmEf4mVktMAPrBeRs8pTcE/nbvAh9v1eKnNaCUeNx5ZCJYbU3buOMDPL3r oh8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728666549; x=1729271349; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=bfj0B3nnHjUxcCyCalhugd5ngmM/JrZzfePhPsFLeh4=; b=Meem3kqTVnnZpxNNJ/+gzW7s92uVRlKrlCKSqwq/owwQmB8XgCUET4v8qMVYTT00vm c/N/cI7iE6vDwhywuLTcwwr6kkIf7FhnyzNVNI5hr/ly0n2zDqVfXJZXv1SY9Iqf/PN7 j6Uki3hFn2yhMWE+nLmBCYDF/Q+1dlArVNU/miJT6CA2LYcC0NcyA98Ttf8KPcp1fdQe QOcLYhSMJBDmjJm8c3Eqf4/B1RmjFFk9NAAd2ZmX8ppwUBUtNoMSCijAwzZzi1KyurBh +0QJVX+NyA4KphfoWjBetEzmynJ5XDaGI3UN6qTYTd7CdX4YofHyZPocEnKvSHTrgW74 DbqQ== X-Gm-Message-State: AOJu0YwnGt1Qgvn7cmWkmZ7Uaw/m+K/z5DvItyo7EHv9TP715ec2E7Jc 9o+lTDksxpRd2eGncgrygryG+9yANzED7b12Hgo/yi5qTZHPSzSzKZOIxzfgnxXjnD+XbPqTw5k RvGEiytqsJGkGnwfveY7F2letpd+e/5eMgeCgRqR7vbfvwFGQQ34RiRRv9n2FR35SqI+CLYzLBl zf7jQMcIevy+wSjOL6ysHY0HPKSY0tvw== X-Google-Smtp-Source: AGHT+IFvX/saq2RUfGzHvn3Yuhv8T3E5DzVonOGZChHXCjZPWicr/2IaSFuxMZRFRkaqCDpZgMyInJz/ X-Received: from palermo.c.googlers.com ([fda3:e722:ac3:cc00:7b:198d:ac11:8138]) (user=ardb job=sendgmr) by 2002:a5d:6890:0:b0:374:badf:9b16 with SMTP id ffacd0b85a97d-37d54de7715mr5662f8f.0.1728666548505; Fri, 11 Oct 2024 10:09:08 -0700 (PDT) Date: Fri, 11 Oct 2024 19:08:50 +0200 In-Reply-To: <20241011170847.334429-10-ardb+git@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20241011170847.334429-10-ardb+git@google.com> X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-Developer-Signature: v=1; a=openpgp-sha256; l=6898; i=ardb@kernel.org; h=from:subject; bh=2jvHADU7c8PNtY41id5iwZpe+A4RE0tCIX4zDl/IOwI=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIZ0zevGeuTemSKv5/VnNF3SJkT37m5jGny9B0qcX3hCdy FY1fcO/jlIWBjEOBlkxRRaB2X/f7Tw9UarWeZYszBxWJpAhDFycAjCR2tMM/wteCl2WXp4vrqrU 8/PM1Tu7eE0Ka+2OVWe/PrexdoZEgQ3DP7MzGyWTi0uENn70OL9B8qPnx/4X27Z1bYtzXq58O1l YjB8A X-Mailer: git-send-email 2.47.0.rc1.288.g06298d1525-goog Message-ID: <20241011170847.334429-12-ardb+git@google.com> Subject: [PATCH v3 2/8] objtool: Allow arch code to discover jump table size From: Ard Biesheuvel To: linux-kernel@vger.kernel.org Cc: llvm@lists.linux.dev, keescook@chromium.org, linux-hardening@vger.kernel.org, nathan@kernel.org, Ard Biesheuvel , Josh Poimboeuf , Peter Zijlstra , Jan Beulich , "Jose E. Marchesi" , Kees Cook Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ard Biesheuvel In preparation for adding support for annotated jump tables, where ELF relocations and symbols are used to describe the locations of jump tables in the executable, refactor the jump table discovery logic so the table size can be returned from arch_find_switch_table(). Signed-off-by: Ard Biesheuvel --- tools/objtool/arch/loongarch/special.c | 3 +- tools/objtool/arch/powerpc/special.c | 3 +- tools/objtool/arch/x86/special.c | 4 ++- tools/objtool/check.c | 31 +++++++++++++------- tools/objtool/include/objtool/check.h | 5 +++- tools/objtool/include/objtool/special.h | 3 +- 6 files changed, 33 insertions(+), 16 deletions(-) diff --git a/tools/objtool/arch/loongarch/special.c b/tools/objtool/arch/lo= ongarch/special.c index 9bba1e9318e0..87230ed570fd 100644 --- a/tools/objtool/arch/loongarch/special.c +++ b/tools/objtool/arch/loongarch/special.c @@ -9,7 +9,8 @@ bool arch_support_alt_relocation(struct special_alt *specia= l_alt, } =20 struct reloc *arch_find_switch_table(struct objtool_file *file, - struct instruction *insn) + struct instruction *insn, + unsigned long *table_size) { return NULL; } diff --git a/tools/objtool/arch/powerpc/special.c b/tools/objtool/arch/powe= rpc/special.c index d33868147196..51610689abf7 100644 --- a/tools/objtool/arch/powerpc/special.c +++ b/tools/objtool/arch/powerpc/special.c @@ -13,7 +13,8 @@ bool arch_support_alt_relocation(struct special_alt *spec= ial_alt, } =20 struct reloc *arch_find_switch_table(struct objtool_file *file, - struct instruction *insn) + struct instruction *insn, + unsigned long *table_size) { exit(-1); } diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/spec= ial.c index 415e4d035e53..f8fb67636384 100644 --- a/tools/objtool/arch/x86/special.c +++ b/tools/objtool/arch/x86/special.c @@ -109,7 +109,8 @@ bool arch_support_alt_relocation(struct special_alt *sp= ecial_alt, * NOTE: MITIGATION_RETPOLINE made it harder still to decode dynamic ju= mps. */ struct reloc *arch_find_switch_table(struct objtool_file *file, - struct instruction *insn) + struct instruction *insn, + unsigned long *table_size) { struct reloc *text_reloc, *rodata_reloc; struct section *table_sec; @@ -150,5 +151,6 @@ struct reloc *arch_find_switch_table(struct objtool_fil= e *file, if (!rodata_reloc) return NULL; =20 + *table_size =3D 0; return rodata_reloc; } diff --git a/tools/objtool/check.c b/tools/objtool/check.c index aa07fdf1cf13..b73e43b9b9e3 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -150,6 +150,15 @@ static inline struct reloc *insn_jump_table(struct ins= truction *insn) return NULL; } =20 +static inline unsigned long insn_jump_table_size(struct instruction *insn) +{ + if (insn->type =3D=3D INSN_JUMP_DYNAMIC || + insn->type =3D=3D INSN_CALL_DYNAMIC) + return insn->_jump_table_size; + + return 0; +} + static bool is_jump_table_jump(struct instruction *insn) { struct alt_group *alt_group =3D insn->alt_group; @@ -2099,6 +2108,7 @@ static int add_special_section_alts(struct objtool_fi= le *file) static int add_jump_table(struct objtool_file *file, struct instruction *i= nsn, struct reloc *next_table) { + unsigned long table_size =3D insn_jump_table_size(insn); struct symbol *pfunc =3D insn_func(insn)->pfunc; struct reloc *table =3D insn_jump_table(insn); unsigned int rtype =3D reloc_type(table); @@ -2116,6 +2126,8 @@ static int add_jump_table(struct objtool_file *file, = struct instruction *insn, unsigned long addend =3D reloc_addend(reloc); =20 /* Check for the end of the table: */ + if (table_size && reloc_offset(reloc) - reloc_offset(table) >=3D table_s= ize) + break; if (reloc !=3D table && reloc =3D=3D next_table) break; =20 @@ -2175,12 +2187,12 @@ static int add_jump_table(struct objtool_file *file= , struct instruction *insn, * find_jump_table() - Given a dynamic jump, find the switch jump table * associated with it. */ -static struct reloc *find_jump_table(struct objtool_file *file, - struct symbol *func, - struct instruction *insn) +static void find_jump_table(struct objtool_file *file, struct symbol *func, + struct instruction *insn) { struct reloc *table_reloc; struct instruction *dest_insn, *orig_insn =3D insn; + unsigned long table_size; =20 /* * Backward search using the @first_jump_src links, these help avoid @@ -2201,17 +2213,17 @@ static struct reloc *find_jump_table(struct objtool= _file *file, insn->jump_dest->offset > orig_insn->offset)) break; =20 - table_reloc =3D arch_find_switch_table(file, insn); + table_reloc =3D arch_find_switch_table(file, insn, &table_size); if (!table_reloc) continue; dest_insn =3D find_insn(file, table_reloc->sym->sec, reloc_addend(table_= reloc)); if (!dest_insn || !insn_func(dest_insn) || insn_func(dest_insn)->pfunc != =3D func) continue; =20 - return table_reloc; + orig_insn->_jump_table =3D table_reloc; + orig_insn->_jump_table_size =3D table_size; + break; } - - return NULL; } =20 /* @@ -2222,7 +2234,6 @@ static void mark_func_jump_tables(struct objtool_file= *file, struct symbol *func) { struct instruction *insn, *last =3D NULL; - struct reloc *reloc; =20 func_for_each_insn(file, func, insn) { if (!last) @@ -2245,9 +2256,7 @@ static void mark_func_jump_tables(struct objtool_file= *file, if (insn->type !=3D INSN_JUMP_DYNAMIC) continue; =20 - reloc =3D find_jump_table(file, func, insn); - if (reloc) - insn->_jump_table =3D reloc; + find_jump_table(file, func, insn); } } =20 diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/= objtool/check.h index daa46f1f0965..e1cd13cd28a3 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -71,7 +71,10 @@ struct instruction { struct instruction *first_jump_src; union { struct symbol *_call_dest; - struct reloc *_jump_table; + struct { + struct reloc *_jump_table; + unsigned long _jump_table_size; + }; }; struct alternative *alts; struct symbol *sym; diff --git a/tools/objtool/include/objtool/special.h b/tools/objtool/includ= e/objtool/special.h index 86d4af9c5aa9..e7ee7ffccefd 100644 --- a/tools/objtool/include/objtool/special.h +++ b/tools/objtool/include/objtool/special.h @@ -38,5 +38,6 @@ bool arch_support_alt_relocation(struct special_alt *spec= ial_alt, struct instruction *insn, struct reloc *reloc); struct reloc *arch_find_switch_table(struct objtool_file *file, - struct instruction *insn); + struct instruction *insn, + unsigned long *table_size); #endif /* _SPECIAL_H */ --=20 2.47.0.rc1.288.g06298d1525-goog