Commit 7e8cdc97 authored by Dmitry Vyukov's avatar Dmitry Vyukov Committed by David S. Miller
Browse files

nfc: Add KCOV annotations



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: default avatarDmitry Vyukov <dvyukov@google.com>
Cc: Bongsu Jeon <bongsu.jeon@samsung.com>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Cc: netdev@vger.kernel.org
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 82fd151d
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -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>
@@ -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) !=
@@ -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();
	}
}

@@ -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,
@@ -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",
@@ -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();
	}
}

+3 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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;
+3 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <net/tcp_states.h>
#include <linux/nfc.h>
#include <linux/export.h>
#include <linux/kcov.h>

#include "nfc.h"

@@ -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,
@@ -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)