aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c973
1 files changed, 830 insertions, 143 deletions
diff --git a/net/socket.c b/net/socket.c
index 75655365b5fd..5e8d0af3c0e7 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -87,6 +87,7 @@
87#include <linux/wireless.h> 87#include <linux/wireless.h>
88#include <linux/nsproxy.h> 88#include <linux/nsproxy.h>
89#include <linux/magic.h> 89#include <linux/magic.h>
90#include <linux/slab.h>
90 91
91#include <asm/uaccess.h> 92#include <asm/uaccess.h>
92#include <asm/unistd.h> 93#include <asm/unistd.h>
@@ -97,6 +98,12 @@
97#include <net/sock.h> 98#include <net/sock.h>
98#include <linux/netfilter.h> 99#include <linux/netfilter.h>
99 100
101#include <linux/if_tun.h>
102#include <linux/ipv6_route.h>
103#include <linux/route.h>
104#include <linux/sockios.h>
105#include <linux/atalk.h>
106
100static int sock_no_open(struct inode *irrelevant, struct file *dontcare); 107static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
101static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, 108static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
102 unsigned long nr_segs, loff_t pos); 109 unsigned long nr_segs, loff_t pos);
@@ -306,18 +313,6 @@ static struct file_system_type sock_fs_type = {
306 .kill_sb = kill_anon_super, 313 .kill_sb = kill_anon_super,
307}; 314};
308 315
309static int sockfs_delete_dentry(struct dentry *dentry)
310{
311 /*
312 * At creation time, we pretended this dentry was hashed
313 * (by clearing DCACHE_UNHASHED bit in d_flags)
314 * At delete time, we restore the truth : not hashed.
315 * (so that dput() can proceed correctly)
316 */
317 dentry->d_flags |= DCACHE_UNHASHED;
318 return 0;
319}
320
321/* 316/*
322 * sockfs_dname() is called from d_path(). 317 * sockfs_dname() is called from d_path().
323 */ 318 */
@@ -328,7 +323,6 @@ static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen)
328} 323}
329 324
330static const struct dentry_operations sockfs_dentry_operations = { 325static const struct dentry_operations sockfs_dentry_operations = {
331 .d_delete = sockfs_delete_dentry,
332 .d_dname = sockfs_dname, 326 .d_dname = sockfs_dname,
333}; 327};
334 328
@@ -349,68 +343,55 @@ static const struct dentry_operations sockfs_dentry_operations = {
349 * but we take care of internal coherence yet. 343 * but we take care of internal coherence yet.
350 */ 344 */
351 345
352static int sock_alloc_fd(struct file **filep, int flags) 346static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
353{ 347{
348 struct qstr name = { .name = "" };
349 struct path path;
350 struct file *file;
354 int fd; 351 int fd;
355 352
356 fd = get_unused_fd_flags(flags); 353 fd = get_unused_fd_flags(flags);
357 if (likely(fd >= 0)) { 354 if (unlikely(fd < 0))
358 struct file *file = get_empty_filp(); 355 return fd;
359
360 *filep = file;
361 if (unlikely(!file)) {
362 put_unused_fd(fd);
363 return -ENFILE;
364 }
365 } else
366 *filep = NULL;
367 return fd;
368}
369
370static int sock_attach_fd(struct socket *sock, struct file *file, int flags)
371{
372 struct dentry *dentry;
373 struct qstr name = { .name = "" };
374 356
375 dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name); 357 path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &name);
376 if (unlikely(!dentry)) 358 if (unlikely(!path.dentry)) {
359 put_unused_fd(fd);
377 return -ENOMEM; 360 return -ENOMEM;
361 }
362 path.mnt = mntget(sock_mnt);
378 363
379 dentry->d_op = &sockfs_dentry_operations; 364 path.dentry->d_op = &sockfs_dentry_operations;
380 /* 365 d_instantiate(path.dentry, SOCK_INODE(sock));
381 * We dont want to push this dentry into global dentry hash table. 366 SOCK_INODE(sock)->i_fop = &socket_file_ops;
382 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
383 * This permits a working /proc/$pid/fd/XXX on sockets
384 */
385 dentry->d_flags &= ~DCACHE_UNHASHED;
386 d_instantiate(dentry, SOCK_INODE(sock));
387 367
388 sock->file = file; 368 file = alloc_file(&path, FMODE_READ | FMODE_WRITE,
389 init_file(file, sock_mnt, dentry, FMODE_READ | FMODE_WRITE,
390 &socket_file_ops); 369 &socket_file_ops);
391 SOCK_INODE(sock)->i_fop = &socket_file_ops; 370 if (unlikely(!file)) {
371 /* drop dentry, keep inode */
372 atomic_inc(&path.dentry->d_inode->i_count);
373 path_put(&path);
374 put_unused_fd(fd);
375 return -ENFILE;
376 }
377
378 sock->file = file;
392 file->f_flags = O_RDWR | (flags & O_NONBLOCK); 379 file->f_flags = O_RDWR | (flags & O_NONBLOCK);
393 file->f_pos = 0; 380 file->f_pos = 0;
394 file->private_data = sock; 381 file->private_data = sock;
395 382
396 return 0; 383 *f = file;
384 return fd;
397} 385}
398 386
399int sock_map_fd(struct socket *sock, int flags) 387int sock_map_fd(struct socket *sock, int flags)
400{ 388{
401 struct file *newfile; 389 struct file *newfile;
402 int fd = sock_alloc_fd(&newfile, flags); 390 int fd = sock_alloc_file(sock, &newfile, flags);
403
404 if (likely(fd >= 0)) {
405 int err = sock_attach_fd(sock, newfile, flags);
406 391
407 if (unlikely(err < 0)) { 392 if (likely(fd >= 0))
408 put_filp(newfile);
409 put_unused_fd(fd);
410 return err;
411 }
412 fd_install(fd, newfile); 393 fd_install(fd, newfile);
413 } 394
414 return fd; 395 return fd;
415} 396}
416 397
@@ -668,10 +649,24 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
668 649
669EXPORT_SYMBOL_GPL(__sock_recv_timestamp); 650EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
670 651
671static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock, 652inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
672 struct msghdr *msg, size_t size, int flags) 653{
654 if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && skb->dropcount)
655 put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL,
656 sizeof(__u32), &skb->dropcount);
657}
658
659void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
660 struct sk_buff *skb)
661{
662 sock_recv_timestamp(msg, sk, skb);
663 sock_recv_drops(msg, sk, skb);
664}
665EXPORT_SYMBOL_GPL(sock_recv_ts_and_drops);
666
667static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock,
668 struct msghdr *msg, size_t size, int flags)
673{ 669{
674 int err;
675 struct sock_iocb *si = kiocb_to_siocb(iocb); 670 struct sock_iocb *si = kiocb_to_siocb(iocb);
676 671
677 si->sock = sock; 672 si->sock = sock;
@@ -680,13 +675,17 @@ static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
680 si->size = size; 675 si->size = size;
681 si->flags = flags; 676 si->flags = flags;
682 677
683 err = security_socket_recvmsg(sock, msg, size, flags);
684 if (err)
685 return err;
686
687 return sock->ops->recvmsg(iocb, sock, msg, size, flags); 678 return sock->ops->recvmsg(iocb, sock, msg, size, flags);
688} 679}
689 680
681static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
682 struct msghdr *msg, size_t size, int flags)
683{
684 int err = security_socket_recvmsg(sock, msg, size, flags);
685
686 return err ?: __sock_recvmsg_nosec(iocb, sock, msg, size, flags);
687}
688
690int sock_recvmsg(struct socket *sock, struct msghdr *msg, 689int sock_recvmsg(struct socket *sock, struct msghdr *msg,
691 size_t size, int flags) 690 size_t size, int flags)
692{ 691{
@@ -702,6 +701,21 @@ int sock_recvmsg(struct socket *sock, struct msghdr *msg,
702 return ret; 701 return ret;
703} 702}
704 703
704static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
705 size_t size, int flags)
706{
707 struct kiocb iocb;
708 struct sock_iocb siocb;
709 int ret;
710
711 init_sync_kiocb(&iocb, NULL);
712 iocb.private = &siocb;
713 ret = __sock_recvmsg_nosec(&iocb, sock, msg, size, flags);
714 if (-EIOCBQUEUED == ret)
715 ret = wait_on_sync_kiocb(&iocb);
716 return ret;
717}
718
705int kernel_recvmsg(struct socket *sock, struct msghdr *msg, 719int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
706 struct kvec *vec, size_t num, size_t size, int flags) 720 struct kvec *vec, size_t num, size_t size, int flags)
707{ 721{
@@ -886,6 +900,24 @@ void dlci_ioctl_set(int (*hook) (unsigned int, void __user *))
886 900
887EXPORT_SYMBOL(dlci_ioctl_set); 901EXPORT_SYMBOL(dlci_ioctl_set);
888 902
903static long sock_do_ioctl(struct net *net, struct socket *sock,
904 unsigned int cmd, unsigned long arg)
905{
906 int err;
907 void __user *argp = (void __user *)arg;
908
909 err = sock->ops->ioctl(sock, cmd, arg);
910
911 /*
912 * If this ioctl is unknown try to hand it down
913 * to the NIC driver.
914 */
915 if (err == -ENOIOCTLCMD)
916 err = dev_ioctl(net, cmd, argp);
917
918 return err;
919}
920
889/* 921/*
890 * With an ioctl, arg may well be a user mode pointer, but we don't know 922 * With an ioctl, arg may well be a user mode pointer, but we don't know
891 * what to do with it - that's up to the protocol still. 923 * what to do with it - that's up to the protocol still.
@@ -905,11 +937,11 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
905 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { 937 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
906 err = dev_ioctl(net, cmd, argp); 938 err = dev_ioctl(net, cmd, argp);
907 } else 939 } else
908#ifdef CONFIG_WIRELESS_EXT 940#ifdef CONFIG_WEXT_CORE
909 if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { 941 if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
910 err = dev_ioctl(net, cmd, argp); 942 err = dev_ioctl(net, cmd, argp);
911 } else 943 } else
912#endif /* CONFIG_WIRELESS_EXT */ 944#endif
913 switch (cmd) { 945 switch (cmd) {
914 case FIOSETOWN: 946 case FIOSETOWN:
915 case SIOCSPGRP: 947 case SIOCSPGRP:
@@ -959,14 +991,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
959 mutex_unlock(&dlci_ioctl_mutex); 991 mutex_unlock(&dlci_ioctl_mutex);
960 break; 992 break;
961 default: 993 default:
962 err = sock->ops->ioctl(sock, cmd, arg); 994 err = sock_do_ioctl(net, sock, cmd, arg);
963
964 /*
965 * If this ioctl is unknown try to hand it down
966 * to the NIC driver.
967 */
968 if (err == -ENOIOCTLCMD)
969 err = dev_ioctl(net, cmd, argp);
970 break; 995 break;
971 } 996 }
972 return err; 997 return err;
@@ -1100,11 +1125,14 @@ static int sock_fasync(int fd, struct file *filp, int on)
1100 fna->fa_next = sock->fasync_list; 1125 fna->fa_next = sock->fasync_list;
1101 write_lock_bh(&sk->sk_callback_lock); 1126 write_lock_bh(&sk->sk_callback_lock);
1102 sock->fasync_list = fna; 1127 sock->fasync_list = fna;
1128 sock_set_flag(sk, SOCK_FASYNC);
1103 write_unlock_bh(&sk->sk_callback_lock); 1129 write_unlock_bh(&sk->sk_callback_lock);
1104 } else { 1130 } else {
1105 if (fa != NULL) { 1131 if (fa != NULL) {
1106 write_lock_bh(&sk->sk_callback_lock); 1132 write_lock_bh(&sk->sk_callback_lock);
1107 *prev = fa->fa_next; 1133 *prev = fa->fa_next;
1134 if (!sock->fasync_list)
1135 sock_reset_flag(sk, SOCK_FASYNC);
1108 write_unlock_bh(&sk->sk_callback_lock); 1136 write_unlock_bh(&sk->sk_callback_lock);
1109 kfree(fa); 1137 kfree(fa);
1110 } 1138 }
@@ -1216,7 +1244,7 @@ static int __sock_create(struct net *net, int family, int type, int protocol,
1216 /* Now protected by module ref count */ 1244 /* Now protected by module ref count */
1217 rcu_read_unlock(); 1245 rcu_read_unlock();
1218 1246
1219 err = pf->create(net, sock, protocol); 1247 err = pf->create(net, sock, protocol, kern);
1220 if (err < 0) 1248 if (err < 0)
1221 goto out_module_put; 1249 goto out_module_put;
1222 1250
@@ -1337,29 +1365,19 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
1337 if (err < 0) 1365 if (err < 0)
1338 goto out_release_both; 1366 goto out_release_both;
1339 1367
1340 fd1 = sock_alloc_fd(&newfile1, flags & O_CLOEXEC); 1368 fd1 = sock_alloc_file(sock1, &newfile1, flags);
1341 if (unlikely(fd1 < 0)) { 1369 if (unlikely(fd1 < 0)) {
1342 err = fd1; 1370 err = fd1;
1343 goto out_release_both; 1371 goto out_release_both;
1344 } 1372 }
1345 1373
1346 fd2 = sock_alloc_fd(&newfile2, flags & O_CLOEXEC); 1374 fd2 = sock_alloc_file(sock2, &newfile2, flags);
1347 if (unlikely(fd2 < 0)) { 1375 if (unlikely(fd2 < 0)) {
1348 err = fd2; 1376 err = fd2;
1349 put_filp(newfile1);
1350 put_unused_fd(fd1);
1351 goto out_release_both;
1352 }
1353
1354 err = sock_attach_fd(sock1, newfile1, flags & O_NONBLOCK);
1355 if (unlikely(err < 0)) {
1356 goto out_fd2;
1357 }
1358
1359 err = sock_attach_fd(sock2, newfile2, flags & O_NONBLOCK);
1360 if (unlikely(err < 0)) {
1361 fput(newfile1); 1377 fput(newfile1);
1362 goto out_fd1; 1378 put_unused_fd(fd1);
1379 sock_release(sock2);
1380 goto out;
1363 } 1381 }
1364 1382
1365 audit_fd_pair(fd1, fd2); 1383 audit_fd_pair(fd1, fd2);
@@ -1385,16 +1403,6 @@ out_release_1:
1385 sock_release(sock1); 1403 sock_release(sock1);
1386out: 1404out:
1387 return err; 1405 return err;
1388
1389out_fd2:
1390 put_filp(newfile1);
1391 sock_release(sock1);
1392out_fd1:
1393 put_filp(newfile2);
1394 sock_release(sock2);
1395 put_unused_fd(fd1);
1396 put_unused_fd(fd2);
1397 goto out;
1398} 1406}
1399 1407
1400/* 1408/*
@@ -1498,17 +1506,13 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
1498 */ 1506 */
1499 __module_get(newsock->ops->owner); 1507 __module_get(newsock->ops->owner);
1500 1508
1501 newfd = sock_alloc_fd(&newfile, flags & O_CLOEXEC); 1509 newfd = sock_alloc_file(newsock, &newfile, flags);
1502 if (unlikely(newfd < 0)) { 1510 if (unlikely(newfd < 0)) {
1503 err = newfd; 1511 err = newfd;
1504 sock_release(newsock); 1512 sock_release(newsock);
1505 goto out_put; 1513 goto out_put;
1506 } 1514 }
1507 1515
1508 err = sock_attach_fd(newsock, newfile, flags & O_NONBLOCK);
1509 if (err < 0)
1510 goto out_fd_simple;
1511
1512 err = security_socket_accept(sock, newsock); 1516 err = security_socket_accept(sock, newsock);
1513 if (err) 1517 if (err)
1514 goto out_fd; 1518 goto out_fd;
@@ -1538,11 +1542,6 @@ out_put:
1538 fput_light(sock->file, fput_needed); 1542 fput_light(sock->file, fput_needed);
1539out: 1543out:
1540 return err; 1544 return err;
1541out_fd_simple:
1542 sock_release(newsock);
1543 put_filp(newfile);
1544 put_unused_fd(newfd);
1545 goto out_put;
1546out_fd: 1545out_fd:
1547 fput(newfile); 1546 fput(newfile);
1548 put_unused_fd(newfd); 1547 put_unused_fd(newfd);
@@ -1965,22 +1964,15 @@ out:
1965 return err; 1964 return err;
1966} 1965}
1967 1966
1968/* 1967static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
1969 * BSD recvmsg interface 1968 struct msghdr *msg_sys, unsigned flags, int nosec)
1970 */
1971
1972SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
1973 unsigned int, flags)
1974{ 1969{
1975 struct compat_msghdr __user *msg_compat = 1970 struct compat_msghdr __user *msg_compat =
1976 (struct compat_msghdr __user *)msg; 1971 (struct compat_msghdr __user *)msg;
1977 struct socket *sock;
1978 struct iovec iovstack[UIO_FASTIOV]; 1972 struct iovec iovstack[UIO_FASTIOV];
1979 struct iovec *iov = iovstack; 1973 struct iovec *iov = iovstack;
1980 struct msghdr msg_sys;
1981 unsigned long cmsg_ptr; 1974 unsigned long cmsg_ptr;
1982 int err, iov_size, total_len, len; 1975 int err, iov_size, total_len, len;
1983 int fput_needed;
1984 1976
1985 /* kernel mode address */ 1977 /* kernel mode address */
1986 struct sockaddr_storage addr; 1978 struct sockaddr_storage addr;
@@ -1990,27 +1982,23 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
1990 int __user *uaddr_len; 1982 int __user *uaddr_len;
1991 1983
1992 if (MSG_CMSG_COMPAT & flags) { 1984 if (MSG_CMSG_COMPAT & flags) {
1993 if (get_compat_msghdr(&msg_sys, msg_compat)) 1985 if (get_compat_msghdr(msg_sys, msg_compat))
1994 return -EFAULT; 1986 return -EFAULT;
1995 } 1987 }
1996 else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr))) 1988 else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
1997 return -EFAULT; 1989 return -EFAULT;
1998 1990
1999 sock = sockfd_lookup_light(fd, &err, &fput_needed);
2000 if (!sock)
2001 goto out;
2002
2003 err = -EMSGSIZE; 1991 err = -EMSGSIZE;
2004 if (msg_sys.msg_iovlen > UIO_MAXIOV) 1992 if (msg_sys->msg_iovlen > UIO_MAXIOV)
2005 goto out_put; 1993 goto out;
2006 1994
2007 /* Check whether to allocate the iovec area */ 1995 /* Check whether to allocate the iovec area */
2008 err = -ENOMEM; 1996 err = -ENOMEM;
2009 iov_size = msg_sys.msg_iovlen * sizeof(struct iovec); 1997 iov_size = msg_sys->msg_iovlen * sizeof(struct iovec);
2010 if (msg_sys.msg_iovlen > UIO_FASTIOV) { 1998 if (msg_sys->msg_iovlen > UIO_FASTIOV) {
2011 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); 1999 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
2012 if (!iov) 2000 if (!iov)
2013 goto out_put; 2001 goto out;
2014 } 2002 }
2015 2003
2016 /* 2004 /*
@@ -2018,46 +2006,47 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
2018 * kernel msghdr to use the kernel address space) 2006 * kernel msghdr to use the kernel address space)
2019 */ 2007 */
2020 2008
2021 uaddr = (__force void __user *)msg_sys.msg_name; 2009 uaddr = (__force void __user *)msg_sys->msg_name;
2022 uaddr_len = COMPAT_NAMELEN(msg); 2010 uaddr_len = COMPAT_NAMELEN(msg);
2023 if (MSG_CMSG_COMPAT & flags) { 2011 if (MSG_CMSG_COMPAT & flags) {
2024 err = verify_compat_iovec(&msg_sys, iov, 2012 err = verify_compat_iovec(msg_sys, iov,
2025 (struct sockaddr *)&addr, 2013 (struct sockaddr *)&addr,
2026 VERIFY_WRITE); 2014 VERIFY_WRITE);
2027 } else 2015 } else
2028 err = verify_iovec(&msg_sys, iov, 2016 err = verify_iovec(msg_sys, iov,
2029 (struct sockaddr *)&addr, 2017 (struct sockaddr *)&addr,
2030 VERIFY_WRITE); 2018 VERIFY_WRITE);
2031 if (err < 0) 2019 if (err < 0)
2032 goto out_freeiov; 2020 goto out_freeiov;
2033 total_len = err; 2021 total_len = err;
2034 2022
2035 cmsg_ptr = (unsigned long)msg_sys.msg_control; 2023 cmsg_ptr = (unsigned long)msg_sys->msg_control;
2036 msg_sys.msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT); 2024 msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
2037 2025
2038 if (sock->file->f_flags & O_NONBLOCK) 2026 if (sock->file->f_flags & O_NONBLOCK)
2039 flags |= MSG_DONTWAIT; 2027 flags |= MSG_DONTWAIT;
2040 err = sock_recvmsg(sock, &msg_sys, total_len, flags); 2028 err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys,
2029 total_len, flags);
2041 if (err < 0) 2030 if (err < 0)
2042 goto out_freeiov; 2031 goto out_freeiov;
2043 len = err; 2032 len = err;
2044 2033
2045 if (uaddr != NULL) { 2034 if (uaddr != NULL) {
2046 err = move_addr_to_user((struct sockaddr *)&addr, 2035 err = move_addr_to_user((struct sockaddr *)&addr,
2047 msg_sys.msg_namelen, uaddr, 2036 msg_sys->msg_namelen, uaddr,
2048 uaddr_len); 2037 uaddr_len);
2049 if (err < 0) 2038 if (err < 0)
2050 goto out_freeiov; 2039 goto out_freeiov;
2051 } 2040 }
2052 err = __put_user((msg_sys.msg_flags & ~MSG_CMSG_COMPAT), 2041 err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT),
2053 COMPAT_FLAGS(msg)); 2042 COMPAT_FLAGS(msg));
2054 if (err) 2043 if (err)
2055 goto out_freeiov; 2044 goto out_freeiov;
2056 if (MSG_CMSG_COMPAT & flags) 2045 if (MSG_CMSG_COMPAT & flags)
2057 err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr, 2046 err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
2058 &msg_compat->msg_controllen); 2047 &msg_compat->msg_controllen);
2059 else 2048 else
2060 err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr, 2049 err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
2061 &msg->msg_controllen); 2050 &msg->msg_controllen);
2062 if (err) 2051 if (err)
2063 goto out_freeiov; 2052 goto out_freeiov;
@@ -2066,21 +2055,166 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
2066out_freeiov: 2055out_freeiov:
2067 if (iov != iovstack) 2056 if (iov != iovstack)
2068 sock_kfree_s(sock->sk, iov, iov_size); 2057 sock_kfree_s(sock->sk, iov, iov_size);
2069out_put: 2058out:
2059 return err;
2060}
2061
2062/*
2063 * BSD recvmsg interface
2064 */
2065
2066SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
2067 unsigned int, flags)
2068{
2069 int fput_needed, err;
2070 struct msghdr msg_sys;
2071 struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed);
2072
2073 if (!sock)
2074 goto out;
2075
2076 err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0);
2077
2070 fput_light(sock->file, fput_needed); 2078 fput_light(sock->file, fput_needed);
2071out: 2079out:
2072 return err; 2080 return err;
2073} 2081}
2074 2082
2075#ifdef __ARCH_WANT_SYS_SOCKETCALL 2083/*
2084 * Linux recvmmsg interface
2085 */
2086
2087int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2088 unsigned int flags, struct timespec *timeout)
2089{
2090 int fput_needed, err, datagrams;
2091 struct socket *sock;
2092 struct mmsghdr __user *entry;
2093 struct compat_mmsghdr __user *compat_entry;
2094 struct msghdr msg_sys;
2095 struct timespec end_time;
2096
2097 if (timeout &&
2098 poll_select_set_timeout(&end_time, timeout->tv_sec,
2099 timeout->tv_nsec))
2100 return -EINVAL;
2101
2102 datagrams = 0;
2103
2104 sock = sockfd_lookup_light(fd, &err, &fput_needed);
2105 if (!sock)
2106 return err;
2107
2108 err = sock_error(sock->sk);
2109 if (err)
2110 goto out_put;
2111
2112 entry = mmsg;
2113 compat_entry = (struct compat_mmsghdr __user *)mmsg;
2114
2115 while (datagrams < vlen) {
2116 /*
2117 * No need to ask LSM for more than the first datagram.
2118 */
2119 if (MSG_CMSG_COMPAT & flags) {
2120 err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
2121 &msg_sys, flags, datagrams);
2122 if (err < 0)
2123 break;
2124 err = __put_user(err, &compat_entry->msg_len);
2125 ++compat_entry;
2126 } else {
2127 err = __sys_recvmsg(sock, (struct msghdr __user *)entry,
2128 &msg_sys, flags, datagrams);
2129 if (err < 0)
2130 break;
2131 err = put_user(err, &entry->msg_len);
2132 ++entry;
2133 }
2076 2134
2135 if (err)
2136 break;
2137 ++datagrams;
2138
2139 /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */
2140 if (flags & MSG_WAITFORONE)
2141 flags |= MSG_DONTWAIT;
2142
2143 if (timeout) {
2144 ktime_get_ts(timeout);
2145 *timeout = timespec_sub(end_time, *timeout);
2146 if (timeout->tv_sec < 0) {
2147 timeout->tv_sec = timeout->tv_nsec = 0;
2148 break;
2149 }
2150
2151 /* Timeout, return less than vlen datagrams */
2152 if (timeout->tv_nsec == 0 && timeout->tv_sec == 0)
2153 break;
2154 }
2155
2156 /* Out of band data, return right away */
2157 if (msg_sys.msg_flags & MSG_OOB)
2158 break;
2159 }
2160
2161out_put:
2162 fput_light(sock->file, fput_needed);
2163
2164 if (err == 0)
2165 return datagrams;
2166
2167 if (datagrams != 0) {
2168 /*
2169 * We may return less entries than requested (vlen) if the
2170 * sock is non block and there aren't enough datagrams...
2171 */
2172 if (err != -EAGAIN) {
2173 /*
2174 * ... or if recvmsg returns an error after we
2175 * received some datagrams, where we record the
2176 * error to return on the next call or if the
2177 * app asks about it using getsockopt(SO_ERROR).
2178 */
2179 sock->sk->sk_err = -err;
2180 }
2181
2182 return datagrams;
2183 }
2184
2185 return err;
2186}
2187
2188SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
2189 unsigned int, vlen, unsigned int, flags,
2190 struct timespec __user *, timeout)
2191{
2192 int datagrams;
2193 struct timespec timeout_sys;
2194
2195 if (!timeout)
2196 return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL);
2197
2198 if (copy_from_user(&timeout_sys, timeout, sizeof(timeout_sys)))
2199 return -EFAULT;
2200
2201 datagrams = __sys_recvmmsg(fd, mmsg, vlen, flags, &timeout_sys);
2202
2203 if (datagrams > 0 &&
2204 copy_to_user(timeout, &timeout_sys, sizeof(timeout_sys)))
2205 datagrams = -EFAULT;
2206
2207 return datagrams;
2208}
2209
2210#ifdef __ARCH_WANT_SYS_SOCKETCALL
2077/* Argument list sizes for sys_socketcall */ 2211/* Argument list sizes for sys_socketcall */
2078#define AL(x) ((x) * sizeof(unsigned long)) 2212#define AL(x) ((x) * sizeof(unsigned long))
2079static const unsigned char nargs[19]={ 2213static const unsigned char nargs[20] = {
2080 AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), 2214 AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
2081 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), 2215 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
2082 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3), 2216 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3),
2083 AL(4) 2217 AL(4),AL(5)
2084}; 2218};
2085 2219
2086#undef AL 2220#undef AL
@@ -2100,7 +2234,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
2100 int err; 2234 int err;
2101 unsigned int len; 2235 unsigned int len;
2102 2236
2103 if (call < 1 || call > SYS_ACCEPT4) 2237 if (call < 1 || call > SYS_RECVMMSG)
2104 return -EINVAL; 2238 return -EINVAL;
2105 2239
2106 len = nargs[call]; 2240 len = nargs[call];
@@ -2178,6 +2312,10 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
2178 case SYS_RECVMSG: 2312 case SYS_RECVMSG:
2179 err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]); 2313 err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]);
2180 break; 2314 break;
2315 case SYS_RECVMMSG:
2316 err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3],
2317 (struct timespec __user *)a[4]);
2318 break;
2181 case SYS_ACCEPT4: 2319 case SYS_ACCEPT4:
2182 err = sys_accept4(a0, (struct sockaddr __user *)a1, 2320 err = sys_accept4(a0, (struct sockaddr __user *)a1,
2183 (int __user *)a[2], a[3]); 2321 (int __user *)a[2], a[3]);
@@ -2300,6 +2438,552 @@ void socket_seq_show(struct seq_file *seq)
2300#endif /* CONFIG_PROC_FS */ 2438#endif /* CONFIG_PROC_FS */
2301 2439
2302#ifdef CONFIG_COMPAT 2440#ifdef CONFIG_COMPAT
2441static int do_siocgstamp(struct net *net, struct socket *sock,
2442 unsigned int cmd, struct compat_timeval __user *up)
2443{
2444 mm_segment_t old_fs = get_fs();
2445 struct timeval ktv;
2446 int err;
2447
2448 set_fs(KERNEL_DS);
2449 err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv);
2450 set_fs(old_fs);
2451 if (!err) {
2452 err = put_user(ktv.tv_sec, &up->tv_sec);
2453 err |= __put_user(ktv.tv_usec, &up->tv_usec);
2454 }
2455 return err;
2456}
2457
2458static int do_siocgstampns(struct net *net, struct socket *sock,
2459 unsigned int cmd, struct compat_timespec __user *up)
2460{
2461 mm_segment_t old_fs = get_fs();
2462 struct timespec kts;
2463 int err;
2464
2465 set_fs(KERNEL_DS);
2466 err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts);
2467 set_fs(old_fs);
2468 if (!err) {
2469 err = put_user(kts.tv_sec, &up->tv_sec);
2470 err |= __put_user(kts.tv_nsec, &up->tv_nsec);
2471 }
2472 return err;
2473}
2474
2475static int dev_ifname32(struct net *net, struct compat_ifreq __user *uifr32)
2476{
2477 struct ifreq __user *uifr;
2478 int err;
2479
2480 uifr = compat_alloc_user_space(sizeof(struct ifreq));
2481 if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
2482 return -EFAULT;
2483
2484 err = dev_ioctl(net, SIOCGIFNAME, uifr);
2485 if (err)
2486 return err;
2487
2488 if (copy_in_user(uifr32, uifr, sizeof(struct compat_ifreq)))
2489 return -EFAULT;
2490
2491 return 0;
2492}
2493
2494static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
2495{
2496 struct compat_ifconf ifc32;
2497 struct ifconf ifc;
2498 struct ifconf __user *uifc;
2499 struct compat_ifreq __user *ifr32;
2500 struct ifreq __user *ifr;
2501 unsigned int i, j;
2502 int err;
2503
2504 if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
2505 return -EFAULT;
2506
2507 if (ifc32.ifcbuf == 0) {
2508 ifc32.ifc_len = 0;
2509 ifc.ifc_len = 0;
2510 ifc.ifc_req = NULL;
2511 uifc = compat_alloc_user_space(sizeof(struct ifconf));
2512 } else {
2513 size_t len =((ifc32.ifc_len / sizeof (struct compat_ifreq)) + 1) *
2514 sizeof (struct ifreq);
2515 uifc = compat_alloc_user_space(sizeof(struct ifconf) + len);
2516 ifc.ifc_len = len;
2517 ifr = ifc.ifc_req = (void __user *)(uifc + 1);
2518 ifr32 = compat_ptr(ifc32.ifcbuf);
2519 for (i = 0; i < ifc32.ifc_len; i += sizeof (struct compat_ifreq)) {
2520 if (copy_in_user(ifr, ifr32, sizeof(struct compat_ifreq)))
2521 return -EFAULT;
2522 ifr++;
2523 ifr32++;
2524 }
2525 }
2526 if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
2527 return -EFAULT;
2528
2529 err = dev_ioctl(net, SIOCGIFCONF, uifc);
2530 if (err)
2531 return err;
2532
2533 if (copy_from_user(&ifc, uifc, sizeof(struct ifconf)))
2534 return -EFAULT;
2535
2536 ifr = ifc.ifc_req;
2537 ifr32 = compat_ptr(ifc32.ifcbuf);
2538 for (i = 0, j = 0;
2539 i + sizeof (struct compat_ifreq) <= ifc32.ifc_len && j < ifc.ifc_len;
2540 i += sizeof (struct compat_ifreq), j += sizeof (struct ifreq)) {
2541 if (copy_in_user(ifr32, ifr, sizeof (struct compat_ifreq)))
2542 return -EFAULT;
2543 ifr32++;
2544 ifr++;
2545 }
2546
2547 if (ifc32.ifcbuf == 0) {
2548 /* Translate from 64-bit structure multiple to
2549 * a 32-bit one.
2550 */
2551 i = ifc.ifc_len;
2552 i = ((i / sizeof(struct ifreq)) * sizeof(struct compat_ifreq));
2553 ifc32.ifc_len = i;
2554 } else {
2555 ifc32.ifc_len = i;
2556 }
2557 if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
2558 return -EFAULT;
2559
2560 return 0;
2561}
2562
2563static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
2564{
2565 struct ifreq __user *ifr;
2566 u32 data;
2567 void __user *datap;
2568
2569 ifr = compat_alloc_user_space(sizeof(*ifr));
2570
2571 if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
2572 return -EFAULT;
2573
2574 if (get_user(data, &ifr32->ifr_ifru.ifru_data))
2575 return -EFAULT;
2576
2577 datap = compat_ptr(data);
2578 if (put_user(datap, &ifr->ifr_ifru.ifru_data))
2579 return -EFAULT;
2580
2581 return dev_ioctl(net, SIOCETHTOOL, ifr);
2582}
2583
2584static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
2585{
2586 void __user *uptr;
2587 compat_uptr_t uptr32;
2588 struct ifreq __user *uifr;
2589
2590 uifr = compat_alloc_user_space(sizeof (*uifr));
2591 if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
2592 return -EFAULT;
2593
2594 if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
2595 return -EFAULT;
2596
2597 uptr = compat_ptr(uptr32);
2598
2599 if (put_user(uptr, &uifr->ifr_settings.ifs_ifsu.raw_hdlc))
2600 return -EFAULT;
2601
2602 return dev_ioctl(net, SIOCWANDEV, uifr);
2603}
2604
2605static int bond_ioctl(struct net *net, unsigned int cmd,
2606 struct compat_ifreq __user *ifr32)
2607{
2608 struct ifreq kifr;
2609 struct ifreq __user *uifr;
2610 mm_segment_t old_fs;
2611 int err;
2612 u32 data;
2613 void __user *datap;
2614
2615 switch (cmd) {
2616 case SIOCBONDENSLAVE:
2617 case SIOCBONDRELEASE:
2618 case SIOCBONDSETHWADDR:
2619 case SIOCBONDCHANGEACTIVE:
2620 if (copy_from_user(&kifr, ifr32, sizeof(struct compat_ifreq)))
2621 return -EFAULT;
2622
2623 old_fs = get_fs();
2624 set_fs (KERNEL_DS);
2625 err = dev_ioctl(net, cmd, &kifr);
2626 set_fs (old_fs);
2627
2628 return err;
2629 case SIOCBONDSLAVEINFOQUERY:
2630 case SIOCBONDINFOQUERY:
2631 uifr = compat_alloc_user_space(sizeof(*uifr));
2632 if (copy_in_user(&uifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
2633 return -EFAULT;
2634
2635 if (get_user(data, &ifr32->ifr_ifru.ifru_data))
2636 return -EFAULT;
2637
2638 datap = compat_ptr(data);
2639 if (put_user(datap, &uifr->ifr_ifru.ifru_data))
2640 return -EFAULT;
2641
2642 return dev_ioctl(net, cmd, uifr);
2643 default:
2644 return -EINVAL;
2645 };
2646}
2647
2648static int siocdevprivate_ioctl(struct net *net, unsigned int cmd,
2649 struct compat_ifreq __user *u_ifreq32)
2650{
2651 struct ifreq __user *u_ifreq64;
2652 char tmp_buf[IFNAMSIZ];
2653 void __user *data64;
2654 u32 data32;
2655
2656 if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
2657 IFNAMSIZ))
2658 return -EFAULT;
2659 if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
2660 return -EFAULT;
2661 data64 = compat_ptr(data32);
2662
2663 u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
2664
2665 /* Don't check these user accesses, just let that get trapped
2666 * in the ioctl handler instead.
2667 */
2668 if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
2669 IFNAMSIZ))
2670 return -EFAULT;
2671 if (__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
2672 return -EFAULT;
2673
2674 return dev_ioctl(net, cmd, u_ifreq64);
2675}
2676
2677static int dev_ifsioc(struct net *net, struct socket *sock,
2678 unsigned int cmd, struct compat_ifreq __user *uifr32)
2679{
2680 struct ifreq __user *uifr;
2681 int err;
2682
2683 uifr = compat_alloc_user_space(sizeof(*uifr));
2684 if (copy_in_user(uifr, uifr32, sizeof(*uifr32)))
2685 return -EFAULT;
2686
2687 err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr);
2688
2689 if (!err) {
2690 switch (cmd) {
2691 case SIOCGIFFLAGS:
2692 case SIOCGIFMETRIC:
2693 case SIOCGIFMTU:
2694 case SIOCGIFMEM:
2695 case SIOCGIFHWADDR:
2696 case SIOCGIFINDEX:
2697 case SIOCGIFADDR:
2698 case SIOCGIFBRDADDR:
2699 case SIOCGIFDSTADDR:
2700 case SIOCGIFNETMASK:
2701 case SIOCGIFPFLAGS:
2702 case SIOCGIFTXQLEN:
2703 case SIOCGMIIPHY:
2704 case SIOCGMIIREG:
2705 if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
2706 err = -EFAULT;
2707 break;
2708 }
2709 }
2710 return err;
2711}
2712
2713static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
2714 struct compat_ifreq __user *uifr32)
2715{
2716 struct ifreq ifr;
2717 struct compat_ifmap __user *uifmap32;
2718 mm_segment_t old_fs;
2719 int err;
2720
2721 uifmap32 = &uifr32->ifr_ifru.ifru_map;
2722 err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
2723 err |= __get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
2724 err |= __get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
2725 err |= __get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
2726 err |= __get_user(ifr.ifr_map.irq, &uifmap32->irq);
2727 err |= __get_user(ifr.ifr_map.dma, &uifmap32->dma);
2728 err |= __get_user(ifr.ifr_map.port, &uifmap32->port);
2729 if (err)
2730 return -EFAULT;
2731
2732 old_fs = get_fs();
2733 set_fs (KERNEL_DS);
2734 err = dev_ioctl(net, cmd, (void __user *)&ifr);
2735 set_fs (old_fs);
2736
2737 if (cmd == SIOCGIFMAP && !err) {
2738 err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
2739 err |= __put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
2740 err |= __put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
2741 err |= __put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
2742 err |= __put_user(ifr.ifr_map.irq, &uifmap32->irq);
2743 err |= __put_user(ifr.ifr_map.dma, &uifmap32->dma);
2744 err |= __put_user(ifr.ifr_map.port, &uifmap32->port);
2745 if (err)
2746 err = -EFAULT;
2747 }
2748 return err;
2749}
2750
2751static int compat_siocshwtstamp(struct net *net, struct compat_ifreq __user *uifr32)
2752{
2753 void __user *uptr;
2754 compat_uptr_t uptr32;
2755 struct ifreq __user *uifr;
2756
2757 uifr = compat_alloc_user_space(sizeof (*uifr));
2758 if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
2759 return -EFAULT;
2760
2761 if (get_user(uptr32, &uifr32->ifr_data))
2762 return -EFAULT;
2763
2764 uptr = compat_ptr(uptr32);
2765
2766 if (put_user(uptr, &uifr->ifr_data))
2767 return -EFAULT;
2768
2769 return dev_ioctl(net, SIOCSHWTSTAMP, uifr);
2770}
2771
2772struct rtentry32 {
2773 u32 rt_pad1;
2774 struct sockaddr rt_dst; /* target address */
2775 struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */
2776 struct sockaddr rt_genmask; /* target network mask (IP) */
2777 unsigned short rt_flags;
2778 short rt_pad2;
2779 u32 rt_pad3;
2780 unsigned char rt_tos;
2781 unsigned char rt_class;
2782 short rt_pad4;
2783 short rt_metric; /* +1 for binary compatibility! */
2784 /* char * */ u32 rt_dev; /* forcing the device at add */
2785 u32 rt_mtu; /* per route MTU/Window */
2786 u32 rt_window; /* Window clamping */
2787 unsigned short rt_irtt; /* Initial RTT */
2788};
2789
2790struct in6_rtmsg32 {
2791 struct in6_addr rtmsg_dst;
2792 struct in6_addr rtmsg_src;
2793 struct in6_addr rtmsg_gateway;
2794 u32 rtmsg_type;
2795 u16 rtmsg_dst_len;
2796 u16 rtmsg_src_len;
2797 u32 rtmsg_metric;
2798 u32 rtmsg_info;
2799 u32 rtmsg_flags;
2800 s32 rtmsg_ifindex;
2801};
2802
2803static int routing_ioctl(struct net *net, struct socket *sock,
2804 unsigned int cmd, void __user *argp)
2805{
2806 int ret;
2807 void *r = NULL;
2808 struct in6_rtmsg r6;
2809 struct rtentry r4;
2810 char devname[16];
2811 u32 rtdev;
2812 mm_segment_t old_fs = get_fs();
2813
2814 if (sock && sock->sk && sock->sk->sk_family == AF_INET6) { /* ipv6 */
2815 struct in6_rtmsg32 __user *ur6 = argp;
2816 ret = copy_from_user (&r6.rtmsg_dst, &(ur6->rtmsg_dst),
2817 3 * sizeof(struct in6_addr));
2818 ret |= __get_user (r6.rtmsg_type, &(ur6->rtmsg_type));
2819 ret |= __get_user (r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len));
2820 ret |= __get_user (r6.rtmsg_src_len, &(ur6->rtmsg_src_len));
2821 ret |= __get_user (r6.rtmsg_metric, &(ur6->rtmsg_metric));
2822 ret |= __get_user (r6.rtmsg_info, &(ur6->rtmsg_info));
2823 ret |= __get_user (r6.rtmsg_flags, &(ur6->rtmsg_flags));
2824 ret |= __get_user (r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex));
2825
2826 r = (void *) &r6;
2827 } else { /* ipv4 */
2828 struct rtentry32 __user *ur4 = argp;
2829 ret = copy_from_user (&r4.rt_dst, &(ur4->rt_dst),
2830 3 * sizeof(struct sockaddr));
2831 ret |= __get_user (r4.rt_flags, &(ur4->rt_flags));
2832 ret |= __get_user (r4.rt_metric, &(ur4->rt_metric));
2833 ret |= __get_user (r4.rt_mtu, &(ur4->rt_mtu));
2834 ret |= __get_user (r4.rt_window, &(ur4->rt_window));
2835 ret |= __get_user (r4.rt_irtt, &(ur4->rt_irtt));
2836 ret |= __get_user (rtdev, &(ur4->rt_dev));
2837 if (rtdev) {
2838 ret |= copy_from_user (devname, compat_ptr(rtdev), 15);
2839 r4.rt_dev = devname; devname[15] = 0;
2840 } else
2841 r4.rt_dev = NULL;
2842
2843 r = (void *) &r4;
2844 }
2845
2846 if (ret) {
2847 ret = -EFAULT;
2848 goto out;
2849 }
2850
2851 set_fs (KERNEL_DS);
2852 ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r);
2853 set_fs (old_fs);
2854
2855out:
2856 return ret;
2857}
2858
2859/* Since old style bridge ioctl's endup using SIOCDEVPRIVATE
2860 * for some operations; this forces use of the newer bridge-utils that
2861 * use compatiable ioctls
2862 */
2863static int old_bridge_ioctl(compat_ulong_t __user *argp)
2864{
2865 compat_ulong_t tmp;
2866
2867 if (get_user(tmp, argp))
2868 return -EFAULT;
2869 if (tmp == BRCTL_GET_VERSION)
2870 return BRCTL_VERSION + 1;
2871 return -EINVAL;
2872}
2873
2874static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
2875 unsigned int cmd, unsigned long arg)
2876{
2877 void __user *argp = compat_ptr(arg);
2878 struct sock *sk = sock->sk;
2879 struct net *net = sock_net(sk);
2880
2881 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
2882 return siocdevprivate_ioctl(net, cmd, argp);
2883
2884 switch (cmd) {
2885 case SIOCSIFBR:
2886 case SIOCGIFBR:
2887 return old_bridge_ioctl(argp);
2888 case SIOCGIFNAME:
2889 return dev_ifname32(net, argp);
2890 case SIOCGIFCONF:
2891 return dev_ifconf(net, argp);
2892 case SIOCETHTOOL:
2893 return ethtool_ioctl(net, argp);
2894 case SIOCWANDEV:
2895 return compat_siocwandev(net, argp);
2896 case SIOCGIFMAP:
2897 case SIOCSIFMAP:
2898 return compat_sioc_ifmap(net, cmd, argp);
2899 case SIOCBONDENSLAVE:
2900 case SIOCBONDRELEASE:
2901 case SIOCBONDSETHWADDR:
2902 case SIOCBONDSLAVEINFOQUERY:
2903 case SIOCBONDINFOQUERY:
2904 case SIOCBONDCHANGEACTIVE:
2905 return bond_ioctl(net, cmd, argp);
2906 case SIOCADDRT:
2907 case SIOCDELRT:
2908 return routing_ioctl(net, sock, cmd, argp);
2909 case SIOCGSTAMP:
2910 return do_siocgstamp(net, sock, cmd, argp);
2911 case SIOCGSTAMPNS:
2912 return do_siocgstampns(net, sock, cmd, argp);
2913 case SIOCSHWTSTAMP:
2914 return compat_siocshwtstamp(net, argp);
2915
2916 case FIOSETOWN:
2917 case SIOCSPGRP:
2918 case FIOGETOWN:
2919 case SIOCGPGRP:
2920 case SIOCBRADDBR:
2921 case SIOCBRDELBR:
2922 case SIOCGIFVLAN:
2923 case SIOCSIFVLAN:
2924 case SIOCADDDLCI:
2925 case SIOCDELDLCI:
2926 return sock_ioctl(file, cmd, arg);
2927
2928 case SIOCGIFFLAGS:
2929 case SIOCSIFFLAGS:
2930 case SIOCGIFMETRIC:
2931 case SIOCSIFMETRIC:
2932 case SIOCGIFMTU:
2933 case SIOCSIFMTU:
2934 case SIOCGIFMEM:
2935 case SIOCSIFMEM:
2936 case SIOCGIFHWADDR:
2937 case SIOCSIFHWADDR:
2938 case SIOCADDMULTI:
2939 case SIOCDELMULTI:
2940 case SIOCGIFINDEX:
2941 case SIOCGIFADDR:
2942 case SIOCSIFADDR:
2943 case SIOCSIFHWBROADCAST:
2944 case SIOCDIFADDR:
2945 case SIOCGIFBRDADDR:
2946 case SIOCSIFBRDADDR:
2947 case SIOCGIFDSTADDR:
2948 case SIOCSIFDSTADDR:
2949 case SIOCGIFNETMASK:
2950 case SIOCSIFNETMASK:
2951 case SIOCSIFPFLAGS:
2952 case SIOCGIFPFLAGS:
2953 case SIOCGIFTXQLEN:
2954 case SIOCSIFTXQLEN:
2955 case SIOCBRADDIF:
2956 case SIOCBRDELIF:
2957 case SIOCSIFNAME:
2958 case SIOCGMIIPHY:
2959 case SIOCGMIIREG:
2960 case SIOCSMIIREG:
2961 return dev_ifsioc(net, sock, cmd, argp);
2962
2963 case SIOCSARP:
2964 case SIOCGARP:
2965 case SIOCDARP:
2966 case SIOCATMARK:
2967 return sock_do_ioctl(net, sock, cmd, arg);
2968 }
2969
2970 /* Prevent warning from compat_sys_ioctl, these always
2971 * result in -EINVAL in the native case anyway. */
2972 switch (cmd) {
2973 case SIOCRTMSG:
2974 case SIOCGIFCOUNT:
2975 case SIOCSRARP:
2976 case SIOCGRARP:
2977 case SIOCDRARP:
2978 case SIOCSIFLINK:
2979 case SIOCGIFSLAVE:
2980 case SIOCSIFSLAVE:
2981 return -EINVAL;
2982 }
2983
2984 return -ENOIOCTLCMD;
2985}
2986
2303static long compat_sock_ioctl(struct file *file, unsigned cmd, 2987static long compat_sock_ioctl(struct file *file, unsigned cmd,
2304 unsigned long arg) 2988 unsigned long arg)
2305{ 2989{
@@ -2318,6 +3002,9 @@ static long compat_sock_ioctl(struct file *file, unsigned cmd,
2318 (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)) 3002 (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
2319 ret = compat_wext_handle_ioctl(net, cmd, arg); 3003 ret = compat_wext_handle_ioctl(net, cmd, arg);
2320 3004
3005 if (ret == -ENOIOCTLCMD)
3006 ret = compat_sock_ioctl_trans(file, sock, cmd, arg);
3007
2321 return ret; 3008 return ret;
2322} 3009}
2323#endif 3010#endif