From 84de8d192815978feaf15aa3ca7183367f8a7da9 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 10 Jan 2012 11:30:41 +0100 Subject: [PATCH] Allocated ioctl data structures dynamically to avoid stack warnings. --- master/cdev.c | 74 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/master/cdev.c b/master/cdev.c index 1fbb2181..76f84fc6 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -1402,43 +1402,55 @@ int ec_cdev_ioctl_config_sdo( unsigned long arg /**< ioctl() argument. */ ) { - ec_ioctl_config_sdo_t data; + ec_ioctl_config_sdo_t *ioctl; const ec_slave_config_t *sc; const ec_sdo_request_t *req; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { + if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) { + return -ENOMEM; + } + + if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) { + kfree(ioctl); return -EFAULT; } - if (down_interruptible(&master->master_sem)) + if (down_interruptible(&master->master_sem)) { + kfree(ioctl); return -EINTR; + } if (!(sc = ec_master_get_config_const( - master, data.config_index))) { + master, ioctl->config_index))) { up(&master->master_sem); EC_MASTER_ERR(master, "Slave config %u does not exist!\n", - data.config_index); + ioctl->config_index); + kfree(ioctl); return -EINVAL; } if (!(req = ec_slave_config_get_sdo_by_pos_const( - sc, data.sdo_pos))) { + sc, ioctl->sdo_pos))) { up(&master->master_sem); EC_MASTER_ERR(master, "Invalid SDO position!\n"); + kfree(ioctl); return -EINVAL; } - data.index = req->index; - data.subindex = req->subindex; - data.size = req->data_size; - memcpy(&data.data, req->data, - min((u32) data.size, (u32) EC_MAX_SDO_DATA_SIZE)); + ioctl->index = req->index; + ioctl->subindex = req->subindex; + ioctl->size = req->data_size; + memcpy(ioctl->data, req->data, + min((u32) ioctl->size, (u32) EC_MAX_SDO_DATA_SIZE)); up(&master->master_sem); - if (copy_to_user((void __user *) arg, &data, sizeof(data))) + if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) { + kfree(ioctl); return -EFAULT; + } + kfree(ioctl); return 0; } @@ -1451,44 +1463,56 @@ int ec_cdev_ioctl_config_idn( unsigned long arg /**< ioctl() argument. */ ) { - ec_ioctl_config_idn_t data; + ec_ioctl_config_idn_t *ioctl; const ec_slave_config_t *sc; const ec_soe_request_t *req; - if (copy_from_user(&data, (void __user *) arg, sizeof(data))) { + if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) { + return -ENOMEM; + } + + if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) { + kfree(ioctl); return -EFAULT; } - if (down_interruptible(&master->master_sem)) + if (down_interruptible(&master->master_sem)) { + kfree(ioctl); return -EINTR; + } if (!(sc = ec_master_get_config_const( - master, data.config_index))) { + master, ioctl->config_index))) { up(&master->master_sem); EC_MASTER_ERR(master, "Slave config %u does not exist!\n", - data.config_index); + ioctl->config_index); + kfree(ioctl); return -EINVAL; } if (!(req = ec_slave_config_get_idn_by_pos_const( - sc, data.idn_pos))) { + sc, ioctl->idn_pos))) { up(&master->master_sem); EC_MASTER_ERR(master, "Invalid IDN position!\n"); + kfree(ioctl); return -EINVAL; } - data.drive_no = req->drive_no; - data.idn = req->idn; - data.state = req->state; - data.size = req->data_size; - memcpy(&data.data, req->data, - min((u32) data.size, (u32) EC_MAX_IDN_DATA_SIZE)); + ioctl->drive_no = req->drive_no; + ioctl->idn = req->idn; + ioctl->state = req->state; + ioctl->size = req->data_size; + memcpy(ioctl->data, req->data, + min((u32) ioctl->size, (u32) EC_MAX_IDN_DATA_SIZE)); up(&master->master_sem); - if (copy_to_user((void __user *) arg, &data, sizeof(data))) + if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) { + kfree(ioctl); return -EFAULT; + } + kfree(ioctl); return 0; }