Tim Waugh 393b61
--- bash-3.2/configure.in.interpreter	2006-09-26 16:05:45.000000000 +0100
Tim Waugh 393b61
+++ bash-3.2/configure.in	2006-12-15 17:56:15.000000000 +0000
Tim Waugh 393b61
@@ -634,7 +634,7 @@
cvsdist 8b5e1e
 
cvsdist 8b5e1e
 AC_CHECK_HEADERS(unistd.h stdlib.h stdarg.h varargs.h limits.h string.h \
cvsdist 8b5e1e
 		 memory.h locale.h termcap.h termio.h termios.h dlfcn.h \
Tim Waugh d98c1b
-		 stddef.h stdint.h netdb.h pwd.h grp.h strings.h regex.h)
Tim Waugh d98c1b
+		 stddef.h stdint.h netdb.h pwd.h grp.h strings.h regex.h elf.h)
Tim Waugh d98c1b
 AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h \
cvsdist 4d371b
 		 sys/resource.h sys/param.h sys/socket.h sys/stat.h \
cvsdist 4d371b
 		 sys/time.h sys/times.h sys/types.h sys/wait.h)
Tim Waugh 393b61
@@ -698,7 +698,7 @@
Tim Waugh 393b61
 AC_CHECK_FUNCS(dup2 eaccess fcntl getdtablesize getgroups gethostname \
Tim Waugh 393b61
 		getpagesize getpeername getrlimit getrusage gettimeofday \
Tim Waugh 393b61
 		kill killpg lstat readlink sbrk select setdtablesize \
Tim Waugh 393b61
-		tcgetpgrp uname ulimit waitpid)
Tim Waugh 393b61
+		tcgetpgrp uname ulimit waitpid pread)
cvsdist 4d371b
 AC_REPLACE_FUNCS(rename)
cvsdist 4d371b
 
cvsdist 4d371b
 dnl checks for c library functions
Tim Waugh 393b61
--- bash-3.2/execute_cmd.c.interpreter	2006-12-15 17:55:53.000000000 +0000
Tim Waugh 393b61
+++ bash-3.2/execute_cmd.c	2006-12-15 17:55:53.000000000 +0000
cvsdist 8b5e1e
@@ -40,6 +40,10 @@
cvsdist 8b5e1e
 #  include <unistd.h>
cvsdist 8b5e1e
 #endif
cvsdist 8b5e1e
 
cvsdist 8b5e1e
+#ifdef HAVE_ELF_H
cvsdist 8b5e1e
+# include <elf.h>
cvsdist 8b5e1e
+#endif
cvsdist 8b5e1e
+
cvsdist 8b5e1e
 #include "posixtime.h"
cvsdist 8b5e1e
 
cvsdist 8b5e1e
 #if defined (HAVE_SYS_RESOURCE_H) && !defined (RLIMTYPE)
