diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2007-01-25 20:34:48 +0100 |
---|---|---|
committer | Adrian Bunk <bunk@stusta.de> | 2007-01-26 20:49:22 +0100 |
commit | ac4d63dab8bb425f1ae037abf349090c12f16883 (patch) | |
tree | bfbdc372765fea14846b7c51b34e725b1a53a30a /net/bluetooth/cmtp/sock.c | |
parent | ecfad2cc55c3de17bc896816c49597cfacf2e3cf (diff) |
[Bluetooth] Fix compat ioctl for BNEP, CMTP and HIDP
There exists no attempt do deal with the fact that a structure with
a uint32_t followed by a pointer is going to be different for 32-bit
and 64-bit userspace. Any 32-bit process trying to use it will be
failing with -EFAULT if it's lucky; suffering from having data dumped
at a random address if it's not.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Diffstat (limited to 'net/bluetooth/cmtp/sock.c')
-rw-r--r-- | net/bluetooth/cmtp/sock.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c index 8f8fad23f78a..84345d4e3c18 100644 --- a/net/bluetooth/cmtp/sock.c +++ b/net/bluetooth/cmtp/sock.c @@ -35,6 +35,7 @@ #include <linux/socket.h> #include <linux/ioctl.h> #include <linux/file.h> +#include <linux/compat.h> #include <net/sock.h> #include <linux/isdn/capilli.h> @@ -138,11 +139,43 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long return -EINVAL; } +#ifdef CONFIG_COMPAT +static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +{ + if (cmd == CMTPGETCONNLIST) { + struct cmtp_connlist_req cl; + uint32_t uci; + int err; + + if (get_user(cl.cnum, (uint32_t __user *) arg) || + get_user(uci, (u32 __user *) (arg + 4))) + return -EFAULT; + + cl.ci = compat_ptr(uci); + + if (cl.cnum <= 0) + return -EINVAL; + + err = cmtp_get_connlist(&cl); + + if (!err && put_user(cl.cnum, (uint32_t __user *) arg)) + err = -EFAULT; + + return err; + } + + return cmtp_sock_ioctl(sock, cmd, arg); +} +#endif + static const struct proto_ops cmtp_sock_ops = { .family = PF_BLUETOOTH, .owner = THIS_MODULE, .release = cmtp_sock_release, .ioctl = cmtp_sock_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = cmtp_sock_compat_ioctl, +#endif .bind = sock_no_bind, .getname = sock_no_getname, .sendmsg = sock_no_sendmsg, |