Subject: kern/5729: ccd disk concatenation may cause kernel panic
To: None <gnats-bugs@gnats.netbsd.org>
From: None <soda@sra.co.jp>
List: netbsd-bugs
Date: 07/10/1998 04:39:40
>Number:         5729
>Category:       kern
>Synopsis:       ccd disk concatenation may cause kernel panic
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jul  9 12:50:01 1998
>Last-Modified:
>Originator:     Noriyuki SODA
>Organization:
	Software Research Associates, Inc.
>Release:        NetBSD-1.3F, Jul 9, 1998
>Environment:
System: NetBSD james 1.3F NetBSD 1.3F (UVM_PMAPNEW) #0: Sun Jul 5 02:59:55 JST 1998 soda@floyd:/usr/current/src/sys/arch/i386/compile/UVM_PMAPNEW i386

>Description:

CCD disk concatenation (i.e. interleave == 0) may cause kernel panic,
due to integer arithmetic overflow.

dbtob(ci->ci_size - cbn) in the following code may overflow int32_t,
which finally cause erroneous disk access.

>How-To-Repeat:

Use CCD with interleave == 0, with large disk partition.

>Fix:

Apply the following patch:

------------------------------------------------------------------------
*** sys/dev/ccd.c~	Sun Mar  1 21:21:04 1998
--- sys/dev/ccd.c	Fri Jul 10 04:12:20 1998
***************
*** 783,788 ****
--- 783,789 ----
  	register struct ccdcinfo *ci, *ci2 = NULL;
  	register struct ccdbuf *cbp;
  	register daddr_t cbn, cboff;
+ 	register u_int64_t cbc;
  	int ccdisk;
  
  #ifdef DEBUG
***************
*** 858,868 ****
  	cbp->cb_buf.b_data = addr;
  	cbp->cb_buf.b_vp = ci->ci_vp;
  	if (cs->sc_ileave == 0)
! 		cbp->cb_buf.b_bcount = dbtob(ci->ci_size - cbn);
  	else
! 		cbp->cb_buf.b_bcount = dbtob(cs->sc_ileave - cboff);
! 	if (cbp->cb_buf.b_bcount > bcount)
! 		cbp->cb_buf.b_bcount = bcount;
  
  	/*
  	 * context for ccdiodone
--- 859,868 ----
  	cbp->cb_buf.b_data = addr;
  	cbp->cb_buf.b_vp = ci->ci_vp;
  	if (cs->sc_ileave == 0)
! 		cbc = dbtob((u_int64_t)(ci->ci_size - cbn));
  	else
! 		cbc = dbtob((u_int64_t)(cs->sc_ileave - cboff));
! 	cbp->cb_buf.b_bcount = cbc < bcount ? cbc : bcount;
  
  	/*
  	 * context for ccdiodone
------------------------------------------------------------------------

How about changing the definition of dbtob() from
	#define	dbtob(x)	((x) << DEV_BSHIFT)
to
	#define	dbtob(x)	((u_int64_t)((x) << DEV_BSHIFT))
for detecting this type of error by compiler warning ?

--
soda@sra.co.jp		Software Research Associates, Inc., Japan
(Noriyuki Soda)			Advanced Technology Group.
>Audit-Trail:
>Unformatted: