Merge 4.14.74 into android-4.14-p
[GitHub/moto-9609/android_kernel_motorola_exynos9610.git] / kernel / module.c
index de66ec82599289d786063457ef46a3619893bb03..1ac74e99397eac0186a88754e652bbaa3f21d130 100644 (file)
@@ -2121,6 +2121,8 @@ void __weak module_arch_freeing_init(struct module *mod)
 {
 }
 
+static void cfi_cleanup(struct module *mod);
+
 /* Free a module, remove from lists, etc. */
 static void free_module(struct module *mod)
 {
@@ -2162,6 +2164,10 @@ static void free_module(struct module *mod)
 
        /* This may be empty, but that's OK */
        disable_ro_nx(&mod->init_layout);
+
+       /* Clean up CFI for the module. */
+       cfi_cleanup(mod);
+
        module_arch_freeing_init(mod);
        module_memfree(mod->init_layout.base);
        kfree(mod->args);
@@ -2855,6 +2861,15 @@ static int check_modinfo_livepatch(struct module *mod, struct load_info *info)
 }
 #endif /* CONFIG_LIVEPATCH */
 
+static void check_modinfo_retpoline(struct module *mod, struct load_info *info)
+{
+       if (retpoline_module_ok(get_modinfo(info, "retpoline")))
+               return;
+
+       pr_warn("%s: loading module not compiled with retpoline compiler.\n",
+               mod->name);
+}
+
 /* Sets info->hdr and info->len. */
 static int copy_module_from_user(const void __user *umod, unsigned long len,
                                  struct load_info *info)
@@ -3021,6 +3036,8 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
                add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
        }
 
+       check_modinfo_retpoline(mod, info);
+
        if (get_modinfo(info, "staging")) {
                add_taint_module(mod, TAINT_CRAP, LOCKDEP_STILL_OK);
                pr_warn("%s: module is from the staging directory, the quality "
@@ -3348,6 +3365,8 @@ int __weak module_finalize(const Elf_Ehdr *hdr,
        return 0;
 }
 
+static void cfi_init(struct module *mod);
+
 static int post_relocation(struct module *mod, const struct load_info *info)
 {
        /* Sort exception table now relocations are done. */
@@ -3360,6 +3379,9 @@ static int post_relocation(struct module *mod, const struct load_info *info)
        /* Setup kallsyms-specific fields. */
        add_kallsyms(mod, info);
 
+       /* Setup CFI for the module. */
+       cfi_init(mod);
+
        /* Arch-specific module finalizing. */
        return module_finalize(info->hdr, info->sechdrs, mod);
 }
@@ -3495,6 +3517,11 @@ static noinline int do_init_module(struct module *mod)
         * walking this with preempt disabled.  In all the failure paths, we
         * call synchronize_sched(), but we don't want to slow down the success
         * path, so use actual RCU here.
+        * Note that module_alloc() on most architectures creates W+X page
+        * mappings which won't be cleaned up until do_free_init() runs.  Any
+        * code such as mark_rodata_ro() which depends on those mappings to
+        * be cleaned up needs to sync with the queued work - ie
+        * rcu_barrier_sched()
         */
        call_rcu_sched(&freeinit->rcu, do_free_init);
        mutex_unlock(&module_mutex);
@@ -4042,7 +4069,7 @@ static unsigned long mod_find_symname(struct module *mod, const char *name)
 
        for (i = 0; i < kallsyms->num_symtab; i++)
                if (strcmp(name, symname(kallsyms, i)) == 0 &&
-                   kallsyms->symtab[i].st_info != 'U')
+                   kallsyms->symtab[i].st_shndx != SHN_UNDEF)
                        return kallsyms->symtab[i].st_value;
        return 0;
 }
@@ -4088,6 +4115,10 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
                if (mod->state == MODULE_STATE_UNFORMED)
                        continue;
                for (i = 0; i < kallsyms->num_symtab; i++) {
+
+                       if (kallsyms->symtab[i].st_shndx == SHN_UNDEF)
+                               continue;
+
                        ret = fn(data, symname(kallsyms, i),
                                 mod, kallsyms->symtab[i].st_value);
                        if (ret != 0)
@@ -4098,6 +4129,22 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
 }
 #endif /* CONFIG_KALLSYMS */
 
+static void cfi_init(struct module *mod)
+{
+#ifdef CONFIG_CFI_CLANG
+       mod->cfi_check =
+               (cfi_check_fn)mod_find_symname(mod, CFI_CHECK_FN_NAME);
+       cfi_module_add(mod, module_addr_min, module_addr_max);
+#endif
+}
+
+static void cfi_cleanup(struct module *mod)
+{
+#ifdef CONFIG_CFI_CLANG
+       cfi_module_remove(mod, module_addr_min, module_addr_max);
+#endif
+}
+
 /* Maximum number of characters written by module_flags() */
 #define MODULE_FLAGS_BUF_SIZE (TAINT_FLAGS_COUNT + 4)