mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-13 14:04:05 +08:00
objtool: Add --cfi to generate the .cfi_sites section
Add the location of all __cfi_##name symbols (as generated by kCFI) to a section such that we might re-write things at kernel boot. Notably; boot time re-hashing and FineIBT are the intended use of this. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20221027092842.568039454@infradead.org
This commit is contained in:
parent
b341b20d64
commit
9a479f766b
@ -80,6 +80,7 @@ const struct option check_options[] = {
|
||||
OPT_BOOLEAN('s', "stackval", &opts.stackval, "validate frame pointer rules"),
|
||||
OPT_BOOLEAN('t', "static-call", &opts.static_call, "annotate static calls"),
|
||||
OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for SMAP"),
|
||||
OPT_BOOLEAN(0 , "cfi", &opts.cfi, "annotate kernel control flow integrity (kCFI) function preambles"),
|
||||
OPT_CALLBACK_OPTARG(0, "dump", NULL, NULL, "orc", "dump metadata", parse_dump),
|
||||
|
||||
OPT_GROUP("Options:"),
|
||||
|
@ -861,6 +861,68 @@ static int create_ibt_endbr_seal_sections(struct objtool_file *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int create_cfi_sections(struct objtool_file *file)
|
||||
{
|
||||
struct section *sec, *s;
|
||||
struct symbol *sym;
|
||||
unsigned int *loc;
|
||||
int idx;
|
||||
|
||||
sec = find_section_by_name(file->elf, ".cfi_sites");
|
||||
if (sec) {
|
||||
INIT_LIST_HEAD(&file->call_list);
|
||||
WARN("file already has .cfi_sites section, skipping");
|
||||
return 0;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
for_each_sec(file, s) {
|
||||
if (!s->text)
|
||||
continue;
|
||||
|
||||
list_for_each_entry(sym, &s->symbol_list, list) {
|
||||
if (sym->type != STT_FUNC)
|
||||
continue;
|
||||
|
||||
if (strncmp(sym->name, "__cfi_", 6))
|
||||
continue;
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
sec = elf_create_section(file->elf, ".cfi_sites", 0, sizeof(unsigned int), idx);
|
||||
if (!sec)
|
||||
return -1;
|
||||
|
||||
idx = 0;
|
||||
for_each_sec(file, s) {
|
||||
if (!s->text)
|
||||
continue;
|
||||
|
||||
list_for_each_entry(sym, &s->symbol_list, list) {
|
||||
if (sym->type != STT_FUNC)
|
||||
continue;
|
||||
|
||||
if (strncmp(sym->name, "__cfi_", 6))
|
||||
continue;
|
||||
|
||||
loc = (unsigned int *)sec->data->d_buf + idx;
|
||||
memset(loc, 0, sizeof(unsigned int));
|
||||
|
||||
if (elf_add_reloc_to_insn(file->elf, sec,
|
||||
idx * sizeof(unsigned int),
|
||||
R_X86_64_PC32,
|
||||
s, sym->offset))
|
||||
return -1;
|
||||
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int create_mcount_loc_sections(struct objtool_file *file)
|
||||
{
|
||||
struct section *sec;
|
||||
@ -4430,6 +4492,13 @@ int check(struct objtool_file *file)
|
||||
warnings += ret;
|
||||
}
|
||||
|
||||
if (opts.cfi) {
|
||||
ret = create_cfi_sections(file);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
warnings += ret;
|
||||
}
|
||||
|
||||
if (opts.rethunk) {
|
||||
ret = create_return_sites_sections(file);
|
||||
if (ret < 0)
|
||||
|
@ -27,6 +27,7 @@ struct opts {
|
||||
bool static_call;
|
||||
bool uaccess;
|
||||
int prefix;
|
||||
bool cfi;
|
||||
|
||||
/* options: */
|
||||
bool backtrace;
|
||||
|
Loading…
Reference in New Issue
Block a user