aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2013-05-07 13:55:47 -0700
committerPaul Eggert2013-05-07 13:55:47 -0700
commitf269bc61c10320cf020e0751e6643fbbb5f059a2 (patch)
tree11e6fc1d07a35c822778784350fa8a3285e30e0e /src
parenta261c53eaefb9f2d0a5e9175827b12ddefddbb7f (diff)
downloademacs-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/ChangeLog8
-rw-r--r--src/unexelf.c53
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 @@
12013-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
12013-05-07 Juri Linkov <juri@jurta.org> 92013-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>
529verify ((! TYPE_SIGNED (ElfW (Half)) || INT_MIN <= TYPE_MINIMUM (ElfW (Half))) 529verify ((! 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
563static void * 564static void *
564entry_address (void *section_h, int idx, int num, int entsize) 565entry_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))
582typedef unsigned char byte; 579typedef 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
602static int 599static ptrdiff_t
603find_section (const char *name, const char *section_names, const char *file_name, 600find_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}