mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 18:43:33 +02:00
nfc pull request for net:
Code improvements - llcp: Fix use-after-free in llcp_sock_release() - llcp: Fix use-after-free race in nfc_llcp_recv_cc() - hci: fix out-of-bounds read in HCP header parsing Regression fixes: - nxp-nci: i2c: use rising-edge IRQ on ACPI systems Signed-off-by: David Heidelberg <david@ixit.cz> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE13oJz+7cK71TpwR0YAI/xNNJIHIFAmoVkekACgkQYAI/xNNJ IHLrlBAApY2wQyqOR/HLGtO99SOKjzyAk5Ke8qv0tkGcTMhH4tlED3rD2tjOs1d6 Fn5LEG7CqqfxX3ly/4B4hGYW4QtXlkTmCPwq7Bv5QnhTYNjwtrW2deLQB0vnPpKN qH8YD227zP12Wt+L68b/envlNDqiHvhkz5yiBfrEJ6yNHQ2ZYzOlVs/8yDqGtzJC HpkL+b3VyCd3RJCPiuWvBmySoQjryij+y51UAfleJSate3y1PnJbjMecRJt50+Vv cwp73Lq+rNHRGDFNwM2XwQh4Sc0QfnIFSHKlrS4N02mtF6tRThvOO28joYPMlDKw k047uZfF9PFeWV2df3bAmfGDK1bAIwb5G9+H2NSnh55pNORxvIb/fyQSWp854riv asJ1iagteRGPHYpKuTLeUxK4+1PW2PWG0vMGOXOrFpWbg4iiOWHqmStTUpNt8j0J M87Ym0rWyBWXljOyVaQySQQY8kjnOVJBX0WdRyo0VZamcqlUv8c8hk3WYvoZo5ko mlMRRbVIO8v4aHhBwLis5UwsYLKoBeoQHYNSIf5gKw+DBqz3KjSFcVSNLEXCP0yG nwqzArAUCok4a5tY08xMGHhJbQbP5F5qt6JTGVikO9Ua6zrbq6ilFQT0d1XFPtBq H2SP5FtnliCnBm+9bs1wxcWzLW+rFcZ9y3/xH7dE0m2CnHaQhxo= =aWIg -----END PGP SIGNATURE----- Merge tag 'nfc-7.1-rc6' of https://codeberg.org/linux-nfc/linux David Heidelberg says: ==================== nfc pull request for net: Code improvements - llcp: Fix use-after-free in llcp_sock_release() - llcp: Fix use-after-free race in nfc_llcp_recv_cc() - hci: fix out-of-bounds read in HCP header parsing Regression fixes: - nxp-nci: i2c: use rising-edge IRQ on ACPI systems Signed-off-by: David Heidelberg <david@ixit.cz> * tag 'nfc-7.1-rc6' of https://codeberg.org/linux-nfc/linux: nfc: nxp-nci: i2c: use rising-edge IRQ on ACPI systems nfc: hci: fix out-of-bounds read in HCP header parsing nfc: llcp: Fix use-after-free race in nfc_llcp_recv_cc() nfc: llcp: Fix use-after-free in llcp_sock_release() ==================== Link: https://patch.msgid.link/217c0646-8a30-4037-b613-580c2b189729@ixit.cz Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
e66c456f7c
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nfc.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
|
@ -267,6 +268,7 @@ static int nxp_nci_i2c_probe(struct i2c_client *client)
|
|||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct nxp_nci_i2c_phy *phy;
|
||||
unsigned long irqflags;
|
||||
int r;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
|
|
@ -303,9 +305,26 @@ static int nxp_nci_i2c_probe(struct i2c_client *client)
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/*
|
||||
* ACPI platforms may report incorrect IRQ trigger types
|
||||
* (e.g. level-high), which can lead to interrupt storms.
|
||||
*
|
||||
* Use the historically stable rising-edge trigger for ACPI devices.
|
||||
*
|
||||
* On non-ACPI systems (e.g. Device Tree), prefer the firmware-
|
||||
* provided trigger type, falling back to rising-edge if not set.
|
||||
*/
|
||||
if (ACPI_COMPANION(dev)) {
|
||||
irqflags = IRQF_TRIGGER_RISING;
|
||||
} else {
|
||||
irqflags = irq_get_trigger_type(client->irq);
|
||||
if (!irqflags)
|
||||
irqflags = IRQF_TRIGGER_RISING;
|
||||
}
|
||||
|
||||
r = request_threaded_irq(client->irq, NULL,
|
||||
nxp_nci_i2c_irq_thread_fn,
|
||||
IRQF_ONESHOT,
|
||||
irqflags | IRQF_ONESHOT,
|
||||
NXP_NCI_I2C_DRIVER_NAME, phy);
|
||||
if (r < 0)
|
||||
nfc_err(&client->dev, "Unable to register IRQ handler\n");
|
||||
|
|
|
|||
|
|
@ -861,6 +861,11 @@ static void nfc_hci_recv_from_llc(struct nfc_hci_dev *hdev, struct sk_buff *skb)
|
|||
struct sk_buff *frag_skb;
|
||||
int msg_len;
|
||||
|
||||
if (!pskb_may_pull(skb, NFC_HCI_HCP_PACKET_HEADER_LEN)) {
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
packet = (struct hcp_packet *)skb->data;
|
||||
if ((packet->header & ~NFC_HCI_FRAGMENT) == 0) {
|
||||
skb_queue_tail(&hdev->rx_hcp_frags, skb);
|
||||
|
|
@ -904,6 +909,11 @@ static void nfc_hci_recv_from_llc(struct nfc_hci_dev *hdev, struct sk_buff *skb)
|
|||
* unblock waiting cmd context. Otherwise, enqueue to dispatch
|
||||
* in separate context where handler can also execute command.
|
||||
*/
|
||||
if (!pskb_may_pull(hcp_skb, NFC_HCI_HCP_HEADER_LEN)) {
|
||||
kfree_skb(hcp_skb);
|
||||
return;
|
||||
}
|
||||
|
||||
packet = (struct hcp_packet *)hcp_skb->data;
|
||||
type = HCP_MSG_GET_TYPE(packet->message.header);
|
||||
if (type == NFC_HCI_HCP_RESPONSE) {
|
||||
|
|
|
|||
|
|
@ -1218,6 +1218,15 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
|
|||
|
||||
sk = &llcp_sock->sk;
|
||||
|
||||
lock_sock(sk);
|
||||
|
||||
/* Check if socket was destroyed whilst waiting for the lock */
|
||||
if (!sk_hashed(sk)) {
|
||||
release_sock(sk);
|
||||
nfc_llcp_sock_put(llcp_sock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Unlink from connecting and link to the client array */
|
||||
nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
|
||||
nfc_llcp_sock_link(&local->sockets, sk);
|
||||
|
|
@ -1229,6 +1238,8 @@ static void nfc_llcp_recv_cc(struct nfc_llcp_local *local,
|
|||
sk->sk_state = LLCP_CONNECTED;
|
||||
sk->sk_state_change(sk);
|
||||
|
||||
release_sock(sk);
|
||||
|
||||
nfc_llcp_sock_put(llcp_sock);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -633,6 +633,8 @@ static int llcp_sock_release(struct socket *sock)
|
|||
|
||||
if (sock->type == SOCK_RAW)
|
||||
nfc_llcp_sock_unlink(&local->raw_sockets, sk);
|
||||
else if (sk->sk_state == LLCP_CONNECTING)
|
||||
nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
|
||||
else
|
||||
nfc_llcp_sock_unlink(&local->sockets, sk);
|
||||
|
||||
|
|
|
|||
|
|
@ -439,6 +439,11 @@ void nci_hci_data_received_cb(void *context,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!pskb_may_pull(skb, NCI_HCI_HCP_PACKET_HEADER_LEN)) {
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
packet = (struct nci_hcp_packet *)skb->data;
|
||||
if ((packet->header & ~NCI_HCI_FRAGMENT) == 0) {
|
||||
skb_queue_tail(&ndev->hci_dev->rx_hcp_frags, skb);
|
||||
|
|
@ -482,6 +487,11 @@ void nci_hci_data_received_cb(void *context,
|
|||
* unblock waiting cmd context. Otherwise, enqueue to dispatch
|
||||
* in separate context where handler can also execute command.
|
||||
*/
|
||||
if (!pskb_may_pull(hcp_skb, NCI_HCI_HCP_HEADER_LEN)) {
|
||||
kfree_skb(hcp_skb);
|
||||
return;
|
||||
}
|
||||
|
||||
packet = (struct nci_hcp_packet *)hcp_skb->data;
|
||||
type = NCI_HCP_MSG_GET_TYPE(packet->message.header);
|
||||
if (type == NCI_HCI_HCP_RESPONSE) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user