kernel/kmod.c
24344 /*
24345 kmod, the new module loader (replaces kerneld)
24346 Kirk Petersen
24347
24348 Reorganized not to be a daemon by Adam Richter, with
24349 guidance from Greg Zornetzer.
24350
24351 Modified to avoid chroot and file sharing problems.
24352 Mikael Pettersson */
24353
24354 #define __KERNEL_SYSCALLS__
24355
24356 #include <linux/sched.h>
24357 #include <linux/unistd.h>
24358 #include <linux/smp_lock.h>
24359
24360 #include <asm/uaccess.h>
24361
24362 /* modprobe_path is set via /proc/sys. */
24363 char modprobe_path[256] = "/sbin/modprobe";
24364
24365 static inline void
24366 use_init_file_context(void)
24367 {
24368 struct fs_struct * fs;
24369
24370 lock_kernel();
24371
24372 /* Don't use the user's root, use init's root instead.
24373 * Note that we can use "init_task" (which is not
24374 * actually the same as the user-level "init" process)
24375 * because we started "init" with a CLONE_FS */
24376 exit_fs(current); /* current->fs->count--; */
24377 fs = init_task.fs;
24378 current->fs = fs;
24379 atomic_inc(&fs->count);
24380
24381 unlock_kernel();
24382 }
24383
24384 static int exec_modprobe(void * module_name)
24385 {
24386 static char * envp[] = { "HOME=/", "TERM=linux",
24387 "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
24388 char *argv[] = { modprobe_path, "-s", "-k",
24389 (char*)module_name, NULL };
24390 int i;
24391
24392 use_init_file_context();
24393
24394 /* Prevent parent user process from sending signals to
24395 * child. Otherwise, if the modprobe program does not
24396 * exist, it might be possible to get a user defined
24397 * signal handler to execute as the super user right
24398 * after the execve fails if you time the signal just
24399 * right. */
24400 spin_lock_irq(¤t->sigmask_lock);
24401 flush_signals(current);
24402 flush_signal_handlers(current);
24403 spin_unlock_irq(¤t->sigmask_lock);
24404
24405 for (i = 0; i < current->files->max_fds; i++ ) {
24406 if (current->files->fd[i]) close(i);
24407 }
24408
24409 /* Drop the "current user" thing */
24410 free_uid(current);
24411
24412 /* Give kmod all privileges.. */
24413 current->uid = current->euid = current->fsuid = 0;
24414 cap_set_full(current->cap_inheritable);
24415 cap_set_full(current->cap_effective);
24416
24417 /* Allow execve args to be in kernel space. */
24418 set_fs(KERNEL_DS);
24419
24420 /* Go, go, go... */
24421 if (execve(modprobe_path, argv, envp) < 0) {
24422 printk(KERN_ERR
24423 "kmod: failed to exec %s -s -k %s, errno = %d\n",
24424 modprobe_path, (char*) module_name, errno);
24425 return -errno;
24426 }
24427 return 0;
24428 }
24429
24430 /* request_module: the function that everyone calls when
24431 * they need a module. */
24432 int request_module(const char * module_name)
24433 {
24434 int pid;
24435 int waitpid_result;
24436 sigset_t tmpsig;
24437
24438 /* Don't allow request_module() before the root fs is
24439 * mounted! */
24440 if (!current->fs->root) {
24441 printk(KERN_ERR "request_module[%s]: Root fs "
24442 "not mounted\n", module_name);
24443 return -EPERM;
24444 }
24445
24446 pid = kernel_thread(exec_modprobe,
24447 (void*) module_name, CLONE_FS);
24448 if (pid < 0) {
24449 printk(KERN_ERR "request_module[%s]: fork failed, "
24450 "errno %d\n", module_name, -pid);
24451 return pid;
24452 }
24453
24454 /* Block everything but SIGKILL/SIGSTOP */
24455 spin_lock_irq(¤t->sigmask_lock);
24456 tmpsig = current->blocked;
24457 siginitsetinv(¤t->blocked,
24458 sigmask(SIGKILL) | sigmask(SIGSTOP));
24459 recalc_sigpending(current);
24460 spin_unlock_irq(¤t->sigmask_lock);
24461
24462 waitpid_result = waitpid(pid, NULL, __WCLONE);
24463
24464 /* Allow signals again.. */
24465 spin_lock_irq(¤t->sigmask_lock);
24466 current->blocked = tmpsig;
24467 recalc_sigpending(current);
24468 spin_unlock_irq(¤t->sigmask_lock);
24469
24470 if (waitpid_result != pid) {
24471 printk (KERN_ERR "kmod: waitpid(%d,NULL,0) failed, "
24472 "returning %d.\n", pid, waitpid_result);
24473 }
24474 return 0;
24475 }
Сайт управляется системой
uCoz