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