mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 17:18:32 +00:00
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
This commit is contained in:
parent
2c4992db70
commit
799eac8c3d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=217531
|
@ -134,7 +134,7 @@ static struct g_part_scheme g_part_gpt_scheme = {
|
|||
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 *table, struct g_consumer *cp,
|
|||
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 *table, struct g_consumer *cp,
|
|||
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 *basetable, struct g_consumer *cp)
|
|||
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 *basetable, struct g_consumer *cp)
|
|||
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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue