Ядро Linux в комментариях

       

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(&current->sigmask_lock); 24401 flush_signals(current); 24402 flush_signal_handlers(current); 24403 spin_unlock_irq(&current->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(&current->sigmask_lock); 24456 tmpsig = current->blocked; 24457 siginitsetinv(&current->blocked, 24458 sigmask(SIGKILL) | sigmask(SIGSTOP)); 24459 recalc_sigpending(current); 24460 spin_unlock_irq(&current->sigmask_lock); 24461 24462 waitpid_result = waitpid(pid, NULL, __WCLONE); 24463 24464 /* Allow signals again.. */ 24465 spin_lock_irq(&current->sigmask_lock); 24466 current->blocked = tmpsig; 24467 recalc_sigpending(current); 24468 spin_unlock_irq(&current->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 }


Содержание раздела