.. | .. |
---|
56 | 56 | int error; |
---|
57 | 57 | struct list_head *pos; |
---|
58 | 58 | void __user *argp = (void __user *)arg; |
---|
| 59 | + void __user *buf; |
---|
| 60 | + int __user *len; |
---|
59 | 61 | |
---|
60 | 62 | vcc = ATM_SD(sock); |
---|
61 | 63 | switch (cmd) { |
---|
.. | .. |
---|
81 | 83 | (int __user *)argp) ? -EFAULT : 0; |
---|
82 | 84 | goto done; |
---|
83 | 85 | } |
---|
84 | | - case SIOCGSTAMP: /* borrowed from IP */ |
---|
85 | | -#ifdef CONFIG_COMPAT |
---|
86 | | - if (compat) |
---|
87 | | - error = compat_sock_get_timestamp(sk, argp); |
---|
88 | | - else |
---|
89 | | -#endif |
---|
90 | | - error = sock_get_timestamp(sk, argp); |
---|
91 | | - goto done; |
---|
92 | | - case SIOCGSTAMPNS: /* borrowed from IP */ |
---|
93 | | -#ifdef CONFIG_COMPAT |
---|
94 | | - if (compat) |
---|
95 | | - error = compat_sock_get_timestampns(sk, argp); |
---|
96 | | - else |
---|
97 | | -#endif |
---|
98 | | - error = sock_get_timestampns(sk, argp); |
---|
99 | | - goto done; |
---|
100 | 86 | case ATM_SETSC: |
---|
101 | 87 | net_warn_ratelimited("ATM_SETSC is obsolete; used by %s:%d\n", |
---|
102 | 88 | current->comm, task_pid_nr(current)); |
---|
.. | .. |
---|
178 | 164 | if (error != -ENOIOCTLCMD) |
---|
179 | 165 | goto done; |
---|
180 | 166 | |
---|
181 | | - error = atm_dev_ioctl(cmd, argp, compat); |
---|
| 167 | + if (cmd == ATM_GETNAMES) { |
---|
| 168 | + if (IS_ENABLED(CONFIG_COMPAT) && compat) { |
---|
| 169 | +#ifdef CONFIG_COMPAT |
---|
| 170 | + struct compat_atm_iobuf __user *ciobuf = argp; |
---|
| 171 | + compat_uptr_t cbuf; |
---|
| 172 | + len = &ciobuf->length; |
---|
| 173 | + if (get_user(cbuf, &ciobuf->buffer)) |
---|
| 174 | + return -EFAULT; |
---|
| 175 | + buf = compat_ptr(cbuf); |
---|
| 176 | +#endif |
---|
| 177 | + } else { |
---|
| 178 | + struct atm_iobuf __user *iobuf = argp; |
---|
| 179 | + len = &iobuf->length; |
---|
| 180 | + if (get_user(buf, &iobuf->buffer)) |
---|
| 181 | + return -EFAULT; |
---|
| 182 | + } |
---|
| 183 | + error = atm_getnames(buf, len); |
---|
| 184 | + } else { |
---|
| 185 | + int number; |
---|
| 186 | + |
---|
| 187 | + if (IS_ENABLED(CONFIG_COMPAT) && compat) { |
---|
| 188 | +#ifdef CONFIG_COMPAT |
---|
| 189 | + struct compat_atmif_sioc __user *csioc = argp; |
---|
| 190 | + compat_uptr_t carg; |
---|
| 191 | + |
---|
| 192 | + len = &csioc->length; |
---|
| 193 | + if (get_user(carg, &csioc->arg)) |
---|
| 194 | + return -EFAULT; |
---|
| 195 | + buf = compat_ptr(carg); |
---|
| 196 | + if (get_user(number, &csioc->number)) |
---|
| 197 | + return -EFAULT; |
---|
| 198 | +#endif |
---|
| 199 | + } else { |
---|
| 200 | + struct atmif_sioc __user *sioc = argp; |
---|
| 201 | + |
---|
| 202 | + len = &sioc->length; |
---|
| 203 | + if (get_user(buf, &sioc->arg)) |
---|
| 204 | + return -EFAULT; |
---|
| 205 | + if (get_user(number, &sioc->number)) |
---|
| 206 | + return -EFAULT; |
---|
| 207 | + } |
---|
| 208 | + error = atm_dev_ioctl(cmd, buf, len, number, compat); |
---|
| 209 | + } |
---|
182 | 210 | |
---|
183 | 211 | done: |
---|
184 | 212 | return error; |
---|
.. | .. |
---|
246 | 274 | static int do_atm_iobuf(struct socket *sock, unsigned int cmd, |
---|
247 | 275 | unsigned long arg) |
---|
248 | 276 | { |
---|
249 | | - struct atm_iobuf __user *iobuf; |
---|
250 | | - struct compat_atm_iobuf __user *iobuf32; |
---|
| 277 | + struct compat_atm_iobuf __user *iobuf32 = compat_ptr(arg); |
---|
251 | 278 | u32 data; |
---|
252 | | - void __user *datap; |
---|
253 | | - int len, err; |
---|
254 | 279 | |
---|
255 | | - iobuf = compat_alloc_user_space(sizeof(*iobuf)); |
---|
256 | | - iobuf32 = compat_ptr(arg); |
---|
257 | | - |
---|
258 | | - if (get_user(len, &iobuf32->length) || |
---|
259 | | - get_user(data, &iobuf32->buffer)) |
---|
260 | | - return -EFAULT; |
---|
261 | | - datap = compat_ptr(data); |
---|
262 | | - if (put_user(len, &iobuf->length) || |
---|
263 | | - put_user(datap, &iobuf->buffer)) |
---|
| 280 | + if (get_user(data, &iobuf32->buffer)) |
---|
264 | 281 | return -EFAULT; |
---|
265 | 282 | |
---|
266 | | - err = do_vcc_ioctl(sock, cmd, (unsigned long) iobuf, 0); |
---|
267 | | - |
---|
268 | | - if (!err) { |
---|
269 | | - if (copy_in_user(&iobuf32->length, &iobuf->length, |
---|
270 | | - sizeof(int))) |
---|
271 | | - err = -EFAULT; |
---|
272 | | - } |
---|
273 | | - |
---|
274 | | - return err; |
---|
| 283 | + return atm_getnames(&iobuf32->length, compat_ptr(data)); |
---|
275 | 284 | } |
---|
276 | 285 | |
---|
277 | 286 | static int do_atmif_sioc(struct socket *sock, unsigned int cmd, |
---|
278 | 287 | unsigned long arg) |
---|
279 | 288 | { |
---|
280 | | - struct atmif_sioc __user *sioc; |
---|
281 | | - struct compat_atmif_sioc __user *sioc32; |
---|
| 289 | + struct compat_atmif_sioc __user *sioc32 = compat_ptr(arg); |
---|
| 290 | + int number; |
---|
282 | 291 | u32 data; |
---|
283 | | - void __user *datap; |
---|
284 | | - int err; |
---|
285 | 292 | |
---|
286 | | - sioc = compat_alloc_user_space(sizeof(*sioc)); |
---|
287 | | - sioc32 = compat_ptr(arg); |
---|
288 | | - |
---|
289 | | - if (copy_in_user(&sioc->number, &sioc32->number, 2 * sizeof(int)) || |
---|
290 | | - get_user(data, &sioc32->arg)) |
---|
| 293 | + if (get_user(data, &sioc32->arg) || get_user(number, &sioc32->number)) |
---|
291 | 294 | return -EFAULT; |
---|
292 | | - datap = compat_ptr(data); |
---|
293 | | - if (put_user(datap, &sioc->arg)) |
---|
294 | | - return -EFAULT; |
---|
295 | | - |
---|
296 | | - err = do_vcc_ioctl(sock, cmd, (unsigned long) sioc, 0); |
---|
297 | | - |
---|
298 | | - if (!err) { |
---|
299 | | - if (copy_in_user(&sioc32->length, &sioc->length, |
---|
300 | | - sizeof(int))) |
---|
301 | | - err = -EFAULT; |
---|
302 | | - } |
---|
303 | | - return err; |
---|
| 295 | + return atm_dev_ioctl(cmd, compat_ptr(data), &sioc32->length, number, 0); |
---|
304 | 296 | } |
---|
305 | 297 | |
---|
306 | 298 | static int do_atm_ioctl(struct socket *sock, unsigned int cmd32, |
---|