Skip to content

Commit

Permalink
nfc: Add KCOV annotations
Browse files Browse the repository at this point in the history
Add remote KCOV annotations for NFC processing that is done
in background threads. This enables efficient coverage-guided
fuzzing of the NFC subsystem.

The intention is to add annotations to background threads that
process skb's that were allocated in syscall context
(thus have a KCOV handle associated with the current fuzz test).
This includes nci_recv_frame() that is called by the virtual nci
driver in the syscall context.

Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Cc: Bongsu Jeon <bongsu.jeon@samsung.com>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Cc: netdev@vger.kernel.org
  • Loading branch information
dvyukov committed Oct 30, 2022
1 parent 02a97e0 commit de17365
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 2 deletions.
8 changes: 7 additions & 1 deletion net/nfc/nci/core.c
Expand Up @@ -24,6 +24,7 @@
#include <linux/sched.h>
#include <linux/bitops.h>
#include <linux/skbuff.h>
#include <linux/kcov.h>

#include "../nfc.h"
#include <net/nfc/nci.h>
Expand Down Expand Up @@ -1472,6 +1473,7 @@ static void nci_tx_work(struct work_struct *work)
skb = skb_dequeue(&ndev->tx_q);
if (!skb)
return;
kcov_remote_start_common(skb_get_kcov_handle(skb));

/* Check if data flow control is used */
if (atomic_read(&conn_info->credits_cnt) !=
Expand All @@ -1487,6 +1489,7 @@ static void nci_tx_work(struct work_struct *work)

mod_timer(&ndev->data_timer,
jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT));
kcov_remote_stop();
}
}

Expand All @@ -1497,7 +1500,8 @@ static void nci_rx_work(struct work_struct *work)
struct nci_dev *ndev = container_of(work, struct nci_dev, rx_work);
struct sk_buff *skb;

while ((skb = skb_dequeue(&ndev->rx_q))) {
for (; (skb = skb_dequeue(&ndev->rx_q)); kcov_remote_stop()) {
kcov_remote_start_common(skb_get_kcov_handle(skb));

/* Send copy to sniffer */
nfc_send_to_raw_sock(ndev->nfc_dev, skb,
Expand Down Expand Up @@ -1551,6 +1555,7 @@ static void nci_cmd_work(struct work_struct *work)
if (!skb)
return;

kcov_remote_start_common(skb_get_kcov_handle(skb));
atomic_dec(&ndev->cmd_cnt);

pr_debug("NCI TX: MT=cmd, PBF=%d, GID=0x%x, OID=0x%x, plen=%d\n",
Expand All @@ -1563,6 +1568,7 @@ static void nci_cmd_work(struct work_struct *work)

mod_timer(&ndev->cmd_timer,
jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT));
kcov_remote_stop();
}
}

Expand Down
4 changes: 3 additions & 1 deletion net/nfc/nci/hci.c
Expand Up @@ -14,6 +14,7 @@
#include <net/nfc/nci.h>
#include <net/nfc/nci_core.h>
#include <linux/nfc.h>
#include <linux/kcov.h>

struct nci_data {
u8 conn_id;
Expand Down Expand Up @@ -409,7 +410,8 @@ static void nci_hci_msg_rx_work(struct work_struct *work)
const struct nci_hcp_message *message;
u8 pipe, type, instruction;

while ((skb = skb_dequeue(&hdev->msg_rx_queue)) != NULL) {
for (; (skb = skb_dequeue(&hdev->msg_rx_queue)); kcov_remote_stop()) {
kcov_remote_start_common(skb_get_kcov_handle(skb));
pipe = NCI_HCP_MSG_GET_PIPE(skb->data[0]);
skb_pull(skb, NCI_HCI_HCP_PACKET_HEADER_LEN);
message = (struct nci_hcp_message *)skb->data;
Expand Down
3 changes: 3 additions & 0 deletions net/nfc/rawsock.c
Expand Up @@ -12,6 +12,7 @@
#include <net/tcp_states.h>
#include <linux/nfc.h>
#include <linux/export.h>
#include <linux/kcov.h>

#include "nfc.h"

Expand Down Expand Up @@ -189,6 +190,7 @@ static void rawsock_tx_work(struct work_struct *work)
}

skb = skb_dequeue(&sk->sk_write_queue);
kcov_remote_start_common(skb_get_kcov_handle(skb));

sock_hold(sk);
rc = nfc_data_exchange(dev, target_idx, skb,
Expand All @@ -197,6 +199,7 @@ static void rawsock_tx_work(struct work_struct *work)
rawsock_report_error(sk, rc);
sock_put(sk);
}
kcov_remote_stop();
}

static int rawsock_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
Expand Down

0 comments on commit de17365

Please sign in to comment.