# HG changeset patch # User Florian Pose # Date 1326191441 -3600 # Node ID 79269cfe25a768d4c110b43ed43f8c9348bc1a0c # Parent a2a675601c989671705d9752c90cc36645ffb2cd Allocated ioctl data structures dynamically to avoid stack warnings. diff -r a2a675601c98 -r 79269cfe25a7 master/cdev.c --- a/master/cdev.c Tue Jan 10 11:30:03 2012 +0100 +++ b/master/cdev.c Tue Jan 10 11:30:41 2012 +0100 @@ -1395,43 +1395,55 @@ 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))) { - return -EFAULT; - } - - if (down_interruptible(&master->master_sem)) + 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)) { + 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"); - 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)); + kfree(ioctl); + return -EINVAL; + } + + 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))) - return -EFAULT; - + if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) { + kfree(ioctl); + return -EFAULT; + } + + kfree(ioctl); return 0; } @@ -1444,44 +1456,56 @@ 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))) { - return -EFAULT; - } - - if (down_interruptible(&master->master_sem)) + 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)) { + 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"); - 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)); + kfree(ioctl); + return -EINVAL; + } + + 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))) - return -EFAULT; - + if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) { + kfree(ioctl); + return -EFAULT; + } + + kfree(ioctl); return 0; }