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

Commit eb70df13 authored by Jarek Poplawski's avatar Jarek Poplawski Committed by David S. Miller
Browse files

af_packet: Don't use skb after dev_queue_xmit()



tpacket_snd() can change and kfree an skb after dev_queue_xmit(),
which is illegal.

With debugging by: Stephen Hemminger <shemminger@vyatta.com>

Reported-by: default avatarMichael Breuer <mbreuer@majjas.com>
With help from: David S. Miller <davem@davemloft.net>
Signed-off-by: default avatarJarek Poplawski <jarkao2@gmail.com>
Tested-by: default avatarMichael <Breuer&lt;mbreuer@majjas.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fa15e99b
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -1021,8 +1021,20 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)

		status = TP_STATUS_SEND_REQUEST;
		err = dev_queue_xmit(skb);
		if (unlikely(err > 0 && (err = net_xmit_errno(err)) != 0))
			goto out_xmit;
		if (unlikely(err > 0)) {
			err = net_xmit_errno(err);
			if (err && __packet_get_status(po, ph) ==
				   TP_STATUS_AVAILABLE) {
				/* skb was destructed already */
				skb = NULL;
				goto out_status;
			}
			/*
			 * skb was dropped but not destructed yet;
			 * let's treat it like congestion or err < 0
			 */
			err = 0;
		}
		packet_increment_head(&po->tx_ring);
		len_sum += tp_len;
	} while (likely((ph != NULL) ||
@@ -1033,9 +1045,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
	err = len_sum;
	goto out_put;

out_xmit:
	skb->destructor = sock_wfree;
	atomic_dec(&po->tx_ring.pending);
out_status:
	__packet_set_status(po, ph, status);
	kfree_skb(skb);