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