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


Groups > linux.kernel > #1299671 > unrolled thread

[PATCH v3 0/2] Convert ppdev to y2038 safe

Started byBamvor Jian Zhang <bamvor.zhangjian@linaro.org>
First post2015-12-31 15:10 +0100
Last post2015-12-31 15:10 +0100
Articles 2 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH v3 0/2] Convert ppdev to y2038 safe Bamvor Jian Zhang <bamvor.zhangjian@linaro.org> - 2015-12-31 15:10 +0100
    [PATCH v3 1/2] ppdev: convert to y2038 safe Bamvor Jian Zhang <bamvor.zhangjian@linaro.org> - 2015-12-31 15:10 +0100

#1299671 — [PATCH v3 0/2] Convert ppdev to y2038 safe

FromBamvor Jian Zhang <bamvor.zhangjian@linaro.org>
Date2015-12-31 15:10 +0100
Subject[PATCH v3 0/2] Convert ppdev to y2038 safe
Message-ID<qLM5r-5qw-3@gated-at.bofh.it>
These series of patches try to convert parport device(ppdev) to
y2038 safe, and support y2038 safe and unsafe application at the
same time. The first two version is here[1][2].

An y2038 safe application/kernel use 64bit time_t(aka time64_t)
to avoid 32-bit time types broken in the year 2038. Given that
some time relative struct(e.g. timeval in ppdev.c) is mainly the
offset of the real time, the old 32bit time_t in such application
is safe. We need to handle the 32bit time_t and 64bit time_t
application at the same time. My approach here is handle them as
different ioctl command for different size of timeval.

Build successful on arm64, arm and x86_64.

Changes since v2:
1.  Fix the wrong parameter in copy_to_user.

Changes since v1:
1.  Fix the warning when build against x86_64.

[1] https://lkml.org/lkml/2015/12/9/32
[2] https://lkml.org/lkml/2015/12/17/111

Bamvor Jian Zhang (2):
  ppdev: convert to y2038 safe
  ppdev: add support for compat ioctl

 drivers/char/ppdev.c | 87 ++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 67 insertions(+), 20 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]


#1299672 — [PATCH v3 1/2] ppdev: convert to y2038 safe

FromBamvor Jian Zhang <bamvor.zhangjian@linaro.org>
Date2015-12-31 15:10 +0100
Subject[PATCH v3 1/2] ppdev: convert to y2038 safe
Message-ID<qLM5s-5qw-7@gated-at.bofh.it>
In reply to#1299671
The y2038 issue for ppdev is changes of timeval in the ioctl
(PPSETTIME and PPGETTIME). The size of struct timeval changes from
8bytes to 16bytes due to the changes of time_t. It lead to the
changes of the command of ioctl, e.g. for PPGETTIME, We have:

on 32-bit (old): 0x80087095
on 32-bit (new): 0x80107095
on 64-bit      : 0x80107095

This patch define these two ioctl commands to support the 32bit
and 64bit time_t application at the same time. And, introduce
pp_set_timeout to remove some duplicated code.

Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
---
 drivers/char/ppdev.c | 75 ++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 55 insertions(+), 20 deletions(-)

diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index ae0b42b..c03d998 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -98,6 +98,13 @@ struct pp_struct {
 #define ROUND_UP(x,y) (((x)+(y)-1)/(y))
 
 static DEFINE_MUTEX(pp_do_mutex);
+
+/* define fixed sized ioctl cmd for y2038 migration */
+#define PPGETTIME32	_IOR(PP_IOCTL, 0x95, s32[2])
+#define PPSETTIME32	_IOW(PP_IOCTL, 0x96, s32[2])
+#define PPGETTIME64	_IOR(PP_IOCTL, 0x95, s64[2])
+#define PPSETTIME64	_IOW(PP_IOCTL, 0x96, s64[2])
+
 static inline void pp_enable_irq (struct pp_struct *pp)
 {
 	struct parport *port = pp->pdev->port;
@@ -322,6 +329,22 @@ static enum ieee1284_phase init_phase (int mode)
 	return IEEE1284_PH_FWD_IDLE;
 }
 
+static int pp_set_timeout(struct pardevice *pdev, long tv_sec, int tv_usec)
+{
+	long to_jiffies;
+
+	if ((tv_sec < 0) || (tv_usec < 0))
+		return -EINVAL;
+
+	to_jiffies = usecs_to_jiffies(tv_usec);
+	to_jiffies += tv_sec * HZ;
+	if (to_jiffies <= 0)
+		return -EINVAL;
+
+	pdev->timeout = to_jiffies;
+	return 0;
+}
+
 static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	unsigned int minor = iminor(file_inode(file));
@@ -495,9 +518,10 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		unsigned char reg;
 		unsigned char mask;
 		int mode;
+		s32 time32[2];
+		s64 time64[2];
+		struct timespec64 ts;
 		int ret;
-		struct timeval par_timeout;
-		long to_jiffies;
 
 	case PPRSTATUS:
 		reg = parport_read_status (port);
@@ -592,29 +616,40 @@ 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))) {
+	case PPSETTIME32:
+		if (copy_from_user(time32, argp, sizeof(time32)))
 			return -EFAULT;
-		}
-		/* Convert to jiffies, place in pp->pdev->timeout */
-		if ((par_timeout.tv_sec < 0) || (par_timeout.tv_usec < 0)) {
-			return -EINVAL;
-		}
-		to_jiffies = ROUND_UP(par_timeout.tv_usec, 1000000/HZ);
-		to_jiffies += par_timeout.tv_sec * (long)HZ;
-		if (to_jiffies <= 0) {
+
+		return pp_set_timeout(pp->pdev, time32[0], time32[1]);
+
+	case PPSETTIME64:
+		if (copy_from_user(time64, argp, sizeof(time64)))
+			return -EFAULT;
+
+		return pp_set_timeout(pp->pdev, time64[0], time64[1]);
+
+	case PPGETTIME32:
+		jiffies_to_timespec64(pp->pdev->timeout, &ts);
+		time32[0] = ts.tv_sec;
+		time32[1] = ts.tv_nsec / NSEC_PER_USEC;
+		if ((time32[0] < 0) || (time32[1] < 0))
 			return -EINVAL;
-		}
-		pp->pdev->timeout = to_jiffies;
+
+		if (copy_to_user(argp, time32, sizeof(time32)))
+			return -EFAULT;
+
 		return 0;
 
-	case PPGETTIME:
-		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)))
+	case PPGETTIME64:
+		jiffies_to_timespec64(pp->pdev->timeout, &ts);
+		time64[0] = ts.tv_sec;
+		time64[1] = ts.tv_nsec / NSEC_PER_USEC;
+		if ((time64[0] < 0) || (time64[1] < 0))
+			return -EINVAL;
+
+		if (copy_to_user(argp, time64, sizeof(time64)))
 			return -EFAULT;
+
 		return 0;
 
 	default:
-- 
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