fix shebang/magic decoding

This commit is contained in:
tg 2014-11-25 22:46:58 +00:00
parent 93448bdf66
commit 2f26836ed1

75
exec.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.138 2014/11/25 21:13:24 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/exec.c,v 1.139 2014/11/25 22:46:58 tg Exp $");
#ifndef MKSH_DEFAULT_EXECSHELL #ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL "/bin/sh" #define MKSH_DEFAULT_EXECSHELL "/bin/sh"
@ -854,10 +854,8 @@ scriptexec(struct op *tp, const char **ap)
{ {
const char *sh; const char *sh;
#ifndef MKSH_SMALL #ifndef MKSH_SMALL
unsigned char *cp;
/* 64 == MAXINTERP in MirBSD <sys/param.h> */
char buf[64];
int fd; int fd;
unsigned char buf[68];
#endif #endif
union mksh_ccphack args, cap; union mksh_ccphack args, cap;
@ -871,33 +869,35 @@ scriptexec(struct op *tp, const char **ap)
#ifndef MKSH_SMALL #ifndef MKSH_SMALL
if ((fd = open(tp->str, O_RDONLY | O_BINARY)) >= 0) { if ((fd = open(tp->str, O_RDONLY | O_BINARY)) >= 0) {
/* read first MAXINTERP octets from file */ unsigned char *cp;
if (read(fd, buf, sizeof(buf)) <= 0) unsigned short m;
/* read error -> no good */ ssize_t n;
buf[0] = '\0';
/* read first couple of octets from file */
n = read(fd, buf, sizeof(buf) - 1);
close(fd); close(fd);
/* read error or short read? */
if (n < 5)
goto nomagic;
/* terminate buffer */
buf[n] = '\0';
/* skip UTF-8 Byte Order Mark, if present */ /* skip UTF-8 Byte Order Mark, if present */
cp = (unsigned char *)buf; cp = buf + (n = ((buf[0] == 0xEF) && (buf[1] == 0xBB) &&
if ((cp[0] == 0xEF) && (cp[1] == 0xBB) && (cp[2] == 0xBF)) (buf[2] == 0xBF)) ? 3 : 0);
cp += 3;
/* save begin of shebang for later */
fd = (char *)cp - buf; /* either 0 or (if BOM) 3 */
/* scan for newline (or CR) or NUL _before_ end of buffer */ /* scan for newline or NUL (end of buffer) */
while ((size_t)((char *)cp - buf) < sizeof(buf)) while (*cp && *cp != '\n')
if (*cp == '\0' || *cp == '\n' || *cp == '\r') {
*cp = '\0';
break;
} else
++cp; ++cp;
/* if the shebang line is longer than MAXINTERP, bail out */ /* if the shebang line is longer than MAXINTERP, bail out */
if ((size_t)((char *)cp - buf) >= sizeof(buf)) if (!*cp)
goto noshebang; goto noshebang;
/* replace newline by NUL */
*cp = '\0';
/* restore begin of shebang position (buf+0 or buf+3) */ /* restore begin of shebang position (buf+0 or buf+3) */
cp = (unsigned char *)(buf + fd); cp = buf + n;
/* bail out if read error (above) or no shebang */ /* bail out if no shebang magic found */
if ((cp[0] != '#') || (cp[1] != '!')) if ((cp[0] != '#') || (cp[1] != '!'))
goto noshebang; goto noshebang;
@ -923,23 +923,24 @@ scriptexec(struct op *tp, const char **ap)
if (*cp) if (*cp)
*tp->args-- = (char *)cp; *tp->args-- = (char *)cp;
} }
goto nomagic;
noshebang: noshebang:
cp = (unsigned char *)buf; m = buf[0] << 8 | buf[1];
if (cp[0] == 0x7F && cp[1] == 'E' && cp[2] == 'L' && if (m == 0x7F45 && buf[2] == 'L' && buf[3] == 'F')
cp[3] == 'F')
errorf("%s: not executable: %d-bit ELF file", tp->str, errorf("%s: not executable: %d-bit ELF file", tp->str,
32 * cp[4]); 32 * buf[4]);
fd = cp[0] << 8 | cp[1]; if ((m == /* OMAGIC */ 0407) ||
if ((fd == /* OMAGIC */ 0407) || (m == /* NMAGIC */ 0410) ||
(fd == /* NMAGIC */ 0410) || (m == /* ZMAGIC */ 0413) ||
(fd == /* ZMAGIC */ 0413) || (m == /* QMAGIC */ 0314) ||
(fd == /* QMAGIC */ 0314) || (m == /* ECOFF_I386 */ 0x4C01) ||
(fd == /* ECOFF_I386 */ 0x4C01) || (m == /* ECOFF_M68K */ 0x0150 || m == 0x5001) ||
(fd == /* ECOFF_M68K */ 0x0150 || fd == 0x5001) || (m == /* ECOFF_SH */ 0x0500 || m == 0x0005) ||
(fd == /* ECOFF_SH */ 0x0500 || fd == 0x0005) || (m == /* "MZ" */ 0x4D5A) ||
(fd == /* "MZ" */ 0x4D5A) || (m == /* gzip */ 0x1F8B) || (m == /* .Z */ 0x1F9D))
(fd == /* gzip */ 0x1F8B)) errorf("%s: not executable: magic %04X", tp->str, m);
errorf("%s: not executable: magic %04X", tp->str, fd); nomagic:
;
} }
#endif #endif
args.ro = tp->args; args.ro = tp->args;