Subject: lib/594: too many fopen()s can cause bus errors
To: None <gnats-admin@sun-lamp.cs.berkeley.edu>
From: None <chs@cs.cmu.edu>
List: netbsd-bugs
Date: 11/28/1994 22:35:03
>Number:         594
>Category:       lib
>Synopsis:       too many fopen()s can cause bus errors
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    gnats-admin (Library Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Nov 28 22:35:02 1994
>Originator:     Chuck Silvers
>Organization:
CMU
>Release:        1.0
>Environment:
System: NetBSD chuq.fac.cs.cmu.edu 1.0 NetBSD 1.0 (SPARC) #39: Fri Nov 18 02:33:07 EST 1994 chs@chuq.fac.cs.cmu.edu:/usr/src/sys/arch/sparc/compile/SPARC sparc


>Description:

In moreglue() in lib/libc/stdio/findfp.c,  the structure assignment
                *p++ = empty;
can cause a bus error if p doesn't happen to be properly aligned.
It never is on (for example) the sparc.


>How-To-Repeat:

Compile and run the following program on an architecture where
ALIGN(sizeof(struct glue)) != sizeof(struct glue)
(with "struct glue" from lib/libc/stdio/glue.h).
The sparc and pmax are the only architectures that I can see
that this is true of just from glancing at their machine/param.h's.

main()
{
    int i;
    for (i = 1; i < 50; i++) {
        (void) fopen("/dev/null", "r");
        printf("%d\n", i);
    }
}

This bus-errors after 17 iterations on my sparc, which is the first time
moreglue() would be called.

>Fix:

*** findfp.c.orig	Tue Nov 29 00:37:58 1994
--- /usr/src/lib/libc/stdio/findfp.c	Tue Nov 29 00:41:54 1994
***************
*** 39,44 ****
--- 39,45 ----
  static char *rcsid = "$Id: findfp.c,v 1.4 1993/12/31 19:14:12 jtc Exp $";
  #endif /* LIBC_SCCS and not lint */
  
+ #include <sys/param.h>
  #include <unistd.h>
  #include <stdio.h>
  #include <errno.h>
***************
*** 74,83 ****
  	register FILE *p;
  	static FILE empty;
  
! 	g = (struct glue *)malloc(sizeof(*g) + n * sizeof(FILE));
  	if (g == NULL)
  		return (NULL);
! 	p = (FILE *)(g + 1);
  	g->next = NULL;
  	g->niobs = n;
  	g->iobs = p;
--- 75,84 ----
  	register FILE *p;
  	static FILE empty;
  
! 	g = (struct glue *)malloc(sizeof(*g) + n * sizeof(FILE) + ALIGNBYTES);
  	if (g == NULL)
  		return (NULL);
! 	p = (FILE *)ALIGN(g + 1);
  	g->next = NULL;
  	g->niobs = n;
  	g->iobs = p;
>Audit-Trail:
>Unformatted: