futex: Fix potential use-after-free in FUTEX_REQUEUE_PI
[pandora-kernel.git] / kernel / kmod.c
index 135041f..a16dac1 100644 (file)
@@ -58,6 +58,12 @@ static DEFINE_SPINLOCK(umh_sysctl_lock);
 */
 char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
 
+static void free_modprobe_argv(struct subprocess_info *info)
+{
+       kfree(info->argv[3]); /* check call_modprobe() */
+       kfree(info->argv);
+}
+
 static int call_modprobe(char *module_name, int wait)
 {
        static char *envp[] = {
@@ -67,10 +73,26 @@ static int call_modprobe(char *module_name, int wait)
                NULL
        };
 
-       char *argv[] = { modprobe_path, "-q", "--", module_name, NULL };
+       char **argv = kmalloc(sizeof(char *[5]), GFP_KERNEL);
+       if (!argv)
+               goto out;
+
+       module_name = kstrdup(module_name, GFP_KERNEL);
+       if (!module_name)
+               goto free_argv;
+
+       argv[0] = modprobe_path;
+       argv[1] = "-q";
+       argv[2] = "--";
+       argv[3] = module_name;  /* check free_modprobe_argv() */
+       argv[4] = NULL;
 
        return call_usermodehelper_fns(modprobe_path, argv, envp,
-                                       wait, NULL, NULL, NULL);
+               wait | UMH_KILLABLE, NULL, free_modprobe_argv, NULL);
+free_argv:
+       kfree(argv);
+out:
+       return -ENOMEM;
 }
 
 /**
@@ -445,6 +467,11 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
        int retval = 0;
 
        helper_lock();
+       if (!sub_info->path) {
+               retval = -EINVAL;
+               goto out;
+       }
+
        if (sub_info->path[0] == '\0')
                goto out;