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/binfmts.h> 12 #include <linux/init.h> 13 #include <linux/file.h> 14 #include <linux/err.h> 15 #include <linux/fs.h> 16 17 static inline bool spacetab(char c) { return c == ' ' || c == '\t'; } 18 static inline char *next_non_spacetab(char *first, const char *last) 19 { 20 for (; first <= last; first++) 21 if (!spacetab(*first)) 22 return first; 23 return NULL; 24 } 25 static inline char *next_terminator(char *first, const char *last) 26 { 27 for (; first <= last; first++) 28 if (spacetab(*first) || !*first) 29 return first; 30 return NULL; 31 } 32 33 static int load_script(struct linux_binprm *bprm) 34 { 35 const char *i_arg, *i_name; 36 char *cp, *buf_end; 37 struct file *file; 38 int retval; 39 40 /* Not ours to exec if we don't start with "#!". */ 41 if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!')) 42 return -ENOEXEC; 43 44 /* 45 * If the script filename will be inaccessible after exec, typically 46 * because it is a "/dev/fd/<fd>/.." path against an O_CLOEXEC fd, give 47 * up now (on the assumption that the interpreter will want to load 48 * this file). 49 */ 50 if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE) 51 return -ENOENT; 52 53 /* Release since we are not mapping a binary into memory. */ 54 allow_write_access(bprm->file); 55 fput(bprm->file); 56 bprm->file = NULL; 57 58 /* 59 * This section handles parsing the #! line into separate 60 * interpreter path and argument strings. We must be careful 61 * because bprm->buf is not yet guaranteed to be NUL-terminated 62 * (though the buffer will have trailing NUL padding when the 63 * file size was smaller than the buffer size). 64 * 65 * We do not want to exec a truncated interpreter path, so either 66 * we find a newline (which indicates nothing is truncated), or 67 * we find a space/tab/NUL after the interpreter path (which 68 * itself may be preceded by spaces/tabs). Truncating the 69 * arguments is fine: the interpreter can re-read the script to 70 * parse them on its own. 71 */ 72 buf_end = bprm->buf + sizeof(bprm->buf) - 1; 73 cp = strnchr(bprm->buf, sizeof(bprm->buf), '\n'); 74 if (!cp) { 75 cp = next_non_spacetab(bprm->buf + 2, buf_end); 76 if (!cp) 77 return -ENOEXEC; /* Entire buf is spaces/tabs */ 78 /* 79 * If there is no later space/tab/NUL we must assume the 80 * interpreter path is truncated. 81 */ 82 if (!next_terminator(cp, buf_end)) 83 return -ENOEXEC; 84 cp = buf_end; 85 } 86 /* NUL-terminate the buffer and any trailing spaces/tabs. */ 87 *cp = '\0'; 88 while (cp > bprm->buf) { 89 cp--; 90 if ((*cp == ' ') || (*cp == '\t')) 91 *cp = '\0'; 92 else 93 break; 94 } 95 for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++); 96 if (*cp == '\0') 97 return -ENOEXEC; /* No interpreter name found */ 98 i_name = cp; 99 i_arg = NULL; 100 for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) 101 /* nothing */ ; 102 while ((*cp == ' ') || (*cp == '\t')) 103 *cp++ = '\0'; 104 if (*cp) 105 i_arg = cp; 106 /* 107 * OK, we've parsed out the interpreter name and 108 * (optional) argument. 109 * Splice in (1) the interpreter's name for argv[0] 110 * (2) (optional) argument to interpreter 111 * (3) filename of shell script (replace argv[0]) 112 * 113 * This is done in reverse order, because of how the 114 * user environment and arguments are stored. 115 */ 116 retval = remove_arg_zero(bprm); 117 if (retval) 118 return retval; 119 retval = copy_strings_kernel(1, &bprm->interp, bprm); 120 if (retval < 0) 121 return retval; 122 bprm->argc++; 123 if (i_arg) { 124 retval = copy_strings_kernel(1, &i_arg, bprm); 125 if (retval < 0) 126 return retval; 127 bprm->argc++; 128 } 129 retval = copy_strings_kernel(1, &i_name, bprm); 130 if (retval) 131 return retval; 132 bprm->argc++; 133 retval = bprm_change_interp(i_name, bprm); 134 if (retval < 0) 135 return retval; 136 137 /* 138 * OK, now restart the process with the interpreter's dentry. 139 */ 140 file = open_exec(i_name); 141 if (IS_ERR(file)) 142 return PTR_ERR(file); 143 144 bprm->file = file; 145 retval = prepare_binprm(bprm); 146 if (retval < 0) 147 return retval; 148 return search_binary_handler(bprm); 149 } 150 151 static struct linux_binfmt script_format = { 152 .module = THIS_MODULE, 153 .load_binary = load_script, 154 }; 155 156 static int __init init_script_binfmt(void) 157 { 158 register_binfmt(&script_format); 159 return 0; 160 } 161 162 static void __exit exit_script_binfmt(void) 163 { 164 unregister_binfmt(&script_format); 165 } 166 167 core_initcall(init_script_binfmt); 168 module_exit(exit_script_binfmt); 169 MODULE_LICENSE("GPL"); 170