Since _file is a short, check that the fd fits in it, otherwise bail with

EMFILE. We treat _file as an unsigned short to double our range, with a
special case for -1 (closed). Make a note of what we should do about stdio
if we ever bump libc. We could change _file in the future compatibly to an
int by putting it in the extension space but for now we don't bother.
This commit is contained in:
christos 2008-03-13 15:40:00 +00:00
parent 546bf50253
commit 749de7f2a4
9 changed files with 70 additions and 28 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: stdio.h,v 1.70 2007/08/02 21:49:09 kristerw Exp $ */
/* $NetBSD: stdio.h,v 1.71 2008/03/13 15:40:00 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
@ -444,7 +444,8 @@ static __inline int __sputc(int _c, FILE *_p) {
#define __sfeof(p) (((p)->_flags & __SEOF) != 0)
#define __sferror(p) (((p)->_flags & __SERR) != 0)
#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
#define __sfileno(p) ((p)->_file)
#define __sfileno(p) \
((p)->_file == -1 ? -1 : (int)(unsigned short)(p)->_file)
#ifndef __lint__
#if !defined(_REENTRANT) && !defined(_PTHREADS)

View File

@ -1,4 +1,4 @@
# $NetBSD: shlib_version,v 1.194 2008/02/10 18:47:06 ad Exp $
# $NetBSD: shlib_version,v 1.195 2008/03/13 15:40:00 christos Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
# things we wish to do on next major version bump:
@ -15,6 +15,7 @@
# - libc/arch/vax/gen/is{inf,nan}.c: remove
# - libc/db/hash/ndbm.c: remove; __ndbm13 -> ndbm
# - libc/net/getnet{ent,namadr}.c, netdb.h: remove __n_pad0
# - libc/stdio: make _file an int, hide struct FILE, stdin, stdout, stderr impls
#
major=12
minor=159

View File

@ -1,4 +1,4 @@
/* $NetBSD: fdopen.c,v 1.14 2003/08/07 16:43:22 agc Exp $ */
/* $NetBSD: fdopen.c,v 1.15 2008/03/13 15:40:00 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)fdopen.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: fdopen.c,v 1.14 2003/08/07 16:43:22 agc Exp $");
__RCSID("$NetBSD: fdopen.c,v 1.15 2008/03/13 15:40:00 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -49,6 +49,7 @@ __RCSID("$NetBSD: fdopen.c,v 1.14 2003/08/07 16:43:22 agc Exp $");
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <limits.h>
#include "reentrant.h"
#include "local.h"
@ -67,6 +68,18 @@ fdopen(fd, mode)
_DIAGASSERT(fd != -1);
/*
* File descriptors are a full int, but _file is only a short.
* If we get a valid file descriptor that is greater or equal to
* USHRT_MAX, then the fd will get sign-extended into an
* invalid file descriptor. Handle this case by failing the
* open. (We treat the short as unsigned, and special-case -1).
*/
if (fd >= USHRT_MAX) {
errno = EMFILE;
return NULL;
}
if ((flags = __sflags(mode, &oflags)) == 0)
return (NULL);

View File

@ -1,4 +1,4 @@
/* $NetBSD: fopen.c,v 1.12 2003/08/07 16:43:24 agc Exp $ */
/* $NetBSD: fopen.c,v 1.13 2008/03/13 15:40:00 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)fopen.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: fopen.c,v 1.12 2003/08/07 16:43:24 agc Exp $");
__RCSID("$NetBSD: fopen.c,v 1.13 2008/03/13 15:40:00 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -48,6 +48,7 @@ __RCSID("$NetBSD: fopen.c,v 1.12 2003/08/07 16:43:24 agc Exp $");
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include "reentrant.h"
#include "local.h"
@ -81,6 +82,18 @@ fopen(file, mode)
goto release;
}
}
/*
* File descriptors are a full int, but _file is only a short.
* If we get a valid file descriptor that is greater or equal to
* USHRT_MAX, then the fd will get sign-extended into an
* invalid file descriptor. Handle this case by failing the
* open. (We treat the short as unsigned, and special-case -1).
*/
if (f >= USHRT_MAX) {
errno = EMFILE;
goto release;
}
fp->_file = f;
fp->_flags = flags;
fp->_cookie = fp;

View File

@ -1,4 +1,4 @@
/* $NetBSD: freopen.c,v 1.14 2003/08/07 16:43:25 agc Exp $ */
/* $NetBSD: freopen.c,v 1.15 2008/03/13 15:40:00 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)freopen.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: freopen.c,v 1.14 2003/08/07 16:43:25 agc Exp $");
__RCSID("$NetBSD: freopen.c,v 1.15 2008/03/13 15:40:00 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -51,6 +51,7 @@ __RCSID("$NetBSD: freopen.c,v 1.14 2003/08/07 16:43:25 agc Exp $");
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <limits.h>
#include "reentrant.h"
#include "local.h"
@ -97,7 +98,7 @@ freopen(file, mode, fp)
(void) __sflush(fp);
/* if close is NULL, closing is a no-op, hence pointless */
isopen = fp->_close != NULL;
if ((wantfd = fp->_file) < 0 && isopen) {
if ((wantfd = __sfileno(fp)) == -1 && isopen) {
(void) (*fp->_close)(fp->_cookie);
isopen = 0;
}
@ -171,6 +172,19 @@ freopen(file, mode, fp)
}
}
/*
* File descriptors are a full int, but _file is only a short.
* If we get a valid file descriptor that is greater or equal to
* USHRT_MAX, then the fd will get sign-extended into an
* invalid file descriptor. Handle this case by failing the
* open. (We treat the short as unsigned, and special-case -1).
*/
if (f >= USHRT_MAX) {
(void)close(f);
errno = EMFILE;
return NULL;
}
fp->_flags = flags;
fp->_file = f;
fp->_cookie = fp;

