linux-old/kernel/kmod.c
<<
>>
Prefs
   1/*
   2        kmod, the new module loader (replaces kerneld)
   3        Kirk Petersen
   4
   5        Reorganized not to be a daemon by Adam Richter, with guidance
   6        from Greg Zornetzer.
   7
   8        Modified to avoid chroot and file sharing problems.
   9        Mikael Pettersson
  10
  11        Limit the concurrent number of kmod modprobes to catch loops from
  12        "modprobe needs a service that is in a module".
  13        Keith Owens <kaos@ocs.com.au> December 1999
  14
  15        Unblock all signals when we exec a usermode process.
  16        Shuu Yamaguchi <shuu@wondernetworkresources.com> December 2000
  17*/
  18
  19#define __KERNEL_SYSCALLS__
  20
  21#include <linux/config.h>
  22#include <linux/module.h>
  23#include <linux/sched.h>
  24#include <linux/unistd.h>
  25#include <linux/kmod.h>
  26#include <linux/smp_lock.h>
  27#include <linux/slab.h>
  28#include <linux/namespace.h>
  29#include <linux/completion.h>
  30
  31#include <asm/uaccess.h>
  32
  33extern int max_threads;
  34
  35static inline void
  36use_init_fs_context(void)
  37{
  38        struct fs_struct *our_fs, *init_fs;
  39        struct dentry *root, *pwd;
  40        struct vfsmount *rootmnt, *pwdmnt;
  41        struct namespace *our_ns, *init_ns;
  42
  43        /*
  44         * Make modprobe's fs context be a copy of init's.
  45         *
  46         * We cannot use the user's fs context, because it
  47         * may have a different root than init.
  48         * Since init was created with CLONE_FS, we can grab
  49         * its fs context from "init_task".
  50         *
  51         * The fs context has to be a copy. If it is shared
  52         * with init, then any chdir() call in modprobe will
  53         * also affect init and the other threads sharing
  54         * init_task's fs context.
  55         *
  56         * We created the exec_modprobe thread without CLONE_FS,
  57         * so we can update the fields in our fs context freely.
  58         */
  59
  60        init_fs = init_task.fs;
  61        init_ns = init_task.namespace;
  62        get_namespace(init_ns);
  63        our_ns = current->namespace;
  64        current->namespace = init_ns;
  65        put_namespace(our_ns);
  66        read_lock(&init_fs->lock);
  67        rootmnt = mntget(init_fs->rootmnt);
  68        root = dget(init_fs->root);
  69        pwdmnt = mntget(init_fs->pwdmnt);
  70        pwd = dget(init_fs->pwd);
  71        read_unlock(&init_fs->lock);
  72
  73        /* FIXME - unsafe ->fs access */
  74        our_fs = current->fs;
  75        our_fs->umask = init_fs->umask;
  76        set_fs_root(our_fs, rootmnt, root);
  77        set_fs_pwd(our_fs, pwdmnt, pwd);
  78        write_lock(&our_fs->lock);
  79        if (our_fs->altroot) {
  80                struct vfsmount *mnt = our_fs->altrootmnt;
  81                struct dentry *dentry = our_fs->altroot;
  82                our_fs->altrootmnt = NULL;
  83                our_fs->altroot = NULL;
  84                write_unlock(&our_fs->lock);
  85                dput(dentry);
  86                mntput(mnt);
  87        } else 
  88                write_unlock(&our_fs->lock);
  89        dput(root);
  90        mntput(rootmnt);
  91        dput(pwd);
  92        mntput(pwdmnt);
  93}
  94
  95int exec_usermodehelper(char *program_path, char *argv[], char *envp[])
  96{
  97        int i;
  98        struct task_struct *curtask = current;
  99
 100        curtask->session = 1;
 101        curtask->pgrp = 1;
 102
 103        use_init_fs_context();
 104
 105        /* Prevent parent user process from sending signals to child.
 106           Otherwise, if the modprobe program does not exist, it might
 107           be possible to get a user defined signal handler to execute
 108           as the super user right after the execve fails if you time
 109           the signal just right.
 110        */
 111        spin_lock_irq(&curtask->sigmask_lock);
 112        sigemptyset(&curtask->blocked);
 113        flush_signals(curtask);
 114        flush_signal_handlers(curtask);
 115        recalc_sigpending(curtask);
 116        spin_unlock_irq(&curtask->sigmask_lock);
 117
 118        for (i = 0; i < curtask->files->max_fds; i++ ) {
 119                if (curtask->files->fd[i]) close(i);
 120        }
 121
 122        switch_uid(INIT_USER);
 123
 124        /* Give kmod all effective privileges.. */
 125        curtask->euid = curtask->uid = curtask->suid = curtask->fsuid = 0;
 126        curtask->egid = curtask->gid = curtask->sgid = curtask->fsgid = 0;
 127
 128        curtask->ngroups = 0;
 129
 130        cap_set_full(curtask->cap_effective);
 131
 132        /* Allow execve args to be in kernel space. */
 133        set_fs(KERNEL_DS);
 134
 135        /* Go, go, go... */
 136        if (execve(program_path, argv, envp) < 0)
 137                return -errno;
 138        return 0;
 139}
 140
 141#ifdef CONFIG_KMOD
 142
 143/*
 144        modprobe_path is set via /proc/sys.
 145*/
 146char modprobe_path[256] = "/sbin/modprobe";
 147
 148static int exec_modprobe(void * module_name)
 149{
 150        static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
 151        char *argv[] = { modprobe_path, "-s", "-k", "--", (char*)module_name, NULL };
 152        int ret;
 153
 154        ret = exec_usermodehelper(modprobe_path, argv, envp);
 155        if (ret) {
 156                printk(KERN_ERR
 157                       "kmod: failed to exec %s -s -k %s, errno = %d\n",
 158                       modprobe_path, (char*) module_name, errno);
 159        }
 160        return ret;
 161}
 162
 163/**
 164 * request_module - try to load a kernel module
 165 * @module_name: Name of module
 166 *
 167 * Load a module using the user mode module loader. The function returns
 168 * zero on success or a negative errno code on failure. Note that a
 169 * successful module load does not mean the module did not then unload
 170 * and exit on an error of its own. Callers must check that the service
 171 * they requested is now available not blindly invoke it.
 172 *
 173 * If module auto-loading support is disabled then this function
 174 * becomes a no-operation.
 175 */
 176int request_module(const char * module_name)
 177{
 178        pid_t pid;
 179        int waitpid_result;
 180        sigset_t tmpsig;
 181        int i;
 182        static atomic_t kmod_concurrent = ATOMIC_INIT(0);
 183#define MAX_KMOD_CONCURRENT 50  /* Completely arbitrary value - KAO */
 184        static int kmod_loop_msg;
 185
 186        /* Don't allow request_module() before the root fs is mounted!  */
 187        if ( ! current->fs->root ) {
 188                printk(KERN_ERR "request_module[%s]: Root fs not mounted\n",
 189                        module_name);
 190                return -EPERM;
 191        }
 192
 193        /* If modprobe needs a service that is in a module, we get a recursive
 194         * loop.  Limit the number of running kmod threads to max_threads/2 or
 195         * MAX_KMOD_CONCURRENT, whichever is the smaller.  A cleaner method
 196         * would be to run the parents of this process, counting how many times
 197         * kmod was invoked.  That would mean accessing the internals of the
 198         * process tables to get the command line, proc_pid_cmdline is static
 199         * and it is not worth changing the proc code just to handle this case. 
 200         * KAO.
 201         */
 202        i = max_threads/2;
 203        if (i > MAX_KMOD_CONCURRENT)
 204                i = MAX_KMOD_CONCURRENT;
 205        atomic_inc(&kmod_concurrent);
 206        if (atomic_read(&kmod_concurrent) > i) {
 207                if (kmod_loop_msg++ < 5)
 208                        printk(KERN_ERR
 209                               "kmod: runaway modprobe loop assumed and stopped\n");
 210                atomic_dec(&kmod_concurrent);
 211                return -ENOMEM;
 212        }
 213
 214        pid = kernel_thread(exec_modprobe, (void*) module_name, 0);
 215        if (pid < 0) {
 216                printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid);
 217                atomic_dec(&kmod_concurrent);
 218                return pid;
 219        }
 220
 221        /* Block everything but SIGKILL/SIGSTOP */
 222        spin_lock_irq(&current->sigmask_lock);
 223        tmpsig = current->blocked;
 224        siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
 225        recalc_sigpending(current);
 226        spin_unlock_irq(&current->sigmask_lock);
 227
 228        waitpid_result = waitpid(pid, NULL, __WCLONE);
 229        atomic_dec(&kmod_concurrent);
 230
 231        /* Allow signals again.. */
 232        spin_lock_irq(&current->sigmask_lock);
 233        current->blocked = tmpsig;
 234        recalc_sigpending(current);
 235        spin_unlock_irq(&current->sigmask_lock);
 236
 237        if (waitpid_result != pid) {
 238                printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n",
 239                       module_name, pid, -waitpid_result);
 240        }
 241        return 0;
 242}
 243#endif /* CONFIG_KMOD */
 244
 245
 246#ifdef CONFIG_HOTPLUG
 247/*
 248        hotplug path is set via /proc/sys
 249        invoked by hotplug-aware bus drivers,
 250        with exec_usermodehelper and some thread-spawner
 251
 252        argv [0] = hotplug_path;
 253        argv [1] = "usb", "scsi", "pci", "network", etc;
 254        ... plus optional type-specific parameters
 255        argv [n] = 0;
 256
 257        envp [*] = HOME, PATH; optional type-specific parameters
 258
 259        a hotplug bus should invoke this for device add/remove
 260        events.  the command is expected to load drivers when
 261        necessary, and may perform additional system setup.
 262*/
 263char hotplug_path[256] = "/sbin/hotplug";
 264
 265EXPORT_SYMBOL(hotplug_path);
 266
 267#endif /* CONFIG_HOTPLUG */
 268
 269struct subprocess_info {
 270        struct completion *complete;
 271        char *path;
 272        char **argv;
 273        char **envp;
 274        pid_t retval;
 275};
 276
 277/*
 278 * This is the task which runs the usermode application
 279 */
 280static int ____call_usermodehelper(void *data)
 281{
 282        struct subprocess_info *sub_info = data;
 283        int retval;
 284
 285        retval = -EPERM;
 286        if (current->fs->root)
 287                retval = exec_usermodehelper(sub_info->path, sub_info->argv, sub_info->envp);
 288
 289        /* Exec failed? */
 290        sub_info->retval = (pid_t)retval;
 291        do_exit(0);
 292}
 293
 294/*
 295 * This is run by keventd.
 296 */
 297static void __call_usermodehelper(void *data)
 298{
 299        struct subprocess_info *sub_info = data;
 300        pid_t pid;
 301
 302        /*
 303         * CLONE_VFORK: wait until the usermode helper has execve'd successfully
 304         * We need the data structures to stay around until that is done.
 305         */
 306        pid = kernel_thread(____call_usermodehelper, sub_info, CLONE_VFORK | SIGCHLD);
 307        if (pid < 0)
 308                sub_info->retval = pid;
 309        complete(sub_info->complete);
 310}
 311
 312/**
 313 * call_usermodehelper - start a usermode application
 314 * @path: pathname for the application
 315 * @argv: null-terminated argument list
 316 * @envp: null-terminated environment list
 317 *
 318 * Runs a user-space application.  The application is started asynchronously.  It
 319 * runs as a child of keventd.  It runs with full root capabilities.  keventd silently
 320 * reaps the child when it exits.
 321 *
 322 * Must be called from process context.  Returns zero on success, else a negative
 323 * error code.
 324 */
 325int call_usermodehelper(char *path, char **argv, char **envp)
 326{
 327        DECLARE_COMPLETION(work);
 328        struct subprocess_info sub_info = {
 329                complete:       &work,
 330                path:           path,
 331                argv:           argv,
 332                envp:           envp,
 333                retval:         0,
 334        };
 335        struct tq_struct tqs = {
 336                routine:        __call_usermodehelper,
 337                data:           &sub_info,
 338        };
 339
 340        if (path[0] == '\0')
 341                goto out;
 342
 343        if (current_is_keventd()) {
 344                /* We can't wait on keventd! */
 345                __call_usermodehelper(&sub_info);
 346        } else {
 347                schedule_task(&tqs);
 348                wait_for_completion(&work);
 349        }
 350out:
 351        return sub_info.retval;
 352}
 353
 354/*
 355 * This is for the serialisation of device probe() functions
 356 * against device open() functions
 357 */
 358static DECLARE_MUTEX(dev_probe_sem);
 359
 360void dev_probe_lock(void)
 361{
 362        down(&dev_probe_sem);
 363}
 364
 365void dev_probe_unlock(void)
 366{
 367        up(&dev_probe_sem);
 368}
 369
 370EXPORT_SYMBOL(exec_usermodehelper);
 371EXPORT_SYMBOL(call_usermodehelper);
 372
 373#ifdef CONFIG_KMOD
 374EXPORT_SYMBOL(request_module);
 375#endif
 376
 377
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.