--- bash-2.05a/config.h.in Mon Oct 22 06:58:13 2001 +++ bash-2.05a-ud/config.h.in Thu Mar 7 17:33:03 2002 @@ -541,6 +541,9 @@ /* Define if you have the pathconf function. */ #undef HAVE_PATHCONF +/* Define if you have the pread function. */ +#undef HAVE_PREAD + /* Define if you have the putenv function. */ #undef HAVE_PUTENV @@ -675,6 +678,9 @@ /* Define if you have the header file. */ #undef HAVE_DLFCN_H +/* Define if you have the header file. */ +#undef HAVE_ELF_H + /* Define if you have the header file. */ #undef HAVE_GRP_H --- bash-2.05a/configure.in Mon Nov 5 12:45:35 2001 +++ bash-2.05a-ud/configure.in Thu Mar 7 17:28:32 2002 @@ -484,7 +484,7 @@ BASH_HEADER_INTTYPES AC_CHECK_HEADERS(unistd.h stdlib.h stdarg.h varargs.h limits.h string.h \ memory.h locale.h termcap.h termio.h termios.h dlfcn.h \ - stddef.h stdint.h netdb.h grp.h strings.h) + stddef.h stdint.h netdb.h grp.h strings.h elf.h) AC_CHECK_HEADERS(sys/ptem.h sys/pte.h sys/stream.h sys/select.h sys/file.h \ sys/resource.h sys/param.h sys/socket.h \ sys/time.h sys/times.h sys/wait.h) @@ -546,7 +546,7 @@ AC_CHECK_FUNCS(bcopy bzero confstr sysco setlinebuf setvbuf setlocale strchr tcgetattr uname \ ulimit tzset siginterrupt memmove ttyname times \ getaddrinfo gethostbyname getservbyname inet_aton \ - vsnprintf snprintf vasprintf asprintf fnmatch) + vsnprintf snprintf vasprintf asprintf fnmatch pread) AC_CHECK_FUNCS(isascii isblank isgraph isprint isspace isxdigit) AC_REPLACE_FUNCS(getcwd strcasecmp strerror strpbrk strtod) AC_REPLACE_FUNCS(strtol strtoul strtoll strtoull strtoimax strtoumax) --- bash-2.05a/execute_cmd.c Mon Oct 29 11:03:18 2001 +++ bash-2.05a-ud/execute_cmd.c Thu Mar 7 17:41:52 2002 @@ -40,6 +40,10 @@ # include #endif +#ifdef HAVE_ELF_H +# include +#endif + #include "posixtime.h" #if defined (HAVE_SYS_RESOURCE_H) && !defined (RLIMTYPE) @@ -3499,12 +3503,21 @@ shell_execve (command, args, env) internal_error ("%s: is a directory", command); else { +#if defined (HAVE_HASH_BANG_EXEC) || defined (HAVE_ELF_H) + int fd = open (command, O_RDONLY); + + if (fd >= 0) + sample_len = read (fd, sample, sizeof (sample)); + else + sample_len = -1; +#endif + #if defined (HAVE_HASH_BANG_EXEC) - READ_SAMPLE_BUF (command, sample, sample_len); if (sample_len > 2 && sample[0] == '#' && sample[1] == '!') { char *interp; + close (fd); interp = getinterp (sample, sample_len, (int *)NULL); errno = i; sys_error ("%s: %s: bad interpreter", command, interp ? interp : ""); @@ -3512,6 +3525,126 @@ shell_execve (command, args, env) return (EX_NOEXEC); } #endif +#if defined (HAVE_ELF_H) + if (i == ENOENT + && sample_len > EI_NIDENT + && memcmp (sample, ELFMAG, SELFMAG) == 0) + { + off_t offset = -1; + + /* It is an ELF file. Now determine whether it is dynamically + linked and if yes, get the offset of the interpreter + string. */ + if (sample[EI_CLASS] == ELFCLASS32) + { + Elf32_Ehdr *ehdr = (Elf32_Ehdr *) sample; + Elf32_Phdr *phdr; + int nphdr = ehdr->e_phnum; + + phdr = (Elf32_Phdr *) malloc (ehdr->e_phnum + * ehdr->e_phentsize); + if (phdr != NULL) + { +#ifdef HAVE_PREAD + sample_len = pread (fd, phdr, + ehdr->e_phnum * ehdr->e_phentsize, + ehdr->e_phoff); +#else + if (lseek (fd, ehdr->e_phoff, SEEK_SET) != -1) + sample_len = read (fd, phdr, + ehdr->e_phnum * ehdr->e_phentsize); + else + sample_len = -1; +#endif + if (sample_len == ehdr->e_phnum * ehdr->e_phentsize) + while (nphdr-- > 0) + if (phdr[nphdr].p_type == PT_INTERP) + { + offset = phdr[nphdr].p_offset; + break; + } + free (phdr); + } + } + else if (sample[EI_CLASS] == ELFCLASS64) + { + Elf64_Ehdr *ehdr = (Elf64_Ehdr *) sample; + Elf64_Phdr *phdr; + int nphdr = ehdr->e_phnum; + + phdr = (Elf64_Phdr *) malloc (ehdr->e_phnum + * ehdr->e_phentsize); + if (phdr != NULL) + { +#ifdef HAVE_PREAD + sample_len = pread (fd, phdr, + ehdr->e_phnum * ehdr->e_phentsize, + ehdr->e_phoff); +#else + if (lseek (fd, ehdr->e_phoff, SEEK_SET) != -1) + sample_len = read (fd, phdr, + ehdr->e_phnum * ehdr->e_phentsize); + else + sample_len = -1; +#endif + if (sample_len == ehdr->e_phnum * ehdr->e_phentsize) + while (nphdr-- > 0) + if (phdr[nphdr].p_type == PT_INTERP) + { + offset = phdr[nphdr].p_offset; + break; + } + free (phdr); + } + } + + if (offset != -1) + { + size_t maxlen = 0; + size_t actlen = 0; + char *interp = NULL; + + do + { + if (actlen == maxlen) + { + char *newinterp = realloc (interp, maxlen += 200); + if (newinterp == NULL) + { + actlen = 0; + break; + } + interp = newinterp; + +#ifdef HAVE_PREAD + actlen = pread (fd, interp, maxlen, offset); +#else + if (lseek (fd, offset, SEEK_SET) != -1) + actlen = read (fd, interp, maxlen); + else + actlen = -1; +#endif + } + } + while (actlen > 0 && memchr (interp, '\0', actlen) == NULL); + + if (actlen > 0) + { + close (fd); + errno = i; + sys_error ("%s: %s: bad ELF interpreter", command, + interp); + free (interp); + return (EX_NOEXEC); + } + + free (interp); + } + } +#endif +#if defined (HAVE_HASH_BANG_EXEC) || defined (HAVE_ELF_H) + close (fd); +#endif errno = i; file_error (command); }