Commit 6fd8c252 authored by Jon Grimm's avatar Jon Grimm

[SCTP] Fix sctp_sendmsg error path when associate fails.

parent 6cf4b403
...@@ -770,7 +770,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, ...@@ -770,7 +770,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
struct sctp_endpoint *ep; struct sctp_endpoint *ep;
struct sctp_association *new_asoc=NULL, *asoc=NULL; struct sctp_association *new_asoc=NULL, *asoc=NULL;
struct sctp_transport *transport, *chunk_tp; struct sctp_transport *transport, *chunk_tp;
struct sctp_chunk *chunk = NULL; struct sctp_chunk *chunk;
union sctp_addr to; union sctp_addr to;
struct sockaddr *msg_name = NULL; struct sockaddr *msg_name = NULL;
struct sctp_sndrcvinfo default_sinfo = { 0 }; struct sctp_sndrcvinfo default_sinfo = { 0 };
...@@ -1066,13 +1066,6 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, ...@@ -1066,13 +1066,6 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
} else } else
chunk_tp = NULL; chunk_tp = NULL;
/* Break the message into multiple chunks of maximum size. */
datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len);
if (!datamsg) {
err = -ENOMEM;
goto out_free;
}
/* Auto-connect, if we aren't connected already. */ /* Auto-connect, if we aren't connected already. */
if (SCTP_STATE_CLOSED == asoc->state) { if (SCTP_STATE_CLOSED == asoc->state) {
err = sctp_primitive_ASSOCIATE(asoc, NULL); err = sctp_primitive_ASSOCIATE(asoc, NULL);
...@@ -1081,6 +1074,13 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, ...@@ -1081,6 +1074,13 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
SCTP_DEBUG_PRINTK("We associated primitively.\n"); SCTP_DEBUG_PRINTK("We associated primitively.\n");
} }
/* Break the message into multiple chunks of maximum size. */
datamsg = sctp_datamsg_from_user(asoc, sinfo, msg, msg_len);
if (!datamsg) {
err = -ENOMEM;
goto out_free;
}
/* Now send the (possibly) fragmented message. */ /* Now send the (possibly) fragmented message. */
list_for_each_safe(pos, temp, &datamsg->chunks) { list_for_each_safe(pos, temp, &datamsg->chunks) {
chunk = list_entry(pos, struct sctp_chunk, frag_list); chunk = list_entry(pos, struct sctp_chunk, frag_list);
...@@ -1096,25 +1096,16 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, ...@@ -1096,25 +1096,16 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
SCTP_DEBUG_PRINTK("We sent primitively.\n"); SCTP_DEBUG_PRINTK("We sent primitively.\n");
} }
sctp_datamsg_free(datamsg); sctp_datamsg_free(datamsg);
err = msg_len;
if (!err) {
err = msg_len;
goto out_unlock;
}
/* If we are already past ASSOCIATE, the lower /* If we are already past ASSOCIATE, the lower
* layers are responsible for association cleanup. * layers are responsible for association cleanup.
*/ */
goto out_free_chunk; goto out_unlock;
out_free: out_free:
if (new_asoc) if (new_asoc)
sctp_association_free(asoc); sctp_association_free(asoc);
out_free_chunk:
/* The datamsg struct will auto-destruct via ref counting. */
if (chunk)
sctp_chunk_free(chunk);
out_unlock: out_unlock:
sctp_release_sock(sk); sctp_release_sock(sk);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment