linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 1/2] gpiolib: Fix line event handling in syscall compatible mode
@ 2020-09-10 10:19 Andy Shevchenko
  2020-09-10 10:19 ` [PATCH v1 2/2] gpiolib: convert to use DEFINE_SEQ_ATTRIBUTE macro Andy Shevchenko
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Andy Shevchenko @ 2020-09-10 10:19 UTC (permalink / raw)
  To: Linus Walleij, Bartosz Golaszewski, linux-gpio, Kent Gibson
  Cc: Andy Shevchenko, Arnd Bergmann

The introduced line even handling ABI in the commit

  61f922db7221 ("gpio: userspace ABI for reading GPIO line events")

missed the fact that 64-bit kernel may serve for 32-bit applications.
In such case the very first check in the lineevent_read() will fail
due to alignment differences.

To workaround this introduce lineeven_to_user() helper which returns actual
size of the structure and copies its content to user if asked.

Fixes: 61f922db7221 ("gpio: userspace ABI for reading GPIO line events")
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/gpio/gpiolib-cdev.c | 41 ++++++++++++++++++++++++++++++++-----
 1 file changed, 36 insertions(+), 5 deletions(-)

diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index e6c9b78adfc2..a6a8384c8255 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -423,6 +423,33 @@ static __poll_t lineevent_poll(struct file *file,
 	return events;
 }
 
+static ssize_t lineevent_to_user(char __user *buf, struct gpioevent_data *ge)
+{
+#ifdef __x86_64__
+	/* i386 has no padding after 'id' */
+	if (in_ia32_syscall()) {
+		struct compat_ge {
+			compat_u64	timestamp __packed;
+			u32		id;
+		} cge;
+
+		if (buf && ge) {
+			cge = (struct compat_ge){ ge->timestamp, ge->id };
+			if (copy_to_user(buf, &cge, sizeof(cge)))
+				return -EFAULT;
+		}
+
+		return sizeof(cge);
+	}
+#endif
+
+	if (buf && ge) {
+		if (copy_to_user(buf, ge, sizeof(*ge)))
+			return -EFAULT;
+	}
+
+	return sizeof(*ge);
+}
 
 static ssize_t lineevent_read(struct file *file,
 			      char __user *buf,
@@ -432,9 +459,12 @@ static ssize_t lineevent_read(struct file *file,
 	struct lineevent_state *le = file->private_data;
 	struct gpioevent_data ge;
 	ssize_t bytes_read = 0;
+	ssize_t ge_size;
 	int ret;
 
-	if (count < sizeof(ge))
+	/* When argument is NULL it returns size of the structure in user space */
+	ge_size = lineevent_to_user(NULL, NULL);
+	if (count < ge_size)
 		return -EINVAL;
 
 	do {
@@ -470,10 +500,11 @@ static ssize_t lineevent_read(struct file *file,
 			break;
 		}
 
-		if (copy_to_user(buf + bytes_read, &ge, sizeof(ge)))
-			return -EFAULT;
-		bytes_read += sizeof(ge);
-	} while (count >= bytes_read + sizeof(ge));
+		ret = lineevent_to_user(buf + bytes_read, &ge);
+		if (ret < 0)
+			return ret;
+		bytes_read += ret;
+	} while (count >= bytes_read + ge_size);
 
 	return bytes_read;
 }
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-09-14 14:26 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-09-10 10:19 [PATCH v1 1/2] gpiolib: Fix line event handling in syscall compatible mode Andy Shevchenko
2020-09-10 10:19 ` [PATCH v1 2/2] gpiolib: convert to use DEFINE_SEQ_ATTRIBUTE macro Andy Shevchenko
2020-09-11 15:45   ` Bartosz Golaszewski
2020-09-11  1:37 ` [PATCH v1 1/2] gpiolib: Fix line event handling in syscall compatible mode kernel test robot
2020-09-11  3:05 ` Kent Gibson
2020-09-11  8:31   ` Andy Shevchenko
2020-09-11  9:12     ` Kent Gibson
2020-09-11  9:53       ` Andy Shevchenko
2020-09-11 10:17         ` Kent Gibson
     [not found]           ` <20200911142846.GM1891694@smile.fi.intel.com>
2020-09-12  2:21             ` Kent Gibson
2020-09-14 12:44               ` Bartosz Golaszewski
2020-09-14 13:04                 ` Andy Shevchenko
2020-09-11 16:20 ` Arnd Bergmann
2020-09-14 14:26   ` Andy Shevchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).