[Python-Dev] unintentional and unsafe use of realpath()

Peter Jones pjones at redhat.com
Sat Sep 10 21:29:31 CEST 2005


Hi,

In Python 2.4.1, Python/sysmodule.c includes a function PySys_SetArgv().
One of the things it does is attempt to resolve symbolic links into
absolute paths.  Currently, it uses readlink() if configure found that
your system supports it, and then it tries to do the same thing again
using realpath() if you system supports that.

This seems wrong; there's really no reason to do both.  So here's a
patch to move the realpath() usage into a #else following the
HAVE_READLINK test:

--- Python-2.4.1/Python/sysmodule.c.readlink	2005-09-10 14:05:26.000000000 -0400
+++ Python-2.4.1/Python/sysmodule.c	2005-09-10 14:06:00.000000000 -0400
@@ -1211,7 +1211,7 @@
 				}
 			}
 		}
-#endif /* HAVE_READLINK */
+#else /* HAVE_READLINK */
 #if SEP == '\\' /* Special case for MS filename syntax */
 		if (argc > 0 && argv0 != NULL) {
 			char *q;
@@ -1244,6 +1244,7 @@
 #endif
 			p = strrchr(argv0, SEP);
 		}
+#endif /* HAVE_READLINK */
 		if (p != NULL) {
 #ifndef RISCOS
 			n = p + 1 - argv0;


Another problem (which I have not fixed) is that when realpath() is
used, in some cases MAXPATHLEN is smaller than the system's
PATH_MAX/pathconf(path, _PC_PATH_MAX).  When that happens, the
realpath() usage is a potential buffer overflow, which can be
selectively aggravated using a carefully constructed symbolic link.
This is the case currently on Fedora Core (Linux) at least, and possibly
other OSes.

Recent versions of gcc include a feature to check for this kind of bug
at runtime, and if you build python with gcc+glibc and the gcc command
line arguments "-Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector"
it will give you a failure that looks something like:

case $MAKEFLAGS in \
*-s*) LD_LIBRARY_PATH=/home/pjones/build/BUILD/Python-2.4.1: CC='gcc
-pthread' LDSHARED='gcc -pthread -shared' OPT='-O2 -g -pipe -Wall
-Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector
--param=ssp-buffer-size=4 -m32 -march=i386 -mtune=pentium4
-fasynchronous-unwind-tables -D_GNU_SOURCE -fPIC -I/usr/kerberos/include
' ./python -E ./setup.py -q build;; \
*) LD_LIBRARY_PATH=/home/pjones/build/BUILD/Python-2.4.1: CC='gcc
-pthread' LDSHARED='gcc -pthread -shared' OPT='-O2 -g -pipe -Wall
-Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector
--param=ssp-buffer-size=4 -m32 -march=i386 -mtune=pentium4
-fasynchronous-unwind-tables -D_GNU_SOURCE -fPIC -I/usr/kerberos/include
' ./python -E ./setup.py build;; \
esac
*** buffer overflow detected ***: ./python terminated
======= Backtrace: =========
/lib/libc.so.6(__chk_fail+0x41)[0x590495]
/lib/libc.so.6(__ptsname_r_chk+0x0)[0x590ac0]
/home/pjones/build/BUILD/Python-2.4.1/libpython2.4.so.1.0(PySys_SetArgv
+0x1a1)[0x228cf5]
/home/pjones/build/BUILD/Python-2.4.1/libpython2.4.so.1.0(Py_Main
+0x671)[0x22bedd]
./python(main+0x2a)[0x804859a]
/lib/libc.so.6(__libc_start_main+0xdf)[0x4c74ff]
./python[0x80484ed]
======= Memory map: ========
00185000-0026e000 r-xp 00000000 03:03
278531     /home/pjones/build/BUILD/Python-2.4.1/libpython2.4.so.1.0
0026e000-00295000 rwxp 000e8000 03:03
278531     /home/pjones/build/BUILD/Python-2.4.1/libpython2.4.so.1.0
00295000-00298000 rwxp 00295000 00:00 0
00495000-004ae000 r-xp 00000000 03:03 1966150    /lib/ld-2.3.90.so
004ae000-004af000 r-xp 00018000 03:03 1966150    /lib/ld-2.3.90.so
004af000-004b0000 rwxp 00019000 03:03 1966150    /lib/ld-2.3.90.so
004b2000-005d7000 r-xp 00000000 03:03 1966261    /lib/libc-2.3.90.so
005d7000-005d9000 r-xp 00124000 03:03 1966261    /lib/libc-2.3.90.so
005d9000-005db000 rwxp 00126000 03:03 1966261    /lib/libc-2.3.90.so
005db000-005dd000 rwxp 005db000 00:00 0
005df000-00602000 r-xp 00000000 03:03 1966272    /lib/libm-2.3.90.so
00602000-00603000 r-xp 00022000 03:03 1966272    /lib/libm-2.3.90.so
00603000-00604000 rwxp 00023000 03:03 1966272    /lib/libm-2.3.90.so
00606000-00608000 r-xp 00000000 03:03 1966270    /lib/libdl-2.3.90.so
00608000-00609000 r-xp 00001000 03:03 1966270    /lib/libdl-2.3.90.so
00609000-0060a000 rwxp 00002000 03:03 1966270    /lib/libdl-2.3.90.so
006f7000-00705000 r-xp 00000000 03:03
1966283    /lib/libpthread-2.3.90.so
00705000-00706000 r-xp 0000d000 03:03
1966283    /lib/libpthread-2.3.90.so
00706000-00707000 rwxp 0000e000 03:03
1966283    /lib/libpthread-2.3.90.so
00707000-00709000 rwxp 00707000 00:00 0
0073f000-00743000 r-xp 00000000 03:03
1442230    /home/pjones/build/BUILD/Python-2.4.1/Modules/stropmodule.so
00743000-00745000 rwxp 00004000 03:03
1442230    /home/pjones/build/BUILD/Python-2.4.1/Modules/stropmodule.so
00a22000-00a2b000 r-xp 00000000 03:03
1966127    /lib/libgcc_s-4.0.1-20050906.so.1
00a2b000-00a2c000 rwxp 00009000 03:03
1966127    /lib/libgcc_s-4.0.1-20050906.so.1
00df7000-00df9000 r-xp 00000000 03:03 1968751    /lib/libutil-2.3.90.so
00df9000-00dfa000 r-xp 00001000 03:03 1968751    /lib/libutil-2.3.90.so
00dfa000-00dfb000 rwxp 00002000 03:03 1968751    /lib/libutil-2.3.90.so
00e33000-00e34000 r-xp 00e33000 00:00 0          [vdso]
08048000-08049000 r-xp 00000000 03:03
278551     /home/pjones/build/BUILD/Python-2.4.1/python
08049000-0804a000 rw-p 00000000 03:03
278551     /home/pjones/build/BUILD/Python-2.4.1/python
08086000-0810b000 rw-p 08086000 00:00 0          [heap]
b7e69000-b7f2c000 rw-p b7e69000 00:00 0
b7f2d000-b7fb1000 rw-p b7f2d000 00:00 0
b7fc4000-b7fc5000 rw-p b7fc4000 00:00 0
bffaf000-bffc5000 rw-p bffaf000 00:00 0          [stack]
/bin/sh: line 1:  9510 Aborted                 (core dumped)
LD_LIBRARY_PATH=/home/pjones/build/BUILD/Python-2.4.1: CC='gcc -pthread'
LDSHARED='gcc -pthread -shared' OPT='-O2 -g -pipe -Wall
-Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector
--param=ssp-buffer-size=4 -m32 -march=i386 -mtune=pentium4
-fasynchronous-unwind-tables -D_GNU_SOURCE -fPIC -I/usr/kerberos/include
' ./python -E ./setup.py -q build
make: *** [sharedmods] Error 134

-- 
  Peter



More information about the Python-Dev mailing list