nalika / rpms / bash

Forked from rpms/bash 2 years ago
Clone
bb9a7e
diff -up bash-4.0/execute_cmd.c.nobits bash-4.0/execute_cmd.c
bb9a7e
--- bash-4.0/execute_cmd.c.nobits	2009-08-11 11:53:38.000000000 +0200
bb9a7e
+++ bash-4.0/execute_cmd.c	2009-08-14 16:18:18.000000000 +0200
bb9a7e
@@ -4747,6 +4747,7 @@ shell_execve (command, args, env)
bb9a7e
 	      && memcmp (sample, ELFMAG, SELFMAG) == 0)
bb9a7e
 	    {
bb9a7e
 	      off_t offset = -1;
bb9a7e
+              int dynamic_nobits = 0;
bb9a7e
 
bb9a7e
 	      /* It is an ELF file.  Now determine whether it is dynamically
bb9a7e
 		 linked and if yes, get the offset of the interpreter
bb9a7e
@@ -4756,13 +4757,61 @@ shell_execve (command, args, env)
bb9a7e
 		{
bb9a7e
 		  Elf32_Ehdr ehdr;
bb9a7e
 		  Elf32_Phdr *phdr;
bb9a7e
-		  int nphdr;
bb9a7e
+                  Elf32_Shdr *shdr;
bb9a7e
+		  int nphdr, nshdr;
bb9a7e
 
bb9a7e
 		  /* We have to copy the data since the sample buffer
bb9a7e
 		     might not be aligned correctly to be accessed as
bb9a7e
 		     an Elf32_Ehdr struct.  */
bb9a7e
 		  memcpy (&ehdr, sample, sizeof (Elf32_Ehdr));
bb9a7e
 
bb9a7e
+		  nshdr = ehdr.e_shnum;
bb9a7e
+		  shdr = (Elf32_Shdr *) malloc (nshdr * ehdr.e_shentsize);
bb9a7e
+                  
bb9a7e
+		  if (shdr != NULL)
bb9a7e
+		    {
bb9a7e
+#ifdef HAVE_PREAD
bb9a7e
+		      sample_len = pread (fd, shdr, nshdr * ehdr.e_shentsize,
bb9a7e
+					  ehdr.e_shoff);
bb9a7e
+#else
bb9a7e
+		      if (lseek (fd, ehdr.e_shoff, SEEK_SET) != -1)
bb9a7e
+			sample_len = read (fd, shdr,
bb9a7e
+					   nshdr * ehdr.e_shentsize);
bb9a7e
+		      else
bb9a7e
+			sample_len = -1;
bb9a7e
+#endif
bb9a7e
+		      if (sample_len == nshdr * ehdr.e_shentsize)
bb9a7e
+                        {
bb9a7e
+                          char *strings = (char *) malloc (shdr[ehdr.e_shstrndx].sh_size);
bb9a7e
+                          if (strings != NULL)
bb9a7e
+                            {
bb9a7e
+#ifdef HAVE_PREAD
bb9a7e
+		              sample_len = pread (fd, strings,
bb9a7e
+                                             shdr[ehdr.e_shstrndx].sh_size,
bb9a7e
+					     shdr[ehdr.e_shstrndx].sh_offset);
bb9a7e
+#else
bb9a7e
+		              if (lseek (fd, shdr[ehdr.e_shstrndx].sh_offset,
bb9a7e
+                                         SEEK_SET) != -1)
bb9a7e
+			        sample_len = read (fd, strings,
bb9a7e
+			  		       shdr[ehdr.e_shstrndx].sh_size);
bb9a7e
+		              else
bb9a7e
+			        sample_len = -1;
bb9a7e
+#endif
bb9a7e
+                              if (sample_len == shdr[ehdr.e_shstrndx].sh_size)
bb9a7e
+			        while (nshdr-- > 0)
bb9a7e
+                                  if (strcmp (strings + shdr[nshdr].sh_name,
bb9a7e
+                                              ".interp") == 0 &&
bb9a7e
+                                      shdr[nshdr].sh_type == SHT_NOBITS)
bb9a7e
+                                    {
bb9a7e
+                                      dynamic_nobits++;
bb9a7e
+                                      break;
bb9a7e
+                                    }
bb9a7e
+                              free (strings);
bb9a7e
+                            }
bb9a7e
+                        }
bb9a7e
+		      free (shdr);
bb9a7e
+		    }
bb9a7e
+
bb9a7e
 		  nphdr = ehdr.e_phnum;
bb9a7e
 		  phdr = (Elf32_Phdr *) malloc (nphdr * ehdr.e_phentsize);
bb9a7e
 		  if (phdr != NULL)
bb9a7e
@@ -4792,13 +4841,60 @@ shell_execve (command, args, env)
bb9a7e
 		{
bb9a7e
 		  Elf64_Ehdr ehdr;
bb9a7e
 		  Elf64_Phdr *phdr;
bb9a7e
-		  int nphdr;
bb9a7e
+                  Elf64_Shdr *shdr;
bb9a7e
+		  int nphdr, nshdr;
bb9a7e
 
bb9a7e
 		  /* We have to copy the data since the sample buffer
bb9a7e
 		     might not be aligned correctly to be accessed as
bb9a7e
 		     an Elf64_Ehdr struct.  */
bb9a7e
 		  memcpy (&ehdr, sample, sizeof (Elf64_Ehdr));
bb9a7e
 
bb9a7e
+		  nshdr = ehdr.e_shnum;
bb9a7e
+		  shdr = (Elf64_Shdr *) malloc (nshdr * ehdr.e_shentsize);
bb9a7e
+		  if (shdr != NULL)
bb9a7e
+		    {
bb9a7e
+#ifdef HAVE_PREAD
bb9a7e
+		      sample_len = pread (fd, shdr, nshdr * ehdr.e_shentsize,
bb9a7e
+					  ehdr.e_shoff);
bb9a7e
+#else
bb9a7e
+		      if (lseek (fd, ehdr.e_shoff, SEEK_SET) != -1)
bb9a7e
+			sample_len = read (fd, shdr,
bb9a7e
+					   nshdr * ehdr.e_shentsize);
bb9a7e
+		      else
bb9a7e
+			sample_len = -1;
bb9a7e
+#endif
bb9a7e
+		      if (sample_len == nshdr * ehdr.e_shentsize)
bb9a7e
+                        {
bb9a7e
+                          char *strings = (char *) malloc (shdr[ehdr.e_shstrndx].sh_size);
bb9a7e
+                          if (strings != NULL)
bb9a7e
+                            {
bb9a7e
+#ifdef HAVE_PREAD
bb9a7e
+		              sample_len = pread (fd, strings,
bb9a7e
+                                             shdr[ehdr.e_shstrndx].sh_size,
bb9a7e
+					     shdr[ehdr.e_shstrndx].sh_offset);
bb9a7e
+#else
bb9a7e
+		              if (lseek (fd, shdr[ehdr.e_shstrndx].sh_offset,
bb9a7e
+                                         SEEK_SET) != -1)
bb9a7e
+			        sample_len = read (fd, strings,
bb9a7e
+			  		       shdr[ehdr.e_shstrndx].sh_size);
bb9a7e
+		              else
bb9a7e
+			        sample_len = -1;
bb9a7e
+#endif
bb9a7e
+                              if (sample_len == shdr[ehdr.e_shstrndx].sh_size)
bb9a7e
+			        while (nshdr-- > 0)
bb9a7e
+                                  if (strcmp (strings + shdr[nshdr].sh_name,
bb9a7e
+                                              ".interp") == 0 &&
bb9a7e
+                                      shdr[nshdr].sh_type == SHT_NOBITS)
bb9a7e
+                                    {
bb9a7e
+                                      dynamic_nobits++;
bb9a7e
+                                      break;
bb9a7e
+                                    }
bb9a7e
+                              free (strings);
bb9a7e
+                            }
bb9a7e
+                        }
bb9a7e
+		      free (shdr);
bb9a7e
+		    }
bb9a7e
+
bb9a7e
 		  nphdr = ehdr.e_phnum;
bb9a7e
 		  phdr = (Elf64_Phdr *) malloc (nphdr * ehdr.e_phentsize);
bb9a7e
 		  if (phdr != NULL)
bb9a7e
@@ -4858,8 +4954,15 @@ shell_execve (command, args, env)
bb9a7e
 		    {
bb9a7e
 		      close (fd);
bb9a7e
 		      errno = i;
bb9a7e
-		      sys_error ("%s: %s: bad ELF interpreter", command,
bb9a7e
-				 interp);
bb9a7e
+                      if (dynamic_nobits > 0)
bb9a7e
+                        {
bb9a7e
+                          sys_error ("%s: bad ELF interpreter", command);
bb9a7e
+                        }
bb9a7e
+                      else
bb9a7e
+                        {
bb9a7e
+		          sys_error ("%s: %s: bad ELF interpreter", command,
bb9a7e
+				     interp);
bb9a7e
+                        }
bb9a7e
 		      free (interp);
bb9a7e
 		      return (EX_NOEXEC);
bb9a7e
 		    }