From 1e1a0592f8309a8253e39d0f6a42193e60d80d23 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 15 Feb 2017 12:33:03 +0100 Subject: [PATCH] kernel: fix crashes on MIPS when loading kernel modules under memory pressure When memory is tight, modules may need to be loaded into vmalloc() space. The code then has to generate jump trampolines which enable relocations between vmalloc space and physical address space. The code had a bug that was freeing these trampolines even when the module was successfully loaded. Signed-off-by: Felix Fietkau --- .../linux/generic/patches-3.18/305-mips_module_reloc.patch | 5 ++++- target/linux/generic/patches-4.4/305-mips_module_reloc.patch | 5 ++++- target/linux/generic/patches-4.9/305-mips_module_reloc.patch | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/target/linux/generic/patches-3.18/305-mips_module_reloc.patch b/target/linux/generic/patches-3.18/305-mips_module_reloc.patch index f8ca91401a..fae7e70f0e 100644 --- a/target/linux/generic/patches-3.18/305-mips_module_reloc.patch +++ b/target/linux/generic/patches-3.18/305-mips_module_reloc.patch @@ -317,7 +317,7 @@ return 0; } -@@ -287,9 +529,33 @@ int module_finalize(const Elf_Ehdr *hdr, +@@ -287,9 +529,36 @@ int module_finalize(const Elf_Ehdr *hdr, list_add(&me->arch.dbe_list, &dbe_list); spin_unlock_irq(&dbe_lock); } @@ -338,6 +338,9 @@ +void module_arch_freeing_init(struct module *mod) +{ ++ if (mod->state == MODULE_STATE_LIVE) ++ return; ++ + if (mod->arch.phys_plt_tbl) { + __module_free(mod->arch.phys_plt_tbl); + mod->arch.phys_plt_tbl = NULL; diff --git a/target/linux/generic/patches-4.4/305-mips_module_reloc.patch b/target/linux/generic/patches-4.4/305-mips_module_reloc.patch index 8b3975fe09..944921fff7 100644 --- a/target/linux/generic/patches-4.4/305-mips_module_reloc.patch +++ b/target/linux/generic/patches-4.4/305-mips_module_reloc.patch @@ -316,7 +316,7 @@ return 0; } -@@ -287,9 +528,33 @@ int module_finalize(const Elf_Ehdr *hdr, +@@ -287,9 +528,36 @@ int module_finalize(const Elf_Ehdr *hdr, list_add(&me->arch.dbe_list, &dbe_list); spin_unlock_irq(&dbe_lock); } @@ -337,6 +337,9 @@ +void module_arch_freeing_init(struct module *mod) +{ ++ if (mod->state == MODULE_STATE_LIVE) ++ return; ++ + if (mod->arch.phys_plt_tbl) { + __module_free(mod->arch.phys_plt_tbl); + mod->arch.phys_plt_tbl = NULL; diff --git a/target/linux/generic/patches-4.9/305-mips_module_reloc.patch b/target/linux/generic/patches-4.9/305-mips_module_reloc.patch index 997105ba1a..1c2bd0aa9f 100644 --- a/target/linux/generic/patches-4.9/305-mips_module_reloc.patch +++ b/target/linux/generic/patches-4.9/305-mips_module_reloc.patch @@ -315,7 +315,7 @@ return 0; } -@@ -349,9 +591,33 @@ int module_finalize(const Elf_Ehdr *hdr, +@@ -349,9 +591,36 @@ int module_finalize(const Elf_Ehdr *hdr, list_add(&me->arch.dbe_list, &dbe_list); spin_unlock_irq(&dbe_lock); } @@ -336,6 +336,9 @@ +void module_arch_freeing_init(struct module *mod) +{ ++ if (mod->state == MODULE_STATE_LIVE) ++ return; ++ + if (mod->arch.phys_plt_tbl) { + __module_free(mod->arch.phys_plt_tbl); + mod->arch.phys_plt_tbl = NULL;