Date: Wed, 6 Feb 2002 20:49:08 -0500 From: Chris Faulhaber <jedgar@fxp.org> To: biometrix <bio.metrix@gte.net> Cc: audit@freebsd.org Subject: Re: tmpfile() libc call causes buffer overflow? Message-ID: <20020207014908.GA88916@peitho.fxp.org> In-Reply-To: <20020207010159.EFLX12982.out008.verizon.net@there> References: <20020207010159.EFLX12982.out008.verizon.net@there>
next in thread | previous in thread | raw e-mail | index | archive | help
--/9DWx/yDrRhgMJTb Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, Feb 05, 2002 at 07:05:30PM +0000, biometrix wrote: > I found if I altered TMPDIR exported variable to an a long string (X50 "G= ")=20 > /usr/bin/pr would exit with a segmentation fault. >=20 > export TMPDIR=3D`perl -e 'print "G" x 50'` > bash-2.05# pr > Cannot defer diagnostic messages > Segmentation fault (core dumped) >=20 > The code executed just before the segmentation fault is : >=20 > if ((err =3D tmpfile()) =3D=3D NULL) { > (void)fputs("Cannot defer diagnosticm=20 > essages\n",stderr); > return(1); > } >=20 actually: =2E.. This GDB was configured as "i386-unknown-freebsd"... Core was generated by `pr'. Program terminated with signal 11, Segmentation fault. Reading symbols from /usr/lib/libc.so.4...done. Reading symbols from /usr/libexec/ld-elf.so.1...done. #0 0x280dac49 in __sfvwrite () from /usr/lib/libc.so.4 (gdb) bt #0 0x280dac49 in __sfvwrite () from /usr/lib/libc.so.4 #1 0x280c69ce in fputs () from /usr/lib/libc.so.4 #2 0x804a87d in usage () at pr.c:1562 #3 0x8048b69 in main (argc=3D1, argv=3D0xbfbffa84) at pr.c:133 (gdb)=20 __sfvwrite() dies when fed a NULL stream. This is triggered by pr(1) attempting to use fputs() with an invalid stream caused by tmpfile() failing. It does not appear to be specific to a long TMPDIR but to any TMPDIR (i.e. any invalid directory) that will cause tmpfile() to fail. The fix to pr(1) is to explicitely set err =3D stderr before eventually calling usage(): Index: pr.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/usr.bin/pr/pr.c,v retrieving revision 1.9.2.1 diff -u -r1.9.2.1 pr.c --- usr.bin/pr/pr.c 4 Mar 2001 08:54:51 -0000 1.9.2.1 +++ usr.bin/pr/pr.c 7 Feb 2002 01:34:58 -0000 @@ -1588,6 +1588,7 @@ * defer diagnostics until processing is done */ if ((err =3D tmpfile()) =3D=3D NULL) { + err =3D stderr; (void)fputs("Cannot defer diagnostic messages\n",stderr); return(1); } The fix to __sfvwrite() is to ensure that fp !=3D NULL: Index: lib/libc/stdio/fvwrite.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/lib/libc/stdio/fvwrite.c,v retrieving revision 1.10 diff -u -r1.10 fvwrite.c --- lib/libc/stdio/fvwrite.c 28 Aug 1999 00:01:06 -0000 1.10 +++ lib/libc/stdio/fvwrite.c 7 Feb 2002 01:44:47 -0000 @@ -42,6 +42,7 @@ "$FreeBSD: src/lib/libc/stdio/fvwrite.c,v 1.10 1999/08/28 00:01:06 peter= Exp $"; #endif /* LIBC_SCCS and not lint */ =20 +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -68,6 +69,10 @@ =20 if ((len =3D uio->uio_resid) =3D=3D 0) return (0); + if (fp =3D=3D NULL) { + errno =3D EBADF; + return (EOF); + } /* make sure we can write */ if (cantwrite(fp)) return (EOF); >=20 > In : /usr/src/lib/libc/stdio/tmpfile.c there is a call for > "tmpdir =3D getenv("TMPDIR");" >=20 > so it returns a filename based on the enviroment variable "TMPDIR" so the= =20 > result of tmpfile() can be poisoned by altering TMPDIR ? >=20 Have you read tmpfile(3)? --=20 Chris D. Faulhaber - jedgar@fxp.org - jedgar@FreeBSD.org -------------------------------------------------------- FreeBSD: The Power To Serve - http://www.FreeBSD.org --/9DWx/yDrRhgMJTb Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (FreeBSD) Comment: FreeBSD: The Power To Serve iEYEARECAAYFAjxh3RMACgkQObaG4P6BelALpACffIyeBSudpkf73TIQ9CQUivko ybAAn0EVqlX/WV5nXl2+V1q9rZyS6xJR =nf14 -----END PGP SIGNATURE----- --/9DWx/yDrRhgMJTb-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020207014908.GA88916>