DF-2493 / fix.diff
diff --git a/sys/dev/disk/nata/ata-raid.c b/sys/dev/disk/nata/ata-raid.c --- a/sys/dev/disk/nata/ata-raid.c +++ b/sys/dev/disk/nata/ata-raid.c @@ -3107,6 +3107,12 @@ raid->interleave = meta->stripe_sectors; raid->width = meta->array_width; raid->total_disks = meta->total_disks; + /* total_disks is read from untrusted on-disk metadata and is used to + * iterate rdp->disks[MAX_DISKS] elsewhere. Reject/cap out-of-range + * values; the on-disk value can otherwise reach 256 and drive OOB + * indexing of disks[]. See DF-2493. */ + if (raid->total_disks > MAX_DISKS) + raid->total_disks = MAX_DISKS; raid->total_sectors = meta->total_sectors; raid->heads = 255; raid->sectors = 63; @@ -3118,6 +3124,13 @@ if (meta->status & NV_S_DEGRADED) raid->status |= AR_S_DEGRADED; + /* meta->disk_number is read straight from untrusted on-disk metadata + * and indexes the fixed disks[MAX_DISKS] array. Reject out-of-range + * values instead of writing past the end of ar_softc. The same guard + * is required in every vendor metadata parser (HighPoint v2/v3, LSI, + * Silicon Image, Promise, Intel). See DF-2493. */ + if (meta->disk_number >= MAX_DISKS) + goto nvidia_out; raid->disks[meta->disk_number].dev = parent; raid->disks[meta->disk_number].sectors = raid->total_sectors / raid->width; |