dl_open segment fault in ubuntu18.10 glibc2.28

Bug #1821677 reported by hongtao.liu on 2019-03-26
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
glibc (Ubuntu)
High
Adam Conrad
Cosmic
Undecided
Unassigned
Disco
High
Adam Conrad

Bug Description

With following testcase:

~/work/glibc$ cat foo.c

#include <dlfcn.h>
#include <stdio.h>

int main(int argc, char **argv) {
  if (argc < 1) return 1;
  printf("Trying to open %s\n", argv[1]);
  void *liball = dlopen(argv[1], RTLD_NOW);
  if(liball == NULL) {
    printf("\nERROR: %s", dlerror());
    return -1;
  }
  if(dlclose(liball)==0) {printf("\n all ok\n");}
  return 0;
}

compile with
~/work/glibc$ gcc -O0 -g foo.c -ldl

then get segment fault:

~/work/glibc$ ./a.out intel64_lin/libsvml.so
Trying to open intel64_lin/libsvml.so
Segmentation fault (core dumped)

coredump as:

(gdb) bt
#0 __GI___libc_free (mem=0x7ffff7d49010) at malloc.c:3085
#1 0x00007ffff7fdb6b6 in open_verify (
    name=0x555555559670 "/home/lilicui/intel64_lin/libsvml.so",
    fbp=fbp@entry=0x7fffffffd530, loader=<optimized out>,
    mode=mode@entry=-1879048190,
    found_other_class=found_other_class@entry=0x7fffffffd51f, free_name=true,
    whatcode=0, fd=3) at dl-load.c:1977
#2 0x00007ffff7fdc926 in _dl_map_object (loader=loader@entry=0x7ffff7ffe190,
    name=name@entry=0x7fffffffe1b7 "/home/lilicui/intel64_lin/libsvml.so",
    type=type@entry=2, trace_mode=trace_mode@entry=0,
    mode=mode@entry=-1879048190, nsid=<optimized out>) at dl-load.c:2401
#3 0x00007ffff7fe79c4 in dl_open_worker (a=a@entry=0x7fffffffdaa0)
    at dl-open.c:228
#4 0x00007ffff7f1b48f in __GI__dl_catch_exception (exception=<optimized out>,
    operate=<optimized out>, args=<optimized out>) at dl-error-skeleton.c:196
#5 0x00007ffff7fe72c6 in _dl_open (
    file=0x7fffffffe1b7 "/home/lilicui/intel64_lin/libsvml.so",
    mode=-2147483646, caller_dlopen=0x5555555551cb <main+86>,
    nsid=<optimized out>, argc=2, argv=0x7fffffffde08, env=0x7fffffffde20)
    at dl-open.c:599
#6 0x00007ffff7faa256 in dlopen_doit (a=a@entry=0x7fffffffdcc0) at dlopen.c:66
#7 0x00007ffff7f1b48f in __GI__dl_catch_exception (
    exception=exception@entry=0x7fffffffdc60, operate=<optimized out>,
--Type <RET> for more, q to quit, c to continue without paging--
    args=<optimized out>) at dl-error-skeleton.c:196
#8 0x00007ffff7f1b51f in __GI__dl_catch_error (
    objname=0x7ffff7fae0f0 <last_result+16>,
    errstring=0x7ffff7fae0f8 <last_result+24>,
    mallocedp=0x7ffff7fae0e8 <last_result+8>, operate=<optimized out>,
    args=<optimized out>) at dl-error-skeleton.c:215
#9 0x00007ffff7faaa25 in _dlerror_run (
    operate=operate@entry=0x7ffff7faa200 <dlopen_doit>,
    args=args@entry=0x7fffffffdcc0) at dlerror.c:163
#10 0x00007ffff7faa2e6 in __dlopen (file=<optimized out>, mode=<optimized out>)
    at dlopen.c:87
#11 0x00005555555551cb in main (argc=2, argv=0x7fffffffde08) at foo.c:7

intel64_lin/libsvml.so is icc19.0(aleady released) runtime library, refer to attachment.

Ubuntu version:

~/work/glibc$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.10
Release: 18.10
Codename: cosmic

Glibc version:

~/work/glibc$ ldd --version
ldd (Ubuntu GLIBC 2.28-0ubuntu1) 2.28
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

It works fine with Glibc_2.28 upstream, and Glibc_2.28 on Fedora 29, but failed with Glibc 2.28 in Ubuntu 18.10

I found ubuntu18.10 was backporting its own patches, would that affect such testcase?

hongtao.liu (liuhongt) on 2019-03-26
information type: Public → Public Security
information type: Public Security → Public
Sunil Pandey (skpgkp1) wrote :
Download full text (7.5 KiB)

This regression caused by following patch. It is mostly arm code but also affecting x86. If I remove this patch segfault will go away.

$ cat unsubmitted-ldso-abi-check.diff
---
 elf/dl-load.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 219 insertions(+)

--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1438,6 +1438,209 @@
     _dl_debug_printf_c ("\t\t(%s)\n", what);
 }

