Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 353718 - dev-util/elfkickers: elfls overflows integers when used over some sstrip'd files
Summary: dev-util/elfkickers: elfls overflows integers when used over some sstrip'd files
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: New packages (show other bugs)
Hardware: All Linux
: High normal (vote)
Assignee: Anthony Basile
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-04 20:49 UTC by Diego Elio Pettenò (RETIRED)
Modified: 2011-02-13 14:15 UTC (History)
1 user (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Diego Elio Pettenò (RETIRED) gentoo-dev 2011-02-04 20:49:19 UTC
This happens with the dynamic_executable_sstrip from the Ruby-Elf testsuite[1], because the .note section is set having a 0-size, which causes an allocation error:

[1] http://www.flameeyes.eu/projects/ruby-elf


(gdb) break exit
Breakpoint 1 at 0x7ffff7aa63f0: file exit.c, line 100.
(gdb) r
Starting program: /usr/bin/elfls tests/data/linux/amd64/gcc/dynamic_executable_sstrip
tests/data/linux/amd64/gcc/dynamic_executable_sstrip* (?62)
Program header table entries: 10 (40 - 270)
Out of memory!

Breakpoint 1, exit (status=1) at exit.c:100
100	exit.c: No such file or directory.
	in exit.c
(gdb) bt
#0  exit (status=1) at exit.c:100
#1  0x00000000004012f8 in getstring (offset=511, size=18446744073709551604, skip=0) at elfls.c:248
#2  0x0000000000401f18 in describephdr (argc=<value optimized out>, argv=<value optimized out>) at elfls.c:647
#3  main (argc=<value optimized out>, argv=<value optimized out>) at elfls.c:867
(gdb) frame 2
#2  0x0000000000401f18 in describephdr (argc=<value optimized out>, argv=<value optimized out>) at elfls.c:647
647	elfls.c: No such file or directory.
	in elfls.c
(gdb) print phdr
$1 = (Elf64_Phdr *) 0x605368
(gdb) print phdr->p_offset
$2 = 499
(gdb) print phdr->p_filesz
$3 = 0

Code:
          case PT_NOTE:
            str = getstring(phdr->p_offset + 12,
                            phdr->p_filesz - 12, FALSE);
            if (str && *str) {

readelf -l fragment of the file's NOTE PH

  NOTE           0x00000000000001f3 0x000000000040028c 0x000000000040028c
                 0x0000000000000000 0x0000000000000020  R      4
Comment 1 Anthony Basile gentoo-dev 2011-02-08 14:49:56 UTC
Okay, easy fix with possibly subtle consequences.  Let me bounce my solution off of you before I commit.

On line 648 we have:

            str = getstring(phdr->p_offset + 12,
                            phdr->p_filesz - 12, FALSE);

and on line 236+ we have:

static char const *getstring(unsigned long offset, unsigned long size,
                             int skip)

    ...

    if (!size)
        return "";

When phdr->p_filesz - 12 is less than 0, this returns a negative number which is mapped to a very large positive number when cast as an unsigned long.  Thus changing the check to

    if (size <= 0) {
        return "";
    }

doesn't work.  But

    if ((long)size <= 0) {
        return "";
    }

does.

Alternatively, one can change the declaration of size from unsigned long to just long in the function header of getstring.  phdr is of type Elf{32,64}_Phdr and p_filesz is of type Elf{32,64}_Word which is typedef uint32_t.  Since sizeof(unsigned long) is 8 and sizeof(uint32_t) is 4, the redeclaration should be safe.  Similarly, it should be safe to declare offset just long as well and add a sanity check for it.

I'm leaning towards my second solution.  Comments?

Comment 2 Diego Elio Pettenò (RETIRED) gentoo-dev 2011-02-12 22:13:18 UTC
Redeclaration looks fine to me.
Comment 3 Anthony Basile gentoo-dev 2011-02-13 14:15:22 UTC
Okay, the fix is in the tree.  I tested it and it worked.  Please reopen if you find anything wrong.