diff options
Diffstat (limited to 'net/nfc')
-rw-r--r-- | net/nfc/af_nfc.c | 3 | ||||
-rw-r--r-- | net/nfc/digital_core.c | 9 | ||||
-rw-r--r-- | net/nfc/digital_dep.c | 2 | ||||
-rw-r--r-- | net/nfc/digital_technology.c | 8 | ||||
-rw-r--r-- | net/nfc/llcp_sock.c | 16 | ||||
-rw-r--r-- | net/nfc/nci/core.c | 1 | ||||
-rw-r--r-- | net/nfc/nci/hci.c | 5 | ||||
-rw-r--r-- | net/nfc/nci/rsp.c | 2 | ||||
-rw-r--r-- | net/nfc/netlink.c | 3 | ||||
-rw-r--r-- | net/nfc/rawsock.c | 4 |
10 files changed, 46 insertions, 7 deletions
diff --git a/net/nfc/af_nfc.c b/net/nfc/af_nfc.c index 54e40fa47822..1859b8e98ded 100644 --- a/net/nfc/af_nfc.c +++ b/net/nfc/af_nfc.c @@ -72,6 +72,9 @@ int nfc_proto_register(const struct nfc_protocol *nfc_proto) proto_tab[nfc_proto->id] = nfc_proto; write_unlock(&proto_tab_lock); + if (rc) + proto_unregister(nfc_proto->proto); + return rc; } EXPORT_SYMBOL(nfc_proto_register); diff --git a/net/nfc/digital_core.c b/net/nfc/digital_core.c index 23c2a118ac9f..28c60e291c7e 100644 --- a/net/nfc/digital_core.c +++ b/net/nfc/digital_core.c @@ -280,6 +280,7 @@ int digital_tg_configure_hw(struct nfc_digital_dev *ddev, int type, int param) static int digital_tg_listen_mdaa(struct nfc_digital_dev *ddev, u8 rf_tech) { struct digital_tg_mdaa_params *params; + int rc; params = kzalloc(sizeof(struct digital_tg_mdaa_params), GFP_KERNEL); if (!params) @@ -294,8 +295,12 @@ static int digital_tg_listen_mdaa(struct nfc_digital_dev *ddev, u8 rf_tech) get_random_bytes(params->nfcid2 + 2, NFC_NFCID2_MAXSIZE - 2); params->sc = DIGITAL_SENSF_FELICA_SC; - return digital_send_cmd(ddev, DIGITAL_CMD_TG_LISTEN_MDAA, NULL, params, - 500, digital_tg_recv_atr_req, NULL); + rc = digital_send_cmd(ddev, DIGITAL_CMD_TG_LISTEN_MDAA, NULL, params, + 500, digital_tg_recv_atr_req, NULL); + if (rc) + kfree(params); + + return rc; } static int digital_tg_listen_md(struct nfc_digital_dev *ddev, u8 rf_tech) diff --git a/net/nfc/digital_dep.c b/net/nfc/digital_dep.c index f72be7433df3..46375ff214c0 100644 --- a/net/nfc/digital_dep.c +++ b/net/nfc/digital_dep.c @@ -1187,6 +1187,8 @@ static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg, } rc = nfc_tm_data_received(ddev->nfc_dev, resp); + if (rc) + resp = NULL; exit: kfree_skb(ddev->chaining_skb); diff --git a/net/nfc/digital_technology.c b/net/nfc/digital_technology.c index fb58ed2dd41d..082dd95f6ef3 100644 --- a/net/nfc/digital_technology.c +++ b/net/nfc/digital_technology.c @@ -473,8 +473,12 @@ static int digital_in_send_sdd_req(struct nfc_digital_dev *ddev, *skb_put(skb, sizeof(u8)) = sel_cmd; *skb_put(skb, sizeof(u8)) = DIGITAL_SDD_REQ_SEL_PAR; - return digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sdd_res, - target); + rc = digital_in_send_cmd(ddev, skb, 30, digital_in_recv_sdd_res, + target); + if (rc) + kfree_skb(skb); + + return rc; } static void digital_in_recv_sens_res(struct nfc_digital_dev *ddev, void *arg, diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c index 44d6b8355eab..ece7a5d59a61 100644 --- a/net/nfc/llcp_sock.c +++ b/net/nfc/llcp_sock.c @@ -119,13 +119,19 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) llcp_sock->service_name_len, GFP_KERNEL); if (!llcp_sock->service_name) { + nfc_llcp_local_put(llcp_sock->local); + llcp_sock->local = NULL; + llcp_sock->dev = NULL; ret = -ENOMEM; goto put_dev; } llcp_sock->ssap = nfc_llcp_get_sdp_ssap(local, llcp_sock); if (llcp_sock->ssap == LLCP_SAP_MAX) { + nfc_llcp_local_put(llcp_sock->local); + llcp_sock->local = NULL; kfree(llcp_sock->service_name); llcp_sock->service_name = NULL; + llcp_sock->dev = NULL; ret = -EADDRINUSE; goto put_dev; } @@ -677,6 +683,10 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, ret = -EISCONN; goto error; } + if (sk->sk_state == LLCP_CONNECTING) { + ret = -EINPROGRESS; + goto error; + } dev = nfc_get_device(addr->dev_idx); if (dev == NULL) { @@ -708,6 +718,8 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, llcp_sock->local = nfc_llcp_local_get(local); llcp_sock->ssap = nfc_llcp_get_local_ssap(local); if (llcp_sock->ssap == LLCP_SAP_MAX) { + nfc_llcp_local_put(llcp_sock->local); + llcp_sock->local = NULL; ret = -ENOMEM; goto put_dev; } @@ -745,8 +757,12 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, sock_unlink: nfc_llcp_put_ssap(local, llcp_sock->ssap); + nfc_llcp_local_put(llcp_sock->local); + llcp_sock->local = NULL; nfc_llcp_sock_unlink(&local->connecting_sockets, sk); + kfree(llcp_sock->service_name); + llcp_sock->service_name = NULL; put_dev: nfc_put_device(dev); diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 6ac1a8d19b88..35cc290389c8 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -1099,6 +1099,7 @@ EXPORT_SYMBOL(nci_allocate_device); void nci_free_device(struct nci_dev *ndev) { nfc_free_device(ndev->nfc_dev); + nci_hci_deallocate(ndev); kfree(ndev); } EXPORT_SYMBOL(nci_free_device); diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c index 2aedac15cb59..309e8cebed55 100644 --- a/net/nfc/nci/hci.c +++ b/net/nfc/nci/hci.c @@ -798,3 +798,8 @@ struct nci_hci_dev *nci_hci_allocate(struct nci_dev *ndev) return hdev; } + +void nci_hci_deallocate(struct nci_dev *ndev) +{ + kfree(ndev->hci_dev); +} diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c index 9b6eb913d801..74e4d5e8c275 100644 --- a/net/nfc/nci/rsp.c +++ b/net/nfc/nci/rsp.c @@ -274,6 +274,8 @@ static void nci_core_conn_close_rsp_packet(struct nci_dev *ndev, conn_info = nci_get_conn_info_by_conn_id(ndev, ndev->cur_id); if (conn_info) { list_del(&conn_info->list); + if (conn_info == ndev->rf_conn_info) + ndev->rf_conn_info = NULL; devm_kfree(&ndev->nfc_dev->dev, conn_info); } } diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index c9d5e9c62178..c90dc2fd13a7 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -850,6 +850,7 @@ static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info) if (!dev->polling) { device_unlock(&dev->dev); + nfc_put_device(dev); return -EINVAL; } @@ -1190,7 +1191,7 @@ static int nfc_genl_fw_download(struct sk_buff *skb, struct genl_info *info) u32 idx; char firmware_name[NFC_FIRMWARE_NAME_MAXSIZE + 1]; - if (!info->attrs[NFC_ATTR_DEVICE_INDEX]) + if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || !info->attrs[NFC_ATTR_FIRMWARE_NAME]) return -EINVAL; idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index 574af981806f..2fba626a0125 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c @@ -117,7 +117,7 @@ static int rawsock_connect(struct socket *sock, struct sockaddr *_addr, if (addr->target_idx > dev->target_next_idx - 1 || addr->target_idx < dev->target_next_idx - dev->n_targets) { rc = -EINVAL; - goto error; + goto put_dev; } rc = nfc_activate_target(dev, addr->target_idx, addr->nfc_protocol); @@ -345,7 +345,7 @@ static int rawsock_create(struct net *net, struct socket *sock, return -ESOCKTNOSUPPORT; if (sock->type == SOCK_RAW) { - if (!capable(CAP_NET_RAW)) + if (!ns_capable(net->user_ns, CAP_NET_RAW)) return -EPERM; sock->ops = &rawsock_raw_ops; } else { |