🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

2 total messages Started by Bruce Robertson Wed, 26 Mar 1986 05:41
Bug with multiple stdio streams on one descriptor, FIX
#281
Author: Bruce Robertson
Date: Wed, 26 Mar 1986 05:41
89 lines
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
Re: Bug with multiple stdio streams on one descriptor, FIX
#287
Author: kwh
Date: Fri, 28 Mar 1986 19:56
20 lines
1534 bytes
In article <562@stride.stride.UUCP> stride!bruce (Bruce Robertson) writes:
>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.

This assumes that all objects of type FILE are in the _iob[] array.
This is not necessarily the case; e.g. there is an auto variable of type
FILE (not FILE*) in sprintf(); there may be others.

Are you sure that having two streams on one descriptor is legal?  Is there
any documentation that explicitly permits or forbids it?

Now, the *real* question.  Why is _bufendtab[] in a separate array, rather
than being another field in the FILE structure where it seems to belong?

Karl W. Z. Heuer (ihnp4!bentley!kwh), The Walking Lint
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads