.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2011 Intel Corporation. All rights reserved. |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License as published by |
---|
6 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
7 | | - * (at your option) any later version. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope that it will be useful, |
---|
10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | | - * GNU General Public License for more details. |
---|
13 | | - * |
---|
14 | | - * You should have received a copy of the GNU General Public License |
---|
15 | | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
---|
16 | 4 | */ |
---|
17 | 5 | |
---|
18 | 6 | #define pr_fmt(fmt) "llcp: %s: " fmt, __func__ |
---|
.. | .. |
---|
111 | 99 | } |
---|
112 | 100 | |
---|
113 | 101 | llcp_sock->dev = dev; |
---|
114 | | - llcp_sock->local = nfc_llcp_local_get(local); |
---|
| 102 | + llcp_sock->local = local; |
---|
115 | 103 | llcp_sock->nfc_protocol = llcp_addr.nfc_protocol; |
---|
116 | 104 | llcp_sock->service_name_len = min_t(unsigned int, |
---|
117 | 105 | llcp_addr.service_name_len, |
---|
.. | .. |
---|
193 | 181 | } |
---|
194 | 182 | |
---|
195 | 183 | llcp_sock->dev = dev; |
---|
196 | | - llcp_sock->local = nfc_llcp_local_get(local); |
---|
| 184 | + llcp_sock->local = local; |
---|
197 | 185 | llcp_sock->nfc_protocol = llcp_addr.nfc_protocol; |
---|
198 | 186 | |
---|
199 | 187 | nfc_llcp_sock_link(&local->raw_sockets, sk); |
---|
.. | .. |
---|
236 | 224 | } |
---|
237 | 225 | |
---|
238 | 226 | static int nfc_llcp_setsockopt(struct socket *sock, int level, int optname, |
---|
239 | | - char __user *optval, unsigned int optlen) |
---|
| 227 | + sockptr_t optval, unsigned int optlen) |
---|
240 | 228 | { |
---|
241 | 229 | struct sock *sk = sock->sk; |
---|
242 | 230 | struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk); |
---|
.. | .. |
---|
259 | 247 | break; |
---|
260 | 248 | } |
---|
261 | 249 | |
---|
262 | | - if (get_user(opt, (u32 __user *) optval)) { |
---|
| 250 | + if (copy_from_sockptr(&opt, optval, sizeof(u32))) { |
---|
263 | 251 | err = -EFAULT; |
---|
264 | 252 | break; |
---|
265 | 253 | } |
---|
.. | .. |
---|
281 | 269 | break; |
---|
282 | 270 | } |
---|
283 | 271 | |
---|
284 | | - if (get_user(opt, (u32 __user *) optval)) { |
---|
| 272 | + if (copy_from_sockptr(&opt, optval, sizeof(u32))) { |
---|
285 | 273 | err = -EFAULT; |
---|
286 | 274 | break; |
---|
287 | 275 | } |
---|
.. | .. |
---|
710 | 698 | if (dev->dep_link_up == false) { |
---|
711 | 699 | ret = -ENOLINK; |
---|
712 | 700 | device_unlock(&dev->dev); |
---|
713 | | - goto put_dev; |
---|
| 701 | + goto sock_llcp_put_local; |
---|
714 | 702 | } |
---|
715 | 703 | device_unlock(&dev->dev); |
---|
716 | 704 | |
---|
717 | 705 | if (local->rf_mode == NFC_RF_INITIATOR && |
---|
718 | 706 | addr->target_idx != local->target_idx) { |
---|
719 | 707 | ret = -ENOLINK; |
---|
720 | | - goto put_dev; |
---|
| 708 | + goto sock_llcp_put_local; |
---|
721 | 709 | } |
---|
722 | 710 | |
---|
723 | 711 | llcp_sock->dev = dev; |
---|
724 | | - llcp_sock->local = nfc_llcp_local_get(local); |
---|
| 712 | + llcp_sock->local = local; |
---|
725 | 713 | llcp_sock->ssap = nfc_llcp_get_local_ssap(local); |
---|
726 | 714 | if (llcp_sock->ssap == LLCP_SAP_MAX) { |
---|
727 | | - nfc_llcp_local_put(llcp_sock->local); |
---|
728 | | - llcp_sock->local = NULL; |
---|
729 | 715 | ret = -ENOMEM; |
---|
730 | | - goto put_dev; |
---|
| 716 | + goto sock_llcp_nullify; |
---|
731 | 717 | } |
---|
732 | 718 | |
---|
733 | 719 | llcp_sock->reserved_ssap = llcp_sock->ssap; |
---|
.. | .. |
---|
743 | 729 | llcp_sock->service_name = kmemdup(addr->service_name, |
---|
744 | 730 | llcp_sock->service_name_len, |
---|
745 | 731 | GFP_KERNEL); |
---|
| 732 | + if (!llcp_sock->service_name) { |
---|
| 733 | + ret = -ENOMEM; |
---|
| 734 | + goto sock_llcp_release; |
---|
| 735 | + } |
---|
746 | 736 | |
---|
747 | 737 | nfc_llcp_sock_link(&local->connecting_sockets, sk); |
---|
748 | 738 | |
---|
.. | .. |
---|
762 | 752 | return ret; |
---|
763 | 753 | |
---|
764 | 754 | sock_unlink: |
---|
765 | | - nfc_llcp_put_ssap(local, llcp_sock->ssap); |
---|
766 | | - nfc_llcp_local_put(llcp_sock->local); |
---|
767 | | - llcp_sock->local = NULL; |
---|
768 | | - |
---|
769 | 755 | nfc_llcp_sock_unlink(&local->connecting_sockets, sk); |
---|
770 | 756 | kfree(llcp_sock->service_name); |
---|
771 | 757 | llcp_sock->service_name = NULL; |
---|
| 758 | + |
---|
| 759 | +sock_llcp_release: |
---|
| 760 | + nfc_llcp_put_ssap(local, llcp_sock->ssap); |
---|
| 761 | + |
---|
| 762 | +sock_llcp_nullify: |
---|
| 763 | + llcp_sock->local = NULL; |
---|
| 764 | + llcp_sock->dev = NULL; |
---|
| 765 | + |
---|
| 766 | +sock_llcp_put_local: |
---|
| 767 | + nfc_llcp_local_put(local); |
---|
772 | 768 | |
---|
773 | 769 | put_dev: |
---|
774 | 770 | nfc_put_device(dev); |
---|
.. | .. |
---|
949 | 945 | .ioctl = sock_no_ioctl, |
---|
950 | 946 | .listen = sock_no_listen, |
---|
951 | 947 | .shutdown = sock_no_shutdown, |
---|
952 | | - .setsockopt = sock_no_setsockopt, |
---|
953 | | - .getsockopt = sock_no_getsockopt, |
---|
954 | 948 | .sendmsg = sock_no_sendmsg, |
---|
955 | 949 | .recvmsg = llcp_sock_recvmsg, |
---|
956 | 950 | .mmap = sock_no_mmap, |
---|