Merge pull request #1211 from joe-lawrence/kpatch-check-relocations-use-after-free

create-diff-object: fix use after free in kpatch-check-relocations()
This commit is contained in:
Joe Lawrence 2021-09-15 10:31:11 -04:00 committed by GitHub
commit f77491d570
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 7 deletions

View File

@ -1940,7 +1940,7 @@ static void kpatch_migrate_included_elements(struct kpatch_elf *kelf, struct kpa
list_del(&sym->list); list_del(&sym->list);
list_add_tail(&sym->list, &out->symbols); list_add_tail(&sym->list, &out->symbols);
sym->index = 0; sym->index = 0;
sym->strip = 0; sym->strip = SYMBOL_DEFAULT;
if (sym->sec && !sym->sec->include) if (sym->sec && !sym->sec->include)
/* break link to non-included section */ /* break link to non-included section */
sym->sec = NULL; sym->sec = NULL;
@ -3234,8 +3234,10 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
special = true; special = true;
list_for_each_entry_safe(rela, safe, &sec->relas, list) { list_for_each_entry_safe(rela, safe, &sec->relas, list) {
if (!rela->need_dynrela) if (!rela->need_dynrela) {
rela->sym->strip = SYMBOL_USED;
continue; continue;
}
/* /*
* Starting with Linux 5.8, .klp.arch sections are no * Starting with Linux 5.8, .klp.arch sections are no
@ -3332,8 +3334,8 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
* later (for example, they may have relocations * later (for example, they may have relocations
* of their own which should be processed). * of their own which should be processed).
*/ */
if (!rela->sym->sec) if (!rela->sym->sec && rela->sym->strip != SYMBOL_USED)
rela->sym->strip = 1; rela->sym->strip = SYMBOL_STRIP;
list_del(&rela->list); list_del(&rela->list);
free(rela); free(rela);
@ -3519,7 +3521,7 @@ static void kpatch_strip_unneeded_syms(struct kpatch_elf *kelf,
struct symbol *sym, *safe; struct symbol *sym, *safe;
list_for_each_entry_safe(sym, safe, &kelf->symbols, list) { list_for_each_entry_safe(sym, safe, &kelf->symbols, list) {
if (sym->strip) { if (sym->strip == SYMBOL_STRIP) {
list_del(&sym->list); list_del(&sym->list);
free(sym); free(sym);
} }

View File

@ -67,6 +67,12 @@ struct section {
}; };
}; };
enum symbol_strip {
SYMBOL_DEFAULT,
SYMBOL_USED,
SYMBOL_STRIP,
};
struct symbol { struct symbol {
struct list_head list; struct list_head list;
struct symbol *twin; struct symbol *twin;
@ -82,7 +88,7 @@ struct symbol {
enum status status; enum status status;
union { union {
int include; /* used in the patched elf */ int include; /* used in the patched elf */
int strip; /* used in the output elf */ enum symbol_strip strip; /* used in the output elf */
}; };
int has_func_profiling; int has_func_profiling;
}; };

@ -1 +1 @@
Subproject commit 0d75b8137a08d62d89acf3358df8f44b1b86ff7a Subproject commit 365ce3af2ba7258d43982028b22d148f5c4686ac