123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- diff --git a/config.h.in b/config.h.in
- index a5ad9e7..62a6b32 100644
- --- a/config.h.in
- +++ b/config.h.in
- @@ -748,6 +748,9 @@
- /* Define if you have the pselect function. */
- #undef HAVE_PSELECT
-
- +/* Define if you have the pread function. */
- +#undef HAVE_PREAD
- +
- /* Define if you have the putenv function. */
- #undef HAVE_PUTENV
-
- @@ -946,6 +949,9 @@
- /* Define if you have the <dlfcn.h> header file. */
- #undef HAVE_DLFCN_H
-
- +/* Define if you have the <elf.h> header file. */
- +#undef HAVE_ELF_H
- +
- /* Define if you have the <grp.h> header file. */
- #undef HAVE_GRP_H
-
- diff --git a/configure.ac b/configure.ac
- index ce4e9b6..eda95d6 100644
- --- a/configure.ac
- +++ b/configure.ac
- @@ -700,7 +700,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 \
- stdbool.h stddef.h stdint.h netdb.h pwd.h grp.h strings.h \
- - regex.h syslog.h ulimit.h)
- + regex.h syslog.h ulimit.h elf.h)
- AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h sys/ioctl.h \
- sys/param.h sys/socket.h sys/stat.h \
- sys/time.h sys/times.h sys/types.h sys/wait.h)
- @@ -771,7 +771,7 @@ dnl checks for system calls
- AC_CHECK_FUNCS(dup2 eaccess fcntl getdtablesize getgroups gethostname \
- getpagesize getpeername getrlimit getrusage gettimeofday \
- kill killpg lstat pselect readlink sbrk select setdtablesize \
- - setitimer tcgetpgrp uname ulimit waitpid)
- + setitimer tcgetpgrp uname ulimit waitpid pread)
- AC_REPLACE_FUNCS(rename)
-
- dnl checks for c library functions
- diff --git a/execute_cmd.c b/execute_cmd.c
- index 2a3df6d..b5cd405 100644
- --- a/execute_cmd.c
- +++ b/execute_cmd.c
- @@ -41,6 +41,10 @@
- # include <unistd.h>
- #endif
-
- +#ifdef HAVE_ELF_H
- +# include <elf.h>
- +#endif
- +
- #include "posixtime.h"
-
- #if defined (HAVE_SYS_RESOURCE_H) && !defined (RLIMTYPE)
- @@ -5486,6 +5490,14 @@ shell_execve (command, args, env)
- {
- /* The file has the execute bits set, but the kernel refuses to
- run it for some reason. See why. */
- +#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 > 0)
- @@ -5495,6 +5507,7 @@ shell_execve (command, args, env)
- char *interp;
- int ilen;
-
- + close (fd);
- interp = getinterp (sample, sample_len, (int *)NULL);
- ilen = strlen (interp);
- errno = i;
- @@ -5510,6 +5523,136 @@ 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
- + && sample_len > sizeof (Elf32_Ehdr))
- + {
- + Elf32_Ehdr ehdr;
- + Elf32_Phdr *phdr;
- + int nphdr;
- +
- + /* We have to copy the data since the sample buffer
- + might not be aligned correctly to be accessed as
- + an Elf32_Ehdr struct. */
- + memcpy (&ehdr, sample, sizeof (Elf32_Ehdr));
- +
- + nphdr = ehdr.e_phnum;
- + phdr = (Elf32_Phdr *) malloc (nphdr * ehdr.e_phentsize);
- + if (phdr != NULL)
- + {
- +#ifdef HAVE_PREAD
- + sample_len = pread (fd, phdr, nphdr * ehdr.e_phentsize,
- + ehdr.e_phoff);
- +#else
- + if (lseek (fd, ehdr.e_phoff, SEEK_SET) != -1)
- + sample_len = read (fd, phdr,
- + nphdr * ehdr.e_phentsize);
- + else
- + sample_len = -1;
- +#endif
- + if (sample_len == nphdr * 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
- + && sample_len > sizeof (Elf64_Ehdr))
- + {
- + Elf64_Ehdr ehdr;
- + Elf64_Phdr *phdr;
- + int nphdr;
- +
- + /* We have to copy the data since the sample buffer
- + might not be aligned correctly to be accessed as
- + an Elf64_Ehdr struct. */
- + memcpy (&ehdr, sample, sizeof (Elf64_Ehdr));
- +
- + nphdr = ehdr.e_phnum;
- + phdr = (Elf64_Phdr *) malloc (nphdr * ehdr.e_phentsize);
- + if (phdr != NULL)
- + {
- +#ifdef HAVE_PREAD
- + sample_len = pread (fd, phdr, nphdr * ehdr.e_phentsize,
- + ehdr.e_phoff);
- +#else
- + if (lseek (fd, ehdr.e_phoff, SEEK_SET) != -1)
- + sample_len = read (fd, phdr,
- + nphdr * ehdr.e_phentsize);
- + else
- + sample_len = -1;
- +#endif
- + if (sample_len == nphdr * 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);
- }
- --
- 2.9.3
|