Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Mar 1997 04:01:49 +0900 (JST)
From:      kato@eclogite.eps.nagoya-u.ac.jp
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/2875: vinvalbuf() clobbers b_vnbufs chain
Message-ID:  <199703041901.EAA01847@gneiss.eps.nagoya-u.ac.jp>
Resent-Message-ID: <199703041910.LAA08444@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         2875
>Category:       kern
>Synopsis:       vinvalbuf() may clobber b_vnbufs chain.
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Mar  4 11:10:01 PST 1997
>Last-Modified:
>Originator:     KATO Takenori
>Organization:
Dept. Earth Planet. Sci, Nagoya Univ, Japan
>Release:        FreeBSD 2.2-GAMMA i386
>Environment:



>Description:


The function vinvalbuf() in vfs_subr.c may clober b_vnbufs chain.

in vinvalbuf():

	s = splbio();
	for (;;) {
		...
		for (bp = blist; bp; bp = nbp) {
			...
			if (bp->b_flags & B_BUSY) {
				...
				splx(s);	<--- (1)
				...
				break;		<--- (2)
			}
		}
	}

Because disk I/O interruption is unmasked at (1), b_vnbufs is operated 
without splbio() after `break' at (2).

>How-To-Repeat:

	

>Fix:
	

*** vfs_subr.c.orig	Wed Mar  5 03:03:56 1997
--- vfs_subr.c	Wed Mar  5 03:44:00 1997
***************
*** 481,488 ****
  			panic("vinvalbuf: dirty bufs");
  	}
  
- 	s = splbio();
  	for (;;) {
  		if ((blist = vp->v_cleanblkhd.lh_first) && (flags & V_SAVEMETA))
  			while (blist && blist->b_lblkno < 0)
  				blist = blist->b_vnbufs.le_next;
--- 481,488 ----
  			panic("vinvalbuf: dirty bufs");
  	}
  
  	for (;;) {
+ 		s = splbio();
  		if ((blist = vp->v_cleanblkhd.lh_first) && (flags & V_SAVEMETA))
  			while (blist && blist->b_lblkno < 0)
  				blist = blist->b_vnbufs.le_next;
***************
*** 502,510 ****
  				error = tsleep((caddr_t) bp,
  				    slpflag | (PRIBIO + 1), "vinvalbuf",
  				    slptimeo);
! 				splx(s);
! 				if (error)
  					return (error);
  				break;
  			}
  			bremfree(bp);
--- 502,511 ----
  				error = tsleep((caddr_t) bp,
  				    slpflag | (PRIBIO + 1), "vinvalbuf",
  				    slptimeo);
! 				if (error) {
! 					splx(s);
  					return (error);
+ 				}
  				break;
  			}
  			bremfree(bp);
***************
*** 522,527 ****
--- 523,529 ----
  			bp->b_flags |= (B_INVAL|B_NOCACHE|B_RELBUF);
  			brelse(bp);
  		}
+ 		splx(s);
  	}
  	splx(s);
  
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199703041901.EAA01847>