.. | .. |
---|
47 | 47 | #if 0 |
---|
48 | 48 | #define dprintk(args...) printk(KERN_DEBUG args) |
---|
49 | 49 | #else |
---|
50 | | -#define dprintk(args...) |
---|
| 50 | +#define dprintk(args...) do {} while (0) |
---|
51 | 51 | #endif |
---|
52 | 52 | |
---|
53 | 53 | /* Maybe we'll add some more in the future. */ |
---|
.. | .. |
---|
276 | 276 | { |
---|
277 | 277 | struct sock *sk = sock->sk; |
---|
278 | 278 | struct llc_sock *llc = llc_sk(sk); |
---|
| 279 | + struct net_device *dev = NULL; |
---|
279 | 280 | struct llc_sap *sap; |
---|
280 | 281 | int rc = -EINVAL; |
---|
281 | 282 | |
---|
.. | .. |
---|
287 | 288 | goto out; |
---|
288 | 289 | rc = -ENODEV; |
---|
289 | 290 | if (sk->sk_bound_dev_if) { |
---|
290 | | - llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); |
---|
291 | | - if (llc->dev && addr->sllc_arphrd != llc->dev->type) { |
---|
292 | | - dev_put(llc->dev); |
---|
293 | | - llc->dev = NULL; |
---|
| 291 | + dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); |
---|
| 292 | + if (dev && addr->sllc_arphrd != dev->type) { |
---|
| 293 | + dev_put(dev); |
---|
| 294 | + dev = NULL; |
---|
294 | 295 | } |
---|
295 | 296 | } else |
---|
296 | | - llc->dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd); |
---|
297 | | - if (!llc->dev) |
---|
| 297 | + dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd); |
---|
| 298 | + if (!dev) |
---|
298 | 299 | goto out; |
---|
299 | 300 | rc = -EUSERS; |
---|
300 | 301 | llc->laddr.lsap = llc_ui_autoport(); |
---|
.. | .. |
---|
304 | 305 | sap = llc_sap_open(llc->laddr.lsap, NULL); |
---|
305 | 306 | if (!sap) |
---|
306 | 307 | goto out; |
---|
| 308 | + |
---|
| 309 | + /* Note: We do not expect errors from this point. */ |
---|
| 310 | + llc->dev = dev; |
---|
| 311 | + dev = NULL; |
---|
| 312 | + |
---|
307 | 313 | memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN); |
---|
308 | 314 | memcpy(&llc->addr, addr, sizeof(llc->addr)); |
---|
309 | 315 | /* assign new connection to its SAP */ |
---|
.. | .. |
---|
311 | 317 | sock_reset_flag(sk, SOCK_ZAPPED); |
---|
312 | 318 | rc = 0; |
---|
313 | 319 | out: |
---|
| 320 | + dev_put(dev); |
---|
314 | 321 | return rc; |
---|
315 | 322 | } |
---|
316 | 323 | |
---|
.. | .. |
---|
333 | 340 | struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr; |
---|
334 | 341 | struct sock *sk = sock->sk; |
---|
335 | 342 | struct llc_sock *llc = llc_sk(sk); |
---|
| 343 | + struct net_device *dev = NULL; |
---|
336 | 344 | struct llc_sap *sap; |
---|
337 | 345 | int rc = -EINVAL; |
---|
338 | | - |
---|
339 | | - dprintk("%s: binding %02X\n", __func__, addr->sllc_sap); |
---|
340 | 346 | |
---|
341 | 347 | lock_sock(sk); |
---|
342 | 348 | if (unlikely(!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr))) |
---|
.. | .. |
---|
346 | 352 | addr->sllc_arphrd = ARPHRD_ETHER; |
---|
347 | 353 | if (unlikely(addr->sllc_family != AF_LLC || addr->sllc_arphrd != ARPHRD_ETHER)) |
---|
348 | 354 | goto out; |
---|
| 355 | + dprintk("%s: binding %02X\n", __func__, addr->sllc_sap); |
---|
349 | 356 | rc = -ENODEV; |
---|
350 | 357 | rcu_read_lock(); |
---|
351 | 358 | if (sk->sk_bound_dev_if) { |
---|
352 | | - llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if); |
---|
353 | | - if (llc->dev) { |
---|
| 359 | + dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if); |
---|
| 360 | + if (dev) { |
---|
354 | 361 | if (is_zero_ether_addr(addr->sllc_mac)) |
---|
355 | | - memcpy(addr->sllc_mac, llc->dev->dev_addr, |
---|
| 362 | + memcpy(addr->sllc_mac, dev->dev_addr, |
---|
356 | 363 | IFHWADDRLEN); |
---|
357 | | - if (addr->sllc_arphrd != llc->dev->type || |
---|
| 364 | + if (addr->sllc_arphrd != dev->type || |
---|
358 | 365 | !ether_addr_equal(addr->sllc_mac, |
---|
359 | | - llc->dev->dev_addr)) { |
---|
| 366 | + dev->dev_addr)) { |
---|
360 | 367 | rc = -EINVAL; |
---|
361 | | - llc->dev = NULL; |
---|
| 368 | + dev = NULL; |
---|
362 | 369 | } |
---|
363 | 370 | } |
---|
364 | | - } else |
---|
365 | | - llc->dev = dev_getbyhwaddr_rcu(&init_net, addr->sllc_arphrd, |
---|
| 371 | + } else { |
---|
| 372 | + dev = dev_getbyhwaddr_rcu(&init_net, addr->sllc_arphrd, |
---|
366 | 373 | addr->sllc_mac); |
---|
367 | | - if (llc->dev) |
---|
368 | | - dev_hold(llc->dev); |
---|
| 374 | + } |
---|
| 375 | + if (dev) |
---|
| 376 | + dev_hold(dev); |
---|
369 | 377 | rcu_read_unlock(); |
---|
370 | | - if (!llc->dev) |
---|
| 378 | + if (!dev) |
---|
371 | 379 | goto out; |
---|
372 | 380 | if (!addr->sllc_sap) { |
---|
373 | 381 | rc = -EUSERS; |
---|
.. | .. |
---|
400 | 408 | goto out_put; |
---|
401 | 409 | } |
---|
402 | 410 | } |
---|
| 411 | + |
---|
| 412 | + /* Note: We do not expect errors from this point. */ |
---|
| 413 | + llc->dev = dev; |
---|
| 414 | + dev = NULL; |
---|
| 415 | + |
---|
403 | 416 | llc->laddr.lsap = addr->sllc_sap; |
---|
404 | 417 | memcpy(llc->laddr.mac, addr->sllc_mac, IFHWADDRLEN); |
---|
405 | 418 | memcpy(&llc->addr, addr, sizeof(llc->addr)); |
---|
.. | .. |
---|
410 | 423 | out_put: |
---|
411 | 424 | llc_sap_put(sap); |
---|
412 | 425 | out: |
---|
| 426 | + dev_put(dev); |
---|
413 | 427 | release_sock(sk); |
---|
414 | 428 | return rc; |
---|
415 | 429 | } |
---|
.. | .. |
---|
718 | 732 | |
---|
719 | 733 | /* put original socket back into a clean listen state. */ |
---|
720 | 734 | sk->sk_state = TCP_LISTEN; |
---|
721 | | - sk->sk_ack_backlog--; |
---|
| 735 | + sk_acceptq_removed(sk); |
---|
722 | 736 | dprintk("%s: ok success on %02X, client on %02X\n", __func__, |
---|
723 | 737 | llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap); |
---|
724 | 738 | frees: |
---|
.. | .. |
---|
993 | 1007 | * llc_ui_getname - return the address info of a socket |
---|
994 | 1008 | * @sock: Socket to get address of. |
---|
995 | 1009 | * @uaddr: Address structure to return information. |
---|
996 | | - * @uaddrlen: Length of address structure. |
---|
997 | 1010 | * @peer: Does user want local or remote address information. |
---|
998 | 1011 | * |
---|
999 | 1012 | * Return the address information of a socket. |
---|
.. | .. |
---|
1063 | 1076 | * Set various connection specific parameters. |
---|
1064 | 1077 | */ |
---|
1065 | 1078 | static int llc_ui_setsockopt(struct socket *sock, int level, int optname, |
---|
1066 | | - char __user *optval, unsigned int optlen) |
---|
| 1079 | + sockptr_t optval, unsigned int optlen) |
---|
1067 | 1080 | { |
---|
1068 | 1081 | struct sock *sk = sock->sk; |
---|
1069 | 1082 | struct llc_sock *llc = llc_sk(sk); |
---|
.. | .. |
---|
1073 | 1086 | lock_sock(sk); |
---|
1074 | 1087 | if (unlikely(level != SOL_LLC || optlen != sizeof(int))) |
---|
1075 | 1088 | goto out; |
---|
1076 | | - rc = get_user(opt, (int __user *)optval); |
---|
| 1089 | + rc = copy_from_sockptr(&opt, optval, sizeof(opt)); |
---|
1077 | 1090 | if (rc) |
---|
1078 | 1091 | goto out; |
---|
1079 | 1092 | rc = -EINVAL; |
---|