diff options
Diffstat (limited to 'net/sctp')
-rw-r--r-- | net/sctp/socket.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index d37d24ff197..59d16ea927f 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -70,6 +70,7 @@ | |||
70 | #include <linux/init.h> | 70 | #include <linux/init.h> |
71 | #include <linux/crypto.h> | 71 | #include <linux/crypto.h> |
72 | #include <linux/slab.h> | 72 | #include <linux/slab.h> |
73 | #include <linux/file.h> | ||
73 | 74 | ||
74 | #include <net/ip.h> | 75 | #include <net/ip.h> |
75 | #include <net/icmp.h> | 76 | #include <net/icmp.h> |
@@ -4292,6 +4293,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval | |||
4292 | { | 4293 | { |
4293 | sctp_peeloff_arg_t peeloff; | 4294 | sctp_peeloff_arg_t peeloff; |
4294 | struct socket *newsock; | 4295 | struct socket *newsock; |
4296 | struct file *newfile; | ||
4295 | int retval = 0; | 4297 | int retval = 0; |
4296 | 4298 | ||
4297 | if (len < sizeof(sctp_peeloff_arg_t)) | 4299 | if (len < sizeof(sctp_peeloff_arg_t)) |
@@ -4305,22 +4307,35 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval | |||
4305 | goto out; | 4307 | goto out; |
4306 | 4308 | ||
4307 | /* Map the socket to an unused fd that can be returned to the user. */ | 4309 | /* Map the socket to an unused fd that can be returned to the user. */ |
4308 | retval = sock_map_fd(newsock, 0); | 4310 | retval = get_unused_fd(); |
4309 | if (retval < 0) { | 4311 | if (retval < 0) { |
4310 | sock_release(newsock); | 4312 | sock_release(newsock); |
4311 | goto out; | 4313 | goto out; |
4312 | } | 4314 | } |
4313 | 4315 | ||
4316 | newfile = sock_alloc_file(newsock, 0, NULL); | ||
4317 | if (unlikely(IS_ERR(newfile))) { | ||
4318 | put_unused_fd(retval); | ||
4319 | sock_release(newsock); | ||
4320 | return PTR_ERR(newfile); | ||
4321 | } | ||
4322 | |||
4314 | SCTP_DEBUG_PRINTK("%s: sk: %p newsk: %p sd: %d\n", | 4323 | SCTP_DEBUG_PRINTK("%s: sk: %p newsk: %p sd: %d\n", |
4315 | __func__, sk, newsock->sk, retval); | 4324 | __func__, sk, newsock->sk, retval); |
4316 | 4325 | ||
4317 | /* Return the fd mapped to the new socket. */ | 4326 | /* Return the fd mapped to the new socket. */ |
4327 | if (put_user(len, optlen)) { | ||
4328 | fput(newfile); | ||
4329 | put_unused_fd(retval); | ||
4330 | return -EFAULT; | ||
4331 | } | ||
4318 | peeloff.sd = retval; | 4332 | peeloff.sd = retval; |
4319 | if (put_user(len, optlen)) | 4333 | if (copy_to_user(optval, &peeloff, len)) { |
4334 | fput(newfile); | ||
4335 | put_unused_fd(retval); | ||
4320 | return -EFAULT; | 4336 | return -EFAULT; |
4321 | if (copy_to_user(optval, &peeloff, len)) | 4337 | } |
4322 | retval = -EFAULT; | 4338 | fd_install(retval, newfile); |
4323 | |||
4324 | out: | 4339 | out: |
4325 | return retval; | 4340 | return retval; |
4326 | } | 4341 | } |