aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/socket.c25
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
4324out: 4339out:
4325 return retval; 4340 return retval;
4326} 4341}