Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 90cb0e47 authored by Chris Lew's avatar Chris Lew
Browse files

net: qrtr: Do not send packets before Hello negotiation



There is a race where broadcast packets can be sent to a node that has
not sent the hello message to the remote processor. This breaks the
protocol expectation. Add a status variable to track when the hello
packet has been sent.

An alternative solution attempted was to remove the nodes from the
broadcast list until the hello packet is sent. This is not a valid
solution because hello messages are broadcasted if the ns is restarted
or started late. There needs to be a status variable separate from the
broadcast list.

Change-Id: I62d2a0241f1e33ef8849164a3334fe213bc0f8c8
Signed-off-by: default avatarChris Lew <clew@codeaurora.org>
parent e48f6bba
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -133,6 +133,7 @@ static DEFINE_MUTEX(qrtr_port_lock);
 * @ep: endpoint
 * @ref: reference count for node
 * @nid: node id
 * @hello_sent: hello packet sent to endpoint
 * @qrtr_tx_flow: remote port tx flow control list
 * @resume_tx: wait until remote port acks control flag
 * @qrtr_tx_lock: lock for qrtr_tx_flow
@@ -146,6 +147,7 @@ struct qrtr_node {
	struct qrtr_endpoint *ep;
	struct kref ref;
	unsigned int nid;
	atomic_t hello_sent;

	struct radix_tree_root qrtr_tx_flow;
	struct wait_queue_head resume_tx;
@@ -486,6 +488,9 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
	size_t len = skb->len;
	int rc = -ENODEV;

	if (!atomic_read(&node->hello_sent) && type != QRTR_TYPE_HELLO)
		return rc;

	confirm_rx = qrtr_tx_wait(node, to, skb->sk, type, flags);
	if (confirm_rx < 0) {
		kfree_skb(skb);
@@ -518,6 +523,9 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
		kfree_skb(skb);
	mutex_unlock(&node->ep_lock);

	if (!rc && type == QRTR_TYPE_HELLO)
		atomic_inc(&node->hello_sent);

	return rc;
}

@@ -743,6 +751,7 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid)
	skb_queue_head_init(&node->rx_queue);
	node->nid = QRTR_EP_NID_AUTO;
	node->ep = ep;
	atomic_set(&node->hello_sent, 0);

	mutex_init(&node->qrtr_tx_lock);
	INIT_RADIX_TREE(&node->qrtr_tx_flow, GFP_KERNEL);