diff options
-rw-r--r-- | include/net/sctp/sctp.h | 1 | ||||
-rw-r--r-- | net/sctp/socket.c | 24 |
2 files changed, 10 insertions, 15 deletions
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index d3685615a8b0..6ee44b24864a 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h | |||
@@ -413,6 +413,7 @@ static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc) | |||
413 | /* Look up the association by its id. */ | 413 | /* Look up the association by its id. */ |
414 | struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id); | 414 | struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id); |
415 | 415 | ||
416 | int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp); | ||
416 | 417 | ||
417 | /* A macro to walk a list of skbs. */ | 418 | /* A macro to walk a list of skbs. */ |
418 | #define sctp_skb_for_each(pos, head, tmp) \ | 419 | #define sctp_skb_for_each(pos, head, tmp) \ |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 408ebd0e7330..06b42b7f5a02 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -4170,14 +4170,16 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv | |||
4170 | } | 4170 | } |
4171 | 4171 | ||
4172 | /* Helper routine to branch off an association to a new socket. */ | 4172 | /* Helper routine to branch off an association to a new socket. */ |
4173 | SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc, | 4173 | int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) |
4174 | struct socket **sockp) | ||
4175 | { | 4174 | { |
4176 | struct sock *sk = asoc->base.sk; | 4175 | struct sctp_association *asoc = sctp_id2assoc(sk, id); |
4177 | struct socket *sock; | 4176 | struct socket *sock; |
4178 | struct sctp_af *af; | 4177 | struct sctp_af *af; |
4179 | int err = 0; | 4178 | int err = 0; |
4180 | 4179 | ||
4180 | if (!asoc) | ||
4181 | return -EINVAL; | ||
4182 | |||
4181 | /* An association cannot be branched off from an already peeled-off | 4183 | /* An association cannot be branched off from an already peeled-off |
4182 | * socket, nor is this supported for tcp style sockets. | 4184 | * socket, nor is this supported for tcp style sockets. |
4183 | */ | 4185 | */ |
@@ -4206,13 +4208,13 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc, | |||
4206 | 4208 | ||
4207 | return err; | 4209 | return err; |
4208 | } | 4210 | } |
4211 | EXPORT_SYMBOL(sctp_do_peeloff); | ||
4209 | 4212 | ||
4210 | static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval, int __user *optlen) | 4213 | static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval, int __user *optlen) |
4211 | { | 4214 | { |
4212 | sctp_peeloff_arg_t peeloff; | 4215 | sctp_peeloff_arg_t peeloff; |
4213 | struct socket *newsock; | 4216 | struct socket *newsock; |
4214 | int retval = 0; | 4217 | int retval = 0; |
4215 | struct sctp_association *asoc; | ||
4216 | 4218 | ||
4217 | if (len < sizeof(sctp_peeloff_arg_t)) | 4219 | if (len < sizeof(sctp_peeloff_arg_t)) |
4218 | return -EINVAL; | 4220 | return -EINVAL; |
@@ -4220,15 +4222,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval | |||
4220 | if (copy_from_user(&peeloff, optval, len)) | 4222 | if (copy_from_user(&peeloff, optval, len)) |
4221 | return -EFAULT; | 4223 | return -EFAULT; |
4222 | 4224 | ||
4223 | asoc = sctp_id2assoc(sk, peeloff.associd); | 4225 | retval = sctp_do_peeloff(sk, peeloff.associd, &newsock); |
4224 | if (!asoc) { | ||
4225 | retval = -EINVAL; | ||
4226 | goto out; | ||
4227 | } | ||
4228 | |||
4229 | SCTP_DEBUG_PRINTK("%s: sk: %p asoc: %p\n", __func__, sk, asoc); | ||
4230 | |||
4231 | retval = sctp_do_peeloff(asoc, &newsock); | ||
4232 | if (retval < 0) | 4226 | if (retval < 0) |
4233 | goto out; | 4227 | goto out; |
4234 | 4228 | ||
@@ -4239,8 +4233,8 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval | |||
4239 | goto out; | 4233 | goto out; |
4240 | } | 4234 | } |
4241 | 4235 | ||
4242 | SCTP_DEBUG_PRINTK("%s: sk: %p asoc: %p newsk: %p sd: %d\n", | 4236 | SCTP_DEBUG_PRINTK("%s: sk: %p newsk: %p sd: %d\n", |
4243 | __func__, sk, asoc, newsock->sk, retval); | 4237 | __func__, sk, newsock->sk, retval); |
4244 | 4238 | ||
4245 | /* Return the fd mapped to the new socket. */ | 4239 | /* Return the fd mapped to the new socket. */ |
4246 | peeloff.sd = retval; | 4240 | peeloff.sd = retval; |