Skip site navigation (1)Skip section navigation (2)
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>