patch-2.3.27 linux/kernel/kmod.c
Next file: linux/kernel/ksyms.c
Previous file: linux/kernel/fork.c
Back to the patch index
Back to the overall index
- Lines: 81
- Date:
Wed Nov 10 10:00:11 1999
- Orig file:
v2.3.26/linux/kernel/kmod.c
- Orig date:
Thu Nov 12 09:58:32 1998
diff -u --recursive --new-file v2.3.26/linux/kernel/kmod.c linux/kernel/kmod.c
@@ -23,22 +23,36 @@
char modprobe_path[256] = "/sbin/modprobe";
static inline void
-use_init_file_context(void)
+use_init_fs_context(void)
{
- struct fs_struct * fs;
-
- lock_kernel();
+ struct fs_struct *our_fs, *init_fs;
/*
- * Don't use the user's root, use init's root instead.
- * Note that we can use "init_task" (which is not actually
- * the same as the user-level "init" process) because we
- * started "init" with a CLONE_FS
+ * Make modprobe's fs context be a copy of init's.
+ *
+ * We cannot use the user's fs context, because it
+ * may have a different root than init.
+ * Since init was created with CLONE_FS, we can grab
+ * its fs context from "init_task".
+ *
+ * The fs context has to be a copy. If it is shared
+ * with init, then any chdir() call in modprobe will
+ * also affect init and the other threads sharing
+ * init_task's fs context.
+ *
+ * We created the exec_modprobe thread without CLONE_FS,
+ * so we can update the fields in our fs context freely.
*/
- exit_fs(current); /* current->fs->count--; */
- fs = init_task.fs;
- current->fs = fs;
- atomic_inc(&fs->count);
+ lock_kernel();
+
+ our_fs = current->fs;
+ dput(our_fs->root);
+ dput(our_fs->pwd);
+
+ init_fs = init_task.fs;
+ our_fs->umask = init_fs->umask;
+ our_fs->root = dget(init_fs->root);
+ our_fs->pwd = dget(init_fs->pwd);
unlock_kernel();
}
@@ -49,7 +63,10 @@
char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL };
int i;
- use_init_file_context();
+ current->session = 1;
+ current->pgrp = 1;
+
+ use_init_fs_context();
/* Prevent parent user process from sending signals to child.
Otherwise, if the modprobe program does not exist, it might
@@ -104,7 +121,7 @@
return -EPERM;
}
- pid = kernel_thread(exec_modprobe, (void*) module_name, CLONE_FS);
+ pid = kernel_thread(exec_modprobe, (void*) module_name, 0);
if (pid < 0) {
printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid);
return pid;
@@ -126,8 +143,8 @@
spin_unlock_irq(¤t->sigmask_lock);
if (waitpid_result != pid) {
- printk (KERN_ERR "kmod: waitpid(%d,NULL,0) failed, returning %d.\n",
- pid, waitpid_result);
+ printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n",
+ module_name, pid, -waitpid_result);
}
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)