summaryrefslogtreecommitdiff
path: root/fs/compat_ioctl.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2019-04-16 22:19:44 +0200
committerArnd Bergmann <arnd@arndb.de>2019-10-23 17:23:47 +0200
commit17c7e7f407085f510a815c0c99b3fd25d5b13110 (patch)
treeaa674e21bcd6b6380049c28333e6b70ab909de34 /fs/compat_ioctl.c
parent5b6c02df50fb28d23c733a24df5a06d0a3f28b93 (diff)
compat_ioctl: handle PPPIOCGIDLE for 64-bit time_t
The ppp_idle structure is defined in terms of __kernel_time_t, which is defined as 'long' on all architectures, and this usage is not affected by the y2038 problem since it transports a time interval rather than an absolute time. However, the ppp user space defines the same structure as time_t, which may be 64-bit wide on new libc versions even on 32-bit architectures. It's easy enough to just handle both possible structure layouts on all architectures, to deal with the possibility that a user space ppp implementation comes with its own ppp_idle structure definition, as well as to document the fact that the driver is y2038-safe. Doing this also avoids the need for a special compat mode translation, since 32-bit and 64-bit kernels now support the same interfaces. The old 32-bit structure is also available on native 64-bit architectures now, but this is harmless. Cc: netdev@vger.kernel.org Cc: linux-ppp@vger.kernel.org Cc: Paul Mackerras <paulus@samba.org> Cc: "David S. Miller" <davem@davemloft.net> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'fs/compat_ioctl.c')
-rw-r--r--fs/compat_ioctl.c38
1 files changed, 5 insertions, 33 deletions
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 0b5a732d7afd..5e59101ef981 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -52,6 +52,7 @@
#include <linux/sort.h>
+#ifdef CONFIG_BLOCK
static int do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int err;
@@ -63,7 +64,6 @@ static int do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return vfs_ioctl(file, cmd, arg);
}
-#ifdef CONFIG_BLOCK
struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
char req_state;
char orphan;
@@ -99,33 +99,6 @@ static int sg_grt_trans(struct file *file,
}
#endif /* CONFIG_BLOCK */
-struct ppp_idle32 {
- compat_time_t xmit_idle;
- compat_time_t recv_idle;
-};
-#define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
-
-static int ppp_gidle(struct file *file, unsigned int cmd,
- struct ppp_idle32 __user *idle32)
-{
- struct ppp_idle __user *idle;
- __kernel_time_t xmit, recv;
- int err;
-
- idle = compat_alloc_user_space(sizeof(*idle));
-
- err = do_ioctl(file, PPPIOCGIDLE, (unsigned long) idle);
-
- if (!err) {
- if (get_user(xmit, &idle->xmit_idle) ||
- get_user(recv, &idle->recv_idle) ||
- put_user(xmit, &idle32->xmit_idle) ||
- put_user(recv, &idle32->recv_idle))
- err = -EFAULT;
- }
- return err;
-}
-
/*
* simple reversible transform to make our table more evenly
* distributed after sorting.
@@ -192,7 +165,8 @@ COMPATIBLE_IOCTL(PPPIOCGDEBUG)
COMPATIBLE_IOCTL(PPPIOCSDEBUG)
/* PPPIOCSPASS is translated */
/* PPPIOCSACTIVE is translated */
-/* PPPIOCGIDLE is translated */
+COMPATIBLE_IOCTL(PPPIOCGIDLE32)
+COMPATIBLE_IOCTL(PPPIOCGIDLE64)
COMPATIBLE_IOCTL(PPPIOCNEWUNIT)
COMPATIBLE_IOCTL(PPPIOCATTACH)
COMPATIBLE_IOCTL(PPPIOCDETACH)
@@ -214,16 +188,14 @@ COMPATIBLE_IOCTL(PPPIOCGL2TPSTATS)
static long do_ioctl_trans(unsigned int cmd,
unsigned long arg, struct file *file)
{
+#ifdef CONFIG_BLOCK
void __user *argp = compat_ptr(arg);
switch (cmd) {
- case PPPIOCGIDLE32:
- return ppp_gidle(file, cmd, argp);
-#ifdef CONFIG_BLOCK
case SG_GET_REQUEST_TABLE:
return sg_grt_trans(file, cmd, argp);
-#endif
}
+#endif
return -ENOIOCTLCMD;
}