+#ifdef __arm__
+/* Read an unsigned leb128 value from P, store the value in VAL, return
+ P incremented past the value. We assume that a word is large enough to
+ hold any value so encoded; if it is smaller than a pointer on some target,
+ pointers should not be leb128 encoded on that target. */
+static unsigned char *
+read_uleb128 (unsigned char *p, unsigned long *val)
+{
+ unsigned int shift = 0;
+ unsigned char byte;
+ unsigned long result;
+
+ result = 0;
+ do
+ {
+ byte = *p++;
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+ }
+ while (byte & 0x80);
+
+ *val = result;
+ return p;
+}
+
+

+#define ATTR_TAG_FILE 1
+#define ABI_VFP_args 28
+#define VFP_ARGS_IN_VFP_REGS 1
+
+/* Check consistency of ABI in the ARM attributes. Search through the
+ section headers looking for the ARM attributes section, then
+ check the VFP_ARGS attribute. */
+static int
+check_arm_attributes_hfabi(int fd, ElfW(Ehdr) *ehdr, bool *is_hf)
+{
+ unsigned int i;
+ ElfW(Shdr) *shdrs;
+ int sh_size = ehdr->e_shentsize * ehdr->e_shnum;
+
+ /* Load in the section headers so we can look for the attributes
+ * section */
+ shdrs = alloca(sh_size);
+ __lseek (fd, ehdr->e_shoff, SEEK_SET);
+ if ((size_t) __libc_read (fd, (void *) shdrs, sh_size) != sh_size)
+ return -1;
+
+ for (i = 0; i < ehdr->e_shnum; i++)
+ {
+ if (SHT_ARM_ATTRIBUTES == shdrs[i].sh_type)
+ {
+ /* We've found a likely section. Load the contents and
+ * check the tags */
+ unsigned char *contents = alloca(shdrs[i].sh_size);
+ unsigned char *p = contents;
+ unsigned char * end;
+
+ __lseek (fd, shdrs[i].sh_offset, SEEK_SET);
+ if ((size_t) __libc_read (fd, (void *) contents, shdrs[i].sh_size) != shdrs[i].sh_size)
+ return -1;
+
+ /* Sanity-check the attribute section details. Make sure
+ * that it's the "aeabi" section, that's all we care
+ * about. */
+ if (*p == 'A')
+ {
+ unsigned long len = shdrs[i].sh_size - 1;
+ unsigned long namelen;
+ p++;
+
+ while (len > 0)
+ {
+ unsigned long section_len = p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
+ if (section_len > len)
+ {
+ _dl_debug_printf_c (" invalid section len %lu, max remaining %lu\n", section_len, len);
+ section_len = len;
+ }
+
+ p += 4;
+ len -= section_len;
+ section_len -= 4;
+
+ if (0 != strcmp((char *)p, "aeabi"))
+ {
+ _dl_debug_printf_c (" ignoring unknown att...

Read more...

Matthias Klose (doko) on 2019-04-02
Changed in glibc (Ubuntu):
importance: Undecided → High
tags: added: rls-dd-incoming
tags: added: rls-cc-incoming
Sunil Pandey (skpgkp1) wrote :

Attached is small test case to reproduce this issue.

$ tar -Jxvf dl-big-note.tar.xz
dl-big-note/
dl-big-note/dl-big-note-lib.S
dl-big-note/dl-big-note.c
dl-big-note/Makefile
$ cd dl-big-note/
$ make runtest
gcc -c -o dl-big-note-lib.o dl-big-note-lib.S
gcc -shared -o dl-big-note-lib.so dl-big-note-lib.o
gcc -o dl-big-note dl-big-note.c -ldl
./dl-big-note
make: *** [Makefile:10: runtest] Segmentation fault (core dumped)

tags: removed: rls-cc-incoming rls-dd-incoming
tags: added: id-5ca6214756f1b84f8df62a00
Adam Conrad (adconrad) on 2019-04-08
Changed in glibc (Ubuntu Disco):
assignee: nobody → Adam Conrad (adconrad)
status: New → Fix Committed
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package glibc - 2.29-0ubuntu2

---------------
glibc (2.29-0ubuntu2) disco; urgency=medium

  * debian/patches/git-updates.diff: Update from upstream stable branch,
    including "S390: Mark vx and vxe as important hwcap" (LP: #1821200)
  * debian/testsuite-xfail-debian.mk: XFAIL new tst-nss-test3 for disco.
  * debian/debhelper.in/libc.postinst: Only restart services once each.
  * debian/patches/arm/unsubmitted-ldso-abi-check.diff: Fix rtld segv in
    dl_open() introduced via merge with upstream at 2.28 (LP: #1821677)
  * debian/testsuite-xfail-debian.mk: XFAIL new tst-support_descriptors.

 -- Adam Conrad <email address hidden> Sun, 07 Apr 2019 14:12:24 -0600

Changed in glibc (Ubuntu Disco):
status: Fix Committed → Fix Released
Sunil Pandey (skpgkp1) wrote :

Is it fixed in 18.04 update release OR any plan to fix it?

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers