Bug 195653

Summary: elftoolchain strip(1) sometimes corrupts a segment's phdr p_memsz
Product: Base System Reporter: Ed Maste <emaste>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me CC: jkoshy, kaiw
Priority: ---    
Version: CURRENT   
Hardware: Any   
OS: Any   
See Also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=191587
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=227552
Bug Depends on:    
Bug Blocks: 195561    

Description Ed Maste freebsd_committer freebsd_triage 2014-12-03 20:21:28 UTC
See PR195661 for an exp-run with WITH_ELFTOOLCHAIN_TOOLS=yes
Antoine found that make and csh segfaultPR195561)

Make, before running elftoolchain strip:

% feynman% readelf -l make.orig                                            
% 
% Elf file type is EXEC (Executable file)
% Entry point 0x4001a0
% There are 5 program headers, starting at offset 64
% 
% Program Headers:
%   Type           Offset             VirtAddr           PhysAddr
%                  FileSiz            MemSiz              Flags  Align
%   LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
%                  0x000000000009185c 0x000000000009185c  R E    200000
%   LOAD           0x0000000000091860 0x0000000000691860 0x0000000000691860
%                  0x0000000000003680 0x0000000000013118  RW     200000
%   NOTE           0x0000000000000158 0x0000000000400158 0x0000000000400158
%                  0x0000000000000030 0x0000000000000030  R      4
%   TLS            0x0000000000091860 0x0000000000691860 0x0000000000691860
%                  0x0000000000000004 0x0000000000000088  R      10
%   GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
%                  0x0000000000000000 0x0000000000000000  RW     8
% 
%  Section to Segment mapping:
%   Segment Sections...
%    00     .note.tag .init .text .fini .rodata .eh_frame 
%    01     .tdata .ctors .dtors .jcr .got.plt .data .bss 
%    02     .note.tag 
%    03     .tdata .tbss 
%    04     

After strip(1):

% feynman% readelf -l make                                                 
% 
% Elf file type is EXEC (Executable file)
% Entry point 0x4001a0
% There are 5 program headers, starting at offset 64
% 
% Program Headers:
%   Type           Offset             VirtAddr           PhysAddr
%                  FileSiz            MemSiz              Flags  Align
%   LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
%                  0x000000000009185c 0x000000000009185c  R E    200000
%   LOAD           0x0000000000091860 0x0000000000691860 0x0000000000691860
%                  0x0000000000003680 0x0000000000013118  RW     200000
%   NOTE           0x0000000000000158 0x0000000000400158 0x0000000000400158
%                  0x0000000000000030 0x0000000000000030  R      4
%   TLS            0x0000000000091860 0x0000000000691860 0x0000000000691860
%                  0x0000000000000004 0x000000000000007c  R      10
%   GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
%                  0x0000000000000000 0x0000000000000000  RW     8
% 
%  Section to Segment mapping:
%   Segment Sections...
%    00     .note.tag .init .text .fini .rodata .eh_frame 
%    01     .tdata .ctors .dtors .jcr .got.plt .data .bss 
%    02     .note.tag 
%    03     .tdata 
%    04     

Note TLS MemSiz 0x88 -> 0x7c and segment 03 dropped .tbss
Comment 1 Ed Maste freebsd_committer freebsd_triage 2014-12-03 20:54:34 UTC
similar cases:

lib/libcrypto.so.7
--- unstripped  2014-12-03 15:52:45.668140759 -0500
+++ stripped    2014-12-03 15:52:45.721733291 -0500
@@ -9,7 +9,7 @@
   LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                  0x00000000001ca3a4 0x00000000001ca3a4  R E    200000
   LOAD           0x00000000001cb000 0x00000000003cb000 0x00000000003cb000
-                 0x0000000000027268 0x0000000000029d50  RW     200000
+                 0x0000000000027268 0x0000000000029d48  RW     200000
   DYNAMIC        0x00000000001e3348 0x00000000003e3348 0x00000000003e3348
                  0x00000000000001a0 0x00000000000001a0  RW     8
   GNU_EH_FRAME   0x000000000019b374 0x000000000019b374 0x000000000019b374
@@ -20,7 +20,7 @@
  Section to Segment mapping:
   Segment Sections...
    00     .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 
-   01     .ctors .dtors .jcr .data.rel.ro .dynamic .got .got.plt .data .bss 
+   01     .ctors .dtors .jcr .data.rel.ro .dynamic .got .got.plt .data 
    02     .dynamic 
    03     .eh_frame_hdr 
    04     

lib/libc.so.7
--- unstripped  2014-12-03 15:52:45.619139832 -0500
+++ stripped    2014-12-03 15:52:45.620140128 -0500
@@ -13,7 +13,7 @@
   DYNAMIC        0x000000000016f168 0x000000000036f168 0x000000000036f168
                  0x0000000000000190 0x0000000000000190  RW     8
   TLS            0x000000000016a000 0x000000000036a000 0x000000000036a000
-                 0x0000000000000004 0x00000000000000a0  R      10
+                 0x0000000000000004 0x0000000000000094  R      10
   GNU_EH_FRAME   0x0000000000146be4 0x0000000000146be4 0x0000000000146be4
                  0x000000000000685c 0x000000000000685c  R      4
   GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
@@ -24,6 +24,6 @@
    00     .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_d .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 
    01     .tdata .ctors .dtors .jcr .data.rel.ro .dynamic .got .got.plt .data .bss 
    02     .dynamic 
-   03     .tdata .tbss 
+   03     .tdata 
    04     .eh_frame_hdr 
    05
Comment 2 commit-hook freebsd_committer freebsd_triage 2014-12-15 18:19:07 UTC
A commit references this bug:

Author: emaste
Date: Mon Dec 15 18:18:58 UTC 2014
New revision: 275810
URL: https://svnweb.freebsd.org/changeset/base/275810

Log:
  Correct elftoolchain strip(1) memory size calculation

  Calculate the segment's memory size (p_memsz) using the virtual
  addresses, not the file offsets. Otherwise padding preceeding SHT_NOBITS
  sections may be excluded from the calculation, resulting in a segment
  that is too small.

  PR:		195653
  Sponsored by:	The FreeBSD Foundation

Changes:
  head/contrib/elftoolchain/elfcopy/segments.c