diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2021-08-17 00:05:17 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2021-08-17 00:05:17 +0200 |
commit | 4a704a0ad95973249544f3f95e30e328e701a871 (patch) | |
tree | 861ef383f6de782b5f09c13d2d9d5d65836c03e1 /linux/dev/drivers | |
parent | f67a2a46931028753364ab6bcb6a43c12f8303b2 (diff) | |
download | gnumach-4a704a0ad95973249544f3f95e30e328e701a871.tar.gz gnumach-4a704a0ad95973249544f3f95e30e328e701a871.tar.bz2 gnumach-4a704a0ad95973249544f3f95e30e328e701a871.zip |
block: Look out for disk sector number overflow
* linux/dev/drivers/block/ahci.c (ahci_do_port_request): Reject sectors
beyond LBA48 or LBA28.
* linux/dev/glue/block.c (check_rw_block): New function.
(rdwr_partial, rdwr_full): Use check_rw_block to reject block number
overflows.
* linux/src/drivers/block/ide.c (do_rw_disk): Reject sectors beyond
LBA28 or CHS.
Diffstat (limited to 'linux/dev/drivers')
-rw-r--r-- | linux/dev/drivers/block/ahci.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/linux/dev/drivers/block/ahci.c b/linux/dev/drivers/block/ahci.c index ce2ac403..b8fd9dae 100644 --- a/linux/dev/drivers/block/ahci.c +++ b/linux/dev/drivers/block/ahci.c @@ -288,7 +288,7 @@ static void ahci_end_request(int uptodate) } /* Push the request to the controler port */ -static void ahci_do_port_request(struct port *port, unsigned long long sector, struct request *rq) +static int ahci_do_port_request(struct port *port, unsigned long long sector, struct request *rq) { struct ahci_command *command = port->command; struct ahci_cmd_tbl *prdtl = port->prdtl; @@ -305,16 +305,25 @@ static void ahci_do_port_request(struct port *port, unsigned long long sector, s fis_h2d = (void*) &prdtl[slot].cfis; fis_h2d->fis_type = FIS_TYPE_REG_H2D; fis_h2d->flags = 128; - if (port->lba48) + if (port->lba48) { + if (sector >= 1ULL << 48) { + printk("sector %llu beyond LBA48\n", sector); + return -EOVERFLOW; + } if (rq->cmd == READ) fis_h2d->command = WIN_READDMA_EXT; else fis_h2d->command = WIN_WRITEDMA_EXT; - else + } else { + if (sector >= 1ULL << 28) { + printk("sector %llu beyond LBA28\n", sector); + return -EOVERFLOW; + } if (rq->cmd == READ) fis_h2d->command = WIN_READDMA; else fis_h2d->command = WIN_WRITEDMA; + } fis_h2d->device = 1<<6; /* LBA */ @@ -353,6 +362,7 @@ static void ahci_do_port_request(struct port *port, unsigned long long sector, s writel(1 << slot, &port->ahci_port->ci); /* TODO: IRQ timeout handler */ + return 0; } /* Called by block core to push a request */ @@ -409,7 +419,8 @@ static void ahci_do_request() /* invoked with cli() */ } /* Push this to the port */ - ahci_do_port_request(port, block, rq); + if (ahci_do_port_request(port, block, rq)) + goto kill_rq; return; kill_rq: |