Tim Waugh 393b61
@@ -3953,13 +3957,21 @@
cvsdist 8b5e1e
 	{
cvsdist 57ff95
 	  /* The file has the execute bits set, but the kernel refuses to
cvsdist 57ff95
 	     run it for some reason.  See why. */
cvsdist 8b5e1e
+#if defined (HAVE_HASH_BANG_EXEC) || defined (HAVE_ELF_H)
cvsdist 57ff95
+	int fd = open (command, O_RDONLY);
cvsdist 8b5e1e
+
cvsdist 57ff95
+	if (fd >= 0)
cvsdist 57ff95
+		sample_len = read (fd, sample, sizeof (sample));
cvsdist 57ff95
+	else
cvsdist 57ff95
+		sample_len = -1;
cvsdist 8b5e1e
+#endif
cvsdist 8b5e1e
 #if defined (HAVE_HASH_BANG_EXEC)
cvsdist 8b5e1e
-	  READ_SAMPLE_BUF (command, sample, sample_len);
cvsdist 8b5e1e
 	  if (sample_len > 2 && sample[0] == '#' && sample[1] == '!')
cvsdist 8b5e1e
 	    {
cvsdist 8b5e1e
 	      char *interp;
Tim Waugh d98c1b
 	      int ilen;
cvsdist 8b5e1e
 
cvsdist 8b5e1e
+	      close (fd);
cvsdist 8b5e1e
 	      interp = getinterp (sample, sample_len, (int *)NULL);
Tim Waugh d98c1b
 	      ilen = strlen (interp);
cvsdist 8b5e1e
 	      errno = i;
Tim Waugh 393b61
@@ -3975,6 +3987,136 @@
cvsdist 8b5e1e
 	      return (EX_NOEXEC);
cvsdist 8b5e1e
 	    }
cvsdist 8b5e1e
 #endif
cvsdist 8b5e1e
+#if defined (HAVE_ELF_H)
cvsdist 8b5e1e
+	  if (i == ENOENT
cvsdist 8b5e1e
+	      && sample_len > EI_NIDENT
cvsdist 8b5e1e
+	      && memcmp (sample, ELFMAG, SELFMAG) == 0)
cvsdist 8b5e1e
+	    {
cvsdist 8b5e1e
+	      off_t offset = -1;
cvsdist 8b5e1e
+
cvsdist 8b5e1e
+	      /* It is an ELF file.  Now determine whether it is dynamically
cvsdist 8b5e1e
+		 linked and if yes, get the offset of the interpreter
cvsdist 8b5e1e
+		 string.  */
cvsdist 8b5e1e
+	      if (sample[EI_CLASS] == ELFCLASS32
cvsdist 8b5e1e
+		  && sample_len > sizeof (Elf32_Ehdr))
cvsdist 8b5e1e
+		{
cvsdist 8b5e1e
+		  Elf32_Ehdr ehdr;
cvsdist 8b5e1e
+		  Elf32_Phdr *phdr;
cvsdist 8b5e1e
+		  int nphdr;
cvsdist 8b5e1e
+
cvsdist 8b5e1e
+		  /* We have to copy the data since the sample buffer
cvsdist 8b5e1e
+		     might not be aligned correctly to be accessed as
cvsdist 8b5e1e
+		     an Elf32_Ehdr struct.  */
cvsdist 8b5e1e
+		  memcpy (&ehdr, sample, sizeof (Elf32_Ehdr));
cvsdist 8b5e1e
+
cvsdist 8b5e1e
+		  nphdr = ehdr.e_phnum;
cvsdist 8b5e1e
+		  phdr = (Elf32_Phdr *) malloc (nphdr * ehdr.e_phentsize);
cvsdist 8b5e1e
+		  if (phdr != NULL)
cvsdist 8b5e1e
+		    {
cvsdist 8b5e1e
+#ifdef HAVE_PREAD
cvsdist 8b5e1e
+		      sample_len = pread (fd, phdr, nphdr * ehdr.e_phentsize,
cvsdist 8b5e1e
+					  ehdr.e_phoff);
cvsdist 8b5e1e
+#else
cvsdist 8b5e1e
+		      if (lseek (fd, ehdr.e_phoff, SEEK_SET) != -1)
cvsdist 8b5e1e
+			sample_len = read (fd, phdr,
cvsdist 8b5e1e
+					   nphdr * ehdr.e_phentsize);
cvsdist 8b5e1e
+		      else
cvsdist 8b5e1e
+			sample_len = -1;
cvsdist 8b5e1e
+#endif
cvsdist 8b5e1e
+		      if (sample_len == nphdr * ehdr.e_phentsize)
cvsdist 8b5e1e
+			while (nphdr-- > 0)
cvsdist 8b5e1e
+			  if (phdr[nphdr].p_type == PT_INTERP)
cvsdist 8b5e1e
+			    {
cvsdist 8b5e1e
+			      offset = phdr[nphdr].p_offset;
cvsdist 8b5e1e
+			      break;
cvsdist 8b5e1e
+			    }
cvsdist 8b5e1e
+		      free (phdr);
cvsdist 8b5e1e
+		    }
cvsdist 8b5e1e
+		}
cvsdist 8b5e1e
+	      else if (sample[EI_CLASS] == ELFCLASS64
cvsdist 8b5e1e
+		       && sample_len > sizeof (Elf64_Ehdr))
cvsdist 8b5e1e
+		{
cvsdist 8b5e1e
+		  Elf64_Ehdr ehdr;
cvsdist 8b5e1e
+		  Elf64_Phdr *phdr;
cvsdist 8b5e1e
+		  int nphdr;
cvsdist 8b5e1e
+
cvsdist 8b5e1e
+		  /* We have to copy the data since the sample buffer
cvsdist 8b5e1e
+		     might not be aligned correctly to be accessed as
cvsdist 8b5e1e
+		     an Elf64_Ehdr struct.  */
cvsdist 8b5e1e
+		  memcpy (&ehdr, sample, sizeof (Elf64_Ehdr));
cvsdist 8b5e1e
+
cvsdist 8b5e1e
+		  nphdr = ehdr.e_phnum;
cvsdist 8b5e1e
+		  phdr = (Elf64_Phdr *) malloc (nphdr * ehdr.e_phentsize);
cvsdist 8b5e1e
+		  if (phdr != NULL)
cvsdist 8b5e1e
+		    {
cvsdist 8b5e1e
+#ifdef HAVE_PREAD
cvsdist 8b5e1e
+		      sample_len = pread (fd, phdr, nphdr * ehdr.e_phentsize,
cvsdist 8b5e1e
+					  ehdr.e_phoff);
cvsdist 8b5e1e
+#else
cvsdist 8b5e1e
+		      if (lseek (fd, ehdr.e_phoff, SEEK_SET) != -1)
cvsdist 8b5e1e
+			sample_len = read (fd, phdr,
cvsdist 8b5e1e
+					   nphdr * ehdr.e_phentsize);
cvsdist 8b5e1e
+		      else
cvsdist 8b5e1e
+			sample_len = -1;
cvsdist 8b5e1e
+#endif
cvsdist 8b5e1e
+		      if (sample_len == nphdr * ehdr.e_phentsize)
cvsdist 8b5e1e
+			while (nphdr-- > 0)
cvsdist 8b5e1e
+			  if (phdr[nphdr].p_type == PT_INTERP)
cvsdist 8b5e1e
+			    {
cvsdist 8b5e1e
+			      offset = phdr[nphdr].p_offset;
cvsdist 8b5e1e
+			      break;
cvsdist 8b5e1e
+			    }
cvsdist 8b5e1e
+		      free (phdr);
cvsdist 8b5e1e
+		    }
cvsdist 8b5e1e
+		}
cvsdist 8b5e1e
+
cvsdist 8b5e1e
+	      if (offset != -1)
cvsdist 8b5e1e
+		{
cvsdist 8b5e1e
+		  size_t maxlen = 0;
cvsdist 8b5e1e
+		  size_t actlen = 0;
cvsdist 8b5e1e
+		  char *interp = NULL;
cvsdist 8b5e1e
+
cvsdist 8b5e1e
+		  do
cvsdist 8b5e1e
+		    {
cvsdist 8b5e1e
+		      if (actlen == maxlen)
cvsdist 8b5e1e
+			{
cvsdist 8b5e1e
+			  char *newinterp = realloc (interp, maxlen += 200);
cvsdist 8b5e1e
+			  if (newinterp == NULL)
cvsdist 8b5e1e
+			    {
cvsdist 8b5e1e
+			      actlen = 0;
cvsdist 8b5e1e
+			      break;
cvsdist 8b5e1e
+			    }
cvsdist 8b5e1e
+			  interp = newinterp;
cvsdist 8b5e1e
+
cvsdist 8b5e1e
+#ifdef HAVE_PREAD
cvsdist 8b5e1e
+			  actlen = pread (fd, interp, maxlen, offset);
cvsdist 8b5e1e
+#else
cvsdist 8b5e1e
+			  if (lseek (fd, offset, SEEK_SET) != -1)
cvsdist 8b5e1e
+			    actlen = read (fd, interp, maxlen);
cvsdist 8b5e1e
+			  else
cvsdist 8b5e1e
+			    actlen = -1;
cvsdist 8b5e1e
+#endif
cvsdist 8b5e1e
+			}
cvsdist 8b5e1e
+		    }
cvsdist 8b5e1e
+		  while (actlen > 0 && memchr (interp, '\0', actlen) == NULL);
cvsdist 8b5e1e
+
cvsdist 8b5e1e
+		  if (actlen > 0)
cvsdist 8b5e1e
+		    {
cvsdist 8b5e1e
+		      close (fd);
cvsdist 8b5e1e
+		      errno = i;
cvsdist 8b5e1e
+		      sys_error ("%s: %s: bad ELF interpreter", command,
cvsdist 8b5e1e
+				 interp);
cvsdist 8b5e1e
+		      free (interp);
cvsdist 8b5e1e
+		      return (EX_NOEXEC);
cvsdist 8b5e1e
+		    }
cvsdist 8b5e1e
+
cvsdist 8b5e1e
+		  free (interp);
cvsdist 8b5e1e
+		}
cvsdist 8b5e1e
+	    }
cvsdist 8b5e1e
+#endif
cvsdist 8b5e1e
+#if defined (HAVE_HASH_BANG_EXEC) || defined (HAVE_ELF_H)
cvsdist 8b5e1e
+	  close (fd);
cvsdist 8b5e1e
+#endif
cvsdist 8b5e1e
 	  errno = i;
cvsdist 8b5e1e
 	  file_error (command);
cvsdist 8b5e1e
 	}
