Skip to content

Commit 9d7d4ad

Browse files
committed
Merge tag 'objtool-core-2024-11-18' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull objtool updates from Ingo Molnar: - Detect non-relocated text references for more robust IBT sealing (Josh Poimboeuf) - Fix build error when building stripped down UAPI headers (HONG Yifan) - Exclude __tracepoints data from ENDBR checks to fix false positives on clang builds (Peter Zijlstra) - Fix ORC unwind for newly forked tasks (Zheng Yejian) - Fix readelf related faddr2line regression (Carlos Llamas) * tag 'objtool-core-2024-11-18' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: objtool: Exclude __tracepoints data from ENDBR checks Revert "scripts/faddr2line: Check only two symbols when calculating symbol size" x86/unwind/orc: Fix unwind for newly forked tasks objtool: Also include tools/include/uapi objtool: Detect non-relocated text references
2 parents 364eeb7 + d5173f7 commit 9d7d4ad

File tree

8 files changed

+81
-55
lines changed

8 files changed

+81
-55
lines changed

arch/x86/kernel/acpi/wakeup_64.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ SYM_FUNC_START(do_suspend_lowlevel)
8787

8888
.align 4
8989
.Lresume_point:
90+
ANNOTATE_NOENDBR
9091
/* We don't restore %rax, it must be 0 anyway */
9192
movq $saved_context, %rax
9293
movq saved_context_cr4(%rax), %rbx

arch/x86/kernel/head_64.S

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ SYM_CODE_START_NOALIGN(startup_64)
7777
lretq
7878

7979
.Lon_kernel_cs:
80+
ANNOTATE_NOENDBR
8081
UNWIND_HINT_END_OF_STACK
8182

8283
#ifdef CONFIG_AMD_MEM_ENCRYPT

arch/x86/kernel/unwind_orc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task,
723723
state->sp = task->thread.sp + sizeof(*frame);
724724
state->bp = READ_ONCE_NOCHECK(frame->bp);
725725
state->ip = READ_ONCE_NOCHECK(frame->ret_addr);
726-
state->signal = (void *)state->ip == ret_from_fork;
726+
state->signal = (void *)state->ip == ret_from_fork_asm;
727727
}
728728

729729
if (get_stack_info((unsigned long *)state->sp, state->task,

scripts/faddr2line

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ __faddr2line() {
252252
found=2
253253
break
254254
fi
255-
done < <(echo "${ELF_SYMS}" | sed 's/\[.*\]//' | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2 | ${GREP} -A1 --no-group-separator " ${sym_name}$")
255+
done < <(echo "${ELF_SYMS}" | sed 's/\[.*\]//' | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2)
256256

257257
if [[ $found = 0 ]]; then
258258
warn "can't find symbol: sym_name: $sym_name sym_sec: $sym_sec sym_addr: $sym_addr sym_elf_size: $sym_elf_size"

tools/objtool/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ LIBELF_LIBS := $(shell $(HOSTPKG_CONFIG) libelf --libs 2>/dev/null || echo -lel
2424
all: $(OBJTOOL)
2525

2626
INCLUDES := -I$(srctree)/tools/include \
27+
-I$(srctree)/tools/include/uapi \
2728
-I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \
2829
-I$(srctree)/tools/arch/$(SRCARCH)/include \
2930
-I$(srctree)/tools/objtool/include \

tools/objtool/arch/x86/decode.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -456,17 +456,19 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
456456
if (!rex_w)
457457
break;
458458

459-
/* skip RIP relative displacement */
460-
if (is_RIP())
461-
break;
462-
463459
/* skip nontrivial SIB */
464460
if (have_SIB()) {
465461
modrm_rm = sib_base;
466462
if (sib_index != CFI_SP)
467463
break;
468464
}
469465

466+
/* lea disp(%rip), %dst */
467+
if (is_RIP()) {
468+
insn->type = INSN_LEA_RIP;
469+
break;
470+
}
471+
470472
/* lea disp(%src), %dst */
471473
ADD_OP(op) {
472474
op->src.offset = ins.displacement.value;
@@ -737,7 +739,10 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
737739
break;
738740
}
739741

740-
insn->immediate = ins.immediate.nbytes ? ins.immediate.value : 0;
742+
if (ins.immediate.nbytes)
743+
insn->immediate = ins.immediate.value;
744+
else if (ins.displacement.nbytes)
745+
insn->immediate = ins.displacement.value;
741746

742747
return 0;
743748
}

tools/objtool/check.c

Lines changed: 65 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4392,6 +4392,51 @@ static bool noendbr_range(struct objtool_file *file, struct instruction *insn)
43924392
return insn->offset == sym->offset + sym->len;
43934393
}
43944394

4395+
static int __validate_ibt_insn(struct objtool_file *file, struct instruction *insn,
4396+
struct instruction *dest)
4397+
{
4398+
if (dest->type == INSN_ENDBR) {
4399+
mark_endbr_used(dest);
4400+
return 0;
4401+
}
4402+
4403+
if (insn_func(dest) && insn_func(insn) &&
4404+
insn_func(dest)->pfunc == insn_func(insn)->pfunc) {
4405+
/*
4406+
* Anything from->to self is either _THIS_IP_ or
4407+
* IRET-to-self.
4408+
*
4409+
* There is no sane way to annotate _THIS_IP_ since the
4410+
* compiler treats the relocation as a constant and is
4411+
* happy to fold in offsets, skewing any annotation we
4412+
* do, leading to vast amounts of false-positives.
4413+
*
4414+
* There's also compiler generated _THIS_IP_ through
4415+
* KCOV and such which we have no hope of annotating.
4416+
*
4417+
* As such, blanket accept self-references without
4418+
* issue.
4419+
*/
4420+
return 0;
4421+
}
4422+
4423+
/*
4424+
* Accept anything ANNOTATE_NOENDBR.
4425+
*/
4426+
if (dest->noendbr)
4427+
return 0;
4428+
4429+
/*
4430+
* Accept if this is the instruction after a symbol
4431+
* that is (no)endbr -- typical code-range usage.
4432+
*/
4433+
if (noendbr_range(file, dest))
4434+
return 0;
4435+
4436+
WARN_INSN(insn, "relocation to !ENDBR: %s", offstr(dest->sec, dest->offset));
4437+
return 1;
4438+
}
4439+
43954440
static int validate_ibt_insn(struct objtool_file *file, struct instruction *insn)
43964441
{
43974442
struct instruction *dest;
@@ -4404,6 +4449,7 @@ static int validate_ibt_insn(struct objtool_file *file, struct instruction *insn
44044449
* direct/indirect branches:
44054450
*/
44064451
switch (insn->type) {
4452+
44074453
case INSN_CALL:
44084454
case INSN_CALL_DYNAMIC:
44094455
case INSN_JUMP_CONDITIONAL:
@@ -4413,6 +4459,23 @@ static int validate_ibt_insn(struct objtool_file *file, struct instruction *insn
44134459
case INSN_RETURN:
44144460
case INSN_NOP:
44154461
return 0;
4462+
4463+
case INSN_LEA_RIP:
4464+
if (!insn_reloc(file, insn)) {
4465+
/* local function pointer reference without reloc */
4466+
4467+
off = arch_jump_destination(insn);
4468+
4469+
dest = find_insn(file, insn->sec, off);
4470+
if (!dest) {
4471+
WARN_INSN(insn, "corrupt function pointer reference");
4472+
return 1;
4473+
}
4474+
4475+
return __validate_ibt_insn(file, insn, dest);
4476+
}
4477+
break;
4478+
44164479
default:
44174480
break;
44184481
}
@@ -4423,13 +4486,6 @@ static int validate_ibt_insn(struct objtool_file *file, struct instruction *insn
44234486
reloc_offset(reloc) + 1,
44244487
(insn->offset + insn->len) - (reloc_offset(reloc) + 1))) {
44254488

4426-
/*
4427-
* static_call_update() references the trampoline, which
4428-
* doesn't have (or need) ENDBR. Skip warning in that case.
4429-
*/
4430-
if (reloc->sym->static_call_tramp)
4431-
continue;
4432-
44334489
off = reloc->sym->offset;
44344490
if (reloc_type(reloc) == R_X86_64_PC32 ||
44354491
reloc_type(reloc) == R_X86_64_PLT32)
@@ -4441,47 +4497,7 @@ static int validate_ibt_insn(struct objtool_file *file, struct instruction *insn
44414497
if (!dest)
44424498
continue;
44434499

4444-
if (dest->type == INSN_ENDBR) {
4445-
mark_endbr_used(dest);
4446-
continue;
4447-
}
4448-
4449-
if (insn_func(dest) && insn_func(insn) &&
4450-
insn_func(dest)->pfunc == insn_func(insn)->pfunc) {
4451-
/*
4452-
* Anything from->to self is either _THIS_IP_ or
4453-
* IRET-to-self.
4454-
*
4455-
* There is no sane way to annotate _THIS_IP_ since the
4456-
* compiler treats the relocation as a constant and is
4457-
* happy to fold in offsets, skewing any annotation we
4458-
* do, leading to vast amounts of false-positives.
4459-
*
4460-
* There's also compiler generated _THIS_IP_ through
4461-
* KCOV and such which we have no hope of annotating.
4462-
*
4463-
* As such, blanket accept self-references without
4464-
* issue.
4465-
*/
4466-
continue;
4467-
}
4468-
4469-
/*
4470-
* Accept anything ANNOTATE_NOENDBR.
4471-
*/
4472-
if (dest->noendbr)
4473-
continue;
4474-
4475-
/*
4476-
* Accept if this is the instruction after a symbol
4477-
* that is (no)endbr -- typical code-range usage.
4478-
*/
4479-
if (noendbr_range(file, dest))
4480-
continue;
4481-
4482-
WARN_INSN(insn, "relocation to !ENDBR: %s", offstr(dest->sec, dest->offset));
4483-
4484-
warnings++;
4500+
warnings += __validate_ibt_insn(file, insn, dest);
44854501
}
44864502

44874503
return warnings;
@@ -4557,6 +4573,7 @@ static int validate_ibt(struct objtool_file *file)
45574573
!strcmp(sec->name, "__jump_table") ||
45584574
!strcmp(sec->name, "__mcount_loc") ||
45594575
!strcmp(sec->name, ".kcfi_traps") ||
4576+
!strcmp(sec->name, "__tracepoints") ||
45604577
strstr(sec->name, "__patchable_function_entries"))
45614578
continue;
45624579

tools/objtool/include/objtool/arch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ enum insn_type {
2828
INSN_CLD,
2929
INSN_TRAP,
3030
INSN_ENDBR,
31+
INSN_LEA_RIP,
3132
INSN_OTHER,
3233
};
3334

0 commit comments

Comments
 (0)