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

2018-08-15 Thread Robert Yang
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().

Signed-off-by: Robert Yang 
---
 libelf/elf_end.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libelf/elf_end.c b/libelf/elf_end.c
index 160f0b8..5388e80 100644
--- a/libelf/elf_end.c
+++ b/libelf/elf_end.c
@@ -165,9 +165,10 @@ elf_end (Elf *elf)
 
/* The section data is allocated if we couldn't mmap
   the file.  Or if we had to decompress.  */
-   if (elf->map_address == NULL
+   if ((elf->map_address == NULL
|| scn->rawdata_base == scn->zdata_base
|| (scn->flags & ELF_F_MALLOCED) != 0)
+   && (scn->data_list.data.d.d_buf != NULL))
  free (scn->rawdata_base);
 
/* Free the list of data buffers for the section.
-- 
2.7.4



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

2018-08-17 Thread Robert Yang




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

Hi,

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)



// Robert



Thanks,

Mark



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 issu

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

2018-08-29 Thread Robert Yang
* V2
  - Also check data_list.data.d.d_buf before free scn->data_base, this can fix
prelink error libqb_1.0.3 on mips and mips64.

* V1
  - Initial version

Robert Yang (1):
  libelf/elf_end.c: check data_list.data.d.d_buf before free it

 libelf/elf_end.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

-- 
2.7.4



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

2018-08-29 Thread Robert Yang
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().

Signed-off-by: Robert Yang 
---
 libelf/elf_end.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/libelf/elf_end.c b/libelf/elf_end.c
index 160f0b8..5280a70 100644
--- a/libelf/elf_end.c
+++ b/libelf/elf_end.c
@@ -160,14 +160,16 @@ elf_end (Elf *elf)
   architecture doesn't require overly stringent
   alignment the raw data buffer is the same as the
   one used for presenting to the caller.  */
-   if (scn->data_base != scn->rawdata_base)
+   if ((scn->data_base != scn->rawdata_base)
+   && (scn->data_list.data.d.d_buf != NULL))
  free (scn->data_base);
 
/* The section data is allocated if we couldn't mmap
   the file.  Or if we had to decompress.  */
-   if (elf->map_address == NULL
+   if ((elf->map_address == NULL
|| scn->rawdata_base == scn->zdata_base
|| (scn->flags & ELF_F_MALLOCED) != 0)
+   && (scn->data_list.data.d.d_buf != NULL))
  free (scn->rawdata_base);
 
/* Free the list of data buffers for the section.
-- 
2.7.4



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

2018-08-30 Thread Robert Yang




On 08/31/2018 03:57 AM, Mark Wielaard wrote:

On Wed, Aug 29, 2018 at 04:53:20PM +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().


Are you sure this isn't a bug in prelink like we discussed last time?
If it isn't, can you give a short example how this issue happens?


Sorry, I can't make sure which ones is wrong, libqb, prelink or elfutils, this
happens when cross compiling, and I've built more than 4 hunderds of packages,
libqb 1.0.3 is the only package which has the problem, I've also fixed prelink,
but it is another segmentation fault error. I've reported this problem to libqb
community, then they make another branch for libqb, and it works well without
any errors, the branch is topic-no-ldsection, and the commit is:
https://github.com/ClusterLabs/libqb/commit/358e0120d8cd288095907869d3f8da92937188a0

I've used gdb/valgrind to debug this segfault, but can't find prelink's distinct
problem, the only problem I found is that elfutil's elf_end() free() a NULL
memory, so I made this patch.

I think that someone who uses libqb_1.0.3 + elfutils + prelink + crosscompile
would meet the same problem.

// Robert



Thanks,

Mark



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

2018-09-02 Thread Robert Yang




On 08/31/2018 05:35 PM, Mark Wielaard wrote:

Hi Robert,

On Fri, 2018-08-31 at 10:17 +0800, Robert Yang wrote:

Sorry, I can't make sure which ones is wrong, libqb, prelink or
elfutils, this
happens when cross compiling, and I've built more than 4 hunderds of packages,
libqb 1.0.3 is the only package which has the problem, I've also fixed prelink,
but it is another segmentation fault error. I've reported this problem to libqb
community, then they make another branch for libqb, and it works well without
any errors, the branch is topic-no-ldsection, and the commit is:
https://github.com/ClusterLabs/libqb/commit/358e0120d8cd288095907869d3f8da92937188a0


So, this is a separate issue? Or does the prelink problem also go away
when using that commit/branch?


I've used gdb/valgrind to debug this segfault, but can't find prelink's distinct
problem, the only problem I found is that elfutil's elf_end() free() a NULL
memory, so I made this patch.


OK. So I believe that is because prelink's error handling seems wrong.
It seems to assume it adding the ELF data buffer itself, so frees it,
but the data actually seemed to come from elf_getdata, so shouldn't
have been freed by prelink.


Thanks, I will investigate that.

// Robert



Thanks,

Mark