aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-10-25 15:48:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-10-25 15:48:22 -0400
commitba7d4f36a2ec7d6f8d9e5c6cabbc57469dd4dc22 (patch)
tree270a5f21aaa73d4c2a0008ec8e60b9fdd199228e
parent5947a64a7e0c70cc16d5d1e5af3cf3b44535047a (diff)
parent702ec3072ae61cdf018725b353ff043e196548a6 (diff)
Merge branch 'work.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull compat_ioctl fixes from Al Viro: "A bunch of compat_ioctl fixes, mostly in bluetooth. Hopefully, most of fs/compat_ioctl.c will get killed off over the next few cycles; between this, tty series already merged and Arnd's work this cycle ought to take a good chunk out of the damn thing..." * 'work.compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: hidp: fix compat_ioctl hidp: constify hidp_connection_add() cmtp: fix compat_ioctl bnep: fix compat_ioctl compat_ioctl: trim the pointless includes
-rw-r--r--fs/compat_ioctl.c69
-rw-r--r--net/bluetooth/bnep/sock.c19
-rw-r--r--net/bluetooth/cmtp/sock.c19
-rw-r--r--net/bluetooth/hidp/core.c10
-rw-r--r--net/bluetooth/hidp/hidp.h2
-rw-r--r--net/bluetooth/hidp/sock.c79
6 files changed, 81 insertions, 117 deletions
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 0c445a03e682..ce2cc2169040 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -22,37 +22,21 @@
22#include <linux/smp.h> 22#include <linux/smp.h>
23#include <linux/ioctl.h> 23#include <linux/ioctl.h>
24#include <linux/if.h> 24#include <linux/if.h>
25#include <linux/if_bridge.h>
26#include <linux/raid/md_u.h> 25#include <linux/raid/md_u.h>
27#include <linux/kd.h>
28#include <linux/route.h>
29#include <linux/in6.h>
30#include <linux/ipv6_route.h>
31#include <linux/skbuff.h>
32#include <linux/netlink.h>
33#include <linux/vt.h>
34#include <linux/falloc.h> 26#include <linux/falloc.h>
35#include <linux/fs.h>
36#include <linux/file.h> 27#include <linux/file.h>
37#include <linux/ppp_defs.h>
38#include <linux/ppp-ioctl.h> 28#include <linux/ppp-ioctl.h>
39#include <linux/if_pppox.h> 29#include <linux/if_pppox.h>
40#include <linux/mtio.h> 30#include <linux/mtio.h>
41#include <linux/tty.h> 31#include <linux/tty.h>
42#include <linux/vt_kern.h> 32#include <linux/vt_kern.h>
43#include <linux/fb.h>
44#include <linux/videodev2.h>
45#include <linux/netdevice.h>
46#include <linux/raw.h> 33#include <linux/raw.h>
47#include <linux/blkdev.h> 34#include <linux/blkdev.h>
48#include <linux/elevator.h>
49#include <linux/rtc.h> 35#include <linux/rtc.h>
50#include <linux/pci.h> 36#include <linux/pci.h>
51#include <linux/serial.h> 37#include <linux/serial.h>
52#include <linux/if_tun.h>
53#include <linux/ctype.h> 38#include <linux/ctype.h>
54#include <linux/syscalls.h> 39#include <linux/syscalls.h>
55#include <linux/atalk.h>
56#include <linux/gfp.h> 40#include <linux/gfp.h>
57#include <linux/cec.h> 41#include <linux/cec.h>
58 42
@@ -74,32 +58,9 @@
74#endif 58#endif
75 59
76#include <linux/uaccess.h> 60#include <linux/uaccess.h>
77#include <linux/ethtool.h>
78#include <linux/mii.h>
79#include <linux/if_bonding.h>
80#include <linux/watchdog.h> 61#include <linux/watchdog.h>
81 62
82#include <linux/soundcard.h> 63#include <linux/soundcard.h>
83#include <linux/lp.h>
84#include <linux/ppdev.h>
85
86#include <linux/atm.h>
87#include <linux/atmarp.h>
88#include <linux/atmclip.h>
89#include <linux/atmdev.h>
90#include <linux/atmioc.h>
91#include <linux/atmlec.h>
92#include <linux/atmmpc.h>
93#include <linux/atmsvc.h>
94#include <linux/atm_tcp.h>
95#include <linux/sonet.h>
96#include <linux/atm_suni.h>
97
98#include <linux/usb.h>
99#include <linux/usbdevice_fs.h>
100#include <linux/nbd.h>
101#include <linux/random.h>
102#include <linux/filter.h>
103 64
104#include <linux/hiddev.h> 65#include <linux/hiddev.h>
105 66
@@ -112,6 +73,7 @@
112#include <linux/sort.h> 73#include <linux/sort.h>
113 74
114#ifdef CONFIG_SPARC 75#ifdef CONFIG_SPARC
76#include <linux/fb.h>
115#include <asm/fbio.h> 77#include <asm/fbio.h>
116#endif 78#endif
117 79
@@ -544,22 +506,6 @@ static int mt_ioctl_trans(struct file *file,
544#define HCIUARTSETFLAGS _IOW('U', 203, int) 506#define HCIUARTSETFLAGS _IOW('U', 203, int)
545#define HCIUARTGETFLAGS _IOR('U', 204, int) 507#define HCIUARTGETFLAGS _IOR('U', 204, int)
546 508
547#define BNEPCONNADD _IOW('B', 200, int)
548#define BNEPCONNDEL _IOW('B', 201, int)
549#define BNEPGETCONNLIST _IOR('B', 210, int)
550#define BNEPGETCONNINFO _IOR('B', 211, int)
551#define BNEPGETSUPPFEAT _IOR('B', 212, int)
552
553#define CMTPCONNADD _IOW('C', 200, int)
554#define CMTPCONNDEL _IOW('C', 201, int)
555#define CMTPGETCONNLIST _IOR('C', 210, int)
556#define CMTPGETCONNINFO _IOR('C', 211, int)
557
558#define HIDPCONNADD _IOW('H', 200, int)
559#define HIDPCONNDEL _IOW('H', 201, int)
560#define HIDPGETCONNLIST _IOR('H', 210, int)
561#define HIDPGETCONNINFO _IOR('H', 211, int)
562
563#define RTC_IRQP_READ32 _IOR('p', 0x0b, compat_ulong_t) 509#define RTC_IRQP_READ32 _IOR('p', 0x0b, compat_ulong_t)
564#define RTC_IRQP_SET32 _IOW('p', 0x0c, compat_ulong_t) 510#define RTC_IRQP_SET32 _IOW('p', 0x0c, compat_ulong_t)
565#define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t) 511#define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t)
@@ -974,19 +920,6 @@ COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
974COMPATIBLE_IOCTL(RFCOMMGETDEVLIST) 920COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
975COMPATIBLE_IOCTL(RFCOMMGETDEVINFO) 921COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
976COMPATIBLE_IOCTL(RFCOMMSTEALDLC) 922COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
977COMPATIBLE_IOCTL(BNEPCONNADD)
978COMPATIBLE_IOCTL(BNEPCONNDEL)
979COMPATIBLE_IOCTL(BNEPGETCONNLIST)
980COMPATIBLE_IOCTL(BNEPGETCONNINFO)
981COMPATIBLE_IOCTL(BNEPGETSUPPFEAT)
982COMPATIBLE_IOCTL(CMTPCONNADD)
983COMPATIBLE_IOCTL(CMTPCONNDEL)
984COMPATIBLE_IOCTL(CMTPGETCONNLIST)
985COMPATIBLE_IOCTL(CMTPGETCONNINFO)
986COMPATIBLE_IOCTL(HIDPCONNADD)
987COMPATIBLE_IOCTL(HIDPCONNDEL)
988COMPATIBLE_IOCTL(HIDPGETCONNLIST)
989COMPATIBLE_IOCTL(HIDPGETCONNINFO)
990/* CAPI */ 923/* CAPI */
991COMPATIBLE_IOCTL(CAPI_REGISTER) 924COMPATIBLE_IOCTL(CAPI_REGISTER)
992COMPATIBLE_IOCTL(CAPI_GET_MANUFACTURER) 925COMPATIBLE_IOCTL(CAPI_GET_MANUFACTURER)
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index 00deacdcb51c..cfd83c5521ae 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -49,18 +49,17 @@ static int bnep_sock_release(struct socket *sock)
49 return 0; 49 return 0;
50} 50}
51 51
52static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 52static int do_bnep_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp)
53{ 53{
54 struct bnep_connlist_req cl; 54 struct bnep_connlist_req cl;
55 struct bnep_connadd_req ca; 55 struct bnep_connadd_req ca;
56 struct bnep_conndel_req cd; 56 struct bnep_conndel_req cd;
57 struct bnep_conninfo ci; 57 struct bnep_conninfo ci;
58 struct socket *nsock; 58 struct socket *nsock;
59 void __user *argp = (void __user *)arg;
60 __u32 supp_feat = BIT(BNEP_SETUP_RESPONSE); 59 __u32 supp_feat = BIT(BNEP_SETUP_RESPONSE);
61 int err; 60 int err;
62 61
63 BT_DBG("cmd %x arg %lx", cmd, arg); 62 BT_DBG("cmd %x arg %p", cmd, argp);
64 63
65 switch (cmd) { 64 switch (cmd) {
66 case BNEPCONNADD: 65 case BNEPCONNADD:
@@ -134,16 +133,22 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
134 return 0; 133 return 0;
135} 134}
136 135
136static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
137{
138 return do_bnep_sock_ioctl(sock, cmd, (void __user *)arg);
139}
140
137#ifdef CONFIG_COMPAT 141#ifdef CONFIG_COMPAT
138static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 142static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
139{ 143{
144 void __user *argp = compat_ptr(arg);
140 if (cmd == BNEPGETCONNLIST) { 145 if (cmd == BNEPGETCONNLIST) {
141 struct bnep_connlist_req cl; 146 struct bnep_connlist_req cl;
147 unsigned __user *p = argp;
142 u32 uci; 148 u32 uci;
143 int err; 149 int err;
144 150
145 if (get_user(cl.cnum, (u32 __user *) arg) || 151 if (get_user(cl.cnum, p) || get_user(uci, p + 1))
146 get_user(uci, (u32 __user *) (arg + 4)))
147 return -EFAULT; 152 return -EFAULT;
148 153
149 cl.ci = compat_ptr(uci); 154 cl.ci = compat_ptr(uci);
@@ -153,13 +158,13 @@ static int bnep_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
153 158
154 err = bnep_get_connlist(&cl); 159 err = bnep_get_connlist(&cl);
155 160
156 if (!err && put_user(cl.cnum, (u32 __user *) arg)) 161 if (!err && put_user(cl.cnum, p))
157 err = -EFAULT; 162 err = -EFAULT;
158 163
159 return err; 164 return err;
160 } 165 }
161 166
162 return bnep_sock_ioctl(sock, cmd, arg); 167 return do_bnep_sock_ioctl(sock, cmd, argp);
163} 168}
164#endif 169#endif
165 170
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
index e08f28fadd65..defdd4871919 100644
--- a/net/bluetooth/cmtp/sock.c
+++ b/net/bluetooth/cmtp/sock.c
@@ -63,17 +63,16 @@ static int cmtp_sock_release(struct socket *sock)
63 return 0; 63 return 0;
64} 64}
65 65
66static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 66static int do_cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp)
67{ 67{
68 struct cmtp_connadd_req ca; 68 struct cmtp_connadd_req ca;
69 struct cmtp_conndel_req cd; 69 struct cmtp_conndel_req cd;
70 struct cmtp_connlist_req cl; 70 struct cmtp_connlist_req cl;
71 struct cmtp_conninfo ci; 71 struct cmtp_conninfo ci;
72 struct socket *nsock; 72 struct socket *nsock;
73 void __user *argp = (void __user *)arg;
74 int err; 73 int err;
75 74
76 BT_DBG("cmd %x arg %lx", cmd, arg); 75 BT_DBG("cmd %x arg %p", cmd, argp);
77 76
78 switch (cmd) { 77 switch (cmd) {
79 case CMTPCONNADD: 78 case CMTPCONNADD:
@@ -137,16 +136,22 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
137 return -EINVAL; 136 return -EINVAL;
138} 137}
139 138
139static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
140{
141 return do_cmtp_sock_ioctl(sock, cmd, (void __user *)arg);
142}
143
140#ifdef CONFIG_COMPAT 144#ifdef CONFIG_COMPAT
141static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 145static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
142{ 146{
147 void __user *argp = compat_ptr(arg);
143 if (cmd == CMTPGETCONNLIST) { 148 if (cmd == CMTPGETCONNLIST) {
144 struct cmtp_connlist_req cl; 149 struct cmtp_connlist_req cl;
150 u32 __user *p = argp;
145 u32 uci; 151 u32 uci;
146 int err; 152 int err;
147 153
148 if (get_user(cl.cnum, (u32 __user *) arg) || 154 if (get_user(cl.cnum, p) || get_user(uci, p + 1))
149 get_user(uci, (u32 __user *) (arg + 4)))
150 return -EFAULT; 155 return -EFAULT;
151 156
152 cl.ci = compat_ptr(uci); 157 cl.ci = compat_ptr(uci);
@@ -156,13 +161,13 @@ static int cmtp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
156 161
157 err = cmtp_get_connlist(&cl); 162 err = cmtp_get_connlist(&cl);
158 163
159 if (!err && put_user(cl.cnum, (u32 __user *) arg)) 164 if (!err && put_user(cl.cnum, p))
160 err = -EFAULT; 165 err = -EFAULT;
161 166
162 return err; 167 return err;
163 } 168 }
164 169
165 return cmtp_sock_ioctl(sock, cmd, arg); 170 return do_cmtp_sock_ioctl(sock, cmd, argp);
166} 171}
167#endif 172#endif
168 173
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 3734dc1788b4..a442e21f3894 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -649,7 +649,7 @@ static void hidp_process_transmit(struct hidp_session *session,
649} 649}
650 650
651static int hidp_setup_input(struct hidp_session *session, 651static int hidp_setup_input(struct hidp_session *session,
652 struct hidp_connadd_req *req) 652 const struct hidp_connadd_req *req)
653{ 653{
654 struct input_dev *input; 654 struct input_dev *input;
655 int i; 655 int i;
@@ -748,7 +748,7 @@ EXPORT_SYMBOL_GPL(hidp_hid_driver);
748/* This function sets up the hid device. It does not add it 748/* This function sets up the hid device. It does not add it
749 to the HID system. That is done in hidp_add_connection(). */ 749 to the HID system. That is done in hidp_add_connection(). */
750static int hidp_setup_hid(struct hidp_session *session, 750static int hidp_setup_hid(struct hidp_session *session,
751 struct hidp_connadd_req *req) 751 const struct hidp_connadd_req *req)
752{ 752{
753 struct hid_device *hid; 753 struct hid_device *hid;
754 int err; 754 int err;
@@ -807,7 +807,7 @@ fault:
807 807
808/* initialize session devices */ 808/* initialize session devices */
809static int hidp_session_dev_init(struct hidp_session *session, 809static int hidp_session_dev_init(struct hidp_session *session,
810 struct hidp_connadd_req *req) 810 const struct hidp_connadd_req *req)
811{ 811{
812 int ret; 812 int ret;
813 813
@@ -906,7 +906,7 @@ static void hidp_session_dev_work(struct work_struct *work)
906static int hidp_session_new(struct hidp_session **out, const bdaddr_t *bdaddr, 906static int hidp_session_new(struct hidp_session **out, const bdaddr_t *bdaddr,
907 struct socket *ctrl_sock, 907 struct socket *ctrl_sock,
908 struct socket *intr_sock, 908 struct socket *intr_sock,
909 struct hidp_connadd_req *req, 909 const struct hidp_connadd_req *req,
910 struct l2cap_conn *conn) 910 struct l2cap_conn *conn)
911{ 911{
912 struct hidp_session *session; 912 struct hidp_session *session;
@@ -1338,7 +1338,7 @@ static int hidp_verify_sockets(struct socket *ctrl_sock,
1338 return 0; 1338 return 0;
1339} 1339}
1340 1340
1341int hidp_connection_add(struct hidp_connadd_req *req, 1341int hidp_connection_add(const struct hidp_connadd_req *req,
1342 struct socket *ctrl_sock, 1342 struct socket *ctrl_sock,
1343 struct socket *intr_sock) 1343 struct socket *intr_sock)
1344{ 1344{
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h
index 8798492a6e99..6ef88d0a1919 100644
--- a/net/bluetooth/hidp/hidp.h
+++ b/net/bluetooth/hidp/hidp.h
@@ -122,7 +122,7 @@ struct hidp_connlist_req {
122 struct hidp_conninfo __user *ci; 122 struct hidp_conninfo __user *ci;
123}; 123};
124 124
125int hidp_connection_add(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock); 125int hidp_connection_add(const struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock);
126int hidp_connection_del(struct hidp_conndel_req *req); 126int hidp_connection_del(struct hidp_conndel_req *req);
127int hidp_get_connlist(struct hidp_connlist_req *req); 127int hidp_get_connlist(struct hidp_connlist_req *req);
128int hidp_get_conninfo(struct hidp_conninfo *ci); 128int hidp_get_conninfo(struct hidp_conninfo *ci);
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c
index 1eaac01f85de..9f85a1943be9 100644
--- a/net/bluetooth/hidp/sock.c
+++ b/net/bluetooth/hidp/sock.c
@@ -46,9 +46,8 @@ static int hidp_sock_release(struct socket *sock)
46 return 0; 46 return 0;
47} 47}
48 48
49static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 49static int do_hidp_sock_ioctl(struct socket *sock, unsigned int cmd, void __user *argp)
50{ 50{
51 void __user *argp = (void __user *) arg;
52 struct hidp_connadd_req ca; 51 struct hidp_connadd_req ca;
53 struct hidp_conndel_req cd; 52 struct hidp_conndel_req cd;
54 struct hidp_connlist_req cl; 53 struct hidp_connlist_req cl;
@@ -57,7 +56,7 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
57 struct socket *isock; 56 struct socket *isock;
58 int err; 57 int err;
59 58
60 BT_DBG("cmd %x arg %lx", cmd, arg); 59 BT_DBG("cmd %x arg %p", cmd, argp);
61 60
62 switch (cmd) { 61 switch (cmd) {
63 case HIDPCONNADD: 62 case HIDPCONNADD:
@@ -122,6 +121,11 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
122 return -EINVAL; 121 return -EINVAL;
123} 122}
124 123
124static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
125{
126 return do_hidp_sock_ioctl(sock, cmd, (void __user *)arg);
127}
128
125#ifdef CONFIG_COMPAT 129#ifdef CONFIG_COMPAT
126struct compat_hidp_connadd_req { 130struct compat_hidp_connadd_req {
127 int ctrl_sock; /* Connected control socket */ 131 int ctrl_sock; /* Connected control socket */
@@ -141,13 +145,15 @@ struct compat_hidp_connadd_req {
141 145
142static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 146static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
143{ 147{
148 void __user *argp = compat_ptr(arg);
149 int err;
150
144 if (cmd == HIDPGETCONNLIST) { 151 if (cmd == HIDPGETCONNLIST) {
145 struct hidp_connlist_req cl; 152 struct hidp_connlist_req cl;
153 u32 __user *p = argp;
146 u32 uci; 154 u32 uci;
147 int err;
148 155
149 if (get_user(cl.cnum, (u32 __user *) arg) || 156 if (get_user(cl.cnum, p) || get_user(uci, p + 1))
150 get_user(uci, (u32 __user *) (arg + 4)))
151 return -EFAULT; 157 return -EFAULT;
152 158
153 cl.ci = compat_ptr(uci); 159 cl.ci = compat_ptr(uci);
@@ -157,39 +163,54 @@ static int hidp_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsigne
157 163
158 err = hidp_get_connlist(&cl); 164 err = hidp_get_connlist(&cl);
159 165
160 if (!err && put_user(cl.cnum, (u32 __user *) arg)) 166 if (!err && put_user(cl.cnum, p))
161 err = -EFAULT; 167 err = -EFAULT;
162 168
163 return err; 169 return err;
164 } else if (cmd == HIDPCONNADD) { 170 } else if (cmd == HIDPCONNADD) {
165 struct compat_hidp_connadd_req ca; 171 struct compat_hidp_connadd_req ca32;
166 struct hidp_connadd_req __user *uca; 172 struct hidp_connadd_req ca;
173 struct socket *csock;
174 struct socket *isock;
167 175
168 uca = compat_alloc_user_space(sizeof(*uca)); 176 if (!capable(CAP_NET_ADMIN))
177 return -EPERM;
169 178
170 if (copy_from_user(&ca, (void __user *) arg, sizeof(ca))) 179 if (copy_from_user(&ca32, (void __user *) arg, sizeof(ca32)))
171 return -EFAULT; 180 return -EFAULT;
172 181
173 if (put_user(ca.ctrl_sock, &uca->ctrl_sock) || 182 ca.ctrl_sock = ca32.ctrl_sock;
174 put_user(ca.intr_sock, &uca->intr_sock) || 183 ca.intr_sock = ca32.intr_sock;
175 put_user(ca.parser, &uca->parser) || 184 ca.parser = ca32.parser;
176 put_user(ca.rd_size, &uca->rd_size) || 185 ca.rd_size = ca32.rd_size;
177 put_user(compat_ptr(ca.rd_data), &uca->rd_data) || 186 ca.rd_data = compat_ptr(ca32.rd_data);
178 put_user(ca.country, &uca->country) || 187 ca.country = ca32.country;
179 put_user(ca.subclass, &uca->subclass) || 188 ca.subclass = ca32.subclass;
180 put_user(ca.vendor, &uca->vendor) || 189 ca.vendor = ca32.vendor;
181 put_user(ca.product, &uca->product) || 190 ca.product = ca32.product;
182 put_user(ca.version, &uca->version) || 191 ca.version = ca32.version;
183 put_user(ca.flags, &uca->flags) || 192 ca.flags = ca32.flags;
184 put_user(ca.idle_to, &uca->idle_to) || 193 ca.idle_to = ca32.idle_to;
185 copy_to_user(&uca->name[0], &ca.name[0], 128)) 194 memcpy(ca.name, ca32.name, 128);
186 return -EFAULT; 195
196 csock = sockfd_lookup(ca.ctrl_sock, &err);
197 if (!csock)
198 return err;
187 199
188 arg = (unsigned long) uca; 200 isock = sockfd_lookup(ca.intr_sock, &err);
201 if (!isock) {
202 sockfd_put(csock);
203 return err;
204 }
189 205
190 /* Fall through. We don't actually write back any _changes_ 206 err = hidp_connection_add(&ca, csock, isock);
191 to the structure anyway, so there's no need to copy back 207 if (!err && copy_to_user(argp, &ca32, sizeof(ca32)))
192 into the original compat version */ 208 err = -EFAULT;
209
210 sockfd_put(csock);
211 sockfd_put(isock);
212
213 return err;
193 } 214 }
194 215
195 return hidp_sock_ioctl(sock, cmd, arg); 216 return hidp_sock_ioctl(sock, cmd, arg);