Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1173831 > unrolled thread

[RFC PATCH v2 0/4] Convert ppdev to y2038 safe

Started byBamvor Zhang Jian <bamvor.zhangjian@linaro.org>
First post2015-06-29 16:30 +0200
Last post2015-06-29 16:30 +0200
Articles 4 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [RFC PATCH v2 0/4] Convert ppdev to y2038 safe Bamvor Zhang Jian <bamvor.zhangjian@linaro.org> - 2015-06-29 16:30 +0200
    [RFC PATCH v2 2/4] time64: add timeval64 helper for compat syscalls Bamvor Zhang Jian <bamvor.zhangjian@linaro.org> - 2015-06-29 16:30 +0200
    [RFC PATCH v2 3/4] ppdev: add compat ioctl Bamvor Zhang Jian <bamvor.zhangjian@linaro.org> - 2015-06-29 16:30 +0200
    [RFC PATCH v2 4/4] y2038: convert ppdev to 2038 safe Bamvor Zhang Jian <bamvor.zhangjian@linaro.org> - 2015-06-29 16:30 +0200

#1173831 — [RFC PATCH v2 0/4] Convert ppdev to y2038 safe

FromBamvor Zhang Jian <bamvor.zhangjian@linaro.org>
Date2015-06-29 16:30 +0200
Subject[RFC PATCH v2 0/4] Convert ppdev to y2038 safe
Message-ID<pGIel-5zg-5@gated-at.bofh.it>
Hi, guys

This is my second attempt to convert ppdev to y2038 safe. The first
version is here[1].

There are two parts in my patches.
01/02 migrate timeval relative struct to 64bit time_t types.
03/04 convert ppdev to y2038 safe in both native 32bit and compat
application.

My patches try to follow the idea from arnd y2038 syscalls patches[2],
but my patches not depend on them.

The reason why I choose ppdev is the ppdev use the timexxx directly
in ioctl compare with the other drivers embedded timexxx in their
own type.

Build pass on arm and arm64 on each patches(with and without
CONFIG_COMPAT_TIME). Unfortunately, there is no parport device
(printer) in my test environment. Hope others could help to test
it.

[1] https://lists.linaro.org/pipermail/y2038/2015-June/000522.html
[2] http://git.kernel.org/cgit/linux/kernel/git/arnd/playground.git/log/?h=y2038-syscalls

Bamvor Zhang Jian (4):
  y2038: add 64bit time_t support in timeval for 32bit architecture
  time64: add timeval64 helper for compat syscalls
  ppdev: add compat ioctl
  y2038: convert ppdev to 2038 safe

 drivers/char/ppdev.c       | 41 ++++++++++++++++++++++++++++++++++-------
 include/linux/compat.h     |  3 +++
 include/linux/time64.h     | 20 ++++++++++++++++++--
 include/uapi/linux/ppdev.h | 14 ++++++++++++--
 include/uapi/linux/time.h  | 16 ++++++++++++++++
 kernel/compat.c            | 17 +++++++++++++++++
 kernel/time/time.c         | 36 ++++++++++++++++++++++++++++++++++++
 7 files changed, 136 insertions(+), 11 deletions(-)

-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1173832 — [RFC PATCH v2 2/4] time64: add timeval64 helper for compat syscalls

FromBamvor Zhang Jian <bamvor.zhangjian@linaro.org>
Date2015-06-29 16:30 +0200
Subject[RFC PATCH v2 2/4] time64: add timeval64 helper for compat syscalls
Message-ID<pGIem-5zg-7@gated-at.bofh.it>
In reply to#1173831
Add __kernel_compat_timeval in uapi in order to use it in ioctl
command because compat_timeval is invisible in uapi. Meanwhile
We could avoid to define it by using the __s32 array in ioctl
command definition. I am sure which one is the better way.
Any suggestion or input is welcome.

This patch also define compat_get_timeval64, compat_put_timeval64
 for converting between compat_timeval and timeval64.

Signed-off-by: Bamvor Zhang Jian <bamvor.zhangjian@linaro.org>
---
 include/linux/compat.h    |  3 +++
 include/uapi/linux/time.h |  6 ++++++
 kernel/compat.c           | 17 +++++++++++++++++
 3 files changed, 26 insertions(+)

diff --git a/include/linux/compat.h b/include/linux/compat.h
index ab25814..14569a7 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -154,6 +154,9 @@ extern int compat_get_timespec(struct timespec *, const void __user *);
 extern int compat_put_timespec(const struct timespec *, void __user *);
 extern int compat_get_timeval(struct timeval *, const void __user *);
 extern int compat_put_timeval(const struct timeval *, void __user *);
+struct timeval64;
+extern int compat_get_timeval64(struct timeval64 *tv, const struct compat_timeval __user *ctv);
+extern int compat_put_timeval64(const struct timeval64 *tv, struct compat_timeval __user *ctv);
 
 /*
  * This function convert a timespec if necessary and returns a *user
diff --git a/include/uapi/linux/time.h b/include/uapi/linux/time.h
index 2ca6a31..9f6093e 100644
--- a/include/uapi/linux/time.h
+++ b/include/uapi/linux/time.h
@@ -76,4 +76,10 @@ struct __kernel_timeval {
 };
 #endif
 
+typedef __s32 __kernel_time32_t;
+struct __kernel_compat_timeval {
+       __kernel_time32_t       tv_sec;
+       __s32                   tv_usec;
+};
+
 #endif /* _UAPI_LINUX_TIME_H */
diff --git a/kernel/compat.c b/kernel/compat.c
index 333d364..ebe45b4 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -172,6 +172,23 @@ int compat_put_timeval(const struct timeval *tv, void __user *utv)
 }
 EXPORT_SYMBOL_GPL(compat_put_timeval);
 
