block: ioctl: fix information leak to userland
Structure hd_geometry is copied to userland with 4 padding bytes
between cylinders and start fields uninitialized on 64-bit platforms.
It leads to leaking of contents of kernel stack memory.
Signed-off-by: Vasiliy Kulikov <segooon@gmail.com>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
(2.6 commit: a014741c0adfb8fb79952939ca087cf03d272bb9)
[WT: different fix from 2.6 because we could not centralize the ioctl, so
all affected drivers had to be fixed ]
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index b1a2766..e462a3c 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -5457,6 +5457,7 @@
{
case HDIO_GETGEO:
/* Get BIOS Disk Geometry. */
+ memset(&Geometry, 0, sizeof(Geometry));
UserGeometry = (DiskGeometry_T *) Argument;
if (UserGeometry == NULL) return -EINVAL;
if (Controller->FirmwareType == DAC960_V1_Controller)
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 36de0ae..85d98d4 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1489,6 +1489,7 @@
case HDIO_GETGEO:
{
struct hd_geometry loc;
+ memset(&loc, 0, sizeof(loc));
loc.heads = unit[drive].type->heads;
loc.sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;
loc.cylinders = unit[drive].type->tracks;
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 62b906c..7e83aeb 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -702,6 +702,7 @@
case HDIO_GETGEO:
{
struct hd_geometry driver_geo;
+ memset(&driver_geo, 0, sizeof(driver_geo));
if (hba[ctlr]->drv[dsk].cylinders) {
driver_geo.heads = hba[ctlr]->drv[dsk].heads;
driver_geo.sectors = hba[ctlr]->drv[dsk].sectors;
@@ -718,6 +719,7 @@
case HDIO_GETGEO_BIG:
{
struct hd_big_geometry driver_geo;
+ memset(&driver_geo, 0, sizeof(driver_geo));
if (hba[ctlr]->drv[dsk].cylinders) {
driver_geo.heads = hba[ctlr]->drv[dsk].heads;
driver_geo.sectors = hba[ctlr]->drv[dsk].sectors;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index dfd891f..af8815d 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -1247,6 +1247,7 @@
{
struct hd_geometry driver_geo;
+ memset(&driver_geo, 0, sizeof(driver_geo));
if (hba[ctlr]->drv[dsk].cylinders) {
driver_geo.heads = hba[ctlr]->drv[dsk].heads;
driver_geo.sectors = hba[ctlr]->drv[dsk].sectors;
@@ -1268,6 +1269,7 @@
{
struct hd_big_geometry driver_geo;
+ memset(&driver_geo, 0, sizeof(driver_geo));
if (hba[ctlr]->drv[dsk].cylinders) {
driver_geo.heads = hba[ctlr]->drv[dsk].heads;
driver_geo.sectors = hba[ctlr]->drv[dsk].sectors;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 24b68c0..f96cc3d 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3504,6 +3504,7 @@
case HDIO_GETGEO:
{
struct hd_geometry loc;
+ memset(&loc, 0, sizeof(loc));
ECALL(get_floppy_geometry(drive, type, &g));
loc.heads = g->head;
loc.sectors = g->sect;
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index d04f0f0..0780a34 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -477,6 +477,7 @@
case HDIO_GETGEO: {
struct hd_geometry geom;
+ memset(&geom, 0, sizeof(geom));
if (!usermem)
return -EINVAL;
@@ -503,6 +504,7 @@
case HDIO_GETGEO_BIG: {
struct hd_big_geometry geom;
+ memset(&geom, 0, sizeof(geom));
if (!usermem)
return -EINVAL;
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 79954a7..da51c29 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -866,6 +866,7 @@
* multiple of 2048 (1M): tell we have 32 sectors, 64 heads,
* whatever cylinders.
*/
+ memset(&geo, 0, sizeof(geo));
err = ! access_ok(VERIFY_WRITE, arg, sizeof(geo));
if (err) return -EFAULT;
size = cards[card_number].mm_size * (1024 / MM_HARDSECT);
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 8f72792..c5b27fa 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -330,6 +330,7 @@
{
struct hd_geometry g;
struct hd_geometry *geometry = (struct hd_geometry *) arg;
+ memset(&g, 0, sizeof(g));
g.heads = xd_info[dev].heads;
g.sectors = xd_info[dev].sectors;
g.cylinders = xd_info[dev].cylinders;
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index 60d092f..1df2dc2 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -637,6 +637,7 @@
case HDIO_GETGEO:
{
struct hd_geometry g;
+ memset(&g, 0, sizeof(g));
if (!loc) return -EINVAL;
g.heads = hd_info[dev].head;
g.sectors = hd_info[dev].sect;
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 474130d..d7fa39d 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -1034,6 +1034,7 @@
{
struct hd_geometry g;
int u=minor&0xF0;
+ memset(&g, 0, sizeof(g));
i2o_block_biosparam(i2ob_sizes[u]<<1,
&g.cylinders, &g.heads, &g.sectors);
g.start = i2ob[minor].start_sect;
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index 5c7816a..f407820 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -802,6 +802,7 @@
case HDIO_GETGEO: {
struct hd_geometry g;
+ memset(&g, 0, sizeof(g));
g.heads = nftl->heads;
g.sectors = nftl->sectors;
g.cylinders = nftl->cylinders;