提交 d9a0fb33 编写于 作者: P Peter Zijlstra 提交者: Zheng Zengkai

objtool: Keep track of retpoline call sites

stable inclusion
from stable-v5.10.133
commit 33092b486686c31432c5354dbb18651e44200668
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=33092b486686c31432c5354dbb18651e44200668

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

commit 43d5430a upstream.

Provide infrastructure for architectures to rewrite/augment compiler
generated retpoline calls. Similar to what we do for static_call()s,
keep track of the instructions that are retpoline calls.

Use the same list_head, since a retpoline call cannot also be a
static_call.
Signed-off-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: NBorislav Petkov <bp@suse.de>
Signed-off-by: NIngo Molnar <mingo@kernel.org>
Reviewed-by: NMiroslav Benes <mbenes@suse.cz>
Link: https://lkml.kernel.org/r/20210326151300.130805730@infradead.org
[bwh: Backported to 5.10: adjust context]
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>
Reviewed-by: NZhang Jianhua <chris.zjh@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 ee38be77
......@@ -88,4 +88,6 @@ int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg);
bool arch_is_retpoline(struct symbol *sym);
int arch_rewrite_retpolines(struct objtool_file *file);
#endif /* _ARCH_H */
......@@ -451,7 +451,7 @@ static int create_static_call_sections(struct objtool_file *file)
return 0;
idx = 0;
list_for_each_entry(insn, &file->static_call_list, static_call_node)
list_for_each_entry(insn, &file->static_call_list, call_node)
idx++;
sec = elf_create_section(file->elf, ".static_call_sites", SHF_WRITE,
......@@ -460,7 +460,7 @@ static int create_static_call_sections(struct objtool_file *file)
return -1;
idx = 0;
list_for_each_entry(insn, &file->static_call_list, static_call_node) {
list_for_each_entry(insn, &file->static_call_list, call_node) {
site = (struct static_call_site *)sec->data->d_buf + idx;
memset(site, 0, sizeof(struct static_call_site));
......@@ -786,13 +786,16 @@ static int add_jump_destinations(struct objtool_file *file)
else
insn->type = INSN_JUMP_DYNAMIC_CONDITIONAL;
list_add_tail(&insn->call_node,
&file->retpoline_call_list);
insn->retpoline_safe = true;
continue;
} else if (insn->func) {
/* internal or external sibling call (with reloc) */
insn->call_dest = reloc->sym;
if (insn->call_dest->static_call_tramp) {
list_add_tail(&insn->static_call_node,
list_add_tail(&insn->call_node,
&file->static_call_list);
}
continue;
......@@ -854,7 +857,7 @@ static int add_jump_destinations(struct objtool_file *file)
/* internal sibling call (without reloc) */
insn->call_dest = insn->jump_dest->func;
if (insn->call_dest->static_call_tramp) {
list_add_tail(&insn->static_call_node,
list_add_tail(&insn->call_node,
&file->static_call_list);
}
}
......@@ -938,6 +941,9 @@ static int add_call_destinations(struct objtool_file *file)
insn->type = INSN_CALL_DYNAMIC;
insn->retpoline_safe = true;
list_add_tail(&insn->call_node,
&file->retpoline_call_list);
remove_insn_ops(insn);
continue;
......@@ -945,7 +951,7 @@ static int add_call_destinations(struct objtool_file *file)
insn->call_dest = reloc->sym;
if (insn->call_dest && insn->call_dest->static_call_tramp) {
list_add_tail(&insn->static_call_node,
list_add_tail(&insn->call_node,
&file->static_call_list);
}
......@@ -1655,6 +1661,11 @@ static void mark_rodata(struct objtool_file *file)
file->rodata = found;
}
__weak int arch_rewrite_retpolines(struct objtool_file *file)
{
return 0;
}
static int decode_sections(struct objtool_file *file)
{
int ret;
......@@ -1683,6 +1694,10 @@ static int decode_sections(struct objtool_file *file)
if (ret)
return ret;
/*
* Must be before add_special_section_alts() as that depends on
* jump_dest being set.
*/
ret = add_jump_destinations(file);
if (ret)
return ret;
......@@ -1719,6 +1734,15 @@ static int decode_sections(struct objtool_file *file)
if (ret)
return ret;
/*
* Must be after add_special_section_alts(), since this will emit
* alternatives. Must be after add_{jump,call}_destination(), since
* those create the call insn lists.
*/
ret = arch_rewrite_retpolines(file);
if (ret)
return ret;
return 0;
}
......
......@@ -39,7 +39,7 @@ struct alt_group {
struct instruction {
struct list_head list;
struct hlist_node hash;
struct list_head static_call_node;
struct list_head call_node;
struct section *sec;
unsigned long offset;
unsigned int len;
......
......@@ -61,6 +61,7 @@ struct objtool_file *objtool_open_read(const char *_objname)
INIT_LIST_HEAD(&file.insn_list);
hash_init(file.insn_hash);
INIT_LIST_HEAD(&file.retpoline_call_list);
INIT_LIST_HEAD(&file.static_call_list);
file.c_file = !vmlinux && find_section_by_name(file.elf, ".comment");
file.ignore_unreachables = no_unreachable;
......
......@@ -18,6 +18,7 @@ struct objtool_file {
struct elf *elf;
struct list_head insn_list;
DECLARE_HASHTABLE(insn_hash, 20);
struct list_head retpoline_call_list;
struct list_head static_call_list;
bool ignore_unreachables, c_file, hints, rodata;
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册