Import 2.1.122
[davej-history.git] / kernel / kmod.c
blob4a7e3ebdabbd88a99d419a7868aa95a6c166a59c
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/types.h>
16 #include <linux/unistd.h>
17 #include <linux/smp_lock.h>
18 #include <linux/signal.h>
20 #include <asm/uaccess.h>
23 modprobe_path is set via /proc/sys.
25 char modprobe_path[256] = "/sbin/modprobe";
28 exec_modprobe is spawned from a kernel-mode user process,
29 then changes its state to behave _as_if_ it was spawned
30 from the kernel's init process
31 (ppid and {e,}gid are not adjusted, but that shouldn't
32 be a problem since we trust modprobe)
34 #define task_init task[smp_num_cpus]
36 static inline void
37 use_init_file_context(void)
39 lock_kernel();
41 /* don't use the user's root, use init's root instead */
42 exit_fs(current); /* current->fs->count--; */
43 current->fs = task_init->fs;
44 atomic_inc(&current->fs->count);
46 unlock_kernel();
49 static int exec_modprobe(void * module_name)
51 static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
52 char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL };
53 int i;
55 use_init_file_context();
57 /* Prevent parent user process from sending signals to child.
58 Otherwise, if the modprobe program does not exist, it might
59 be possible to get a user defined signal handler to execute
60 as the super user right after the execve fails if you time
61 the signal just right.
63 spin_lock_irq(&current->sigmask_lock);
64 flush_signals(current);
65 flush_signal_handlers(current);
66 spin_unlock_irq(&current->sigmask_lock);
68 for (i = 0; i < current->files->max_fds; i++ ) {
69 if (current->files->fd[i]) close(i);
72 /* Drop the "current user" thing */
73 free_uid(current);
75 /* Give kmod all privileges.. */
76 current->uid = current->euid = current->fsuid = 0;
77 cap_set_full(current->cap_inheritable);
78 cap_set_full(current->cap_effective);
80 /* Allow execve args to be in kernel space. */
81 set_fs(KERNEL_DS);
83 /* Go, go, go... */
84 if (execve(modprobe_path, argv, envp) < 0) {
85 printk(KERN_ERR
86 "kmod: failed to exec %s -s -k %s, errno = %d\n",
87 modprobe_path, (char*) module_name, errno);
88 return -errno;
90 return 0;
94 request_module: the function that everyone calls when they need
95 a module.
97 int request_module(const char * module_name)
99 int pid;
100 int waitpid_result;
101 sigset_t tmpsig;
103 /* Don't allow request_module() before the root fs is mounted! */
104 if ( ! current->fs->root ) {
105 printk(KERN_ERR "request_module[%s]: Root fs not mounted\n",
106 module_name);
107 return -EPERM;
110 pid = kernel_thread(exec_modprobe, (void*) module_name, CLONE_FS);
111 if (pid < 0) {
112 printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid);
113 return pid;
116 /* Block everything but SIGKILL/SIGSTOP */
117 spin_lock_irq(&current->sigmask_lock);
118 tmpsig = current->blocked;
119 siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
120 recalc_sigpending(current);
121 spin_unlock_irq(&current->sigmask_lock);
123 waitpid_result = waitpid(pid, NULL, __WCLONE);
125 /* Allow signals again.. */
126 spin_lock_irq(&current->sigmask_lock);
127 current->blocked = tmpsig;
128 recalc_sigpending(current);
129 spin_unlock_irq(&current->sigmask_lock);
131 if (waitpid_result != pid) {
132 printk (KERN_ERR "kmod: waitpid(%d,NULL,0) failed, returning %d.\n",
133 pid, waitpid_result);
135 return 0;