Bug with multiple stdio streams on one descriptor, FIX
Bruce Robertson
bruce at stride.UUCP
Wed Mar 26 15:41:18 AEST 1986
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 at utah-gr.arpa
More information about the Net.bugs.usg
mailing list