[PATCH] ensure NULL deref can't possibly happen in is_exported()
[cascardo/linux.git] / kernel / module.c
index ddfe45a..d75275d 100644 (file)
@@ -64,26 +64,17 @@ static DEFINE_SPINLOCK(modlist_lock);
 static DEFINE_MUTEX(module_mutex);
 static LIST_HEAD(modules);
 
-static DEFINE_MUTEX(notify_mutex);
-static struct notifier_block * module_notify_list;
+static BLOCKING_NOTIFIER_HEAD(module_notify_list);
 
 int register_module_notifier(struct notifier_block * nb)
 {
-       int err;
-       mutex_lock(&notify_mutex);
-       err = notifier_chain_register(&module_notify_list, nb);
-       mutex_unlock(&notify_mutex);
-       return err;
+       return blocking_notifier_chain_register(&module_notify_list, nb);
 }
 EXPORT_SYMBOL(register_module_notifier);
 
 int unregister_module_notifier(struct notifier_block * nb)
 {
-       int err;
-       mutex_lock(&notify_mutex);
-       err = notifier_chain_unregister(&module_notify_list, nb);
-       mutex_unlock(&notify_mutex);
-       return err;
+       return blocking_notifier_chain_unregister(&module_notify_list, nb);
 }
 EXPORT_SYMBOL(unregister_module_notifier);
 
@@ -136,7 +127,7 @@ extern const unsigned long __start___kcrctab_gpl_future[];
 #ifndef CONFIG_MODVERSIONS
 #define symversion(base, idx) NULL
 #else
-#define symversion(base, idx) ((base) ? ((base) + (idx)) : NULL)
+#define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
 #endif
 
 /* lookup symbol in given range of kernel_symbols */
@@ -714,14 +705,14 @@ EXPORT_SYMBOL(__symbol_put);
 
 void symbol_put_addr(void *addr)
 {
-       unsigned long flags;
+       struct module *modaddr;
 
-       spin_lock_irqsave(&modlist_lock, flags);
-       if (!kernel_text_address((unsigned long)addr))
-               BUG();
+       if (core_kernel_text((unsigned long)addr))
+               return;
 
-       module_put(module_text_address((unsigned long)addr));
-       spin_unlock_irqrestore(&modlist_lock, flags);
+       if (!(modaddr = module_text_address((unsigned long)addr)))
+               BUG();
+       module_put(modaddr);
 }
 EXPORT_SYMBOL_GPL(symbol_put_addr);
 
@@ -1263,6 +1254,7 @@ static inline int license_is_gpl_compatible(const char *license)
                || strcmp(license, "GPL v2") == 0
                || strcmp(license, "GPL and additional rights") == 0
                || strcmp(license, "Dual BSD/GPL") == 0
+               || strcmp(license, "Dual MIT/GPL") == 0
                || strcmp(license, "Dual MPL/GPL") == 0);
 }
 
@@ -1334,7 +1326,7 @@ int is_exported(const char *name, const struct module *mod)
        if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab))
                return 1;
        else
-               if (lookup_symbol(name, mod->syms, mod->syms + mod->num_syms))
+               if (mod && lookup_symbol(name, mod->syms, mod->syms + mod->num_syms))
                        return 1;
                else
                        return 0;
@@ -1816,9 +1808,8 @@ sys_init_module(void __user *umod,
        /* Drop lock so they can recurse */
        mutex_unlock(&module_mutex);
 
-       mutex_lock(&notify_mutex);
-       notifier_call_chain(&module_notify_list, MODULE_STATE_COMING, mod);
-       mutex_unlock(&notify_mutex);
+       blocking_notifier_call_chain(&module_notify_list,
+                       MODULE_STATE_COMING, mod);
 
        /* Start the module */
        if (mod->init != NULL)