Article View: net.bugs.usg
Article #281Bug with multiple stdio streams on one descriptor, FIX
From: Bruce Robertson
Date: Wed, 26 Mar 1986 05:41
Date: Wed, 26 Mar 1986 05:41
89 lines
3076 bytes
3076 bytes
Description:
There is a bug in Standard I/O for System V Release 2 Version 2. If
you have more than one FILE stream open on a single file descriptor,
bad things to your malloc() heap space happen.
Throughout the stdio code, the end of the buffer associated with
a stream is referenced by the macro _bufend(). This macro is
defined in /usr/include/stdio.h, and references a table of pointers
the end of the buffers. The problem is, the table is referenced
like this:
_bufendtab[(p)->_file]
where `p' is your FILE pointer. This is wrong. What you really
want to do is reference the table like this:
_bufendtab[(p) - &_iob[0]]
which associates slots in the table of pointers with slots in
the table of _iob structures.
Repeat-By:
int fd;
FILE *fp1, *fp2;
fd = open("/dev/tty", 2);
fp1 = fdopen(fd, "r");
fp2 = fdopen(fd, "w");
Subsequent fputs() calls to `fp2' will cause random areas of
memory to be modified, because the data structures that describe
the length of the buffer have been clobbered.
Fix:
Two fixes - one to /usr/include/stdio.h, and another to
/usr/src/lib/libc/port/print/doprnt.c, which also references
the table incorrectly, without using the macro. Note that
after making the change to /usr/include/stdio.h, you must
recompile everything in /usr/src/lib/libc/port/stdio.
*** /usr/include/stdio.h-old Mon Jul 2 19:32:20 1984
--- /usr/include/stdio.h Tue Mar 4 22:14:47 1986
***************
*** 54,60
#define stdout (&_iob[1])
#define stderr (&_iob[2])
! #define _bufend(p) _bufendtab[(p)->_file]
#define _bufsiz(p) (_bufend(p) - (p)->_base)
#ifndef lint
--- 54,60 -----
#define stdout (&_iob[1])
#define stderr (&_iob[2])
! #define _bufend(p) _bufendtab[(p) - &_iob[0]]
#define _bufsiz(p) (_bufend(p) - (p)->_base)
#ifndef lint
*** /usr/src/lib/libc/port/print/doprnt.c-old Tue Mar 25 21:26:41 1986
--- /usr/src/lib/libc/port/print/doprnt.c Tue Mar 25 21:26:43 1986
***************
*** 159,165
bufptr = iop->_ptr;
bufferend = (fno == _NFILE) ?
(unsigned char *)((long) bufptr | (-1L & ~HIBITL))
! : _bufendtab[fno];
}
/*
--- 159,165 -----
bufptr = iop->_ptr;
bufferend = (fno == _NFILE) ?
(unsigned char *)((long) bufptr | (-1L & ~HIBITL))
! : _bufend(iop);
}
/*
--
Bruce Robertson
UUCP: cbosgd!utah-cs!utah-gr!stride!bruce
ARPA: stride!bruce@utah-gr.arpa
Technical Details
Message-ID:
<562@stride.stride.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!think!harvard!seismo!utah-cs!utah-gr!stride!bruceShow Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!think!harvard!seismo!utah-cs!utah-gr!stride!bruce From: bruce@stride.UUCP (Bruce Robertson) Newsgroups: net.bugs.usg Subject: Bug with multiple stdio streams on one descriptor, FIX Message-ID: <562@stride.stride.UUCP> Date: Wed, 26-Mar-86 00:41:18 EST Article-I.D.: stride.562 Posted: Wed Mar 26 00:41:18 1986 Date-Received: Sat, 29-Mar-86 01:19:00 EST Reply-To: bruce@stride.UUCP (Bruce Robertson) Organization: Stride Micro, Reno, NV. Lines: 89