Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 1 Feb 2011 09:27:29 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r218162 - stable/8/sys/geom/part
Message-ID:  <201102010927.p119RTT2065573@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 



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