NetBSD Problem Report #42312

From www@NetBSD.org  Fri Nov 13 18:35:04 2009
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by www.NetBSD.org (Postfix) with ESMTP id D500B63B8CD
	for <gnats-bugs@gnats.netbsd.org>; Fri, 13 Nov 2009 18:35:03 +0000 (UTC)
Message-Id: <20091113183503.71F6863B844@www.NetBSD.org>
Date: Fri, 13 Nov 2009 18:35:03 +0000 (UTC)
From: tlambert@apple.com
Reply-To: tlambert@apple.com
To: gnats-bugs@NetBSD.org
Subject: Range problem in clrbit()s in tty_subr.c
X-Send-Pr-Version: www-1.0

>Number:         42312
>Category:       kern
>Synopsis:       Range problem in clrbit()s in tty_subr.c
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Nov 13 18:40:01 +0000 2009
>Closed-Date:    Fri Nov 13 19:19:38 +0000 2009
>Last-Modified:  Fri Nov 27 09:20:07 +0000 2009
>Originator:     Terry Lambert
>Release:        Release 5.0.1
>Organization:
Apple
>Environment:
N/A
>Description:
When the following code is run on a count of bytes or an offset + len that pushes it to exactly a byte boundary, it will zero one byte beyond the end of the buffer.  If the buffer is up against a page boundary, the system will panic, and if not, it will result in touching the first byte of the buffer following.  Since tty buffers are typically allocated in 1K chunks, there is a 1:4 probabiliy of this being in unmapped space on a system with 4K pages.  This is the code:

[...]
	eby = (off+len) / NBBY;
	ebi = (off+len) % NBBY;
	if (sby == eby) {
		mask = ((1 << (ebi - sbi)) - 1) << sbi;
		cp[sby] &= ~mask;
	} else {
		mask = (1<<sbi) - 1;
		cp[sby++] &= mask;

		mask = (1<<ebi) - 1;
		cp[eby] &= ~mask;

		for (i = sby; i < eby; i++)
			cp[i] = 0x00;
	}

...consider an 'off' value of 0x3fc and a 'len' value of 4; NBBY is 8, so:

(gdb) p/x (0x3fc + 4) % 8
$16 = 0x0 (ebi)
(gdb) p/x (0x3fc + 4) / 8
$17 = 0x80 (eby)

For this code:

		mask = (1<<ebi) - 1;
		cp[eby] &= ~mask;

		for (i = sby; i < eby; i++)

mask = (1<<0) - 1          /* == 0 */
cp[0x80] &= ~0;               /* promoted to lval type; unsigned char == 0xff */

...range should be per the 'for' loop, which is the interval [sby..eby).
>How-To-Repeat:
This is hard to reproduce, and is theoretical on the basis of problems observed in Mac OS X, which incorporates identical code.
>Fix:
- 		mask = (1<<ebi) - 1;
-		cp[eby] &= ~mask;
---
+		if ((mask = (1<<ebi) - 1) != 0);
+			cp[eby] &= ~mask;

>Release-Note:

>Audit-Trail:

State-Changed-From-To: open->closed
State-Changed-By: dsl@NetBSD.org
State-Changed-When: Fri, 13 Nov 2009 19:19:38 +0000
State-Changed-Why:
Similar fix applied.
Pullup requested for NetBSD 5


From: David Laight <dsl@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/42312 CVS commit: src/sys/kern
Date: Fri, 13 Nov 2009 19:15:24 +0000

 Module Name:	src
 Committed By:	dsl
 Date:		Fri Nov 13 19:15:24 UTC 2009

 Modified Files:
 	src/sys/kern: tty_subr.c

 Log Message:
 Fix clrbits() so that it doesn't mask no bits out of the byte after the
 range (when the last bit to be cleared is the msb of a byte).
 Fixes PR/42312 in a slightly better way than proposed.


 To generate a diff of this commit:
 cvs rdiff -u -r1.37 -r1.38 src/sys/kern/tty_subr.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Stephen Borrill <sborrill@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/42312 CVS commit: [netbsd-5] src/sys/kern
Date: Fri, 27 Nov 2009 09:15:27 +0000

 Module Name:	src
 Committed By:	sborrill
 Date:		Fri Nov 27 09:15:27 UTC 2009

 Modified Files:
 	src/sys/kern [netbsd-5]: tty_subr.c

 Log Message:
 Pull up the following revisions(s) (requested by dsl in ticket #1141):
 	sys/kern/tty_subr.c:	revision 1.38

 Fix clrbits() so that it doesn't mask no bits out of the byte after the
 range (when the last bit to be cleared is the msb of a byte).
 Fixes PR/42312.


 To generate a diff of this commit:
 cvs rdiff -u -r1.34 -r1.34.4.1 src/sys/kern/tty_subr.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Stephen Borrill <sborrill@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/42312 CVS commit: [netbsd-5-0] src/sys/kern
Date: Fri, 27 Nov 2009 09:19:13 +0000

 Module Name:	src
 Committed By:	sborrill
 Date:		Fri Nov 27 09:19:13 UTC 2009

 Modified Files:
 	src/sys/kern [netbsd-5-0]: tty_subr.c

 Log Message:
 Pull up the following revisions(s) (requested by dsl in ticket #1141):
 	sys/kern/tty_subr.c:	revision 1.38

 Fix clrbits() so that it doesn't mask no bits out of the byte after the
 range (when the last bit to be cleared is the msb of a byte).
 Fixes PR/42312.


 To generate a diff of this commit:
 cvs rdiff -u -r1.34 -r1.34.8.1 src/sys/kern/tty_subr.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.