+int compat_get_timeval64(struct timeval64 *tv, const struct compat_timeval __user *ctv)
+{
+	return (!access_ok(VERIFY_READ, ctv, sizeof(*ctv)) ||
+			__get_user(tv->tv_sec, &ctv->tv_sec) ||
+			__get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
+}
+EXPORT_SYMBOL_GPL(compat_get_timeval64);
+
+/* TODO: is it ok that just put to user without implicit cast? */
+int compat_put_timeval64(const struct timeval64 *tv, struct compat_timeval *ctv)
+{
+	return (!access_ok(VERIFY_WRITE, ctv, sizeof(*ctv)) ||
+			__put_user(tv->tv_sec, &ctv->tv_sec) ||
+			__put_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
+}
+EXPORT_SYMBOL_GPL(compat_put_timeval64);
+
 int compat_get_timespec(struct timespec *ts, const void __user *uts)
 {
 	if (COMPAT_USE_64BIT_TIME)
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1173835 — [RFC PATCH v2 3/4] ppdev: add compat ioctl

FromBamvor Zhang Jian <bamvor.zhangjian@linaro.org>
Date2015-06-29 16:30 +0200
Subject[RFC PATCH v2 3/4] ppdev: add compat ioctl
Message-ID<pGIem-5zg-17@gated-at.bofh.it>
In reply to#1173831
Add compat ioctl in ppdev in order to solve the y2038 issue in
later patch.
This patch simply add pp_do_ioctl to compat_ioctl, because I found
that all the ioctl access the arg as a pointer.

Signed-off-by: Bamvor Zhang Jian <bamvor.zhangjian@linaro.org>
---
 drivers/char/ppdev.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index ae0b42b..9207658 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -69,6 +69,7 @@
 #include <linux/ppdev.h>
 #include <linux/mutex.h>
 #include <linux/uaccess.h>
+#include <linux/compat.h>
 
 #define PP_VERSION "ppdev: user-space parallel port driver"
 #define CHRDEV "ppdev"
@@ -635,6 +636,11 @@ static long pp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	return ret;
 }
 
+static long pp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	return pp_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
+}
+
 static int pp_open (struct inode * inode, struct file * file)
 {
 	unsigned int minor = iminor(inode);
@@ -744,6 +750,9 @@ static const struct file_operations pp_fops = {
 	.write		= pp_write,
 	.poll		= pp_poll,
 	.unlocked_ioctl	= pp_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= pp_compat_ioctl,
+#endif
 	.open		= pp_open,
 	.release	= pp_release,
 };
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1173837 — [RFC PATCH v2 4/4] y2038: convert ppdev to 2038 safe

FromBamvor Zhang Jian <bamvor.zhangjian@linaro.org>
Date2015-06-29 16:30 +0200
Subject[RFC PATCH v2 4/4] y2038: convert ppdev to 2038 safe
Message-ID<pGIem-5zg-25@gated-at.bofh.it>
In reply to#1173831
Convert ppdev use 64bit time_t internally by replacing timeval to
timeval64.

In order to migrate to y2038 safe, split ioctl command PP[SG]ETTIME
to PP[SG]ETTIME64(y2038 safe) and PP[SG]ETTIME32 (the legacy
behavior in 32bit application). The 32bit application should make
use of PP[SG]ETTIME64 and __kernel_timeval to migrate to time64_t.

Signed-off-by: Bamvor Zhang Jian <bamvor.zhangjian@linaro.org>
---
 drivers/char/ppdev.c       | 32 +++++++++++++++++++++++++-------
 include/uapi/linux/ppdev.h | 14 ++++++++++++--
 2 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 9207658..a103d3d 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -497,8 +497,9 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		unsigned char mask;
 		int mode;
 		int ret;
-		struct timeval par_timeout;
+		struct timeval64 par_timeout;
 		long to_jiffies;
+		int is_not_compat_timeval = 0;
 
 	case PPRSTATUS:
 		reg = parport_read_status (port);
@@ -593,9 +594,17 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		atomic_sub (ret, &pp->irqc);
 		return 0;
 
-	case PPSETTIME:
-		if (copy_from_user (&par_timeout, argp, sizeof(struct timeval))) {
-			return -EFAULT;
+	case PPSETTIME64:
+		is_not_compat_timeval = 1;
+	case PPSETTIME32:
+		if (is_not_compat_timeval) {
+			if (get_timeval64(&par_timeout, argp)) {
+				return -EFAULT;
+			}
+		} else {
+			if (compat_get_timeval64(&par_timeout, argp)) {
+				return -EFAULT;
+			}
 		}
 		/* Convert to jiffies, place in pp->pdev->timeout */
 		if ((par_timeout.tv_sec < 0) || (par_timeout.tv_usec < 0)) {
@@ -609,13 +618,22 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		pp->pdev->timeout = to_jiffies;
 		return 0;
 
-	case PPGETTIME:
+	case PPGETTIME64:
+		is_not_compat_timeval = 1;
+	case PPGETTIME32:
 		to_jiffies = pp->pdev->timeout;
 		memset(&par_timeout, 0, sizeof(par_timeout));
 		par_timeout.tv_sec = to_jiffies / HZ;
 		par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ);
-		if (copy_to_user (argp, &par_timeout, sizeof(struct timeval)))
-			return -EFAULT;
+		if (is_not_compat_timeval) {
+			if (put_timeval64(&par_timeout, argp)) {
+				return -EFAULT;
+			}
+		} else {
+			if (compat_put_timeval64(&par_timeout, argp)) {
+				return -EFAULT;
+			}
+		}
 		return 0;
 
 	default:
diff --git a/include/uapi/linux/ppdev.h b/include/uapi/linux/ppdev.h
index dc18c5d..d62a47d 100644
--- a/include/uapi/linux/ppdev.h
+++ b/include/uapi/linux/ppdev.h
@@ -74,8 +74,18 @@ struct ppdev_frob_struct {
 #define PPSETPHASE	_IOW(PP_IOCTL, 0x94, int)
 
 /* Set and get port timeout (struct timeval's) */
-#define PPGETTIME	_IOR(PP_IOCTL, 0x95, struct timeval)
-#define PPSETTIME	_IOW(PP_IOCTL, 0x96, struct timeval)
+/* Force application use 64 time_t ioctl */
+/* TODO: It is an open question about we should use a __xxx_timeval or an
+ * implicit array.
+ * replace struct __kernel_timeval with __s32[4]
+ * replace struct compat_timeval with __s32[2]
+ */
+#define PPGETTIME	PPGETTIME64
+#define PPSETTIME	PPSETTIME64
+#define PPGETTIME64	_IOR(PP_IOCTL, 0x95, struct __kernel_timeval)
+#define PPSETTIME64	_IOW(PP_IOCTL, 0x96, struct __kernel_timeval)
+#define PPGETTIME32	_IOR(PP_IOCTL, 0x9c, struct __kernel_compat_timeval)
+#define PPSETTIME32	_IOW(PP_IOCTL, 0x9d, struct __kernel_compat_timeval)
 
 /* Get available modes (what the hardware can do) */
 #define PPGETMODES	_IOR(PP_IOCTL, 0x97, unsigned int)
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web