| .. | .. |
|---|
| 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__ |
|---|
| .. | .. |
|---|
| 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 | } |
|---|
| .. | .. |
|---|
| 743 | 731 | llcp_sock->service_name = kmemdup(addr->service_name, |
|---|
| 744 | 732 | llcp_sock->service_name_len, |
|---|
| 745 | 733 | GFP_KERNEL); |
|---|
| 734 | + if (!llcp_sock->service_name) { |
|---|
| 735 | + ret = -ENOMEM; |
|---|
| 736 | + goto sock_llcp_release; |
|---|
| 737 | + } |
|---|
| 746 | 738 | |
|---|
| 747 | 739 | nfc_llcp_sock_link(&local->connecting_sockets, sk); |
|---|
| 748 | 740 | |
|---|
| .. | .. |
|---|
| 762 | 754 | return ret; |
|---|
| 763 | 755 | |
|---|
| 764 | 756 | 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 | 757 | nfc_llcp_sock_unlink(&local->connecting_sockets, sk); |
|---|
| 770 | 758 | kfree(llcp_sock->service_name); |
|---|
| 771 | 759 | llcp_sock->service_name = NULL; |
|---|
| 760 | + |
|---|
| 761 | +sock_llcp_release: |
|---|
| 762 | + nfc_llcp_put_ssap(local, llcp_sock->ssap); |
|---|
| 763 | + nfc_llcp_local_put(llcp_sock->local); |
|---|
| 764 | + llcp_sock->local = NULL; |
|---|
| 772 | 765 | |
|---|
| 773 | 766 | put_dev: |
|---|
| 774 | 767 | nfc_put_device(dev); |
|---|
| .. | .. |
|---|
| 949 | 942 | .ioctl = sock_no_ioctl, |
|---|
| 950 | 943 | .listen = sock_no_listen, |
|---|
| 951 | 944 | .shutdown = sock_no_shutdown, |
|---|
| 952 | | - .setsockopt = sock_no_setsockopt, |
|---|
| 953 | | - .getsockopt = sock_no_getsockopt, |
|---|
| 954 | 945 | .sendmsg = sock_no_sendmsg, |
|---|
| 955 | 946 | .recvmsg = llcp_sock_recvmsg, |
|---|
| 956 | 947 | .mmap = sock_no_mmap, |
|---|