mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-22 10:48:02 +00:00
geom_part: Check number of GPT entries and size of GPT entry
Current specification does not have upper limit of the number of
partition entries and the size of partition entry. In
799eac8c3d
Andrey V. Elsukov introduced a
limit maximum number of GPT entries to 4k, but that is for write routine
(gpart create) only. When attaching disks that have large number of GPT
entries exceeding the limit, or disks with large size of partition
entry, it is still possible to exhaust kernel memory.
1. Reuse the limit of the maximum number of partition entries.
2. Limit the maximum size of GPT entry to 1k.
In current specification (2.10) the size of GPT entry is 128 *
2^n while n >= 0, and the size - 128 is reserved. 1k should be
sufficient enough for foreseen future.
PR: 266548
Discussed with: imp
Reviewed by: markj
MFC after: 1 month
Differential Revision: https://reviews.freebsd.org/D36717
This commit is contained in:
parent
3467e28f3d
commit
5be5d0d5cb
|
@ -85,6 +85,7 @@ enum gpt_state {
|
|||
GPT_STATE_MISSING, /* No signature found. */
|
||||
GPT_STATE_CORRUPT, /* Checksum mismatch. */
|
||||
GPT_STATE_INVALID, /* Nonconformant/invalid. */
|
||||
GPT_STATE_UNSUPPORTED, /* Not supported. */
|
||||
GPT_STATE_OK /* Perfectly fine. */
|
||||
};
|
||||
|
||||
|
@ -148,6 +149,8 @@ static kobj_method_t g_part_gpt_methods[] = {
|
|||
{ 0, 0 }
|
||||
};
|
||||
|
||||
#define MAXENTSIZE 1024
|
||||
|
||||
static struct g_part_scheme g_part_gpt_scheme = {
|
||||
"GPT",
|
||||
g_part_gpt_methods,
|
||||
|
@ -548,6 +551,11 @@ gpt_read_tbl(struct g_part_gpt_table *table, struct g_consumer *cp,
|
|||
|
||||
if (hdr == NULL)
|
||||
return (NULL);
|
||||
if (hdr->hdr_entries > g_part_gpt_scheme.gps_maxent ||
|
||||
hdr->hdr_entsz > MAXENTSIZE) {
|
||||
table->state[elt] = GPT_STATE_UNSUPPORTED;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
pp = cp->provider;
|
||||
table->lba[elt] = hdr->hdr_lba_table;
|
||||
|
@ -961,10 +969,25 @@ g_part_gpt_read(struct g_part_table *basetable, struct g_consumer *cp)
|
|||
/* Fail if we haven't got any good tables at all. */
|
||||
if (table->state[GPT_ELT_PRITBL] != GPT_STATE_OK &&
|
||||
table->state[GPT_ELT_SECTBL] != GPT_STATE_OK) {
|
||||
printf("GEOM: %s: corrupt or invalid GPT detected.\n",
|
||||
pp->name);
|
||||
printf("GEOM: %s: GPT rejected -- may not be recoverable.\n",
|
||||
pp->name);
|
||||
if (table->state[GPT_ELT_PRITBL] == GPT_STATE_UNSUPPORTED &&
|
||||
table->state[GPT_ELT_SECTBL] == GPT_STATE_UNSUPPORTED &&
|
||||
gpt_matched_hdrs(prihdr, sechdr)) {
|
||||
printf("GEOM: %s: unsupported GPT detected.\n",
|
||||
pp->name);
|
||||
printf(
|
||||
"GEOM: %s: number of GPT entries: %u, entry size: %uB.\n",
|
||||
pp->name, prihdr->hdr_entries, prihdr->hdr_entsz);
|
||||
printf(
|
||||
"GEOM: %s: maximum supported number of GPT entries: %u, entry size: %uB.\n",
|
||||
pp->name, g_part_gpt_scheme.gps_maxent, MAXENTSIZE);
|
||||
printf("GEOM: %s: GPT rejected.\n", pp->name);
|
||||
} else {
|
||||
printf("GEOM: %s: corrupt or invalid GPT detected.\n",
|
||||
pp->name);
|
||||
printf(
|
||||
"GEOM: %s: GPT rejected -- may not be recoverable.\n",
|
||||
pp->name);
|
||||
}
|
||||
if (prihdr != NULL)
|
||||
g_free(prihdr);
|
||||
if (pritbl != NULL)
|
||||
|
|
Loading…
Reference in a new issue