summaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2018-09-06 23:17:20 +0200
committerArnd Bergmann <arnd@arndb.de>2019-10-23 17:23:44 +0200
commit5565a3cac5038561155e57451604fce2b5eb4dd7 (patch)
tree60c22373d9f60b9704abceac4af14fc2790fd461 /drivers/isdn
parent0ba9841adb8659856cebb3b54a555e45a5f7fce5 (diff)
downloadlinux-5565a3cac5038561155e57451604fce2b5eb4dd7.tar.gz
linux-5565a3cac5038561155e57451604fce2b5eb4dd7.tar.bz2
linux-5565a3cac5038561155e57451604fce2b5eb4dd7.zip
compat_ioctl: move isdn/capi ioctl translation into driver
Neither the old isdn4linux interface nor the newer mISDN stack ever had working 32-bit compat mode as far as I can tell. However, the CAPI stack has some ioctl commands that are correctly listed in fs/compat_ioctl.c. We can trivially move all of those into the corresponding file that implement the native handlers by adding a compat_ioctl redirect to that. I did notice that treating CAPI_MANUFACTURER_CMD() as compatible is broken, so I'm also adding a handler for that, realizing that in all likelyhood, nobody is ever going to call it. Cc: Karsten Keil <isdn@linux-pingi.de> Cc: netdev@vger.kernel.org Cc: isdn4linux@listserv.isdn4linux.de Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/capi/capi.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index c92b405b7646..6fbe3949026c 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -950,6 +950,34 @@ capi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return ret;
}
+#ifdef CONFIG_COMPAT
+static long
+capi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int ret;
+
+ if (cmd == CAPI_MANUFACTURER_CMD) {
+ struct {
+ compat_ulong_t cmd;
+ compat_uptr_t data;
+ } mcmd32;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (copy_from_user(&mcmd32, compat_ptr(arg), sizeof(mcmd32)))
+ return -EFAULT;
+
+ mutex_lock(&capi_mutex);
+ ret = capi20_manufacturer(mcmd32.cmd, compat_ptr(mcmd32.data));
+ mutex_unlock(&capi_mutex);
+
+ return ret;
+ }
+
+ return capi_unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
+}
+#endif
+
static int capi_open(struct inode *inode, struct file *file)
{
struct capidev *cdev;
@@ -996,6 +1024,9 @@ static const struct file_operations capi_fops =
.write = capi_write,
.poll = capi_poll,
.unlocked_ioctl = capi_unlocked_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = capi_compat_ioctl,
+#endif
.open = capi_open,
.release = capi_release,
};