Bug 723243 - glibc: CWD being appended as search directory for shared objects when LD_LIBRARY_PATH ends up with colon
Summary: glibc: CWD being appended as search directory for shared objects when LD_LIBR...
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2011-07-19 14:05 UTC by Jan Lieskovsky
Modified: 2019-09-29 12:46 UTC (History)
4 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2011-07-19 14:19:11 UTC


Attachments (Terms of Use)

Description Jan Lieskovsky 2011-07-19 14:05:34 UTC
It was found that current working directory was appended (automatically) to the end of shared objects search path, when the LD_LIBRARY_PATH environment variable was specified with the ':' (colon) character at the end. A local attacker could create a specially-crafted dynamic shared object / library and trick another local user (victim) into modification of their LD_LIBRARY_PATH variable, which would lead to arbitrary code (provided by the attacker) execution with the privileges of the user running the tool (victim).

References:
[1] https://bugzilla.novell.com/show_bug.cgi?id=706670

Comment 1 Jan Lieskovsky 2011-07-19 14:08:03 UTC
Public PoC from [1] how to reproduce the issue:
===============================================

Steps to Reproduce:
1. as user nobody copy /lib/libc.so.6 to /tmp
2. as user someuser verify that $LD_LIBRARY_PATH is empty
3. as user someuser execute "export
LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
4. as user someuser $LD_LIBRARY_PATH using "printenv LD_LIBRARY_PATH"
5. the result look like someuser@machine:~> printenv LD_LIBRARY_PATH
/usr/local/lib/:
6. as user someuser execute "ldd /bin/ls" in $HOME
7. verify that the result will look like
someuser@machine:~> ldd /bin/ls
        linux-vdso.so.1 =>  (0x00007fffe29ff000)
        librt.so.1 => /lib64/librt.so.1 (0x00002b464f03d000)
        libacl.so.1 => /lib64/libacl.so.1 (0x00002b464f146000)
        libc.so.6 => /lib64/libc.so.6 (0x00002b464f24d000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b464f48e000)
        /lib64/ld-linux-x86-64.so.2 (0x00002b464ef21000)
        libattr.so.1 => /lib64/libattr.so.1 (0x00002b464f5a7000)
8. This is fine
9. as user someuser change to directory /tmp (cd /tmp)

10. 6. as user someuser execute "ldd /bin/ls" in $HOME
7. verify that the result will on SLES10SP4 look like
someuser@machine:tmp> ldd /bin/ls
        linux-vdso.so.1 =>  (0x00007fff45dff000)
        librt.so.1 => /lib64/librt.so.1 (0x00002ac2f283d000)
        libacl.so.1 => /lib64/libacl.so.1 (0x00002ac2f2946000)
        libc.so.6 => /lib64/libc.so.6 (0x00002ac2f2a4d000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00002ac2f2c8e000)
        /lib64/ld-linux-x86-64.so.2 (0x00002ac2f2721000)
        libattr.so.1 => /lib64/libattr.so.1 (0x00002ac2f2da7000)
But on OpenSUSE 11.3 (did not check other versions sofar) it will look like:
someuser@machine:tmp> ldd /bin/ls
        linux-gate.so.1 =>  (0xb783e000)
        librt.so.1 => /lib/librt.so.1 (0xb77f3000)
        libselinux.so.1 => /lib/libselinux.so.1 (0xb77d4000)
        libcap.so.2 => /lib/libcap.so.2 (0xb77ce000)
        libacl.so.1 => /lib/libacl.so.1 (0xb77c4000)
        libc.so.6 (0xb7658000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xb763d000)
        /lib/ld-linux.so.2 (0xb7820000)
        libdl.so.2 => /lib/libdl.so.2 (0xb7638000)
        libattr.so.1 => /lib/libattr.so.1 (0xb7632000)
Actual Results:  
With OpenSUSE 11.3 a LD_LIBRARY_PATH=/some/trusted/path: leads to cwd to be
prepended in the search path for shared libraries. 

someuser@machine:tmp> ldd /bin/ls
        linux-gate.so.1 =>  (0xb783e000)
        librt.so.1 => /lib/librt.so.1 (0xb77f3000)
        libselinux.so.1 => /lib/libselinux.so.1 (0xb77d4000)
        libcap.so.2 => /lib/libcap.so.2 (0xb77ce000)
        libacl.so.1 => /lib/libacl.so.1 (0xb77c4000)
        libc.so.6 (0xb7658000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xb763d000)
        /lib/ld-linux.so.2 (0xb7820000)
        libdl.so.2 => /lib/libdl.so.2 (0xb7638000)
        libattr.so.1 => /lib/libattr.so.1 (0xb7632000)

The problem does not exist with SLES10SP4

Expected Results:  
someuser@machine:tmp> ldd /bin/ls
        linux-gate.so.1 =>  (0xb783e000)
        librt.so.1 => /lib/librt.so.1 (0xb77f3000)
        libselinux.so.1 => /lib/libselinux.so.1 (0xb77d4000)
        libcap.so.2 => /lib/libcap.so.2 (0xb77ce000)
        libacl.so.1 => /lib/libacl.so.1 (0xb77c4000)
        libc.so.6 => /lib/libc.so.6 (0xb7658000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xb763d000)
        /lib/ld-linux.so.2 (0xb7820000)
        libdl.so.2 => /lib/libdl.so.2 (0xb7638000)
        libattr.so.1 => /lib/libattr.so.1 (0xb7632000)

Comment 2 Jan Lieskovsky 2011-07-19 14:09:29 UTC
This issue affects the versions of the glibc package, as shipped with Red Hat Enterprise Linux 4, 5, and 6.

--

This issue affects the versions of the glibc package, as shipped with Fedora release of 14 and 15.

Comment 5 Andreas Schwab 2011-07-19 14:19:11 UTC
Which is exactly how it is defined.

Comment 6 Jan Lieskovsky 2011-07-19 14:28:14 UTC
(In reply to comment #5)
> Which is exactly how it is defined.

Thanks, Andreas. Could you point me (link here URL to the documentation) where it is defined? Thanks, Jan.

Comment 7 Tomas Hoger 2011-07-19 14:34:59 UTC
Older bugs related to this: bug #59978, bug #60511, bug #75428, probably more.

The best explanation found in those:
  http://sources.redhat.com/ml/libc-hacker/2002-02/msg00124.html

Comment 8 Tomas Hoger 2011-07-19 14:37:59 UTC
(In reply to comment #7)
> The best explanation found in those:
>   http://sources.redhat.com/ml/libc-hacker/2002-02/msg00124.html

Which quotes:
  http://www.sco.com/developers/gabi/latest/ch5.dynamic.html

Comment 9 Jakub Jelinek 2011-07-19 14:38:12 UTC
It is an obvious user bug.
Should be using
LD_LIBRARY_PATH=/usr/local/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
instead.  AFAIK most scripts get it right.

Comment 10 Tomas Hoger 2011-07-19 14:58:06 UTC
(In reply to comment #9)
> AFAIK most scripts get it right.

Still a lot of scripts get written that don't, sadly.

Do anyone see a good reason for the spec to require "/foo:" to be handled as "/foo:.", rather than being little more strict and requiring explicit "." when CWD is to be searched, and ignoring empty paths?  Is that for consistency with $PATH handling?


Note You need to log in before you can comment on or make changes to this bug.