diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2006-10-15 11:30:22 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-10-16 02:14:27 -0400 |
commit | e9c5702e3c5558dade169949abd730173e87ef9c (patch) | |
tree | 58ec8dcd1497b51e1d6a447d8c4a34a0bd2f108d /net/bluetooth/cmtp | |
parent | 39c850863d5e36e72ecf9bc3537ec717bcce97fd (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>
Diffstat (limited to 'net/bluetooth/cmtp')
-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 10ad7fd91d83..0547edd57734 100644 --- a/net/bluetooth/cmtp/sock.c +++ b/net/bluetooth/cmtp/sock.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/socket.h> | 34 | #include <linux/socket.h> |
35 | #include <linux/ioctl.h> | 35 | #include <linux/ioctl.h> |
36 | #include <linux/file.h> | 36 | #include <linux/file.h> |
37 | #include <linux/compat.h> | ||
37 | #include <net/sock.h> | 38 | #include <net/sock.h> |
38 | 39 | ||
39 | #include <linux/isdn/capilli.h> | 40 | #include <linux/isdn/capilli.h> |
@@ -137,11 +138,43 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
137 | return -EINVAL; | 138 | return -EINVAL; |
138 | } | 139 | } |
139 | 140 | ||
141 | #ifdef CONFIG_COMPAT | ||
142 | static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
143 | { | ||
144 | if (cmd == CMTPGETCONNLIST) { | ||
145 | struct cmtp_connlist_req cl; | ||
146 | uint32_t uci; | ||
147 | int err; | ||
148 | |||
149 | if (get_user(cl.cnum, (uint32_t __user *) arg) || | ||
150 | get_user(uci, (u32 __user *) (arg + 4))) | ||
151 | return -EFAULT; | ||
152 | |||
153 | cl.ci = compat_ptr(uci); | ||
154 | |||
155 | if (cl.cnum <= 0) | ||
156 | return -EINVAL; | ||
157 | |||
158 | err = cmtp_get_connlist(&cl); | ||
159 | |||
160 | if (!err && put_user(cl.cnum, (uint32_t __user *) arg)) | ||
161 | err = -EFAULT; | ||
162 | |||
163 | return err; | ||
164 | } | ||
165 | |||
166 | return cmtp_sock_ioctl(sock, cmd, arg); | ||
167 | } | ||
168 | #endif | ||
169 | |||
140 | static const struct proto_ops cmtp_sock_ops = { | 170 | static const struct proto_ops cmtp_sock_ops = { |
141 | .family = PF_BLUETOOTH, | 171 | .family = PF_BLUETOOTH, |
142 | .owner = THIS_MODULE, | 172 | .owner = THIS_MODULE, |
143 | .release = cmtp_sock_release, | 173 | .release = cmtp_sock_release, |
144 | .ioctl = cmtp_sock_ioctl, | 174 | .ioctl = cmtp_sock_ioctl, |
175 | #ifdef CONFIG_COMPAT | ||
176 | .compat_ioctl = cmtp_sock_compat_ioctl, | ||
177 | #endif | ||
145 | .bind = sock_no_bind, | 178 | .bind = sock_no_bind, |
146 | .getname = sock_no_getname, | 179 | .getname = sock_no_getname, |
147 | .sendmsg = sock_no_sendmsg, | 180 | .sendmsg = sock_no_sendmsg, |