Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 19 Jul 2012 19:15:06 GMT
From:      Mark Johnston <markjdb@gmail.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/170003: [ichsmb] buffer overflow during block read
Message-ID:  <201207191915.q6JJF6AN023826@red.freebsd.org>
Resent-Message-ID: <201207191920.q6JJKDFs098818@freefall.freebsd.org>

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

>Number:         170003
>Category:       kern
>Synopsis:       [ichsmb] buffer overflow during block read
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jul 19 19:20:13 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator:     Mark Johnston
>Release:        CURRENT
>Organization:
Sandvine Inc.
>Environment:
FreeBSD oddish 10.0-CURRENT FreeBSD 10.0-CURRENT #0 r237931+09aeb19-dirty: Sun Jul  1 13:10:47 EDT 2012     mark@oddish:/home/mark/src/obj/usr/home/mark/src/freebsd/sys/GENERIC  amd64
>Description:
ichsmb(4) uses a 32-byte buffer in the softc to hold the bytes received from a block read command. When such a command is issued, the hardware is supposed to fill out the host data 0 register with the number of bytes to be returned. Some devices return more than 32 bytes for some reason, causing ichsmb to clobber parts of its softc. In my case, the mutex gets overwritten, leading to a panic during execution of the next smbus command.
>How-To-Repeat:
It may not be reproducible depending on the devices available on the bus. Try running the program here: http://www.student.cs.uwaterloo.ca/~m6johnst/smbbread.c
>Fix:
Attached patch.

Patch attached with submission follows:

diff --git a/sys/dev/ichsmb/ichsmb.c b/sys/dev/ichsmb/ichsmb.c
index 5ff54db..ac4d191 100644
--- a/sys/dev/ichsmb/ichsmb.c
+++ b/sys/dev/ichsmb/ichsmb.c
@@ -575,8 +575,9 @@ ichsmb_device_intr(void *cookie)
 
 				/* First interrupt, get the count also */
 				if (sc->block_index == 0) {
-					sc->block_count = bus_read_1(
-					    sc->io_res, ICH_D0);
+					sc->block_count = min(
+					    bus_read_1(sc->io_res, ICH_D0),
+					    sizeof(sc->block_data));
 				}
 
 				/* Get next byte, if any */


>Release-Note:
>Audit-Trail:
>Unformatted:



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