patch-2.1.116 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: 80
- Date:
Mon Aug 17 16:46:06 1998
- Orig file:
v2.1.115/linux/kernel/kmod.c
- Orig date:
Tue Jul 28 14:21:10 1998
diff -u --recursive --new-file v2.1.115/linux/kernel/kmod.c linux/kernel/kmod.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/unistd.h>
#include <linux/smp_lock.h>
+#include <linux/signal.h>
#include <asm/uaccess.h>
@@ -22,7 +23,6 @@
modprobe_path is set via /proc/sys.
*/
char modprobe_path[256] = "/sbin/modprobe";
-static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
/*
exec_modprobe is spawned from a kernel-mode user process,
@@ -41,14 +41,15 @@
/* don't use the user's root, use init's root instead */
exit_fs(current); /* current->fs->count--; */
current->fs = task_init->fs;
- current->fs->count++;
+ atomic_inc(¤t->fs->count);
unlock_kernel();
}
static int exec_modprobe(void * module_name)
{
- char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL};
+ static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
+ char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL };
int i;
use_init_file_context();
@@ -68,8 +69,8 @@
if (current->files->fd[i]) close(i);
}
- /* kernel_thread() -> ... -> charge_uid(current, 1) workaround */
- charge_uid(current, -1);
+ /* Drop the "current user" thing */
+ free_uid(current);
/* Give kmod all privileges.. */
current->uid = current->euid = current->fsuid = 0;
@@ -97,6 +98,7 @@
{
int pid;
int waitpid_result;
+ sigset_t tmpsig;
/* Don't allow request_module() before the root fs is mounted! */
if ( ! current->fs->root ) {
@@ -107,10 +109,25 @@
pid = kernel_thread(exec_modprobe, (void*) module_name, CLONE_FS);
if (pid < 0) {
- printk(KERN_ERR "kmod: fork failed, errno %d\n", -pid);
+ printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid);
return pid;
}
+
+ /* Block everything but SIGKILL/SIGSTOP */
+ spin_lock_irq(¤t->sigmask_lock);
+ tmpsig = current->blocked;
+ siginitset(¤t->blocked, ~(sigmask(SIGKILL)|sigmask(SIGSTOP)));
+ recalc_sigpending(current);
+ spin_unlock_irq(¤t->sigmask_lock);
+
waitpid_result = waitpid(pid, NULL, __WCLONE);
+
+ /* Allow signals again.. */
+ spin_lock_irq(¤t->sigmask_lock);
+ current->blocked = tmpsig;
+ recalc_sigpending(current);
+ 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);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov