shithub: riscv

Download patch

ref: 5b24195a0a8dc6f2f83eb142dfbc714fc5fc8a8a
parent: b5008f3b562404811a81a755c6d06b47f47e545f
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Jan 3 23:26:58 EST 2015

sdiahci: sanitize ahci pci bar

make sure the ahci pci bar is not in i/o space and has
the right size. also make sure Aport registers are within
the ahci bar range.

--- a/sys/src/9/pc/sdiahci.c
+++ b/sys/src/9/pc/sdiahci.c
@@ -2159,8 +2159,10 @@
 	while((p = pcimatch(p, 0, 0)) != nil){
 		if((type = didtype(p)) == -1)
 			continue;
-		if(p->mem[Abar].bar == 0)
+		io = p->mem[Abar].bar;
+		if(io == 0 || (io & 1) != 0 || p->mem[Abar].size < 0x180)
 			continue;
+		io &= ~0xf;
 		if(niactlr == NCtlr){
 			print("iapnp: %s: too many controllers\n", tname[type]);
 			break;
@@ -2169,7 +2171,6 @@
 		s = sdevs + niactlr;
 		memset(c, 0, sizeof *c);
 		memset(s, 0, sizeof *s);
-		io = p->mem[Abar].bar & ~0xf;
 		c->mmio = vmap(io, p->mem[Abar].size);
 		if(c->mmio == 0){
 			print("%s: address %#p in use did %.4ux\n",
@@ -2208,11 +2209,14 @@
 			d->ctlr = c;
 			if((c->hba->pi & 1<<i) == 0)
 				continue;
-			snprint(d->name, sizeof d->name, "iahci%d.%d", niactlr, i);
-			d->port = (Aport*)(c->mmio + 0x80*i + 0x100);
+			io = 0x100 + 0x80*i;
+			if((io + 0x80) > p->mem[Abar].size)
+				continue;
+			d->port = (Aport*)(c->mmio + io);
 			d->portc.p = d->port;
 			d->portc.m = &d->portm;
 			d->driveno = n++;
+			snprint(d->name, sizeof d->name, "iahci%d.%d", niactlr, i);
 			c->drive[d->driveno] = d;
 			iadrive[niadrive + d->driveno] = d;
 		}