sctp: fix panic when sending auth chunks
[cascardo/linux.git] / net / sctp / output.c
index 1541a91..2e9223b 100644 (file)
@@ -582,9 +582,7 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
                         */
                        pkt_size -= WORD_ROUND(chunk->skb->len);
 
-                       if (chunk == packet->auth && !list_empty(&packet->chunk_list))
-                               list_add(&chunk->list, &packet->chunk_list);
-                       else if (!sctp_chunk_is_data(chunk))
+                       if (!sctp_chunk_is_data(chunk) && chunk != packet->auth)
                                sctp_chunk_free(chunk);
 
                        if (!pkt_size)
@@ -605,6 +603,18 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
                                                 (struct sctp_auth_chunk *)auth,
                                                 gfp);
 
+               if (packet->auth) {
+                       if (!list_empty(&packet->chunk_list)) {
+                               /* We will generate more packets, so re-queue
+                                * auth chunk.
+                                */
+                               list_add(&chunk->list, &packet->chunk_list);
+                       } else {
+                               sctp_chunk_free(packet->auth);
+                               packet->auth = NULL;
+                       }
+               }
+
                if (!gso)
                        break;
 
@@ -735,6 +745,8 @@ err:
        }
        goto out;
 nomem:
+       if (packet->auth && list_empty(&packet->auth->list))
+               sctp_chunk_free(packet->auth);
        err = -ENOMEM;
        goto err;
 }