Re: [PATCH] libelf/elf_end.c: check data_list.data.d.d_buf before free it

2018-08-20 Thread Robert Yang




On 08/17/2018 06:10 PM, Mark Wielaard wrote:

Hi Robert,

[I don't have very good internet connectivity so cannot easily get all
  the bits and sources to replicate/inspect. So apologies if I am
  misinterpreting something.]

On Fri, Aug 17, 2018 at 04:25:07PM +0800, Robert Yang wrote:

On 08/17/2018 03:25 AM, Mark Wielaard wrote:

On Thu, Aug 16, 2018 at 10:34:23AM +0800, Robert Yang wrote:

The one which actually saves the data is data_list.data.d.d_buf, so check it
before free rawdata_base.

This can fix a segmentation fault when prelink libqb_1.0.3:
prelink: /usr/lib/libqb.so.0.18.2: Symbol section index outside of section 
numbers

The segmentation fault happens when prelink call elf_end().


Could you run your reproducer under valgrind and show what it
says before your patch? And/Or post the file (libqb) to replicate
the reproducer somewhere to see exactly what goes wrong?

I don't fully understand what is going wrong. Is the section data
pointing to the file data or something created by elf_newdata?


Thanks for the reply, I found this problem in a cross build environment,
but we are using elfutils as native tool (directly running on host), its
version is 0.172, srcrev=01e87ab4c5a6a249c04e22a97a4221d3.

$ VALGRIND_LIB=/path/to/usr/lib/valgrind valgrind prelink --root
/path/to/core-image-minimal/1.0-r0/rootfs -amR -N -c /etc/prelink.conf
--dynamic-linker /lib/ld-linux-x86-64.so.2 -v

Here are the problems related to elfutils:

prelink: /usr/lib/libqb.so.0.19.0: Symbol section index outside of section 
numbers
==25330== Invalid free() / delete / delete[] / realloc()
==25330==at 0x4C3026B: free (in 
/path/to/recipe-sysroot-native/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25330==by 0x50991F5: elf_end (elf_end.c:171)
==25330==by 0x41E916: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x422233: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x408BE1: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x409015: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x4038FB: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x52CF04A: (below main) (in 
/buildarea1/lyang1/test_up/tmp/sysroots-uninative/x86_64-linux/lib/libc-2.27.so)
==25330==  Address 0x9305300 is 0 bytes inside a block of size 20 free'd
==25330==at 0x4C3026B: free (in 
/path/to/recipe-sysroot-native/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25330==by 0x41E8B7: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x422233: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x408BE1: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x409015: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x4038FB: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x52CF04A: (below main) (in 
/buildarea1/lyang1/test_up/tmp/sysroots-uninative/x86_64-linux/lib/libc-2.27.so)
==25330==  Block was alloc'd at
==25330==at 0x4C2F03F: malloc (in 
/path/to/recipe-sysroot-native/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==25330==by 0x509DE8E: __libelf_set_rawdata_wrlock (elf_getdata.c:329)
==25330==by 0x509E20E: __elf_getdata_rdlock (elf_getdata.c:532)
==25330==by 0x509E24D: elf_getdata (elf_getdata.c:559)
==25330==by 0x420A70: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x413860: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x408D64: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x409015: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x4038FB: ??? (in 
/path/to/recipe-sysroot-native/usr/sbin/prelink)
==25330==by 0x52CF04A: (below main) (in 
/buildarea1/lyang1/test_up/tmp/sysroots-uninative/x86_64-linux/lib/libc-2.27.so)


Thanks, that does suggest to me there is a bug in prelink.
Although it isn't completely clear. If you could run the same with
prelink debuginfo so we can see the source lines that would be great.

The reason I think this is a prelink issues is because it looks like
it is calling elf_getdata () to get the data, and then frees the buffer.
The idea is that you only own the data of an elf section if you created
it yourself with elf_newdata (). Otherwise, as seems to have happened
here, libelf owns the data buffer and has to free it.

I think that prelink is preparing the ELF file, but then half way
through encounters an error. It then frees all the ELF section data it
believed it created itself. But because of the error it probably didn't
(yet) do that. And so frees some data that it got directly from
elf_getdata () and didn't create itself. Then it calls elf_end () and
libelf also thinks it owns that data and frees it again.

It probably only happens when prelink encounters some other issue while
processing a file.


Yes, I 

Accessing String Table Indexes for .rodata

2018-08-20 Thread Henry C
Hi,

I have a sample code like this:
#include 

void myprintf(const char* ptr) {
printf("%p\n", ptr);
}

int main() {
myprintf("hello world");
myprintf("\0\0");
myprintf("ab\0cde");
}

I would like to access the .rodata by using elf.h.  Someone told me
this is the right place to ask how.  If not, please do let me know.

I am able to access the string table for .rodata section by calling my function:
void print_rodata_table64(int32_t fd,
Elf64_Ehdr eh,
Elf64_Shdr sh_table[],
uint32_t indexToRodata)
{
char* sh_str; /* section-header string-table is also a section. */

/* Read section-header string-table */
Elf64_Shdr& sh = sh_table[indexToRodata];
sh_str = malloc(sh.sh_size);
lseek(fd, (off_t)sh.sh_offset, SEEK_SET);
read(fd, (void *)sh_str, sh.sh_size);
for (uint64_t i = 0; i < sh.sh_size; i++) {
printf("data[%lu]=%u|%c\n", i, (uint32_t)sh_str[i], sh_str[i]);
}
}

Tho, I have no clue how to get the index to each of the string in the
string table above.

Any sample code or pointer is highly appreciated!

And one more related question is that I noticed the virtual memory
addresses of the string literals are same as the offsets to the
(executable) file.  Is it intended?  Guaranteed?


Thanks!