diff options
| author | Paul Eggert | 2013-05-07 13:55:47 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-05-07 13:55:47 -0700 |
| commit | f269bc61c10320cf020e0751e6643fbbb5f059a2 (patch) | |
| tree | 11e6fc1d07a35c822778784350fa8a3285e30e0e /src | |
| parent | a261c53eaefb9f2d0a5e9175827b12ddefddbb7f (diff) | |
| download | emacs-f269bc61c10320cf020e0751e6643fbbb5f059a2.tar.gz emacs-f269bc61c10320cf020e0751e6643fbbb5f059a2.zip | |
* unexelf.c: Don't assume ElfW (Half) fits in int.
(entry_address, find_section, unexec): Use ptrdiff_t, not int,
when dealing with ElfW (Half) values, since they can exceed 2**31
on 64-bit OpenBSD hosts. Problem reported privately by Han Boetes.
(entry_address): Omit unused NUM arg. All uses changed.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/unexelf.c | 53 |
2 files changed, 34 insertions, 27 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index e2cde630333..55b71844144 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2013-05-07 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | * unexelf.c: Don't assume ElfW (Half) fits in int. | ||
| 4 | (entry_address, find_section, unexec): Use ptrdiff_t, not int, | ||
| 5 | when dealing with ElfW (Half) values, since they can exceed 2**31 | ||
| 6 | on 64-bit OpenBSD hosts. Problem reported privately by Han Boetes. | ||
| 7 | (entry_address): Omit unused NUM arg. All uses changed. | ||
| 8 | |||
| 1 | 2013-05-07 Juri Linkov <juri@jurta.org> | 9 | 2013-05-07 Juri Linkov <juri@jurta.org> |
| 2 | 10 | ||
| 3 | * callint.c (Fcall_interactively): Set `visargs[i]' for code 'n' | 11 | * callint.c (Fcall_interactively): Set `visargs[i]' for code 'n' |
diff --git a/src/unexelf.c b/src/unexelf.c index b2a9878b5e9..4e50bb86367 100644 --- a/src/unexelf.c +++ b/src/unexelf.c | |||
| @@ -522,12 +522,13 @@ typedef struct { | |||
| 522 | # define ElfW(type) ElfExpandBitsW (ELFSIZE, type) | 522 | # define ElfW(type) ElfExpandBitsW (ELFSIZE, type) |
| 523 | #endif | 523 | #endif |
| 524 | 524 | ||
| 525 | /* The code often converts ElfW (Half) values like e_shentsize to int; | 525 | /* The code often converts ElfW (Half) values like e_shentsize to ptrdiff_t; |
| 526 | check that this doesn't lose information. */ | 526 | check that this doesn't lose information. */ |
| 527 | #include <intprops.h> | 527 | #include <intprops.h> |
| 528 | #include <verify.h> | 528 | #include <verify.h> |
| 529 | verify ((! TYPE_SIGNED (ElfW (Half)) || INT_MIN <= TYPE_MINIMUM (ElfW (Half))) | 529 | verify ((! TYPE_SIGNED (ElfW (Half)) |
| 530 | && TYPE_MAXIMUM (ElfW (Half)) <= INT_MAX); | 530 | || PTRDIFF_MIN <= TYPE_MINIMUM (ElfW (Half))) |
| 531 | && TYPE_MAXIMUM (ElfW (Half)) <= PTRDIFF_MAX); | ||
| 531 | 532 | ||
| 532 | #ifdef UNEXELF_DEBUG | 533 | #ifdef UNEXELF_DEBUG |
| 533 | # define DEBUG_LOG(expr) fprintf (stderr, #expr " 0x%jx\n", (uintmax_t) (expr)) | 534 | # define DEBUG_LOG(expr) fprintf (stderr, #expr " 0x%jx\n", (uintmax_t) (expr)) |
| @@ -561,22 +562,18 @@ verify ((! TYPE_SIGNED (ElfW (Half)) || INT_MIN <= TYPE_MINIMUM (ElfW (Half))) | |||
| 561 | */ | 562 | */ |
| 562 | 563 | ||
| 563 | static void * | 564 | static void * |
| 564 | entry_address (void *section_h, int idx, int num, int entsize) | 565 | entry_address (void *section_h, ptrdiff_t idx, ptrdiff_t entsize) |
| 565 | { | 566 | { |
| 566 | char *h = section_h; | 567 | char *h = section_h; |
| 567 | ptrdiff_t n = idx; | 568 | return h + idx * entsize; |
| 568 | return h + entsize * n; | ||
| 569 | } | 569 | } |
| 570 | 570 | ||
| 571 | #define OLD_SECTION_H(n) \ | 571 | #define OLD_SECTION_H(n) \ |
| 572 | (*(ElfW (Shdr) *) entry_address (old_section_h, n, old_file_h->e_shnum, \ | 572 | (*(ElfW (Shdr) *) entry_address (old_section_h, n, old_file_h->e_shentsize)) |
| 573 | old_file_h->e_shentsize)) | ||
| 574 | #define NEW_SECTION_H(n) \ | 573 | #define NEW_SECTION_H(n) \ |
| 575 | (*(ElfW (Shdr) *) entry_address (new_section_h, n, new_file_h->e_shnum, \ | 574 | (*(ElfW (Shdr) *) entry_address (new_section_h, n, new_file_h->e_shentsize)) |
| 576 | new_file_h->e_shentsize)) | ||
| 577 | #define NEW_PROGRAM_H(n) \ | 575 | #define NEW_PROGRAM_H(n) \ |
| 578 | (*(ElfW (Phdr) *) entry_address (new_program_h, n, new_file_h->e_phnum, \ | 576 | (*(ElfW (Phdr) *) entry_address (new_program_h, n, new_file_h->e_phentsize)) |
| 579 | new_file_h->e_phentsize)) | ||
| 580 | 577 | ||
| 581 | #define PATCH_INDEX(n) ((n) += old_bss_index <= (n)) | 578 | #define PATCH_INDEX(n) ((n) += old_bss_index <= (n)) |
| 582 | typedef unsigned char byte; | 579 | typedef unsigned char byte; |
| @@ -599,12 +596,12 @@ round_up (ElfW (Addr) x, ElfW (Addr) y) | |||
| 599 | If we don't find the section NAME, that is a fatal error | 596 | If we don't find the section NAME, that is a fatal error |
| 600 | if NOERROR is false; return -1 if NOERROR is true. */ | 597 | if NOERROR is false; return -1 if NOERROR is true. */ |
| 601 | 598 | ||
| 602 | static int | 599 | static ptrdiff_t |
| 603 | find_section (const char *name, const char *section_names, const char *file_name, | 600 | find_section (const char *name, const char *section_names, const char *file_name, |
| 604 | ElfW (Ehdr) *old_file_h, ElfW (Shdr) *old_section_h, | 601 | ElfW (Ehdr) *old_file_h, ElfW (Shdr) *old_section_h, |
| 605 | bool noerror) | 602 | bool noerror) |
| 606 | { | 603 | { |
| 607 | int idx; | 604 | ptrdiff_t idx; |
| 608 | 605 | ||
| 609 | for (idx = 1; idx < old_file_h->e_shnum; idx++) | 606 | for (idx = 1; idx < old_file_h->e_shnum; idx++) |
| 610 | { | 607 | { |
| @@ -662,14 +659,15 @@ unexec (const char *new_name, const char *old_name) | |||
| 662 | ElfW (Off) old_bss_offset; | 659 | ElfW (Off) old_bss_offset; |
| 663 | ElfW (Word) new_data2_incr; | 660 | ElfW (Word) new_data2_incr; |
| 664 | 661 | ||
| 665 | int n, nn; | 662 | ptrdiff_t n, nn; |
| 666 | int old_bss_index, old_sbss_index, old_plt_index; | 663 | ptrdiff_t old_bss_index, old_sbss_index, old_plt_index; |
| 667 | int old_data_index, new_data2_index; | 664 | ptrdiff_t old_data_index, new_data2_index; |
| 668 | #if defined _SYSTYPE_SYSV || defined __sgi | 665 | #if defined _SYSTYPE_SYSV || defined __sgi |
| 669 | int old_mdebug_index; | 666 | ptrdiff_t old_mdebug_index; |
| 670 | #endif | 667 | #endif |
| 671 | struct stat stat_buf; | 668 | struct stat stat_buf; |
| 672 | off_t old_file_size; | 669 | off_t old_file_size; |
| 670 | int mask; | ||
| 673 | 671 | ||
| 674 | /* Open the old file, allocate a buffer of the right size, and read | 672 | /* Open the old file, allocate a buffer of the right size, and read |
| 675 | in the file contents. */ | 673 | in the file contents. */ |
| @@ -785,7 +783,7 @@ unexec (const char *new_name, const char *old_name) | |||
| 785 | new_data2_incr = new_data2_size + (new_data2_offset - old_bss_offset); | 783 | new_data2_incr = new_data2_size + (new_data2_offset - old_bss_offset); |
| 786 | 784 | ||
| 787 | #ifdef UNEXELF_DEBUG | 785 | #ifdef UNEXELF_DEBUG |
| 788 | fprintf (stderr, "old_bss_index %d\n", old_bss_index); | 786 | fprintf (stderr, "old_bss_index %td\n", old_bss_index); |
| 789 | DEBUG_LOG (old_bss_addr); | 787 | DEBUG_LOG (old_bss_addr); |
| 790 | DEBUG_LOG (old_bss_size); | 788 | DEBUG_LOG (old_bss_size); |
| 791 | DEBUG_LOG (old_bss_offset); | 789 | DEBUG_LOG (old_bss_offset); |
| @@ -840,9 +838,9 @@ unexec (const char *new_name, const char *old_name) | |||
| 840 | 838 | ||
| 841 | #ifdef UNEXELF_DEBUG | 839 | #ifdef UNEXELF_DEBUG |
| 842 | DEBUG_LOG (old_file_h->e_shoff); | 840 | DEBUG_LOG (old_file_h->e_shoff); |
| 843 | fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum); | 841 | fprintf (stderr, "Old section count %td\n", (ptrdiff_t) old_file_h->e_shnum); |
| 844 | DEBUG_LOG (new_file_h->e_shoff); | 842 | DEBUG_LOG (new_file_h->e_shoff); |
| 845 | fprintf (stderr, "New section count %d\n", new_file_h->e_shnum); | 843 | fprintf (stderr, "New section count %td\n", (ptrdiff_t) new_file_h->e_shnum); |
| 846 | #endif | 844 | #endif |
| 847 | 845 | ||
| 848 | /* Fix up a new program header. Extend the writable data segment so | 846 | /* Fix up a new program header. Extend the writable data segment so |
| @@ -1089,8 +1087,9 @@ temacs: | |||
| 1089 | if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG | 1087 | if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG |
| 1090 | && old_mdebug_index != -1) | 1088 | && old_mdebug_index != -1) |
| 1091 | { | 1089 | { |
| 1092 | int diff = NEW_SECTION_H (nn).sh_offset | 1090 | ptrdiff_t new_offset = NEW_SECTION_H (nn).sh_offset; |
| 1093 | - OLD_SECTION_H (old_mdebug_index).sh_offset; | 1091 | ptrdiff_t old_offset = OLD_SECTION_H (old_mdebug_index).sh_offset; |
| 1092 | ptrdiff_t diff = new_offset - old_offset; | ||
| 1094 | HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base); | 1093 | HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base); |
| 1095 | 1094 | ||
| 1096 | if (diff) | 1095 | if (diff) |
| @@ -1170,7 +1169,7 @@ temacs: | |||
| 1170 | || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) | 1169 | || NEW_SECTION_H (nn).sh_type == SHT_DYNSYM) |
| 1171 | { | 1170 | { |
| 1172 | ElfW (Shdr) *spt = &NEW_SECTION_H (nn); | 1171 | ElfW (Shdr) *spt = &NEW_SECTION_H (nn); |
| 1173 | unsigned int num = spt->sh_size / spt->sh_entsize; | 1172 | ptrdiff_t num = spt->sh_size / spt->sh_entsize; |
| 1174 | ElfW (Sym) * sym = (ElfW (Sym) *) (NEW_SECTION_H (nn).sh_offset + | 1173 | ElfW (Sym) * sym = (ElfW (Sym) *) (NEW_SECTION_H (nn).sh_offset + |
| 1175 | new_base); | 1174 | new_base); |
| 1176 | for (; num--; sym++) | 1175 | for (; num--; sym++) |
| @@ -1326,9 +1325,9 @@ temacs: | |||
| 1326 | if (stat (new_name, &stat_buf) != 0) | 1325 | if (stat (new_name, &stat_buf) != 0) |
| 1327 | fatal ("Can't stat (%s): %s", new_name, strerror (errno)); | 1326 | fatal ("Can't stat (%s): %s", new_name, strerror (errno)); |
| 1328 | 1327 | ||
| 1329 | n = umask (777); | 1328 | mask = umask (777); |
| 1330 | umask (n); | 1329 | umask (mask); |
| 1331 | stat_buf.st_mode |= 0111 & ~n; | 1330 | stat_buf.st_mode |= 0111 & ~mask; |
| 1332 | if (chmod (new_name, stat_buf.st_mode) != 0) | 1331 | if (chmod (new_name, stat_buf.st_mode) != 0) |
| 1333 | fatal ("Can't chmod (%s): %s", new_name, strerror (errno)); | 1332 | fatal ("Can't chmod (%s): %s", new_name, strerror (errno)); |
| 1334 | } | 1333 | } |