Bug 26577 - Stack overflow in dlopen
Summary: Stack overflow in dlopen
Status: UNCONFIRMED
Alias: None
Product: glibc
Classification: Unclassified
Component: dynamic-link (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-09-07 07:17 UTC by SunshineFly
Modified: 2020-09-07 17:08 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description SunshineFly 2020-09-07 07:17:03 UTC
Stack overflow in dlopen (dlfcn/dlopen.c)

###### Glibc revision

version : <= 2.34

###### Build platform

Ubuntu 18.10 LTS (Linux ubuntu 4.18.0-25-generic x86_64)   
ldd (Ubuntu GLIBC 2.28-0ubuntu1) 2.28

Ubuntu 20.04.1 LTS (Linux ubuntu 5.4.0-42-generic #46-Ubuntu x86_64) 
ldd (Ubuntu GLIBC 2.31-0ubuntu9) 2.31

###### Build steps

```
gcc poc.c -ldl
```

###### Test case

poc.c
```
#include <stdio.h>
#include <dlfcn.h>
#include <string.h>
char file[10000000];
int main()
{
    memset(file,'A',10000000);
    void* handle = dlopen(file, 0x2);
    return 0;
}
```

###### Execution steps

```
$ 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.
$ uname -a
Linux ubuntu 4.18.0-25-generic #26-Ubuntu SMP Mon Jun 24 09:32:08 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/issue
Ubuntu 18.10 \n \l
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.10
Release:	18.10
Codename:	cosmic
$ gcc poc.c -ldl
$ ./a.out 
Segmentation fault (core dumped)

$ gdb -q ./a.out 
Reading symbols from ./a.out...(no debugging symbols found)...done.
(gdb) r
Starting program: /home/test/Lua/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7fdacf7 in open_path (name=name@entry=0x555555558040 <file> 'A' <repeats 200 times>..., namelen=namelen@entry=10000001, mode=mode@entry=-1879048190, 
    sps=sps@entry=0x7ffff7ffc8d0 <rtld_search_dirs>, realname=realname@entry=0x7fffffffd780, fbp=fbp@entry=0x7fffffffd790, loader=0x7ffff7ffe190, whatcode=64, found_other_class=0x7fffffffd77f)
    at dl-load.c:2041
2041	dl-load.c: No such file or directory.
(gdb) bt
#0  0x00007ffff7fdacf7 in open_path (name=name@entry=0x555555558040 <file> 'A' <repeats 200 times>..., namelen=namelen@entry=10000001, mode=mode@entry=-1879048190, 
    sps=sps@entry=0x7ffff7ffc8d0 <rtld_search_dirs>, realname=realname@entry=0x7fffffffd780, fbp=fbp@entry=0x7fffffffd790, loader=0x7ffff7ffe190, whatcode=64, found_other_class=0x7fffffffd77f)
    at dl-load.c:2041
#1  0x00007ffff7fdcd4e in _dl_map_object (loader=loader@entry=0x7ffff7ffe190, name=name@entry=0x555555558040 <file> 'A' <repeats 200 times>..., type=type@entry=2, trace_mode=trace_mode@entry=0, 
    mode=mode@entry=-1879048190, nsid=<optimized out>) at dl-load.c:2388
#2  0x00007ffff7fe79c4 in dl_open_worker (a=a@entry=0x7fffffffdd00) at dl-open.c:228
#3  0x00007ffff7f1f48f in __GI__dl_catch_exception (exception=<optimized out>, operate=<optimized out>, args=<optimized out>) at dl-error-skeleton.c:196
#4  0x00007ffff7fe72c6 in _dl_open (file=0x555555558040 <file> 'A' <repeats 200 times>..., mode=-2147483646, caller_dlopen=0x555555555174 <main+47>, nsid=<optimized out>, argc=1, argv=0x7fffffffe058, 
    env=0x7fffffffe068) at dl-open.c:599
#5  0x00007ffff7fae256 in dlopen_doit (a=a@entry=0x7fffffffdf20) at dlopen.c:66
#6  0x00007ffff7f1f48f in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdec0, operate=<optimized out>, args=<optimized out>) at dl-error-skeleton.c:196
#7  0x00007ffff7f1f51f in __GI__dl_catch_error (objname=0x7ffff7fb20f0 <last_result+16>, errstring=0x7ffff7fb20f8 <last_result+24>, mallocedp=0x7ffff7fb20e8 <last_result+8>, operate=<optimized out>, 
    args=<optimized out>) at dl-error-skeleton.c:215
#8  0x00007ffff7faea25 in _dlerror_run (operate=operate@entry=0x7ffff7fae200 <dlopen_doit>, args=args@entry=0x7fffffffdf20) at dlerror.c:163
#9  0x00007ffff7fae2e6 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:87
#10 0x0000555555555174 in main ()
(gdb) x/3i $rip
=> 0x7ffff7fdacf7 <open_path+215>:	callq  0x7ffff7ff3900 <mempcpy>
   0x7ffff7fdacfc <open_path+220>:	mov    %rax,%r14
   0x7ffff7fdacff <open_path+223>:	lea    -0xc0(%rbp),%rax
(gdb) 
```

```
$ ldd --version
ldd (Ubuntu GLIBC 2.31-0ubuntu9) 2.31
Copyright (C) 2020 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.
$ uname -a
Linux ubuntu 5.4.0-42-generic #46-Ubuntu SMP Fri Jul 10 00:24:02 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/issue
Ubuntu 20.04.1 LTS \n \l
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.1 LTS
Release:	20.04
Codename:	focal
$ gcc poc.c -ldl
$ ./a.out 
Segmentation fault (core dumped)
$ gdb -q ./a.out
pwndbg> r
Starting program: /home/test/Desktop/a.out 

Program received signal SIGSEGV, Segmentation fault.
pwndbg> bt
#0  0x00007ffff7fd7ac3 in ?? () from /lib64/ld-linux-x86-64.so.2
#1  0x00007ffff7fd9ae2 in ?? () from /lib64/ld-linux-x86-64.so.2
#2  0x00007ffff7fe4d37 in ?? () from /lib64/ld-linux-x86-64.so.2
#3  0x00007ffff7f22728 in __GI__dl_catch_exception (exception=<optimized out>, operate=<optimized out>, args=<optimized out>) at dl-error-skeleton.c:208
#4  0x00007ffff7fe45fa in ?? () from /lib64/ld-linux-x86-64.so.2
#5  0x00007ffff7fb234c in dlopen_doit (a=a@entry=0x7fffffffdf60) at dlopen.c:66
#6  0x00007ffff7f22728 in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdf00, operate=<optimized out>, args=<optimized out>) at dl-error-skeleton.c:208
#7  0x00007ffff7f227f3 in __GI__dl_catch_error (objname=0x7ffff7fb60f0 <last_result+16>, errstring=0x7ffff7fb60f8 <last_result+24>, mallocedp=0x7ffff7fb60e8 <last_result+8>, operate=<optimized out>, args=<optimized out>) at dl-error-skeleton.c:227
#8  0x00007ffff7fb2b59 in _dlerror_run (operate=operate@entry=0x7ffff7fb22f0 <dlopen_doit>, args=args@entry=0x7fffffffdf60) at dlerror.c:170
#9  0x00007ffff7fb23da in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:87
#10 0x000055555555519c in main ()
#11 0x00007ffff7de60b3 in __libc_start_main (main=0x555555555169 <main>, argc=1, argv=0x7fffffffe0a8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe098) at ../csu/libc-start.c:308
#12 0x00005555555550ae in _start ()
pwndbg> x/3i $rip
=> 0x7ffff7fd7ac3:	or     QWORD PTR [rsp+0xff8],0x0
   0x7ffff7fd7acc:	cmp    rsp,rax
   0x7ffff7fd7acf:	jne    0x7ffff7fd7abc
```
Comment 1 Florian Weimer 2020-09-07 09:30:21 UTC
This is caused by the alloca in dl-load.c during pathname construction. We cannot trivially replace this with malloc because this allocation would leak most of the time because of the way free works for the dl-minimal.c malloc.

I'm setting security- (no security impact) because the dlopen argument does not cross a trust boundary.

-- 
Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
Commercial register: Amtsgericht Muenchen, HRB 153243,
Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael O'Neill
Comment 2 SunshineFly 2020-09-07 10:12:09 UTC
(In reply to Florian Weimer from comment #1)
> This is caused by the alloca in dl-load.c during pathname construction. We
> cannot trivially replace this with malloc because this allocation would leak
> most of the time because of the way free works for the dl-minimal.c malloc.
> 
> I'm setting security- (no security impact) because the dlopen argument does
> not cross a trust boundary.
> 
> -- 
> Red Hat GmbH, https://de.redhat.com/ , Registered seat: Grasbrunn,
> Commercial register: Amtsgericht Muenchen, HRB 153243,
> Managing Directors: Charles Cachera, Brian Klemm, Laurie Krebs, Michael
> O'Neill

I analyzed the availability of the problem and concluded that it would only cause a crash.
I think it's a safety issue.
Comment 3 jsm-csl@polyomino.org.uk 2020-09-07 17:08:31 UTC
The dlopen path is definitely trusted, since arbitrary code will be 
executed from any library you dlopen (ELF constructors even if you never 
call any functions from the library).  So this is an ordinary, 
non-security bug.