Import 2.3.30pre6
[davej-history.git] / kernel / kmod.c
blob36d75438053ddf36c55370ab5bd8321c5292d0ae
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_fs_context(void)
28 struct fs_struct *our_fs, *init_fs;
31 * Make modprobe's fs context be a copy of init's.
33 * We cannot use the user's fs context, because it
34 * may have a different root than init.
35 * Since init was created with CLONE_FS, we can grab
36 * its fs context from "init_task".
38 * The fs context has to be a copy. If it is shared
39 * with init, then any chdir() call in modprobe will
40 * also affect init and the other threads sharing
41 * init_task's fs context.
43 * We created the exec_modprobe thread without CLONE_FS,
44 * so we can update the fields in our fs context freely.
46 lock_kernel();
48 our_fs = current->fs;
49 dput(our_fs->root);
50 dput(our_fs->pwd);
52 init_fs = init_task.fs;
53 our_fs->umask = init_fs->umask;
54 our_fs->root = dget(init_fs->root);
55 our_fs->pwd = dget(init_fs->pwd);
57 unlock_kernel();
60 static int exec_modprobe(void * module_name)
62 static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
63 char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL };
64 int i;
66 current->session = 1;
67 current->pgrp = 1;
69 use_init_fs_context();
71 /* Prevent parent user process from sending signals to child.
72 Otherwise, if the modprobe program does not exist, it might
73 be possible to get a user defined signal handler to execute
74 as the super user right after the execve fails if you time
75 the signal just right.
77 spin_lock_irq(&current->sigmask_lock);
78 flush_signals(current);
79 flush_signal_handlers(current);
80 spin_unlock_irq(&current->sigmask_lock);
82 for (i = 0; i < current->files->max_fds; i++ ) {
83 if (current->files->fd[i]) close(i);
86 /* Drop the "current user" thing */
87 free_uid(current);
89 /* Give kmod all privileges.. */
90 current->uid = current->euid = current->fsuid = 0;
91 cap_set_full(current->cap_inheritable);
92 cap_set_full(current->cap_effective);
94 /* Allow execve args to be in kernel space. */
95 set_fs(KERNEL_DS);
97 /* Go, go, go... */
98 if (execve(modprobe_path, argv, envp) < 0) {
99 printk(KERN_ERR
100 "kmod: failed to exec %s -s -k %s, errno = %d\n",
101 modprobe_path, (char*) module_name, errno);
102 return -errno;
104 return 0;
108 request_module: the function that everyone calls when they need
109 a module.
111 int request_module(const char * module_name)
113 int pid;
114 int waitpid_result;
115 sigset_t tmpsig;
117 /* Don't allow request_module() before the root fs is mounted! */
118 if ( ! current->fs->root ) {
119 printk(KERN_ERR "request_module[%s]: Root fs not mounted\n",
120 module_name);
121 return -EPERM;
124 pid = kernel_thread(exec_modprobe, (void*) module_name, 0);
125 if (pid < 0) {
126 printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid);
127 return pid;
130 /* Block everything but SIGKILL/SIGSTOP */
131 spin_lock_irq(&current->sigmask_lock);
132 tmpsig = current->blocked;
133 siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
134 recalc_sigpending(current);
135 spin_unlock_irq(&current->sigmask_lock);
137 waitpid_result = waitpid(pid, NULL, __WCLONE);
139 /* Allow signals again.. */
140 spin_lock_irq(&current->sigmask_lock);
141 current->blocked = tmpsig;
142 recalc_sigpending(current);
143 spin_unlock_irq(&current->sigmask_lock);
145 if (waitpid_result != pid) {
146 printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n",
147 module_name, pid, -waitpid_result);
149 return 0;