microblaze: uaccess: fix put_user and get_user macros
[linux-2.6.git] / kernel / kmod.c
index b750675..bf0e231 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/unistd.h>
 #include <linux/kmod.h>
 #include <linux/slab.h>
-#include <linux/mnt_namespace.h>
 #include <linux/completion.h>
 #include <linux/file.h>
 #include <linux/fdtable.h>
@@ -38,6 +37,8 @@
 #include <linux/suspend.h>
 #include <asm/uaccess.h>
 
+#include <trace/events/module.h>
+
 extern int max_threads;
 
 static struct workqueue_struct *khelper_wq;
@@ -85,6 +86,10 @@ int __request_module(bool wait, const char *fmt, ...)
        if (ret >= MODULE_NAME_LEN)
                return -ENAMETOOLONG;
 
+       ret = security_kernel_module_request(module_name);
+       if (ret)
+               return ret;
+
        /* If modprobe needs a service that is in a module, we get a recursive
         * loop.  Limit the number of running kmod threads to max_threads/2 or
         * MAX_KMOD_CONCURRENT, whichever is the smaller.  A cleaner method
@@ -109,6 +114,8 @@ int __request_module(bool wait, const char *fmt, ...)
                return -ENOMEM;
        }
 
+       trace_module_request(module_name, wait, _RET_IP_);
+
        ret = call_usermodehelper(modprobe_path, argv, envp,
                        wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC);
        atomic_dec(&kmod_concurrent);
@@ -370,8 +377,10 @@ struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
        sub_info->argv = argv;
        sub_info->envp = envp;
        sub_info->cred = prepare_usermodehelper_creds();
-       if (!sub_info->cred)
+       if (!sub_info->cred) {
+               kfree(sub_info);
                return NULL;
+       }
 
   out:
        return sub_info;
@@ -461,6 +470,7 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
        int retval = 0;
 
        BUG_ON(atomic_read(&sub_info->cred->usage) != 1);
+       validate_creds(sub_info->cred);
 
        helper_lock();
        if (sub_info->path[0] == '\0')
@@ -510,13 +520,15 @@ int call_usermodehelper_pipe(char *path, char **argv, char **envp,
                return -ENOMEM;
 
        ret = call_usermodehelper_stdinpipe(sub_info, filp);
-       if (ret < 0)
-               goto out;
+       if (ret < 0) {
+               call_usermodehelper_freeinfo(sub_info);
+               return ret;
+       }
 
-       return call_usermodehelper_exec(sub_info, UMH_WAIT_EXEC);
+       ret = call_usermodehelper_exec(sub_info, UMH_WAIT_EXEC);
+       if (ret < 0)    /* Failed to execute helper, close pipe */
+               filp_close(*filp, NULL);
 
-  out:
-       call_usermodehelper_freeinfo(sub_info);
        return ret;
 }
 EXPORT_SYMBOL(call_usermodehelper_pipe);