Greg Zornetzer - gaz+@andrew.cmu.edu
"Light shines brightest in the darkest night"
http://www.contrib.andrew.cmu.edu/~gaz
--- linux/kernel/kmod.c.back Thu Aug 13 12:27:58 1998
+++ linux/kernel/kmod.c Mon Aug 17 15:08:55 1998
@@ -7,6 +7,9 @@
Modified to avoid chroot and file sharing problems.
Mikael Pettersson
+
+ Blocked all signals during waitpid in request_module, to prevent
+ abnormal termination of waitpid, minor fixups - Greg Zornetzer
*/
#define __KERNEL_SYSCALLS__
@@ -15,14 +18,14 @@
#include <linux/types.h>
#include <linux/unistd.h>
#include <linux/smp_lock.h>
-
+#include <linux/signal.h>
#include <asm/uaccess.h>
/*
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,
@@ -50,6 +53,7 @@
{
char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL};
int i;
+ char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
use_init_file_context();
@@ -97,6 +101,7 @@
{
int pid;
int waitpid_result;
+ sigset_t tempsig;
/* Don't allow request_module() before the root fs is mounted! */
if ( ! current->fs->root ) {
@@ -107,13 +112,39 @@
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]: thread failed, errno %d\n", module_name, -pid);
return pid;
}
+
+ /* Save the current sigmask, then block everything, except
+ SIGSTOP & SIGKILL */
+ spin_lock_irq(¤t->sigmask_lock);
+ memcpy(&tempsig, ¤t->blocked, sizeof(sigset_t));
+ sigfillset(¤t->blocked);
+ sigdelset(¤t->blocked, SIGSTOP);
+ sigdelset(¤t->blocked, SIGKILL);
+ recalc_sigpending(current);
+ spin_unlock_irq(¤t->sigmask_lock);
+
waitpid_result = waitpid(pid, NULL, __WCLONE);
+
+ /* Replace the pristine sigmask */
+ spin_lock_irq(¤t->sigmask_lock);
+ memcpy(¤t->blocked, &tempsig, sizeof(sigset_t));
+ 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);
+ printk (KERN_ERR "request_module[%s]: waitpid of proc. %d failed, returning %d.\n",
+ module_name, pid, waitpid_result);
}
return 0;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html