提交 2671a075 编写于 作者: J Josh Poimboeuf 提交者: Zheng Zengkai

objtool: Re-add UNWIND_HINT_{SAVE_RESTORE}

stable inclusion
from stable-v5.10.133
commit df93717a32f57e1b033dbfa2a78809d7d4000648
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5PTAS
CVE: CVE-2022-29900,CVE-2022-23816,CVE-2022-29901

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=df93717a32f57e1b033dbfa2a78809d7d4000648

--------------------------------

commit 8faea26e upstream.

Commit

  c536ed2f ("objtool: Remove SAVE/RESTORE hints")

removed the save/restore unwind hints because they were no longer
needed. Now they're going to be needed again so re-add them.
Signed-off-by: NJosh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: NBorislav Petkov <bp@suse.de>
Signed-off-by: NThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Signed-off-by: NBen Hutchings <ben@decadent.org.uk>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NLin Yujun <linyujun809@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 f9dd6118
...@@ -8,11 +8,11 @@ ...@@ -8,11 +8,11 @@
#ifdef __ASSEMBLY__ #ifdef __ASSEMBLY__
.macro UNWIND_HINT_EMPTY .macro UNWIND_HINT_EMPTY
UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_CALL end=1 UNWIND_HINT type=UNWIND_HINT_TYPE_CALL end=1
.endm .endm
.macro UNWIND_HINT_ENTRY .macro UNWIND_HINT_ENTRY
UNWIND_HINT sp_reg=ORC_REG_UNDEFINED type=UNWIND_HINT_TYPE_ENTRY end=1 UNWIND_HINT type=UNWIND_HINT_TYPE_ENTRY end=1
.endm .endm
.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0 .macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 partial=0
...@@ -56,6 +56,14 @@ ...@@ -56,6 +56,14 @@
UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=8 type=UNWIND_HINT_TYPE_FUNC UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=8 type=UNWIND_HINT_TYPE_FUNC
.endm .endm
.macro UNWIND_HINT_SAVE
UNWIND_HINT type=UNWIND_HINT_TYPE_SAVE
.endm
.macro UNWIND_HINT_RESTORE
UNWIND_HINT type=UNWIND_HINT_TYPE_RESTORE
.endm
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* _ASM_X86_UNWIND_HINTS_H */ #endif /* _ASM_X86_UNWIND_HINTS_H */
...@@ -40,6 +40,8 @@ struct unwind_hint { ...@@ -40,6 +40,8 @@ struct unwind_hint {
#define UNWIND_HINT_TYPE_REGS_PARTIAL 2 #define UNWIND_HINT_TYPE_REGS_PARTIAL 2
#define UNWIND_HINT_TYPE_FUNC 3 #define UNWIND_HINT_TYPE_FUNC 3
#define UNWIND_HINT_TYPE_ENTRY 4 #define UNWIND_HINT_TYPE_ENTRY 4
#define UNWIND_HINT_TYPE_SAVE 5
#define UNWIND_HINT_TYPE_RESTORE 6
#ifdef CONFIG_STACK_VALIDATION #ifdef CONFIG_STACK_VALIDATION
...@@ -102,7 +104,7 @@ struct unwind_hint { ...@@ -102,7 +104,7 @@ struct unwind_hint {
* the debuginfo as necessary. It will also warn if it sees any * the debuginfo as necessary. It will also warn if it sees any
* inconsistencies. * inconsistencies.
*/ */
.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 .macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
.Lunwind_hint_ip_\@: .Lunwind_hint_ip_\@:
.pushsection .discard.unwind_hints .pushsection .discard.unwind_hints
/* struct unwind_hint */ /* struct unwind_hint */
...@@ -126,7 +128,7 @@ struct unwind_hint { ...@@ -126,7 +128,7 @@ struct unwind_hint {
#define STACK_FRAME_NON_STANDARD(func) #define STACK_FRAME_NON_STANDARD(func)
#else #else
#define ANNOTATE_INTRA_FUNCTION_CALL #define ANNOTATE_INTRA_FUNCTION_CALL
.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 .macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
.endm .endm
#endif #endif
......
...@@ -40,6 +40,8 @@ struct unwind_hint { ...@@ -40,6 +40,8 @@ struct unwind_hint {
#define UNWIND_HINT_TYPE_REGS_PARTIAL 2 #define UNWIND_HINT_TYPE_REGS_PARTIAL 2
#define UNWIND_HINT_TYPE_FUNC 3 #define UNWIND_HINT_TYPE_FUNC 3
#define UNWIND_HINT_TYPE_ENTRY 4 #define UNWIND_HINT_TYPE_ENTRY 4
#define UNWIND_HINT_TYPE_SAVE 5
#define UNWIND_HINT_TYPE_RESTORE 6
#ifdef CONFIG_STACK_VALIDATION #ifdef CONFIG_STACK_VALIDATION
...@@ -102,7 +104,7 @@ struct unwind_hint { ...@@ -102,7 +104,7 @@ struct unwind_hint {
* the debuginfo as necessary. It will also warn if it sees any * the debuginfo as necessary. It will also warn if it sees any
* inconsistencies. * inconsistencies.
*/ */
.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 .macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
.Lunwind_hint_ip_\@: .Lunwind_hint_ip_\@:
.pushsection .discard.unwind_hints .pushsection .discard.unwind_hints
/* struct unwind_hint */ /* struct unwind_hint */
...@@ -126,7 +128,7 @@ struct unwind_hint { ...@@ -126,7 +128,7 @@ struct unwind_hint {
#define STACK_FRAME_NON_STANDARD(func) #define STACK_FRAME_NON_STANDARD(func)
#else #else
#define ANNOTATE_INTRA_FUNCTION_CALL #define ANNOTATE_INTRA_FUNCTION_CALL
.macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0 .macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 end=0
.endm .endm
#endif #endif
......
...@@ -1751,6 +1751,17 @@ static int read_unwind_hints(struct objtool_file *file) ...@@ -1751,6 +1751,17 @@ static int read_unwind_hints(struct objtool_file *file)
insn->hint = true; insn->hint = true;
if (hint->type == UNWIND_HINT_TYPE_SAVE) {
insn->hint = false;
insn->save = true;
continue;
}
if (hint->type == UNWIND_HINT_TYPE_RESTORE) {
insn->restore = true;
continue;
}
if (hint->type == UNWIND_HINT_TYPE_REGS_PARTIAL) { if (hint->type == UNWIND_HINT_TYPE_REGS_PARTIAL) {
struct symbol *sym = find_symbol_by_offset(insn->sec, insn->offset); struct symbol *sym = find_symbol_by_offset(insn->sec, insn->offset);
...@@ -2846,6 +2857,35 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, ...@@ -2846,6 +2857,35 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
state.instr += insn->instr; state.instr += insn->instr;
if (insn->hint) { if (insn->hint) {
if (insn->restore) {
struct instruction *save_insn, *i;
i = insn;
save_insn = NULL;
sym_for_each_insn_continue_reverse(file, func, i) {
if (i->save) {
save_insn = i;
break;
}
}
if (!save_insn) {
WARN_FUNC("no corresponding CFI save for CFI restore",
sec, insn->offset);
return 1;
}
if (!save_insn->visited) {
WARN_FUNC("objtool isn't smart enough to handle this CFI save/restore combo",
sec, insn->offset);
return 1;
}
insn->cfi = save_insn->cfi;
nr_cfi_reused++;
}
state.cfi = *insn->cfi; state.cfi = *insn->cfi;
} else { } else {
/* XXX track if we actually changed state.cfi */ /* XXX track if we actually changed state.cfi */
......
...@@ -47,6 +47,7 @@ struct instruction { ...@@ -47,6 +47,7 @@ struct instruction {
unsigned long immediate; unsigned long immediate;
bool dead_end, ignore, ignore_alts; bool dead_end, ignore, ignore_alts;
bool hint; bool hint;
bool save, restore;
bool retpoline_safe; bool retpoline_safe;
bool entry; bool entry;
s8 instr; s8 instr;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册