View File

@ -1,4 +1,4 @@
/* $NetBSD: fseeko.c,v 1.6 2006/12/18 00:40:14 christos Exp $ */
/* $NetBSD: fseeko.c,v 1.7 2008/03/13 15:40:00 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
@ -34,7 +34,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: fseeko.c,v 1.6 2006/12/18 00:40:14 christos Exp $");
__RCSID("$NetBSD: fseeko.c,v 1.7 2008/03/13 15:40:00 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
@ -145,7 +145,7 @@ fseeko(FILE *fp, off_t offset, int whence)
goto dumb;
if ((fp->_flags & __SOPT) == 0) {
if (seekfn != __sseek ||
fp->_file < 0 || fstat(fp->_file, &st) ||
__sfileno(fp) == -1 || fstat(__sfileno(fp), &st) ||
!S_ISREG(st.st_mode)) {
fp->_flags |= __SNPT;
goto dumb;
@ -161,7 +161,7 @@ fseeko(FILE *fp, off_t offset, int whence)
if (whence == SEEK_SET)
target = offset;
else {
if (fstat(fp->_file, &st))
if (fstat(__sfileno(fp), &st))
goto dumb;
target = st.st_size + offset;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: makebuf.c,v 1.14 2003/08/07 16:43:28 agc Exp $ */
/* $NetBSD: makebuf.c,v 1.15 2008/03/13 15:40:00 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)makebuf.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: makebuf.c,v 1.14 2003/08/07 16:43:28 agc Exp $");
__RCSID("$NetBSD: makebuf.c,v 1.15 2008/03/13 15:40:00 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -86,7 +86,7 @@ __smakebuf(fp)
flags |= __SMBF;
fp->_bf._base = fp->_p = p;
fp->_bf._size = size;
if (couldbetty && isatty(fp->_file))
if (couldbetty && isatty(__sfileno(fp)))
flags |= __SLBF;
fp->_flags |= flags;
}
@ -106,7 +106,7 @@ __swhatbuf(fp, bufsize, couldbetty)
_DIAGASSERT(bufsize != NULL);
_DIAGASSERT(couldbetty != NULL);
if (fp->_file < 0 || fstat(fp->_file, &st) < 0) {
if (__sfileno(fp) == -1 || fstat(__sfileno(fp), &st) < 0) {
*couldbetty = 0;
*bufsize = BUFSIZ;
return (__SNPT);

View File

@ -1,4 +1,4 @@
/* $NetBSD: stdio.c,v 1.13 2003/08/07 16:43:33 agc Exp $ */
/* $NetBSD: stdio.c,v 1.14 2008/03/13 15:40:00 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)stdio.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: stdio.c,v 1.13 2003/08/07 16:43:33 agc Exp $");
__RCSID("$NetBSD: stdio.c,v 1.14 2008/03/13 15:40:00 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -68,7 +68,7 @@ __sread(cookie, buf, n)
_DIAGASSERT(fp != NULL);
_DIAGASSERT(buf != NULL);
ret = read(fp->_file, buf, (size_t)n);
ret = read(__sfileno(fp), buf, (size_t)n);
/* if the read succeeded, update the current offset */
if (ret >= 0)
fp->_offset += ret;
@ -89,9 +89,9 @@ __swrite(cookie, buf, n)
_DIAGASSERT(buf != NULL);
if (fp->_flags & __SAPP)
(void) lseek(fp->_file, (off_t)0, SEEK_END);
(void) lseek(__sfileno(fp), (off_t)0, SEEK_END);
fp->_flags &= ~__SOFF; /* in case FAPPEND mode is set */
return (write(fp->_file, buf, (size_t)n));
return write(__sfileno(fp), buf, (size_t)n);
}
fpos_t
@ -105,7 +105,7 @@ __sseek(cookie, offset, whence)
_DIAGASSERT(fp != NULL);
ret = lseek(fp->_file, (off_t)offset, whence);
ret = lseek(__sfileno(fp), (off_t)offset, whence);
if (ret == -1L)
fp->_flags &= ~__SOFF;
else {
@ -122,5 +122,5 @@ __sclose(cookie)
_DIAGASSERT(cookie != NULL);
return (close(((FILE *)cookie)->_file));
return close(__sfileno((FILE *)cookie));
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfwprintf.c,v 1.10 2007/02/03 00:28:33 christos Exp $ */
/* $NetBSD: vfwprintf.c,v 1.11 2008/03/13 15:40:00 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
@ -38,7 +38,7 @@
static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93";
__FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.27 2007/01/09 00:28:08 imp Exp $");
#else
__RCSID("$NetBSD: vfwprintf.c,v 1.10 2007/02/03 00:28:33 christos Exp $");
__RCSID("$NetBSD: vfwprintf.c,v 1.11 2008/03/13 15:40:00 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -812,7 +812,7 @@ WDECL(__vf,printf_unlocked)(FILE *fp, const CHAR_T *fmt0, va_list ap)
/* optimise fprintf(stderr) (and other unbuffered Unix files) */
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
fp->_file >= 0)
__sfileno(fp) != -1)
return (__sbprintf(fp, fmt0, ap));
fmt = (CHAR_T *)__UNCONST(fmt0);