Thread (9 messages) 9 messages, 4 authors, 2017-08-19

[patch v3 1/3] drivers: jtag: Add JTAG core driver

From: Oleksandr Shamray <hidden>
Date: 2017-08-16 14:24:22
Also in: linux-devicetree, linux-serial, lkml, openbmc

-----Original Message-----
From: arndbergmann at gmail.com [mailto:arndbergmann at gmail.com] On
Behalf Of Arnd Bergmann
Sent: Tuesday, August 15, 2017 2:16 PM
To: Oleksandr Shamray <redacted>
Cc: gregkh <gregkh@linuxfoundation.org>; Linux Kernel Mailing List <linux-
kernel at vger.kernel.org>; Linux ARM [off-list ref];
devicetree at vger.kernel.org; OpenBMC Maillist [off-list ref];
Joel Stanley [off-list ref]; Ji?? P?rko [off-list ref]; Tobias Klauser
[off-list ref]; linux-serial at vger.kernel.org; mec at shout.net;
vadimp at maellanox.com; system-sw-low-level <system-sw-low-
level at mellanox.com>; Rob Herring [off-list ref]; openocd-devel-
owner at lists.sourceforge.net; Jiri Pirko [off-list ref]
Subject: Re: [patch v3 1/3] drivers: jtag: Add JTAG core driver

On Tue, Aug 15, 2017 at 12:00 PM, Oleksandr Shamray
[off-list ref] wrote:
quoted
+       case JTAG_IOCXFER:
+               if (copy_from_user(&xfer, varg, sizeof(struct jtag_xfer)))
+                       return -EFAULT;
+
+               if (xfer.length >= JTAG_MAX_XFER_DATA_LEN)
+                       return -EFAULT;
+
+               user_tdio_data = xfer.tdio;
+               xfer.tdio = jtag_copy_from_user((void __user *)user_tdio_data,
+                                               xfer.length);
+               if (!xfer.tdio)
+                       return -ENOMEM;
This is not safe for 32-bit processes on 64-bit kernels, since the structure layout
differs for the pointer member. It's better to always use either rework the
structure to avoid the pointer, or to use a
__u64 member to store it, and then use u64_to_user_ptr() to convert it in the
kernel.
Thanks,  I think using __u64 instead of  pointer will be a good solution.
quoted
+       case JTAG_GIOCSTATUS:
+               if (jtag->ops->status_get)
+                       err = jtag->ops->status_get(jtag,
+                                               (enum jtag_endstate
+ *)&value);
This pointer cast is also not safe, as an enum might have a different size than
the 'value' variable that is not an enum. I think you need to change the
argument type for the callback, or maybe use another intermediate.
quoted
+static int jtag_open(struct inode *inode, struct file *file) {
+       struct jtag *jtag = container_of(inode->i_cdev, struct jtag,
+cdev);
+
+       spin_lock(&jtag->lock);
+
+       if (jtag->is_open) {
+               dev_info(NULL, "jtag already opened\n");
+               spin_unlock(&jtag->lock);
+               return -EBUSY;
+       }
+
+       jtag->is_open = true;
+       file->private_data = jtag;
+       spin_unlock(&jtag->lock);
+       return 0;
+}
Does the 'is_open' flag protect you from something that doesn't also happen
after a 'dup()' call on the file descriptor?
is_open flag protects from the opening file more than one time.
quoted
+ * @mode: access mode
+ * @type: transfer type
+ * @direction: xfer direction
+ * @length: xfer bits len
+ * @tdio : xfer data array
+ * @endir: xfer end state
+ *
+ * Structure represents interface to Aspeed JTAG device for jtag sdr
+xfer
+ * execution.
+ */
+struct jtag_xfer {
+       __u8    mode;
+       __u8    type;
+       __u8    direction;
+       __u32   length;
+       __u8    *tdio;
+       __u8    endstate;
+};
As mentioned above, the pointer in here makes it incompatible. Also, you
should reorder the members to avoid the implied padding.
Moving the 'endstate' before 'length' is sufficient.
Thank. I will do it.
        Arnd
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help