diff options
author | David S. Miller <davem@davemloft.net> | 2020-09-09 11:04:39 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-09-09 11:04:39 -0700 |
commit | 0ddaa27803847f8c14a9aa8ebee4fff5f1a1c379 (patch) | |
tree | ba215a0109a91902809faed11a077eeb1ba5a7d7 /net | |
parent | ba9e04a7ddf4f22a10e05bf9403db6b97743c7bf (diff) | |
parent | 4a009cb04aeca0de60b73f37b102573354214b52 (diff) | |
download | linux-0ddaa27803847f8c14a9aa8ebee4fff5f1a1c379.tar.bz2 |
Merge branch 'net-skb_put_padto-fixes'
Eric Dumazet says:
====================
net: skb_put_padto() fixes
sysbot reported a bug in qrtr leading to use-after-free.
First patch fixes the issue.
Second patch addes __must_check attribute to avoid similar
issues in the future.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/qrtr/qrtr.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index 90c558f89d46..957aa9263ba4 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -332,8 +332,7 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, { struct qrtr_hdr_v1 *hdr; size_t len = skb->len; - int rc = -ENODEV; - int confirm_rx; + int rc, confirm_rx; confirm_rx = qrtr_tx_wait(node, to->sq_node, to->sq_port, type); if (confirm_rx < 0) { @@ -357,15 +356,17 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, hdr->size = cpu_to_le32(len); hdr->confirm_rx = !!confirm_rx; - skb_put_padto(skb, ALIGN(len, 4) + sizeof(*hdr)); - - mutex_lock(&node->ep_lock); - if (node->ep) - rc = node->ep->xmit(node->ep, skb); - else - kfree_skb(skb); - mutex_unlock(&node->ep_lock); + rc = skb_put_padto(skb, ALIGN(len, 4) + sizeof(*hdr)); + if (!rc) { + mutex_lock(&node->ep_lock); + rc = -ENODEV; + if (node->ep) + rc = node->ep->xmit(node->ep, skb); + else + kfree_skb(skb); + mutex_unlock(&node->ep_lock); + } /* Need to ensure that a subsequent message carries the otherwise lost * confirm_rx flag if we dropped this one */ if (rc && confirm_rx) |