Package: elinks
Version: 0.11.1-1.2
Severity: grave
Tags: security, patch
Hi,
Elinks loads untrusted gettext catalog from the relative directory
../po/, and crashes (SIGSEGV) if the loaded file is corrupted. You
can check by yourself with with the following commands:
$ mkdir -p /tmp/elinks/{run,po}
$ cp /usr/share/locale/fr/LC_MESSAGES/elinks.mo /tmp/elinks/po/fr.gmo
$ dd if=/dev/urandom of=/tmp/elinks/po/fr.gmo bs=1024 seek=1 count=200
$ cd /tmp/elinks/run
$ LANG=fr_FR strace -eopen -otrace elinks
[...]
open(/usr/lib/locale/locale-archive, O_RDONLY|O_LARGEFILE) = 3
open(/usr/share/locale/locale.alias, O_RDONLY|O_LARGEFILE) = 3
open(../po/fr_FR.gmo, O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or
directory)
open(/usr/share/locale/fr_FR/LC_MESSAGES/messages.mo, O_RDONLY|O_LARGEFILE) =
-1 ENOENT (No such file or directory)
open(../po/fr.gmo, O_RDONLY|O_LARGEFILE) = 3
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV (core dumped) +++
Process 29917 detached
A gdb backtrace is included at the end of the message.
I tagged this bug as grave+security because it can be used to make
elinks load any corrupted file, and possibly execute arbitrary code.
Imagine an evil user placing some specially crafted files in
/tmp/po/. Then, another user (root for example) runs elinks from a
directory /tmp/foo/, and thus loads the bad file(s).
A quick grep for '\.\./po' in the elinks sources gives the culprit
function : add_filename_to_string() around line 216 of file
elinks-0.11.1/src/intl/gettext/loadmsgcat.c.
IMHO, changing this function to return NULL unconditionally should fix
the problem (I did not want to download all the build dependencies to
verify).
Regards,
Arnaud Giersch
$ gdb -q /usr/bin/elinks -c core
(no debugging symbols found)
Using host libthread_db library /lib/tls/i686/cmov/libthread_db.so.1.
warning: Can't read pathname for load map: Input/output error.
Reading symbols from /usr/lib/libgnutls.so.13...(no debugging symbols
found)...done.
Loaded symbols for /usr/lib/libgnutls.so.13
Reading symbols from /usr/lib/liblua50.so.5.0...(no debugging symbols
found)...done.
Loaded symbols for /usr/lib/liblua50.so.5.0
Reading symbols from /usr/lib/liblualib50.so.5.0...(no debugging symbols
found)...done.
Loaded symbols for /usr/lib/liblualib50.so.5.0
Reading symbols from /lib/tls/i686/cmov/libm.so.6...
(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libm.so.6
Reading symbols from /usr/lib/libperl.so.5.8...(no debugging symbols
found)...done.
Loaded symbols for /usr/lib/libperl.so.5.8
Reading symbols from /lib/tls/i686/cmov/libdl.so.2...(no debugging symbols
found)...done.
Loaded symbols for /lib/tls/i686/cmov/libdl.so.2
Reading symbols from /lib/tls/i686/cmov/libpthread.so.0...
(no debugging symbols found)...done.
Loaded symbols for /lib/tls/i686/cmov/libpthread.so.0
Reading symbols from /lib/tls/i686/cmov/libc.so.6...(no debugging symbols
found)...done.
Loaded symbols for /lib/tls/i686/cmov/libc.so.6
Reading symbols from /lib/tls/i686/cmov/libcrypt.so.1...(no debugging symbols
found)...done.
Loaded symbols for /lib/tls/i686/cmov/libcrypt.so.1
Reading symbols from /usr/lib/libgpm.so.1...
(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libgpm.so.1
Reading symbols from /usr/lib/libz.so.1...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libz.so.1
Reading symbols from /lib/libbz2.so.1.0...(no debugging symbols found)...done.
Loaded symbols for /lib/libbz2.so.1.0
Reading symbols from /usr/lib/libexpat.so.1...
(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libexpat.so.1
Reading symbols from /usr/lib/libgnutls-openssl.so.13...(no debugging symbols
found)...done.
Loaded symbols for /usr/lib/libgnutls-openssl.so.13
Reading symbols from /usr/lib/libtasn1.so.3...(no debugging symbols
found)...done.
Loaded symbols for /usr/lib/libtasn1.so.3
Reading symbols from /usr/lib/libgcrypt.so.11...
(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libgcrypt.so.11
Reading symbols from /usr/lib/libgpg-error.so.0...(no debugging symbols
found)...done.
Loaded symbols for /usr/lib/libgpg-error.so.0
Reading symbols from /lib/ld-linux.so.2...Reading symbols from
/usr/lib/debug/lib/ld-2.3.6.so...(no debugging symbols found)...done.
(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /lib/tls/i686/cmov/libnsl.so.1...(no debugging symbols
found)...done.
Loaded symbols for /lib/tls/i686/cmov/libnsl.so.1
(no debugging symbols found)
Core was generated by `elinks'.
Program terminated with signal 11, Segmentation fault.
#0 0x0809da6c in _nl_find_msg ()
(gdb) where
#0 0x0809da6c in _nl_find_msg ()
#1 0x0809f4fe in _nl_init_domain_conv ()
#2 0x0809fc28 in _nl_load_domain ()
#3 0x0809e896 in _nl_find_domain ()
#4 0x0809de99 in dcigettext__ ()
#5 0x0809d4c1 in dcgettext__ ()
#6 0x0809e8c2 in gettext__ ()
#7 0x080a356e in get_dyn_full_version ()
#8