* HISTORICAL NOTE: From 1993 to mid-2005, FreeBSD parsed out the tokens as * found on the first line of the script, and setup each token as a separate * value in arg[]. This extra processing did not match the behavior of other * OS's, and caused a few subtle problems. For one, it meant the kernel was * deciding how those values should be parsed (wrt characters for quoting or * comments, etc
| 99 | * 6.x branch on May 28, 2005 (matching __FreeBSD_version 600029). |
| 100 | */ |
| 101 | int |
| 102 | exec_shell_imgact(struct image_params *imgp) |
| 103 | { |
| 104 | const char *image_header = imgp->image_header; |
| 105 | const char *ihp, *interpb, *interpe, *maxp, *optb, *opte, *fname; |
| 106 | int error, offset; |
| 107 | size_t length; |
| 108 | struct vattr vattr; |
| 109 | struct sbuf *sname; |
| 110 | |
| 111 | /* a shell script? */ |
| 112 | if (((const short *)image_header)[0] != SHELLMAGIC) |
| 113 | return (-1); |
| 114 | |
| 115 | /* |
| 116 | * Don't allow a shell script to be the shell for a shell |
| 117 | * script. :-) |
| 118 | */ |
| 119 | if (imgp->interpreted & IMGACT_SHELL) |
| 120 | return (ENOEXEC); |
| 121 | |
| 122 | imgp->interpreted |= IMGACT_SHELL; |
| 123 | |
| 124 | /* |
| 125 | * At this point we have the first page of the file mapped. |
| 126 | * However, we don't know how far into the page the contents are |
| 127 | * valid -- the actual file might be much shorter than the page. |
| 128 | * So find out the file size. |
| 129 | */ |
| 130 | error = VOP_GETATTR(imgp->vp, &vattr, imgp->proc->p_ucred); |
| 131 | if (error) |
| 132 | return (error); |
| 133 | |
| 134 | /* |
| 135 | * Copy shell name and arguments from image_header into a string |
| 136 | * buffer. |
| 137 | */ |
| 138 | maxp = &image_header[MIN(vattr.va_size, MAXSHELLCMDLEN)]; |
| 139 | ihp = &image_header[2]; |
| 140 | |
| 141 | /* |
| 142 | * Find the beginning and end of the interpreter_name. If the |
| 143 | * line does not include any interpreter, or if the name which |
| 144 | * was found is too long, we bail out. |
| 145 | */ |
| 146 | while (ihp < maxp && ((*ihp == ' ') || (*ihp == '\t'))) |
| 147 | ihp++; |
| 148 | interpb = ihp; |
| 149 | while (ihp < maxp && ((*ihp != ' ') && (*ihp != '\t') && (*ihp != '\n') |
| 150 | && (*ihp != '\0'))) |
| 151 | ihp++; |
| 152 | interpe = ihp; |
| 153 | if (interpb == interpe) |
| 154 | return (ENOEXEC); |
| 155 | if (interpe - interpb >= MAXINTERP) |
| 156 | return (ENAMETOOLONG); |
| 157 | |
| 158 | /* |
nothing calls this directly
no test coverage detected