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