Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1173831 > unrolled thread
| Started by | Bamvor Zhang Jian <bamvor.zhangjian@linaro.org> |
|---|---|
| First post | 2015-06-29 16:30 +0200 |
| Last post | 2015-06-29 16:30 +0200 |
| Articles | 4 — 1 participant |
Back to article view | Back to linux.kernel
[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
| From | Bamvor Zhang Jian <bamvor.zhangjian@linaro.org> |
|---|---|
| Date | 2015-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]
| From | Bamvor Zhang Jian <bamvor.zhangjian@linaro.org> |
|---|---|
| Date | 2015-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]
| From | Bamvor Zhang Jian <bamvor.zhangjian@linaro.org> |
|---|---|
| Date | 2015-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]
| From | Bamvor Zhang Jian <bamvor.zhangjian@linaro.org> |
|---|---|
| Date | 2015-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