linux-old/fs/binfmt_script.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/binfmt_script.c
   3 *
   4 *  Copyright (C) 1996  Martin von Löwis
   5 *  original #!-checking implemented by tytso.
   6 */
   7
   8#include <linux/module.h>
   9#include <linux/string.h>
  10#include <linux/stat.h>
  11#include <linux/slab.h>
  12#include <linux/binfmts.h>
  13#include <linux/init.h>
  14#include <linux/file.h>
  15#include <linux/smp_lock.h>
  16
  17static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
  18{
  19        char *cp, *i_name, *i_arg;
  20        struct file *file;
  21        char interp[BINPRM_BUF_SIZE];
  22        int retval;
  23
  24        if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang)) 
  25                return -ENOEXEC;
  26        /*
  27         * This section does the #! interpretation.
  28         * Sorta complicated, but hopefully it will work.  -TYT
  29         */
  30
  31        bprm->sh_bang++;
  32        allow_write_access(bprm->file);
  33        fput(bprm->file);
  34        bprm->file = NULL;
  35
  36        bprm->buf[BINPRM_BUF_SIZE - 1] = '\0';
  37        if ((cp = strchr(bprm->buf, '\n')) == NULL)
  38                cp = bprm->buf+BINPRM_BUF_SIZE-1;
  39        *cp = '\0';
  40        while (cp > bprm->buf) {
  41                cp--;
  42                if ((*cp == ' ') || (*cp == '\t'))
  43                        *cp = '\0';
  44                else
  45                        break;
  46        }
  47        for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
  48        if (*cp == '\0') 
  49                return -ENOEXEC; /* No interpreter name found */
  50        i_name = cp;
  51        i_arg = 0;
  52        for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++)
  53                /* nothing */ ;
  54        while ((*cp == ' ') || (*cp == '\t'))
  55                *cp++ = '\0';
  56        if (*cp)
  57                i_arg = cp;
  58        strcpy (interp, i_name);
  59        /*
  60         * OK, we've parsed out the interpreter name and
  61         * (optional) argument.
  62         * Splice in (1) the interpreter's name for argv[0]
  63         *           (2) (optional) argument to interpreter
  64         *           (3) filename of shell script (replace argv[0])
  65         *
  66         * This is done in reverse order, because of how the
  67         * user environment and arguments are stored.
  68         */
  69        remove_arg_zero(bprm);
  70        retval = copy_strings_kernel(1, &bprm->filename, bprm);
  71        if (retval < 0) return retval; 
  72        bprm->argc++;
  73        if (i_arg) {
  74                retval = copy_strings_kernel(1, &i_arg, bprm);
  75                if (retval < 0) return retval; 
  76                bprm->argc++;
  77        }
  78        retval = copy_strings_kernel(1, &i_name, bprm);
  79        if (retval) return retval; 
  80        bprm->argc++;
  81        /*
  82         * OK, now restart the process with the interpreter's dentry.
  83         */
  84        file = open_exec(interp);
  85        if (IS_ERR(file))
  86                return PTR_ERR(file);
  87
  88        bprm->file = file;
  89        retval = prepare_binprm(bprm);
  90        if (retval < 0)
  91                return retval;
  92        return search_binary_handler(bprm,regs);
  93}
  94
  95struct linux_binfmt script_format = {
  96        NULL, THIS_MODULE, load_script, NULL, NULL, 0
  97};
  98
  99static int __init init_script_binfmt(void)
 100{
 101        return register_binfmt(&script_format);
 102}
 103
 104static void __exit exit_script_binfmt(void)
 105{
 106        unregister_binfmt(&script_format);
 107}
 108
 109module_init(init_script_binfmt)
 110module_exit(exit_script_binfmt)
 111MODULE_LICENSE("GPL");
 112
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.