Tim Waugh 393b61
--- bash-3.2/config.h.in.interpreter	2006-12-15 17:55:53.000000000 +0000
Tim Waugh 393b61
+++ bash-3.2/config.h.in	2006-12-15 17:55:53.000000000 +0000
Tim Waugh 393b61
@@ -646,6 +646,9 @@
Tim Waugh 393b61
 /* Define if you have the pathconf function. */
Tim Waugh 393b61
 #undef HAVE_PATHCONF
Tim Waugh 393b61
 
Tim Waugh 393b61
+/* Define if you have the pread function. */
Tim Waugh 393b61
+#undef HAVE_PREAD
Tim Waugh 393b61
+
Tim Waugh 393b61
 /* Define if you have the putenv function.  */
Tim Waugh 393b61
 #undef HAVE_PUTENV
Tim Waugh 393b61
 
Tim Waugh 393b61
@@ -823,6 +826,9 @@
Tim Waugh 393b61
 /* Define if you have the <dlfcn.h> header file.  */
Tim Waugh 393b61
 #undef HAVE_DLFCN_H
Tim Waugh 393b61
 
Tim Waugh 393b61
+/* Define if you have the <elf.h> header file.  */
Tim Waugh 393b61
+#undef HAVE_ELF_H
Tim Waugh 393b61
+
Tim Waugh 393b61
 /* Define if you have the <grp.h> header file.  */
Tim Waugh 393b61
 #undef HAVE_GRP_H
Tim Waugh 393b61