public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [Bug libelf/31225] New: Crash when using elf_memory() on a compressed section; fixed with s/ELF_C_READ/ELF_C_READ_MMAP/
@ 2024-01-09 18:52 bruening at google dot com
  2024-01-23 13:55 ` [Bug libelf/31225] " mark at klomp dot org
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: bruening at google dot com @ 2024-01-09 18:52 UTC (permalink / raw)
  To: elfutils-devel

https://sourceware.org/bugzilla/show_bug.cgi?id=31225

            Bug ID: 31225
           Summary: Crash when using elf_memory() on a compressed section;
                    fixed with s/ELF_C_READ/ELF_C_READ_MMAP/
           Product: elfutils
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: libelf
          Assignee: unassigned at sourceware dot org
          Reporter: bruening at google dot com
                CC: elfutils-devel at sourceware dot org
  Target Milestone: ---

When setting up libelf with elf_memory() we observe repeatable crashes on any
compressed debug section.  The problem seems to be from elf_memory() using the
ELF_C_READ command, which is not really supported: elf32_getshdr.c looks for
ELF_C_READ_MMAP instead and makes a copy of read-only data in that case.

Changing elf_memory() to pass ELF_C_READ_MMAP solves the problem:

--------------------------------------------------------------
diff --git a/libelf/elf_memory.c b/libelf/elf_memory.c
index a47f1d24..13d77cb7 100644
--- a/libelf/elf_memory.c
+++ b/libelf/elf_memory.c
@@ -46,5 +46,5 @@ elf_memory (char *image, size_t size)
       return NULL;
     }

-  return __libelf_read_mmaped_file (-1, image, 0, size, ELF_C_READ, NULL);
+  return __libelf_read_mmaped_file (-1, image, 0, size, ELF_C_READ_MMAP,
NULL);
 }
--------------------------------------------------------------

There seem to not be any tests of elf_memory() either so maybe there are few
users and that is why no one else has hit this.

More details on the crash which is hit examining ld-linux-x86-64.so.2 which has
compressed sections on this machine:

--------------------------------------------------------------
Program received signal SIGSEGV, Segmentation fault.                            
0x0000555555584764 in elf_compress (scn=scn@entry=0x5555555fa6a8,
type=type@entry=0, flags=flags@entry=0) at elf_compress.c:732
732               shdr->sh_size = scn->zdata_size;                              
(gdb) bt                                                                        
#0  0x0000555555584764 in elf_compress (scn=scn@entry=0x5555555fa6a8,
type=type@entry=0, flags=flags@entry=0) at elf_compress.c:732
#1  0x0000555555575cba in check_section (result=result@entry=0x5555555f8440,
shstrndx=shstrndx@entry=31, scn=scn@entry=0x5555555fa6a8,
inscngrp=inscngrp@entry=false)
    at dwarf_begin_elf.c:238                                                    
#2  0x0000555555576480 in global_read (shstrndx=<optimized out>, elf=<optimized
out>, result=0x5555555f8440) at dwarf_begin_elf.c:452
#3  dwarf_begin_elf (elf=0x5555555f94c0, cmd=DWARF_C_READ, scngrp=0x0) at
dwarf_begin_elf.c:603
(gdb) list                                                                      
727               shdr->sh_flags &= ~SHF_COMPRESSED;                   
728             }                                                               
729           else                                                              
730             {                                                               
731               Elf64_Shdr *shdr = elf64_getshdr (scn);                     
732               shdr->sh_size = scn->zdata_size;                              
733               shdr->sh_addralign = scn->zdata_align;                     
734               shdr->sh_flags &= ~SHF_COMPRESSED;             
735             }                                                               
736                                                                             
(gdb) p shdr                                                                    
$1 = (Elf64_Shdr *) 0x7ffdf79bdc88                                              
(gdb) p *shdr                                                                   
$2 = {                                                                          
  sh_name = 214,                                                                
  sh_type = 1,                                                                  
  sh_flags = 2048,                                                              
  sh_addr = 0,                                                                  
  sh_offset = 640,                                                              
  sh_size = 1151,                                                               
  sh_link = 0,                                                                  
  sh_info = 0,                                                                  
  sh_addralign = 8,                                                             
  sh_entsize = 0                                                                
}                                                                               
(gdb) memquery shdr                                                             
7ffdf7939000-7ffdf79be000 r--p 00000000 fe:01 21499176                  
/usr/lib/debug/.build-id/ac/cffc5784c4a469d09348e3f7ec53a74096fbd3.debug
--------------------------------------------------------------

They do seem to be compressed:
--------------------------------------------------------------
$ readelf -S
/usr/lib/debug/.build-id/ac/cffc5784c4a469d09348e3f7ec53a74096fbd3.debug
  [21] .debug_aranges    PROGBITS         0000000000000000  00000280
       000000000000047f  0000000000000000   C       0     0     8
  [22] .debug_info       PROGBITS         0000000000000000  00000700
       0000000000054087  0000000000000000   C       0     0     8
  [23] .debug_abbrev     PROGBITS         0000000000000000  00054788
       000000000000451e  0000000000000000   C       0     0     8
  [24] .debug_line       PROGBITS         0000000000000000  00058ca8
       000000000000fdbe  0000000000000000   C       0     0     8
  [25] .debug_str        PROGBITS         0000000000000000  00068a68
       00000000000037e6  0000000000000001 MSC       0     0     8
  [26] .debug_line_str   PROGBITS         0000000000000000  0006c250
       00000000000006fc  0000000000000001 MSC       0     0     8
  [27] .debug_loclists   PROGBITS         0000000000000000  0006c950
       000000000000f5f2  0000000000000000   C       0     0     8
  [28] .debug_rnglists   PROGBITS         0000000000000000  0007bf48
       00000000000026b6  0000000000000000   C       0     0     8
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  R (retain), D (mbind), l (large), p (processor specific)
--------------------------------------------------------------

Is this fix we found the permanent solution?  I don't know this source code:
not sure why ELF_C_READ exists?  Should it be removed?  If not, should
elf32_getshdr.c and other code consider ELF_C_READ?  Do you want me to submit
this patch plus attempt to add a test, or someone on your end will take this
over?

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2024-02-02 21:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-09 18:52 [Bug libelf/31225] New: Crash when using elf_memory() on a compressed section; fixed with s/ELF_C_READ/ELF_C_READ_MMAP/ bruening at google dot com
2024-01-23 13:55 ` [Bug libelf/31225] " mark at klomp dot org
2024-01-23 22:36 ` bruening at google dot com
2024-02-01 14:39 ` mark at klomp dot org
2024-02-02 20:01 ` bruening at google dot com
2024-02-02 21:45 ` mark at klomp dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).