From nobody@FreeBSD.org  Mon Jun 14 13:36:05 2010
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 8F259106564A
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 14 Jun 2010 13:36:05 +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 665558FC20
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 14 Jun 2010 13:36:05 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o5EDa5kw074168
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 14 Jun 2010 13:36:05 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o5EDa4sg074143;
	Mon, 14 Jun 2010 13:36:04 GMT
	(envelope-from nobody)
Message-Id: <201006141336.o5EDa4sg074143@www.freebsd.org>
Date: Mon, 14 Jun 2010 13:36:04 GMT
From: Bruce Cran <bruce@cran.org.uk>
To: freebsd-gnats-submit@FreeBSD.org
Subject: graid3 panic: g_read_data: invalid length 262144
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         147851
>Category:       kern
>Synopsis:       [geom] [panic] graid3 panic: g_read_data: invalid length 262144
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    ae
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jun 14 13:40:01 UTC 2010
>Closed-Date:    Sat Feb 05 14:34:47 UTC 2011
>Last-Modified:  Sat Feb 05 14:34:47 UTC 2011
>Originator:     Bruce Cran
>Release:        9.0-HEAD-20100610-JPSNAP
>Organization:
>Environment:
N/A (installing)
>Description:
When running:

graid3 label -v -h -s 131072 -r home /dev/ada1 /dev/ada2 /dev/ada3

the following panic occurs:

panic: g_read_data(): invalid length 262144

g_read_data()
g_part_gpt_probe()
g_part_probe()
g_part_taste()
g_new_provider_event()
g_run_events()
g_event_procbody()
fork_exit()
fork_trampoline()
>How-To-Repeat:
graid3 label -v -h -s 131072 -r <label> disk1 disk2 disk3
>Fix:


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-geom 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Tue Jun 15 01:19:02 UTC 2010 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=147851 
Responsible-Changed-From-To: freebsd-geom->ae 
Responsible-Changed-By: ae 
Responsible-Changed-When: Tue Jan 11 10:27:37 UTC 2011 
Responsible-Changed-Why:  
Take it. 

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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/147851: commit references a PR
Date: Wed, 12 Jan 2011 13:55:20 +0000 (UTC)

 Author: ae
 Date: Wed Jan 12 13:55:01 2011
 New Revision: 217305
 URL: http://svn.freebsd.org/changeset/base/217305
 
 Log:
   Sector size can not be greater than MAXPHYS. Since GRAID3 calculates
   sector size from user-specified block size, report to user about
   big blocksize.
   
   PR:		kern/147851
   MFC after:	1 week
 
 Modified:
   head/sbin/geom/class/raid3/geom_raid3.c
   head/sys/geom/raid3/g_raid3.c
 
 Modified: head/sbin/geom/class/raid3/geom_raid3.c
 ==============================================================================
 --- head/sbin/geom/class/raid3/geom_raid3.c	Wed Jan 12 13:16:35 2011	(r217304)
 +++ head/sbin/geom/class/raid3/geom_raid3.c	Wed Jan 12 13:55:01 2011	(r217305)
 @@ -213,6 +213,11 @@ raid3_label(struct gctl_req *req)
  	md.md_sectorsize = sectorsize * (nargs - 2);
  	md.md_mediasize -= (md.md_mediasize % md.md_sectorsize);
  
 +	if (md.md_sectorsize > MAXPHYS) {
 +		gctl_error(req, "The blocksize is too big.");
 +		return;
 +	}
 +
  	/*
  	 * Clear last sector first, to spoil all components if device exists.
  	 */
 
 Modified: head/sys/geom/raid3/g_raid3.c
 ==============================================================================
 --- head/sys/geom/raid3/g_raid3.c	Wed Jan 12 13:16:35 2011	(r217304)
 +++ head/sys/geom/raid3/g_raid3.c	Wed Jan 12 13:55:01 2011	(r217305)
 @@ -2913,6 +2913,10 @@ g_raid3_read_metadata(struct g_consumer 
  		    cp->provider->name);
  		return (error);
  	}
 +	if (md->md_sectorsize > MAXPHYS) {
 +		G_RAID3_DEBUG(0, "The blocksize is too big.");
 +		return (EINVAL);
 +	}
  
  	return (0);
  }
 _______________________________________________
 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/147851: commit references a PR
