Import 2.3.1pre2
[davej-history.git] / kernel / kmod.c
blob8b19e2415db307ec2cb699e2d60574e28782953d
1 /*
2 kmod, the new module loader (replaces kerneld)
3 Kirk Petersen
5 Reorganized not to be a daemon by Adam Richter, with guidance
6 from Greg Zornetzer.
8 Modified to avoid chroot and file sharing problems.
9 Mikael Pettersson
12 #define __KERNEL_SYSCALLS__
14 #include <linux/sched.h>
15 #include <linux/unistd.h>
16 #include <linux/smp_lock.h>
18 #include <asm/uaccess.h>
21 modprobe_path is set via /proc/sys.
23 char modprobe_path[256] = "/sbin/modprobe";
25 static inline void
26 use_init_file_context(void)
28 struct fs_struct * fs;
30 lock_kernel();
33 * Don't use the user's root, use init's root instead.
34 * Note that we can use "init_task" (which is not actually
35 * the same as the user-level "init" process) because we
36 * started "init" with a CLONE_FS
38 exit_fs(current); /* current->fs->count--; */
39 fs = init_task.fs;
40 current->fs = fs;
41 atomic_inc(&fs->count);
43 unlock_kernel();
46 static int exec_modprobe(void * module_name)
48 static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
49 char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL };
50 int i;
52 use_init_file_context();
54 /* Prevent parent user process from sending signals to child.
55 Otherwise, if the modprobe program does not exist, it might
56 be possible to get a user defined signal handler to execute
57 as the super user right after the execve fails if you time
58 the signal just right.
60 spin_lock_irq(&current->sigmask_lock);
61 flush_signals(current);
62 flush_signal_handlers(current);
63 spin_unlock_irq(&current->sigmask_lock);
65 for (i = 0; i < current->files->max_fds; i++ ) {
66 if (current->files->fd[i]) close(i);
69 /* Drop the "current user" thing */
70 free_uid(current);
72 /* Give kmod all privileges.. */
73 current->uid = current->euid = current->fsuid = 0;
74 cap_set_full(current->cap_inheritable);
75 cap_set_full(current->cap_effective);
77 /* Allow execve args to be in kernel space. */
78 set_fs(KERNEL_DS);
80 /* Go, go, go... */
81 if (execve(modprobe_path, argv, envp) < 0) {
82 printk(KERN_ERR
83 "kmod: failed to exec %s -s -k %s, errno = %d\n",
84 modprobe_path, (char*) module_name, errno);
85 return -errno;
87 return 0;
91 request_module: the function that everyone calls when they need
92 a module.
94 int request_module(const char * module_name)
96 int pid;
97 int waitpid_result;
98 sigset_t tmpsig;
100 /* Don't allow request_module() before the root fs is mounted! */
101 if ( ! current->fs->root ) {
102 printk(KERN_ERR "request_module[%s]: Root fs not mounted\n",
103 module_name);
104 return -EPERM;
107 pid = kernel_thread(exec_modprobe, (void*) module_name, CLONE_FS);
108 if (pid < 0) {
109 printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid);
110 return pid;
113 /* Block everything but SIGKILL/SIGSTOP */
114 spin_lock_irq(&current->sigmask_lock);
115 tmpsig = current->blocked;
116 siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
117 recalc_sigpending(current);
118 spin_unlock_irq(&current->sigmask_lock);
120 waitpid_result = waitpid(pid, NULL, __WCLONE);
122 /* Allow signals again.. */
123 spin_lock_irq(&current->sigmask_lock);
124 current->blocked = tmpsig;
125 recalc_sigpending(current);
126 spin_unlock_irq(&current->sigmask_lock);
128 if (waitpid_result != pid) {
129 printk (KERN_ERR "kmod: waitpid(%d,NULL,0) failed, returning %d.\n",
130 pid, waitpid_result);
132 return 0;