.. | .. |
---|
45 | 45 | static void l2cap_sock_init(struct sock *sk, struct sock *parent); |
---|
46 | 46 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, |
---|
47 | 47 | int proto, gfp_t prio, int kern); |
---|
| 48 | +static void l2cap_sock_cleanup_listen(struct sock *parent); |
---|
48 | 49 | |
---|
49 | 50 | bool l2cap_is_socket(struct socket *sock) |
---|
50 | 51 | { |
---|
.. | .. |
---|
161 | 162 | break; |
---|
162 | 163 | } |
---|
163 | 164 | |
---|
164 | | - if (chan->psm && bdaddr_type_is_le(chan->src_type)) |
---|
| 165 | + /* Use L2CAP_MODE_LE_FLOWCTL (CoC) in case of LE address and |
---|
| 166 | + * L2CAP_MODE_EXT_FLOWCTL (ECRED) has not been set. |
---|
| 167 | + */ |
---|
| 168 | + if (chan->psm && bdaddr_type_is_le(chan->src_type) && |
---|
| 169 | + chan->mode != L2CAP_MODE_EXT_FLOWCTL) |
---|
165 | 170 | chan->mode = L2CAP_MODE_LE_FLOWCTL; |
---|
166 | 171 | |
---|
167 | 172 | chan->state = BT_BOUND; |
---|
.. | .. |
---|
170 | 175 | done: |
---|
171 | 176 | release_sock(sk); |
---|
172 | 177 | return err; |
---|
| 178 | +} |
---|
| 179 | + |
---|
| 180 | +static void l2cap_sock_init_pid(struct sock *sk) |
---|
| 181 | +{ |
---|
| 182 | + struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
---|
| 183 | + |
---|
| 184 | + /* Only L2CAP_MODE_EXT_FLOWCTL ever need to access the PID in order to |
---|
| 185 | + * group the channels being requested. |
---|
| 186 | + */ |
---|
| 187 | + if (chan->mode != L2CAP_MODE_EXT_FLOWCTL) |
---|
| 188 | + return; |
---|
| 189 | + |
---|
| 190 | + spin_lock(&sk->sk_peer_lock); |
---|
| 191 | + sk->sk_peer_pid = get_pid(task_tgid(current)); |
---|
| 192 | + spin_unlock(&sk->sk_peer_lock); |
---|
173 | 193 | } |
---|
174 | 194 | |
---|
175 | 195 | static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, |
---|
.. | .. |
---|
240 | 260 | return -EINVAL; |
---|
241 | 261 | } |
---|
242 | 262 | |
---|
243 | | - if (chan->psm && bdaddr_type_is_le(chan->src_type)) |
---|
| 263 | + /* Use L2CAP_MODE_LE_FLOWCTL (CoC) in case of LE address and |
---|
| 264 | + * L2CAP_MODE_EXT_FLOWCTL (ECRED) has not been set. |
---|
| 265 | + */ |
---|
| 266 | + if (chan->psm && bdaddr_type_is_le(chan->src_type) && |
---|
| 267 | + chan->mode != L2CAP_MODE_EXT_FLOWCTL) |
---|
244 | 268 | chan->mode = L2CAP_MODE_LE_FLOWCTL; |
---|
| 269 | + |
---|
| 270 | + l2cap_sock_init_pid(sk); |
---|
245 | 271 | |
---|
246 | 272 | err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), |
---|
247 | 273 | &la.l2_bdaddr, la.l2_bdaddr_type); |
---|
.. | .. |
---|
282 | 308 | case L2CAP_MODE_BASIC: |
---|
283 | 309 | case L2CAP_MODE_LE_FLOWCTL: |
---|
284 | 310 | break; |
---|
| 311 | + case L2CAP_MODE_EXT_FLOWCTL: |
---|
| 312 | + if (!enable_ecred) { |
---|
| 313 | + err = -EOPNOTSUPP; |
---|
| 314 | + goto done; |
---|
| 315 | + } |
---|
| 316 | + break; |
---|
285 | 317 | case L2CAP_MODE_ERTM: |
---|
286 | 318 | case L2CAP_MODE_STREAMING: |
---|
287 | 319 | if (!disable_ertm) |
---|
288 | 320 | break; |
---|
289 | | - /* fall through */ |
---|
| 321 | + fallthrough; |
---|
290 | 322 | default: |
---|
291 | 323 | err = -EOPNOTSUPP; |
---|
292 | 324 | goto done; |
---|
293 | 325 | } |
---|
| 326 | + |
---|
| 327 | + l2cap_sock_init_pid(sk); |
---|
294 | 328 | |
---|
295 | 329 | sk->sk_max_ack_backlog = backlog; |
---|
296 | 330 | sk->sk_ack_backlog = 0; |
---|
.. | .. |
---|
397 | 431 | return sizeof(struct sockaddr_l2); |
---|
398 | 432 | } |
---|
399 | 433 | |
---|
| 434 | +static int l2cap_get_mode(struct l2cap_chan *chan) |
---|
| 435 | +{ |
---|
| 436 | + switch (chan->mode) { |
---|
| 437 | + case L2CAP_MODE_BASIC: |
---|
| 438 | + return BT_MODE_BASIC; |
---|
| 439 | + case L2CAP_MODE_ERTM: |
---|
| 440 | + return BT_MODE_ERTM; |
---|
| 441 | + case L2CAP_MODE_STREAMING: |
---|
| 442 | + return BT_MODE_STREAMING; |
---|
| 443 | + case L2CAP_MODE_LE_FLOWCTL: |
---|
| 444 | + return BT_MODE_LE_FLOWCTL; |
---|
| 445 | + case L2CAP_MODE_EXT_FLOWCTL: |
---|
| 446 | + return BT_MODE_EXT_FLOWCTL; |
---|
| 447 | + } |
---|
| 448 | + |
---|
| 449 | + return -EINVAL; |
---|
| 450 | +} |
---|
| 451 | + |
---|
400 | 452 | static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, |
---|
401 | 453 | char __user *optval, int __user *optlen) |
---|
402 | 454 | { |
---|
.. | .. |
---|
426 | 478 | break; |
---|
427 | 479 | } |
---|
428 | 480 | |
---|
| 481 | + /* Only BR/EDR modes are supported here */ |
---|
| 482 | + switch (chan->mode) { |
---|
| 483 | + case L2CAP_MODE_BASIC: |
---|
| 484 | + case L2CAP_MODE_ERTM: |
---|
| 485 | + case L2CAP_MODE_STREAMING: |
---|
| 486 | + break; |
---|
| 487 | + default: |
---|
| 488 | + err = -EINVAL; |
---|
| 489 | + break; |
---|
| 490 | + } |
---|
| 491 | + |
---|
| 492 | + if (err < 0) |
---|
| 493 | + break; |
---|
| 494 | + |
---|
429 | 495 | memset(&opts, 0, sizeof(opts)); |
---|
430 | 496 | opts.imtu = chan->imtu; |
---|
431 | 497 | opts.omtu = chan->omtu; |
---|
.. | .. |
---|
434 | 500 | opts.fcs = chan->fcs; |
---|
435 | 501 | opts.max_tx = chan->max_tx; |
---|
436 | 502 | opts.txwin_size = chan->tx_win; |
---|
| 503 | + |
---|
| 504 | + BT_DBG("mode 0x%2.2x", chan->mode); |
---|
437 | 505 | |
---|
438 | 506 | len = min_t(unsigned int, len, sizeof(opts)); |
---|
439 | 507 | if (copy_to_user(optval, (char *) &opts, len)) |
---|
.. | .. |
---|
507 | 575 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
---|
508 | 576 | struct bt_security sec; |
---|
509 | 577 | struct bt_power pwr; |
---|
510 | | - int len, err = 0; |
---|
| 578 | + u32 phys; |
---|
| 579 | + int len, mode, err = 0; |
---|
511 | 580 | |
---|
512 | 581 | BT_DBG("sk %p", sk); |
---|
513 | 582 | |
---|
.. | .. |
---|
611 | 680 | err = -EFAULT; |
---|
612 | 681 | break; |
---|
613 | 682 | |
---|
| 683 | + case BT_PHY: |
---|
| 684 | + if (sk->sk_state != BT_CONNECTED) { |
---|
| 685 | + err = -ENOTCONN; |
---|
| 686 | + break; |
---|
| 687 | + } |
---|
| 688 | + |
---|
| 689 | + phys = hci_conn_get_phy(chan->conn->hcon); |
---|
| 690 | + |
---|
| 691 | + if (put_user(phys, (u32 __user *) optval)) |
---|
| 692 | + err = -EFAULT; |
---|
| 693 | + break; |
---|
| 694 | + |
---|
| 695 | + case BT_MODE: |
---|
| 696 | + if (!enable_ecred) { |
---|
| 697 | + err = -ENOPROTOOPT; |
---|
| 698 | + break; |
---|
| 699 | + } |
---|
| 700 | + |
---|
| 701 | + if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { |
---|
| 702 | + err = -EINVAL; |
---|
| 703 | + break; |
---|
| 704 | + } |
---|
| 705 | + |
---|
| 706 | + mode = l2cap_get_mode(chan); |
---|
| 707 | + if (mode < 0) { |
---|
| 708 | + err = mode; |
---|
| 709 | + break; |
---|
| 710 | + } |
---|
| 711 | + |
---|
| 712 | + if (put_user(mode, (u8 __user *) optval)) |
---|
| 713 | + err = -EFAULT; |
---|
| 714 | + break; |
---|
| 715 | + |
---|
614 | 716 | default: |
---|
615 | 717 | err = -ENOPROTOOPT; |
---|
616 | 718 | break; |
---|
.. | .. |
---|
637 | 739 | } |
---|
638 | 740 | |
---|
639 | 741 | static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, |
---|
640 | | - char __user *optval, unsigned int optlen) |
---|
| 742 | + sockptr_t optval, unsigned int optlen) |
---|
641 | 743 | { |
---|
642 | 744 | struct sock *sk = sock->sk; |
---|
643 | 745 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
---|
.. | .. |
---|
670 | 772 | opts.txwin_size = chan->tx_win; |
---|
671 | 773 | |
---|
672 | 774 | len = min_t(unsigned int, sizeof(opts), optlen); |
---|
673 | | - if (copy_from_user((char *) &opts, optval, len)) { |
---|
| 775 | + if (copy_from_sockptr(&opts, optval, len)) { |
---|
674 | 776 | err = -EFAULT; |
---|
675 | 777 | break; |
---|
676 | 778 | } |
---|
.. | .. |
---|
685 | 787 | break; |
---|
686 | 788 | } |
---|
687 | 789 | |
---|
688 | | - chan->mode = opts.mode; |
---|
689 | | - switch (chan->mode) { |
---|
690 | | - case L2CAP_MODE_LE_FLOWCTL: |
---|
691 | | - break; |
---|
| 790 | + /* Only BR/EDR modes are supported here */ |
---|
| 791 | + switch (opts.mode) { |
---|
692 | 792 | case L2CAP_MODE_BASIC: |
---|
693 | 793 | clear_bit(CONF_STATE2_DEVICE, &chan->conf_state); |
---|
694 | 794 | break; |
---|
.. | .. |
---|
696 | 796 | case L2CAP_MODE_STREAMING: |
---|
697 | 797 | if (!disable_ertm) |
---|
698 | 798 | break; |
---|
699 | | - /* fall through */ |
---|
| 799 | + fallthrough; |
---|
700 | 800 | default: |
---|
701 | 801 | err = -EINVAL; |
---|
702 | 802 | break; |
---|
703 | 803 | } |
---|
| 804 | + |
---|
| 805 | + if (err < 0) |
---|
| 806 | + break; |
---|
| 807 | + |
---|
| 808 | + chan->mode = opts.mode; |
---|
| 809 | + |
---|
| 810 | + BT_DBG("mode 0x%2.2x", chan->mode); |
---|
704 | 811 | |
---|
705 | 812 | chan->imtu = opts.imtu; |
---|
706 | 813 | chan->omtu = opts.omtu; |
---|
.. | .. |
---|
711 | 818 | break; |
---|
712 | 819 | |
---|
713 | 820 | case L2CAP_LM: |
---|
714 | | - if (get_user(opt, (u32 __user *) optval)) { |
---|
| 821 | + if (copy_from_sockptr(&opt, optval, sizeof(u32))) { |
---|
715 | 822 | err = -EFAULT; |
---|
716 | 823 | break; |
---|
717 | 824 | } |
---|
.. | .. |
---|
748 | 855 | return err; |
---|
749 | 856 | } |
---|
750 | 857 | |
---|
| 858 | +static int l2cap_set_mode(struct l2cap_chan *chan, u8 mode) |
---|
| 859 | +{ |
---|
| 860 | + switch (mode) { |
---|
| 861 | + case BT_MODE_BASIC: |
---|
| 862 | + if (bdaddr_type_is_le(chan->src_type)) |
---|
| 863 | + return -EINVAL; |
---|
| 864 | + mode = L2CAP_MODE_BASIC; |
---|
| 865 | + clear_bit(CONF_STATE2_DEVICE, &chan->conf_state); |
---|
| 866 | + break; |
---|
| 867 | + case BT_MODE_ERTM: |
---|
| 868 | + if (!disable_ertm || bdaddr_type_is_le(chan->src_type)) |
---|
| 869 | + return -EINVAL; |
---|
| 870 | + mode = L2CAP_MODE_ERTM; |
---|
| 871 | + break; |
---|
| 872 | + case BT_MODE_STREAMING: |
---|
| 873 | + if (!disable_ertm || bdaddr_type_is_le(chan->src_type)) |
---|
| 874 | + return -EINVAL; |
---|
| 875 | + mode = L2CAP_MODE_STREAMING; |
---|
| 876 | + break; |
---|
| 877 | + case BT_MODE_LE_FLOWCTL: |
---|
| 878 | + if (!bdaddr_type_is_le(chan->src_type)) |
---|
| 879 | + return -EINVAL; |
---|
| 880 | + mode = L2CAP_MODE_LE_FLOWCTL; |
---|
| 881 | + break; |
---|
| 882 | + case BT_MODE_EXT_FLOWCTL: |
---|
| 883 | + /* TODO: Add support for ECRED PDUs to BR/EDR */ |
---|
| 884 | + if (!bdaddr_type_is_le(chan->src_type)) |
---|
| 885 | + return -EINVAL; |
---|
| 886 | + mode = L2CAP_MODE_EXT_FLOWCTL; |
---|
| 887 | + break; |
---|
| 888 | + default: |
---|
| 889 | + return -EINVAL; |
---|
| 890 | + } |
---|
| 891 | + |
---|
| 892 | + chan->mode = mode; |
---|
| 893 | + |
---|
| 894 | + return 0; |
---|
| 895 | +} |
---|
| 896 | + |
---|
751 | 897 | static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, |
---|
752 | | - char __user *optval, unsigned int optlen) |
---|
| 898 | + sockptr_t optval, unsigned int optlen) |
---|
753 | 899 | { |
---|
754 | 900 | struct sock *sk = sock->sk; |
---|
755 | 901 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
---|
.. | .. |
---|
758 | 904 | struct l2cap_conn *conn; |
---|
759 | 905 | int len, err = 0; |
---|
760 | 906 | u32 opt; |
---|
| 907 | + u16 mtu; |
---|
| 908 | + u8 mode; |
---|
761 | 909 | |
---|
762 | 910 | BT_DBG("sk %p", sk); |
---|
763 | 911 | |
---|
.. | .. |
---|
781 | 929 | sec.level = BT_SECURITY_LOW; |
---|
782 | 930 | |
---|
783 | 931 | len = min_t(unsigned int, sizeof(sec), optlen); |
---|
784 | | - if (copy_from_user((char *) &sec, optval, len)) { |
---|
| 932 | + if (copy_from_sockptr(&sec, optval, len)) { |
---|
785 | 933 | err = -EFAULT; |
---|
786 | 934 | break; |
---|
787 | 935 | } |
---|
.. | .. |
---|
799 | 947 | |
---|
800 | 948 | conn = chan->conn; |
---|
801 | 949 | |
---|
802 | | - /*change security for LE channels */ |
---|
| 950 | + /* change security for LE channels */ |
---|
803 | 951 | if (chan->scid == L2CAP_CID_ATT) { |
---|
804 | | - if (smp_conn_security(conn->hcon, sec.level)) |
---|
| 952 | + if (smp_conn_security(conn->hcon, sec.level)) { |
---|
| 953 | + err = -EINVAL; |
---|
805 | 954 | break; |
---|
| 955 | + } |
---|
| 956 | + |
---|
806 | 957 | set_bit(FLAG_PENDING_SECURITY, &chan->flags); |
---|
807 | 958 | sk->sk_state = BT_CONFIG; |
---|
808 | 959 | chan->state = BT_CONFIG; |
---|
.. | .. |
---|
826 | 977 | break; |
---|
827 | 978 | } |
---|
828 | 979 | |
---|
829 | | - if (get_user(opt, (u32 __user *) optval)) { |
---|
| 980 | + if (copy_from_sockptr(&opt, optval, sizeof(u32))) { |
---|
830 | 981 | err = -EFAULT; |
---|
831 | 982 | break; |
---|
832 | 983 | } |
---|
.. | .. |
---|
841 | 992 | break; |
---|
842 | 993 | |
---|
843 | 994 | case BT_FLUSHABLE: |
---|
844 | | - if (get_user(opt, (u32 __user *) optval)) { |
---|
| 995 | + if (copy_from_sockptr(&opt, optval, sizeof(u32))) { |
---|
845 | 996 | err = -EFAULT; |
---|
846 | 997 | break; |
---|
847 | 998 | } |
---|
.. | .. |
---|
877 | 1028 | pwr.force_active = BT_POWER_FORCE_ACTIVE_ON; |
---|
878 | 1029 | |
---|
879 | 1030 | len = min_t(unsigned int, sizeof(pwr), optlen); |
---|
880 | | - if (copy_from_user((char *) &pwr, optval, len)) { |
---|
| 1031 | + if (copy_from_sockptr(&pwr, optval, len)) { |
---|
881 | 1032 | err = -EFAULT; |
---|
882 | 1033 | break; |
---|
883 | 1034 | } |
---|
.. | .. |
---|
889 | 1040 | break; |
---|
890 | 1041 | |
---|
891 | 1042 | case BT_CHANNEL_POLICY: |
---|
892 | | - if (get_user(opt, (u32 __user *) optval)) { |
---|
| 1043 | + if (copy_from_sockptr(&opt, optval, sizeof(u32))) { |
---|
893 | 1044 | err = -EFAULT; |
---|
894 | 1045 | break; |
---|
895 | 1046 | } |
---|
.. | .. |
---|
931 | 1082 | break; |
---|
932 | 1083 | } |
---|
933 | 1084 | |
---|
934 | | - if (sk->sk_state == BT_CONNECTED) { |
---|
| 1085 | + if (chan->mode == L2CAP_MODE_LE_FLOWCTL && |
---|
| 1086 | + sk->sk_state == BT_CONNECTED) { |
---|
935 | 1087 | err = -EISCONN; |
---|
936 | 1088 | break; |
---|
937 | 1089 | } |
---|
938 | 1090 | |
---|
939 | | - if (get_user(opt, (u16 __user *) optval)) { |
---|
| 1091 | + if (copy_from_sockptr(&mtu, optval, sizeof(u16))) { |
---|
940 | 1092 | err = -EFAULT; |
---|
941 | 1093 | break; |
---|
942 | 1094 | } |
---|
943 | 1095 | |
---|
944 | | - chan->imtu = opt; |
---|
| 1096 | + if (chan->mode == L2CAP_MODE_EXT_FLOWCTL && |
---|
| 1097 | + sk->sk_state == BT_CONNECTED) |
---|
| 1098 | + err = l2cap_chan_reconfigure(chan, mtu); |
---|
| 1099 | + else |
---|
| 1100 | + chan->imtu = mtu; |
---|
| 1101 | + |
---|
| 1102 | + break; |
---|
| 1103 | + |
---|
| 1104 | + case BT_MODE: |
---|
| 1105 | + if (!enable_ecred) { |
---|
| 1106 | + err = -ENOPROTOOPT; |
---|
| 1107 | + break; |
---|
| 1108 | + } |
---|
| 1109 | + |
---|
| 1110 | + BT_DBG("sk->sk_state %u", sk->sk_state); |
---|
| 1111 | + |
---|
| 1112 | + if (sk->sk_state != BT_BOUND) { |
---|
| 1113 | + err = -EINVAL; |
---|
| 1114 | + break; |
---|
| 1115 | + } |
---|
| 1116 | + |
---|
| 1117 | + if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { |
---|
| 1118 | + err = -EINVAL; |
---|
| 1119 | + break; |
---|
| 1120 | + } |
---|
| 1121 | + |
---|
| 1122 | + if (copy_from_sockptr(&mode, optval, sizeof(u8))) { |
---|
| 1123 | + err = -EFAULT; |
---|
| 1124 | + break; |
---|
| 1125 | + } |
---|
| 1126 | + |
---|
| 1127 | + BT_DBG("mode %u", mode); |
---|
| 1128 | + |
---|
| 1129 | + err = l2cap_set_mode(chan, mode); |
---|
| 1130 | + if (err) |
---|
| 1131 | + break; |
---|
| 1132 | + |
---|
| 1133 | + BT_DBG("mode 0x%2.2x", chan->mode); |
---|
| 1134 | + |
---|
945 | 1135 | break; |
---|
946 | 1136 | |
---|
947 | 1137 | default: |
---|
.. | .. |
---|
996 | 1186 | |
---|
997 | 1187 | if (sk->sk_state == BT_CONNECT2 && test_bit(BT_SK_DEFER_SETUP, |
---|
998 | 1188 | &bt_sk(sk)->flags)) { |
---|
999 | | - if (bdaddr_type_is_le(pi->chan->src_type)) { |
---|
| 1189 | + if (pi->chan->mode == L2CAP_MODE_EXT_FLOWCTL) { |
---|
| 1190 | + sk->sk_state = BT_CONNECTED; |
---|
| 1191 | + pi->chan->state = BT_CONNECTED; |
---|
| 1192 | + __l2cap_ecred_conn_rsp_defer(pi->chan); |
---|
| 1193 | + } else if (bdaddr_type_is_le(pi->chan->src_type)) { |
---|
1000 | 1194 | sk->sk_state = BT_CONNECTED; |
---|
1001 | 1195 | pi->chan->state = BT_CONNECTED; |
---|
1002 | 1196 | __l2cap_le_connect_rsp_defer(pi->chan); |
---|
.. | .. |
---|
1115 | 1309 | struct l2cap_conn *conn; |
---|
1116 | 1310 | int err = 0; |
---|
1117 | 1311 | |
---|
1118 | | - BT_DBG("sock %p, sk %p", sock, sk); |
---|
| 1312 | + BT_DBG("sock %p, sk %p, how %d", sock, sk, how); |
---|
| 1313 | + |
---|
| 1314 | + /* 'how' parameter is mapped to sk_shutdown as follows: |
---|
| 1315 | + * SHUT_RD (0) --> RCV_SHUTDOWN (1) |
---|
| 1316 | + * SHUT_WR (1) --> SEND_SHUTDOWN (2) |
---|
| 1317 | + * SHUT_RDWR (2) --> SHUTDOWN_MASK (3) |
---|
| 1318 | + */ |
---|
| 1319 | + how++; |
---|
1119 | 1320 | |
---|
1120 | 1321 | if (!sk) |
---|
1121 | 1322 | return 0; |
---|
1122 | 1323 | |
---|
1123 | 1324 | lock_sock(sk); |
---|
1124 | 1325 | |
---|
1125 | | - if (sk->sk_shutdown) |
---|
| 1326 | + if ((sk->sk_shutdown & how) == how) |
---|
1126 | 1327 | goto shutdown_already; |
---|
1127 | 1328 | |
---|
1128 | 1329 | BT_DBG("Handling sock shutdown"); |
---|
.. | .. |
---|
1145 | 1346 | * has already been actioned to close the L2CAP |
---|
1146 | 1347 | * link such as by l2cap_disconnection_req(). |
---|
1147 | 1348 | */ |
---|
1148 | | - if (sk->sk_shutdown) |
---|
1149 | | - goto has_shutdown; |
---|
| 1349 | + if ((sk->sk_shutdown & how) == how) |
---|
| 1350 | + goto shutdown_matched; |
---|
1150 | 1351 | } |
---|
1151 | 1352 | |
---|
1152 | | - sk->sk_shutdown = SHUTDOWN_MASK; |
---|
| 1353 | + /* Try setting the RCV_SHUTDOWN bit, return early if SEND_SHUTDOWN |
---|
| 1354 | + * is already set |
---|
| 1355 | + */ |
---|
| 1356 | + if ((how & RCV_SHUTDOWN) && !(sk->sk_shutdown & RCV_SHUTDOWN)) { |
---|
| 1357 | + sk->sk_shutdown |= RCV_SHUTDOWN; |
---|
| 1358 | + if ((sk->sk_shutdown & how) == how) |
---|
| 1359 | + goto shutdown_matched; |
---|
| 1360 | + } |
---|
| 1361 | + |
---|
| 1362 | + sk->sk_shutdown |= SEND_SHUTDOWN; |
---|
1153 | 1363 | release_sock(sk); |
---|
1154 | 1364 | |
---|
1155 | 1365 | l2cap_chan_lock(chan); |
---|
.. | .. |
---|
1179 | 1389 | err = bt_sock_wait_state(sk, BT_CLOSED, |
---|
1180 | 1390 | sk->sk_lingertime); |
---|
1181 | 1391 | |
---|
1182 | | -has_shutdown: |
---|
| 1392 | +shutdown_matched: |
---|
1183 | 1393 | l2cap_chan_put(chan); |
---|
1184 | 1394 | sock_put(sk); |
---|
1185 | 1395 | |
---|
.. | .. |
---|
1205 | 1415 | if (!sk) |
---|
1206 | 1416 | return 0; |
---|
1207 | 1417 | |
---|
| 1418 | + l2cap_sock_cleanup_listen(sk); |
---|
1208 | 1419 | bt_sock_unlink(&l2cap_sk_list, sk); |
---|
1209 | 1420 | |
---|
1210 | | - err = l2cap_sock_shutdown(sock, 2); |
---|
| 1421 | + err = l2cap_sock_shutdown(sock, SHUT_RDWR); |
---|
1211 | 1422 | chan = l2cap_pi(sk)->chan; |
---|
1212 | 1423 | |
---|
1213 | 1424 | l2cap_chan_hold(chan); |
---|
.. | .. |
---|
1414 | 1625 | if (!skb) |
---|
1415 | 1626 | return ERR_PTR(err); |
---|
1416 | 1627 | |
---|
| 1628 | + /* Channel lock is released before requesting new skb and then |
---|
| 1629 | + * reacquired thus we need to recheck channel state. |
---|
| 1630 | + */ |
---|
| 1631 | + if (chan->state != BT_CONNECTED) { |
---|
| 1632 | + kfree_skb(skb); |
---|
| 1633 | + return ERR_PTR(-ENOTCONN); |
---|
| 1634 | + } |
---|
| 1635 | + |
---|
1417 | 1636 | skb->priority = sk->sk_priority; |
---|
1418 | 1637 | |
---|
1419 | 1638 | bt_cb(skb)->l2cap.chan = chan; |
---|
.. | .. |
---|
1483 | 1702 | return sk->sk_sndtimeo; |
---|
1484 | 1703 | } |
---|
1485 | 1704 | |
---|
| 1705 | +static struct pid *l2cap_sock_get_peer_pid_cb(struct l2cap_chan *chan) |
---|
| 1706 | +{ |
---|
| 1707 | + struct sock *sk = chan->data; |
---|
| 1708 | + |
---|
| 1709 | + return sk->sk_peer_pid; |
---|
| 1710 | +} |
---|
| 1711 | + |
---|
1486 | 1712 | static void l2cap_sock_suspend_cb(struct l2cap_chan *chan) |
---|
1487 | 1713 | { |
---|
1488 | 1714 | struct sock *sk = chan->data; |
---|
.. | .. |
---|
1517 | 1743 | .suspend = l2cap_sock_suspend_cb, |
---|
1518 | 1744 | .set_shutdown = l2cap_sock_set_shutdown_cb, |
---|
1519 | 1745 | .get_sndtimeo = l2cap_sock_get_sndtimeo_cb, |
---|
| 1746 | + .get_peer_pid = l2cap_sock_get_peer_pid_cb, |
---|
1520 | 1747 | .alloc_skb = l2cap_sock_alloc_skb_cb, |
---|
1521 | 1748 | .filter = l2cap_sock_filter, |
---|
1522 | 1749 | }; |
---|
.. | .. |
---|
1698 | 1925 | .recvmsg = l2cap_sock_recvmsg, |
---|
1699 | 1926 | .poll = bt_sock_poll, |
---|
1700 | 1927 | .ioctl = bt_sock_ioctl, |
---|
| 1928 | + .gettstamp = sock_gettstamp, |
---|
1701 | 1929 | .mmap = sock_no_mmap, |
---|
1702 | 1930 | .socketpair = sock_no_socketpair, |
---|
1703 | 1931 | .shutdown = l2cap_sock_shutdown, |
---|