Allocated ioctl data structures dynamically to avoid stack warnings.
authorFlorian Pose <fp@igh-essen.com>
Tue, 10 Jan 2012 11:30:41 +0100
changeset 2260 f9b1c6d58435
parent 2259 5538f60ea32c
child 2262 797756190ddb
Allocated ioctl data structures dynamically to avoid stack warnings.
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
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- *  $Id: cdev.c,v ebda087981e1 2011/09/15 13:58:58 fp $
+ *  $Id$
  *
  *  Copyright (C) 2006-2008  Florian Pose, Ingenieurgemeinschaft IgH
  *
@@ -1406,43 +1406,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 (ec_mutex_lock_interruptible(&master->master_mutex))
+    if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
+        return -ENOMEM;
+    }
+
+    if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
+        kfree(ioctl);
+        return -EFAULT;
+    }
+
+    if (ec_mutex_lock_interruptible(&master->master_mutex)) {
+        kfree(ioctl);
         return -EINTR;
+    }
 
     if (!(sc = ec_master_get_config_const(
-                    master, data.config_index))) {
+                    master, ioctl->config_index))) {
         ec_mutex_unlock(&master->master_mutex);
         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))) {
         ec_mutex_unlock(&master->master_mutex);
         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));
 
     ec_mutex_unlock(&master->master_mutex);
 
-    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;
 }
 
@@ -1455,44 +1467,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 (ec_mutex_lock_interruptible(&master->master_mutex))
+    if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
+        return -ENOMEM;
+    }
+
+    if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
+        kfree(ioctl);
+        return -EFAULT;
+    }
+
+    if (ec_mutex_lock_interruptible(&master->master_mutex)) {
+        kfree(ioctl);
         return -EINTR;
+    }
 
     if (!(sc = ec_master_get_config_const(
-                    master, data.config_index))) {
+                    master, ioctl->config_index))) {
         ec_mutex_unlock(&master->master_mutex);
         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))) {
         ec_mutex_unlock(&master->master_mutex);
         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));
 
     ec_mutex_unlock(&master->master_mutex);
 
-    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;
 }