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>
