summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Lowe <richlowe@richlowe.net>2013-08-07 17:49:24 -0400
committerRichard Lowe <richlowe@richlowe.net>2013-08-18 12:13:39 -0400
commitf0a0736fb13261a73aa20b1516bcc521f0fb7f15 (patch)
treedbf1e066cdc882bfef5bc7c5b8bdeb405e89d188
parentc894effd15e1470607e79c76f273f4565720d0f6 (diff)
downloadillumos-joyent-f0a0736fb13261a73aa20b1516bcc521f0fb7f15.tar.gz
4011 ar does weird things with extended ELF sections
Reviewed by: Jason King <jason.brian.king@gmail.com> Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net> Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r--usr/src/cmd/sgs/ar/common/ar.msg2
-rw-r--r--usr/src/cmd/sgs/ar/common/file.c33
2 files changed, 32 insertions, 3 deletions
diff --git a/usr/src/cmd/sgs/ar/common/ar.msg b/usr/src/cmd/sgs/ar/common/ar.msg
index f82a689966..a0da94da04 100644
--- a/usr/src/cmd/sgs/ar/common/ar.msg
+++ b/usr/src/cmd/sgs/ar/common/ar.msg
@@ -70,6 +70,8 @@
@ MSG_ELF_GETSCN_FILE "ar: %s has no section header or bad elf format: %s\n"
@ MSG_ELF_GETSCN_AR "ar: %s(%s) has no section header or bad elf \
format: %s\n"
+@ MSG_ELF_GETSHSTRNDX_FILE "ar: %s has no string table index: %s\n"
+@ MSG_ELF_GETSHSTRNDX_AR "ar: %s(%s) has no string table index: %s\n"
@ MSG_ELF_MALARCHIVE "ar: %s: offset %lld: malformed archive: %s\n"
@ MSG_ELF_RAWFILE "ar: elf_rawfile() failed: %s\n"
@ MSG_ELF_VERSION "ar: libelf.a out of date: %s\n"
diff --git a/usr/src/cmd/sgs/ar/common/file.c b/usr/src/cmd/sgs/ar/common/file.c
index 0c48b9f622..e3aa7fa0a5 100644
--- a/usr/src/cmd/sgs/ar/common/file.c
+++ b/usr/src/cmd/sgs/ar/common/file.c
@@ -205,6 +205,7 @@ recover_padding(Elf *elf, ARFILE *file)
{
size_t extent;
size_t padding;
+ size_t shnum;
GElf_Ehdr ehdr;
@@ -222,8 +223,11 @@ recover_padding(Elf *elf, ARFILE *file)
* we've found the end, and the difference is padding (We assume
* that no ELF section can fit into PADSZ bytes).
*/
+ if (elf_getshdrnum(elf, &shnum) == -1)
+ return;
+
extent = gelf_getehdr(elf, &ehdr)
- ? (ehdr.e_shoff + (ehdr.e_shnum * ehdr.e_shentsize)) : 0;
+ ? (ehdr.e_shoff + (shnum * ehdr.e_shentsize)) : 0;
/*
* If the extent exceeds the end of the archive member
@@ -552,11 +556,33 @@ mksymtab(const char *arname, ARFILEP **symlist, int *found_obj)
exit(1);
}
if (gelf_getehdr(elf, &ehdr) != 0) {
+ size_t shstrndx = 0;
if ((class = gelf_getclass(elf)) == ELFCLASS64) {
fptr->ar_flag |= F_CLASS64;
} else if (class == ELFCLASS32)
fptr->ar_flag |= F_CLASS32;
- scn = elf_getscn(elf, ehdr.e_shstrndx);
+
+ if (elf_getshdrstrndx(elf, &shstrndx) == -1) {
+ if (fptr->ar_pathname != NULL) {
+ (void) fprintf(stderr,
+ MSG_INTL(MSG_ELF_GETSHSTRNDX_FILE),
+ fptr->ar_pathname, elf_errmsg(-1));
+ } else {
+ (void) fprintf(stderr,
+ MSG_INTL(MSG_ELF_GETSHSTRNDX_AR),
+ arname, fptr->ar_longname,
+ elf_errmsg(-1));
+ }
+ num_errs++;
+ if (newfd) {
+ (void) close(newfd);
+ newfd = 0;
+ }
+ (void) elf_end(elf);
+ continue;
+ }
+
+ scn = elf_getscn(elf, shstrndx);
if (scn == NULL) {
if (fptr->ar_pathname != NULL)
(void) fprintf(stderr,
@@ -640,7 +666,7 @@ mksymtab(const char *arname, ARFILEP **symlist, int *found_obj)
continue;
}
*found_obj = 1;
- if (shdr.sh_type == SHT_SYMTAB)
+ if (shdr.sh_type == SHT_SYMTAB) {
if (search_sym_tab(arname, fptr, elf,
scn, &nsyms, symlist,
&num_errs) == -1) {
@@ -650,6 +676,7 @@ mksymtab(const char *arname, ARFILEP **symlist, int *found_obj)
}
continue;
}
+ }
}
}
mem_offset += sizeof (struct ar_hdr) + fptr->ar_size;