aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>2016-07-22 23:33:44 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-25 14:23:27 -0400
commit52253db924d1480bf2543afbb9551de31381aab9 (patch)
tree19f8eb666ef960c901e3837a5b183370d53b926b
parenteefc1b1d105ee4d2ce907833ce675f1e9599b5e3 (diff)
sctp: also point GSO head_skb to the sk when it's available
The head skb for GSO packets won't travel through the inner depths of SCTP stack as it doesn't contain any chunks on it. That means skb->sk doesn't get set and then when sctp_recvmsg() calls sctp_inet6_skb_msgname() on the head_skb it panics, as this last needs to check flags at the socket (sp->v4mapped). The fix is to initialize skb->sk for th head skb once we are able to do it. That is, when the first chunk is processed. Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/sctp/ulpevent.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index f6219b164b42..1bc4f71aaba8 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -91,6 +91,7 @@ int sctp_ulpevent_is_notification(const struct sctp_ulpevent *event)
91static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event, 91static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event,
92 const struct sctp_association *asoc) 92 const struct sctp_association *asoc)
93{ 93{
94 struct sctp_chunk *chunk = event->chunk;
94 struct sk_buff *skb; 95 struct sk_buff *skb;
95 96
96 /* Cast away the const, as we are just wanting to 97 /* Cast away the const, as we are just wanting to
@@ -101,6 +102,8 @@ static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event,
101 event->asoc = (struct sctp_association *)asoc; 102 event->asoc = (struct sctp_association *)asoc;
102 atomic_add(event->rmem_len, &event->asoc->rmem_alloc); 103 atomic_add(event->rmem_len, &event->asoc->rmem_alloc);
103 sctp_skb_set_owner_r(skb, asoc->base.sk); 104 sctp_skb_set_owner_r(skb, asoc->base.sk);
105 if (chunk && chunk->head_skb && !chunk->head_skb->sk)
106 chunk->head_skb->sk = asoc->base.sk;
104} 107}
105 108
106/* A simple destructor to give up the reference to the association. */ 109/* A simple destructor to give up the reference to the association. */