Date: Tue, 18 Jan 2011 09:53:00 +0000 (UTC)

 Author: ae
 Date: Tue Jan 18 09:52:53 2011
 New Revision: 217531
 URL: http://svn.freebsd.org/changeset/base/217531
 
 Log:
   Limit maximum number of GPT entries to 4k. It is most realistic value
   and can prevent kernel memory exhausting when big value is specified
   from command line.
   
   Split reading and writing operation to several iteration to do not
   trigger KASSERT when data length is greater than MAXPHYS.
   
   PR:             kern/144962, kern/147851
   MFC after:      2 weeks
 
 Modified:
   head/sys/geom/part/g_part_gpt.c
 
 Modified: head/sys/geom/part/g_part_gpt.c
 ==============================================================================
 --- head/sys/geom/part/g_part_gpt.c	Tue Jan 18 06:24:52 2011	(r217530)
 +++ head/sys/geom/part/g_part_gpt.c	Tue Jan 18 09:52:53 2011	(r217531)
 @@ -134,7 +134,7 @@ static struct g_part_scheme g_part_gpt_s
  	sizeof(struct g_part_gpt_table),
  	.gps_entrysz = sizeof(struct g_part_gpt_entry),
  	.gps_minent = 128,
 -	.gps_maxent = INT_MAX,
 +	.gps_maxent = 4096,
  	.gps_bootcodesz = MBRSIZE,
  };
  G_PART_SCHEME_DECLARE(g_part_gpt);
 @@ -317,7 +317,7 @@ gpt_read_tbl(struct g_part_gpt_table *ta
  	struct g_provider *pp;
  	struct gpt_ent *ent, *tbl;
  	char *buf, *p;
 -	unsigned int idx, sectors, tblsz;
 +	unsigned int idx, sectors, tblsz, size;
  	int error;
  
  	if (hdr == NULL)
 @@ -329,11 +329,19 @@ gpt_read_tbl(struct g_part_gpt_table *ta
  	table->state[elt] = GPT_STATE_MISSING;
  	tblsz = hdr->hdr_entries * hdr->hdr_entsz;
  	sectors = (tblsz + pp->sectorsize - 1) / pp->sectorsize;
 -	buf = g_read_data(cp, table->lba[elt] * pp->sectorsize, 
 -	    sectors * pp->sectorsize, &error);
 -	if (buf == NULL)
 -		return (NULL);
 -
 +	buf = g_malloc(sectors * pp->sectorsize, M_WAITOK | M_ZERO);
 +	for (idx = 0; idx < sectors; idx += MAXPHYS / pp->sectorsize) {
 +		size = (sectors - idx > MAXPHYS / pp->sectorsize) ?  MAXPHYS:
 +		    (sectors - idx) * pp->sectorsize;
 +		p = g_read_data(cp, (table->lba[elt] + idx) * pp->sectorsize,
 +		    size, &error);
 +		if (p == NULL) {
 +			g_free(buf);
 +			return (NULL);
 +		}
 +		bcopy(p, buf + idx * pp->sectorsize, size);
 +		g_free(p);
 +	}
  	table->state[elt] = GPT_STATE_CORRUPT;
  	if (crc32(buf, tblsz) != hdr->hdr_crc_table) {
  		g_free(buf);
 @@ -986,10 +994,15 @@ g_part_gpt_write(struct g_part_table *ba
  	crc = crc32(buf, table->hdr->hdr_size);
  	le32enc(buf + 16, crc);
  
 -	error = g_write_data(cp, table->lba[GPT_ELT_PRITBL] * pp->sectorsize,
 -	    buf + pp->sectorsize, tblsz * pp->sectorsize);
 -	if (error)
 -		goto out;
 +	for (index = 0; index < tblsz; index += MAXPHYS / pp->sectorsize) {
 +		error = g_write_data(cp,
 +		    (table->lba[GPT_ELT_PRITBL] + index) * pp->sectorsize,
 +		    buf + (index + 1) * pp->sectorsize,
 +		    (tblsz - index > MAXPHYS / pp->sectorsize) ? MAXPHYS:
 +		    (tblsz - index) * pp->sectorsize);
 +		if (error)
 +			goto out;
 +	}
  	error = g_write_data(cp, table->lba[GPT_ELT_PRIHDR] * pp->sectorsize,
  	    buf, pp->sectorsize);
  	if (error)
 @@ -1003,10 +1016,15 @@ g_part_gpt_write(struct g_part_table *ba
  	crc = crc32(buf, table->hdr->hdr_size);
  	le32enc(buf + 16, crc);
  
 -	error = g_write_data(cp, table->lba[GPT_ELT_SECTBL] * pp->sectorsize,
 -	    buf + pp->sectorsize, tblsz * pp->sectorsize);
 -	if (error)
 -		goto out;
 +	for (index = 0; index < tblsz; index += MAXPHYS / pp->sectorsize) {
 +		error = g_write_data(cp,
 +		    (table->lba[GPT_ELT_SECTBL] + index) * pp->sectorsize,
 +		    buf + (index + 1) * pp->sectorsize,
 +		    (tblsz - index > MAXPHYS / pp->sectorsize) ? MAXPHYS:
 +		    (tblsz - index) * pp->sectorsize);
 +		if (error)
 +			goto out;
 +	}
  	error = g_write_data(cp, table->lba[GPT_ELT_SECHDR] * pp->sectorsize,
  	    buf, pp->sectorsize);
  
 _______________________________________________
 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->patched 
State-Changed-By: ae 
State-Changed-When: Tue Jan 18 10:11:20 UTC 2011 
State-Changed-Why:  
Patched in head/. 

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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/147851: commit references a PR
Date: Wed, 19 Jan 2011 05:13:45 +0000 (UTC)

 Author: ae
 Date: Wed Jan 19 05:13:40 2011
 New Revision: 217572
 URL: http://svn.freebsd.org/changeset/base/217572
 
 Log:
   MFC r217305:
     Sector size can not be greater than MAXPHYS. Since GRAID3 calculates
     sector size from user-specified block size, report to user about
     big blocksize.
   
     PR:		kern/147851
 
 Modified:
   stable/8/sbin/geom/class/raid3/geom_raid3.c
   stable/8/sys/geom/raid3/g_raid3.c
 Directory Properties:
   stable/8/sbin/geom/   (props changed)
   stable/8/sbin/geom/class/multipath/   (props changed)
   stable/8/sbin/geom/class/part/   (props changed)
   stable/8/sbin/geom/class/sched/gsched.8   (props changed)
   stable/8/sbin/geom/class/stripe/   (props changed)
   stable/8/sys/   (props changed)
   stable/8/sys/amd64/include/xen/   (props changed)
   stable/8/sys/cddl/contrib/opensolaris/   (props changed)
   stable/8/sys/contrib/dev/acpica/   (props changed)
   stable/8/sys/contrib/pf/   (props changed)
 
 Modified: stable/8/sbin/geom/class/raid3/geom_raid3.c
 ==============================================================================
 --- stable/8/sbin/geom/class/raid3/geom_raid3.c	Wed Jan 19 05:08:32 2011	(r217571)
 +++ stable/8/sbin/geom/class/raid3/geom_raid3.c	Wed Jan 19 05:13:40 2011	(r217572)
 @@ -212,6 +212,11 @@ raid3_label(struct gctl_req *req)
  	md.md_sectorsize = sectorsize * (nargs - 2);
  	md.md_mediasize -= (md.md_mediasize % md.md_sectorsize);
  
 +	if (md.md_sectorsize > MAXPHYS) {
 +		gctl_error(req, "The blocksize is too big.");
 +		return;
 +	}
 +
  	/*
  	 * Clear last sector first, to spoil all components if device exists.
  	 */
 
 Modified: stable/8/sys/geom/raid3/g_raid3.c
 ==============================================================================
 --- stable/8/sys/geom/raid3/g_raid3.c	Wed Jan 19 05:08:32 2011	(r217571)
 +++ stable/8/sys/geom/raid3/g_raid3.c	Wed Jan 19 05:13:40 2011	(r217572)
 @@ -2913,6 +2913,10 @@ g_raid3_read_metadata(struct g_consumer 
  		    cp->provider->name);
  		return (error);
  	}
 +	if (md->md_sectorsize > MAXPHYS) {
 +		G_RAID3_DEBUG(0, "The blocksize is too big.");
 +		return (EINVAL);
 +	}
  
  	return (0);
  }
 _______________________________________________
 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/147851: commit references a PR
Date: Tue,  1 Feb 2011 09:27:38 +0000 (UTC)

 Author: ae
 Date: Tue Feb  1 09:27:28 2011
 New Revision: 218162
 URL: http://svn.freebsd.org/changeset/base/218162
 
 Log:
   MFC r217531:
     Limit maximum number of GPT entries to 4k. It is most realistic value
     and can prevent kernel memory exhausting when big value is specified
     from command line.
   
     Split reading and writing operation to several iterations to do not
     trigger KASSERT when data length is greater than MAXPHYS.
   
     PR:             kern/144962, kern/147851
 
 Modified:
   stable/8/sys/geom/part/g_part_gpt.c
 Directory Properties:
   stable/8/sys/   (props changed)
   stable/8/sys/amd64/include/xen/   (props changed)
   stable/8/sys/cddl/contrib/opensolaris/   (props changed)
   stable/8/sys/contrib/dev/acpica/   (props changed)
   stable/8/sys/contrib/pf/   (props changed)
 
 Modified: stable/8/sys/geom/part/g_part_gpt.c
 ==============================================================================
 --- stable/8/sys/geom/part/g_part_gpt.c	Tue Feb  1 09:27:24 2011	(r218161)
 +++ stable/8/sys/geom/part/g_part_gpt.c	Tue Feb  1 09:27:28 2011	(r218162)
 @@ -134,7 +134,7 @@ static struct g_part_scheme g_part_gpt_s
  	sizeof(struct g_part_gpt_table),
  	.gps_entrysz = sizeof(struct g_part_gpt_entry),
  	.gps_minent = 128,
 -	.gps_maxent = INT_MAX,
 +	.gps_maxent = 4096,
  	.gps_bootcodesz = MBRSIZE,
  };
  G_PART_SCHEME_DECLARE(g_part_gpt);
 @@ -317,7 +317,7 @@ gpt_read_tbl(struct g_part_gpt_table *ta
  	struct g_provider *pp;
  	struct gpt_ent *ent, *tbl;
  	char *buf, *p;
 -	unsigned int idx, sectors, tblsz;
 +	unsigned int idx, sectors, tblsz, size;
  	int error;
  
  	if (hdr == NULL)
 @@ -329,11 +329,19 @@ gpt_read_tbl(struct g_part_gpt_table *ta
  	table->state[elt] = GPT_STATE_MISSING;
  	tblsz = hdr->hdr_entries * hdr->hdr_entsz;
  	sectors = (tblsz + pp->sectorsize - 1) / pp->sectorsize;
 -	buf = g_read_data(cp, table->lba[elt] * pp->sectorsize, 
 -	    sectors * pp->sectorsize, &error);
 -	if (buf == NULL)
 -		return (NULL);
 -
 +	buf = g_malloc(sectors * pp->sectorsize, M_WAITOK | M_ZERO);
 +	for (idx = 0; idx < sectors; idx += MAXPHYS / pp->sectorsize) {
 +		size = (sectors - idx > MAXPHYS / pp->sectorsize) ?  MAXPHYS:
 +		    (sectors - idx) * pp->sectorsize;
 +		p = g_read_data(cp, (table->lba[elt] + idx) * pp->sectorsize,
 +		    size, &error);
 +		if (p == NULL) {
 +			g_free(buf);
 +			return (NULL);
 +		}
 +		bcopy(p, buf + idx * pp->sectorsize, size);
 +		g_free(p);
 +	}
  	table->state[elt] = GPT_STATE_CORRUPT;
  	if (crc32(buf, tblsz) != hdr->hdr_crc_table) {
  		g_free(buf);
 @@ -986,10 +994,15 @@ g_part_gpt_write(struct g_part_table *ba
  	crc = crc32(buf, table->hdr->hdr_size);
  	le32enc(buf + 16, crc);
  
 -	error = g_write_data(cp, table->lba[GPT_ELT_PRITBL] * pp->sectorsize,
 -	    buf + pp->sectorsize, tblsz * pp->sectorsize);
 -	if (error)
 -		goto out;
 +	for (index = 0; index < tblsz; index += MAXPHYS / pp->sectorsize) {
 +		error = g_write_data(cp,
 +		    (table->lba[GPT_ELT_PRITBL] + index) * pp->sectorsize,
 +		    buf + (index + 1) * pp->sectorsize,
 +		    (tblsz - index > MAXPHYS / pp->sectorsize) ? MAXPHYS:
 +		    (tblsz - index) * pp->sectorsize);
 +		if (error)
 +			goto out;
 +	}
  	error = g_write_data(cp, table->lba[GPT_ELT_PRIHDR] * pp->sectorsize,
  	    buf, pp->sectorsize);
  	if (error)
 @@ -1003,10 +1016,15 @@ g_part_gpt_write(struct g_part_table *ba
  	crc = crc32(buf, table->hdr->hdr_size);
  	le32enc(buf + 16, crc);
  
 -	error = g_write_data(cp, table->lba[GPT_ELT_SECTBL] * pp->sectorsize,
 -	    buf + pp->sectorsize, tblsz * pp->sectorsize);
 -	if (error)
 -		goto out;
 +	for (index = 0; index < tblsz; index += MAXPHYS / pp->sectorsize) {
 +		error = g_write_data(cp,
 +		    (table->lba[GPT_ELT_SECTBL] + index) * pp->sectorsize,
 +		    buf + (index + 1) * pp->sectorsize,
 +		    (tblsz - index > MAXPHYS / pp->sectorsize) ? MAXPHYS:
 +		    (tblsz - index) * pp->sectorsize);
 +		if (error)
 +			goto out;
 +	}
  	error = g_write_data(cp, table->lba[GPT_ELT_SECHDR] * pp->sectorsize,
  	    buf, pp->sectorsize);
  
 _______________________________________________
 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: patched->closed 
State-Changed-By: ae 
State-Changed-When: Sat Feb 5 14:33:43 UTC 2011 
State-Changed-Why:  
Fix commited to head/ and stable/8. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=147851 
>Unformatted:
