aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c373
1 files changed, 223 insertions, 150 deletions
diff --git a/net/socket.c b/net/socket.c
index a00851f981db..b13042f68c02 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -68,6 +68,7 @@
68#include <linux/netdevice.h> 68#include <linux/netdevice.h>
69#include <linux/proc_fs.h> 69#include <linux/proc_fs.h>
70#include <linux/seq_file.h> 70#include <linux/seq_file.h>
71#include <linux/mutex.h>
71#include <linux/wanrouter.h> 72#include <linux/wanrouter.h>
72#include <linux/if_bridge.h> 73#include <linux/if_bridge.h>
73#include <linux/if_frad.h> 74#include <linux/if_frad.h>
@@ -84,10 +85,7 @@
84#include <linux/compat.h> 85#include <linux/compat.h>
85#include <linux/kmod.h> 86#include <linux/kmod.h>
86#include <linux/audit.h> 87#include <linux/audit.h>
87 88#include <linux/wireless.h>
88#ifdef CONFIG_NET_RADIO
89#include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
90#endif /* CONFIG_NET_RADIO */
91 89
92#include <asm/uaccess.h> 90#include <asm/uaccess.h>
93#include <asm/unistd.h> 91#include <asm/unistd.h>
@@ -109,6 +107,10 @@ static unsigned int sock_poll(struct file *file,
109 struct poll_table_struct *wait); 107 struct poll_table_struct *wait);
110static long sock_ioctl(struct file *file, 108static long sock_ioctl(struct file *file,
111 unsigned int cmd, unsigned long arg); 109 unsigned int cmd, unsigned long arg);
110#ifdef CONFIG_COMPAT
111static long compat_sock_ioctl(struct file *file,
112 unsigned int cmd, unsigned long arg);
113#endif
112static int sock_fasync(int fd, struct file *filp, int on); 114static int sock_fasync(int fd, struct file *filp, int on);
113static ssize_t sock_readv(struct file *file, const struct iovec *vector, 115static ssize_t sock_readv(struct file *file, const struct iovec *vector,
114 unsigned long count, loff_t *ppos); 116 unsigned long count, loff_t *ppos);
@@ -117,6 +119,9 @@ static ssize_t sock_writev(struct file *file, const struct iovec *vector,
117static ssize_t sock_sendpage(struct file *file, struct page *page, 119static ssize_t sock_sendpage(struct file *file, struct page *page,
118 int offset, size_t size, loff_t *ppos, int more); 120 int offset, size_t size, loff_t *ppos, int more);
119 121
122extern ssize_t generic_splice_sendpage(struct inode *inode, struct file *out,
123 size_t len, unsigned int flags);
124
120 125
121/* 126/*
122 * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear 127 * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
@@ -130,13 +135,17 @@ static struct file_operations socket_file_ops = {
130 .aio_write = sock_aio_write, 135 .aio_write = sock_aio_write,
131 .poll = sock_poll, 136 .poll = sock_poll,
132 .unlocked_ioctl = sock_ioctl, 137 .unlocked_ioctl = sock_ioctl,
138#ifdef CONFIG_COMPAT
139 .compat_ioctl = compat_sock_ioctl,
140#endif
133 .mmap = sock_mmap, 141 .mmap = sock_mmap,
134 .open = sock_no_open, /* special open code to disallow open via /proc */ 142 .open = sock_no_open, /* special open code to disallow open via /proc */
135 .release = sock_close, 143 .release = sock_close,
136 .fasync = sock_fasync, 144 .fasync = sock_fasync,
137 .readv = sock_readv, 145 .readv = sock_readv,
138 .writev = sock_writev, 146 .writev = sock_writev,
139 .sendpage = sock_sendpage 147 .sendpage = sock_sendpage,
148 .splice_write = generic_splice_sendpage,
140}; 149};
141 150
142/* 151/*
@@ -314,7 +323,8 @@ static int init_inodecache(void)
314{ 323{
315 sock_inode_cachep = kmem_cache_create("sock_inode_cache", 324 sock_inode_cachep = kmem_cache_create("sock_inode_cache",
316 sizeof(struct socket_alloc), 325 sizeof(struct socket_alloc),
317 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, 326 0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
327 SLAB_MEM_SPREAD),
318 init_once, NULL); 328 init_once, NULL);
319 if (sock_inode_cachep == NULL) 329 if (sock_inode_cachep == NULL)
320 return -ENOMEM; 330 return -ENOMEM;
@@ -351,8 +361,8 @@ static struct dentry_operations sockfs_dentry_operations = {
351/* 361/*
352 * Obtains the first available file descriptor and sets it up for use. 362 * Obtains the first available file descriptor and sets it up for use.
353 * 363 *
354 * This function creates file structure and maps it to fd space 364 * These functions create file structures and maps them to fd space
355 * of current process. On success it returns file descriptor 365 * of the current process. On success it returns file descriptor
356 * and file struct implicitly stored in sock->file. 366 * and file struct implicitly stored in sock->file.
357 * Note that another thread may close file descriptor before we return 367 * Note that another thread may close file descriptor before we return
358 * from this function. We use the fact that now we do not refer 368 * from this function. We use the fact that now we do not refer
@@ -365,53 +375,90 @@ static struct dentry_operations sockfs_dentry_operations = {
365 * but we take care of internal coherence yet. 375 * but we take care of internal coherence yet.
366 */ 376 */
367 377
368int sock_map_fd(struct socket *sock) 378static int sock_alloc_fd(struct file **filep)
369{ 379{
370 int fd; 380 int fd;
371 struct qstr this;
372 char name[32];
373
374 /*
375 * Find a file descriptor suitable for return to the user.
376 */
377 381
378 fd = get_unused_fd(); 382 fd = get_unused_fd();
379 if (fd >= 0) { 383 if (likely(fd >= 0)) {
380 struct file *file = get_empty_filp(); 384 struct file *file = get_empty_filp();
381 385
382 if (!file) { 386 *filep = file;
387 if (unlikely(!file)) {
383 put_unused_fd(fd); 388 put_unused_fd(fd);
384 fd = -ENFILE; 389 return -ENFILE;
385 goto out;
386 } 390 }
391 } else
392 *filep = NULL;
393 return fd;
394}
387 395
388 this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino); 396static int sock_attach_fd(struct socket *sock, struct file *file)
389 this.name = name; 397{
390 this.hash = SOCK_INODE(sock)->i_ino; 398 struct qstr this;
399 char name[32];
400
401 this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
402 this.name = name;
403 this.hash = SOCK_INODE(sock)->i_ino;
404
405 file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
406 if (unlikely(!file->f_dentry))
407 return -ENOMEM;
408
409 file->f_dentry->d_op = &sockfs_dentry_operations;
410 d_add(file->f_dentry, SOCK_INODE(sock));
411 file->f_vfsmnt = mntget(sock_mnt);
412 file->f_mapping = file->f_dentry->d_inode->i_mapping;
413
414 sock->file = file;
415 file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
416 file->f_mode = FMODE_READ | FMODE_WRITE;
417 file->f_flags = O_RDWR;
418 file->f_pos = 0;
419 file->private_data = sock;
420
421 return 0;
422}
423
424int sock_map_fd(struct socket *sock)
425{
426 struct file *newfile;
427 int fd = sock_alloc_fd(&newfile);
391 428
392 file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this); 429 if (likely(fd >= 0)) {
393 if (!file->f_dentry) { 430 int err = sock_attach_fd(sock, newfile);
394 put_filp(file); 431
432 if (unlikely(err < 0)) {
433 put_filp(newfile);
395 put_unused_fd(fd); 434 put_unused_fd(fd);
396 fd = -ENOMEM; 435 return err;
397 goto out;
398 } 436 }
399 file->f_dentry->d_op = &sockfs_dentry_operations; 437 fd_install(fd, newfile);
400 d_add(file->f_dentry, SOCK_INODE(sock)); 438 }
401 file->f_vfsmnt = mntget(sock_mnt); 439 return fd;
402 file->f_mapping = file->f_dentry->d_inode->i_mapping; 440}
403 441
404 sock->file = file; 442static struct socket *sock_from_file(struct file *file, int *err)
405 file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops; 443{
406 file->f_mode = FMODE_READ | FMODE_WRITE; 444 struct inode *inode;
407 file->f_flags = O_RDWR; 445 struct socket *sock;
408 file->f_pos = 0; 446
409 file->private_data = sock; 447 if (file->f_op == &socket_file_ops)
410 fd_install(fd, file); 448 return file->private_data; /* set in sock_map_fd */
449
450 inode = file->f_dentry->d_inode;
451 if (!S_ISSOCK(inode->i_mode)) {
452 *err = -ENOTSOCK;
453 return NULL;
411 } 454 }
412 455
413out: 456 sock = SOCKET_I(inode);
414 return fd; 457 if (sock->file != file) {
458 printk(KERN_ERR "socki_lookup: socket file changed!\n");
459 sock->file = file;
460 }
461 return sock;
415} 462}
416 463
417/** 464/**
@@ -430,31 +477,31 @@ out:
430struct socket *sockfd_lookup(int fd, int *err) 477struct socket *sockfd_lookup(int fd, int *err)
431{ 478{
432 struct file *file; 479 struct file *file;
433 struct inode *inode;
434 struct socket *sock; 480 struct socket *sock;
435 481
436 if (!(file = fget(fd))) 482 if (!(file = fget(fd))) {
437 {
438 *err = -EBADF; 483 *err = -EBADF;
439 return NULL; 484 return NULL;
440 } 485 }
441 486 sock = sock_from_file(file, err);
442 if (file->f_op == &socket_file_ops) 487 if (!sock)
443 return file->private_data; /* set in sock_map_fd */
444
445 inode = file->f_dentry->d_inode;
446 if (!S_ISSOCK(inode->i_mode)) {
447 *err = -ENOTSOCK;
448 fput(file); 488 fput(file);
449 return NULL; 489 return sock;
450 } 490}
451 491
452 sock = SOCKET_I(inode); 492static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
453 if (sock->file != file) { 493{
454 printk(KERN_ERR "socki_lookup: socket file changed!\n"); 494 struct file *file;
455 sock->file = file; 495 struct socket *sock;
496
497 file = fget_light(fd, fput_needed);
498 if (file) {
499 sock = sock_from_file(file, err);
500 if (sock)
501 return sock;
502 fput_light(file, *fput_needed);
456 } 503 }
457 return sock; 504 return NULL;
458} 505}
459 506
460/** 507/**
@@ -496,7 +543,7 @@ static int sock_no_open(struct inode *irrelevant, struct file *dontcare)
496 return -ENXIO; 543 return -ENXIO;
497} 544}
498 545
499struct file_operations bad_sock_fops = { 546const struct file_operations bad_sock_fops = {
500 .owner = THIS_MODULE, 547 .owner = THIS_MODULE,
501 .open = sock_no_open, 548 .open = sock_no_open,
502}; 549};
@@ -792,36 +839,36 @@ static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf,
792 * with module unload. 839 * with module unload.
793 */ 840 */
794 841
795static DECLARE_MUTEX(br_ioctl_mutex); 842static DEFINE_MUTEX(br_ioctl_mutex);
796static int (*br_ioctl_hook)(unsigned int cmd, void __user *arg) = NULL; 843static int (*br_ioctl_hook)(unsigned int cmd, void __user *arg) = NULL;
797 844
798void brioctl_set(int (*hook)(unsigned int, void __user *)) 845void brioctl_set(int (*hook)(unsigned int, void __user *))
799{ 846{
800 down(&br_ioctl_mutex); 847 mutex_lock(&br_ioctl_mutex);
801 br_ioctl_hook = hook; 848 br_ioctl_hook = hook;
802 up(&br_ioctl_mutex); 849 mutex_unlock(&br_ioctl_mutex);
803} 850}
804EXPORT_SYMBOL(brioctl_set); 851EXPORT_SYMBOL(brioctl_set);
805 852
806static DECLARE_MUTEX(vlan_ioctl_mutex); 853static DEFINE_MUTEX(vlan_ioctl_mutex);
807static int (*vlan_ioctl_hook)(void __user *arg); 854static int (*vlan_ioctl_hook)(void __user *arg);
808 855
809void vlan_ioctl_set(int (*hook)(void __user *)) 856void vlan_ioctl_set(int (*hook)(void __user *))
810{ 857{
811 down(&vlan_ioctl_mutex); 858 mutex_lock(&vlan_ioctl_mutex);
812 vlan_ioctl_hook = hook; 859 vlan_ioctl_hook = hook;
813 up(&vlan_ioctl_mutex); 860 mutex_unlock(&vlan_ioctl_mutex);
814} 861}
815EXPORT_SYMBOL(vlan_ioctl_set); 862EXPORT_SYMBOL(vlan_ioctl_set);
816 863
817static DECLARE_MUTEX(dlci_ioctl_mutex); 864static DEFINE_MUTEX(dlci_ioctl_mutex);
818static int (*dlci_ioctl_hook)(unsigned int, void __user *); 865static int (*dlci_ioctl_hook)(unsigned int, void __user *);
819 866
820void dlci_ioctl_set(int (*hook)(unsigned int, void __user *)) 867void dlci_ioctl_set(int (*hook)(unsigned int, void __user *))
821{ 868{
822 down(&dlci_ioctl_mutex); 869 mutex_lock(&dlci_ioctl_mutex);
823 dlci_ioctl_hook = hook; 870 dlci_ioctl_hook = hook;
824 up(&dlci_ioctl_mutex); 871 mutex_unlock(&dlci_ioctl_mutex);
825} 872}
826EXPORT_SYMBOL(dlci_ioctl_set); 873EXPORT_SYMBOL(dlci_ioctl_set);
827 874
@@ -840,11 +887,11 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
840 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { 887 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
841 err = dev_ioctl(cmd, argp); 888 err = dev_ioctl(cmd, argp);
842 } else 889 } else
843#ifdef WIRELESS_EXT 890#ifdef CONFIG_WIRELESS_EXT
844 if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { 891 if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
845 err = dev_ioctl(cmd, argp); 892 err = dev_ioctl(cmd, argp);
846 } else 893 } else
847#endif /* WIRELESS_EXT */ 894#endif /* CONFIG_WIRELESS_EXT */
848 switch (cmd) { 895 switch (cmd) {
849 case FIOSETOWN: 896 case FIOSETOWN:
850 case SIOCSPGRP: 897 case SIOCSPGRP:
@@ -865,10 +912,10 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
865 if (!br_ioctl_hook) 912 if (!br_ioctl_hook)
866 request_module("bridge"); 913 request_module("bridge");
867 914
868 down(&br_ioctl_mutex); 915 mutex_lock(&br_ioctl_mutex);
869 if (br_ioctl_hook) 916 if (br_ioctl_hook)
870 err = br_ioctl_hook(cmd, argp); 917 err = br_ioctl_hook(cmd, argp);
871 up(&br_ioctl_mutex); 918 mutex_unlock(&br_ioctl_mutex);
872 break; 919 break;
873 case SIOCGIFVLAN: 920 case SIOCGIFVLAN:
874 case SIOCSIFVLAN: 921 case SIOCSIFVLAN:
@@ -876,10 +923,10 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
876 if (!vlan_ioctl_hook) 923 if (!vlan_ioctl_hook)
877 request_module("8021q"); 924 request_module("8021q");
878 925
879 down(&vlan_ioctl_mutex); 926 mutex_lock(&vlan_ioctl_mutex);
880 if (vlan_ioctl_hook) 927 if (vlan_ioctl_hook)
881 err = vlan_ioctl_hook(argp); 928 err = vlan_ioctl_hook(argp);
882 up(&vlan_ioctl_mutex); 929 mutex_unlock(&vlan_ioctl_mutex);
883 break; 930 break;
884 case SIOCGIFDIVERT: 931 case SIOCGIFDIVERT:
885 case SIOCSIFDIVERT: 932 case SIOCSIFDIVERT:
@@ -893,9 +940,9 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
893 request_module("dlci"); 940 request_module("dlci");
894 941
895 if (dlci_ioctl_hook) { 942 if (dlci_ioctl_hook) {
896 down(&dlci_ioctl_mutex); 943 mutex_lock(&dlci_ioctl_mutex);
897 err = dlci_ioctl_hook(cmd, argp); 944 err = dlci_ioctl_hook(cmd, argp);
898 up(&dlci_ioctl_mutex); 945 mutex_unlock(&dlci_ioctl_mutex);
899 } 946 }
900 break; 947 break;
901 default: 948 default:
@@ -1289,19 +1336,17 @@ asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
1289{ 1336{
1290 struct socket *sock; 1337 struct socket *sock;
1291 char address[MAX_SOCK_ADDR]; 1338 char address[MAX_SOCK_ADDR];
1292 int err; 1339 int err, fput_needed;
1293 1340
1294 if((sock = sockfd_lookup(fd,&err))!=NULL) 1341 if((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL)
1295 { 1342 {
1296 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) { 1343 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
1297 err = security_socket_bind(sock, (struct sockaddr *)address, addrlen); 1344 err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
1298 if (err) { 1345 if (!err)
1299 sockfd_put(sock); 1346 err = sock->ops->bind(sock,
1300 return err; 1347 (struct sockaddr *)address, addrlen);
1301 }
1302 err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen);
1303 } 1348 }
1304 sockfd_put(sock); 1349 fput_light(sock->file, fput_needed);
1305 } 1350 }
1306 return err; 1351 return err;
1307} 1352}
@@ -1318,20 +1363,17 @@ int sysctl_somaxconn = SOMAXCONN;
1318asmlinkage long sys_listen(int fd, int backlog) 1363asmlinkage long sys_listen(int fd, int backlog)
1319{ 1364{
1320 struct socket *sock; 1365 struct socket *sock;
1321 int err; 1366 int err, fput_needed;
1322 1367
1323 if ((sock = sockfd_lookup(fd, &err)) != NULL) { 1368 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) {
1324 if ((unsigned) backlog > sysctl_somaxconn) 1369 if ((unsigned) backlog > sysctl_somaxconn)
1325 backlog = sysctl_somaxconn; 1370 backlog = sysctl_somaxconn;
1326 1371
1327 err = security_socket_listen(sock, backlog); 1372 err = security_socket_listen(sock, backlog);
1328 if (err) { 1373 if (!err)
1329 sockfd_put(sock); 1374 err = sock->ops->listen(sock, backlog);
1330 return err;
1331 }
1332 1375
1333 err=sock->ops->listen(sock, backlog); 1376 fput_light(sock->file, fput_needed);
1334 sockfd_put(sock);
1335 } 1377 }
1336 return err; 1378 return err;
1337} 1379}
@@ -1352,10 +1394,11 @@ asmlinkage long sys_listen(int fd, int backlog)
1352asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen) 1394asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen)
1353{ 1395{
1354 struct socket *sock, *newsock; 1396 struct socket *sock, *newsock;
1355 int err, len; 1397 struct file *newfile;
1398 int err, len, newfd, fput_needed;
1356 char address[MAX_SOCK_ADDR]; 1399 char address[MAX_SOCK_ADDR];
1357 1400
1358 sock = sockfd_lookup(fd, &err); 1401 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1359 if (!sock) 1402 if (!sock)
1360 goto out; 1403 goto out;
1361 1404
@@ -1372,35 +1415,48 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _
1372 */ 1415 */
1373 __module_get(newsock->ops->owner); 1416 __module_get(newsock->ops->owner);
1374 1417
1418 newfd = sock_alloc_fd(&newfile);
1419 if (unlikely(newfd < 0)) {
1420 err = newfd;
1421 goto out_release;
1422 }
1423
1424 err = sock_attach_fd(newsock, newfile);
1425 if (err < 0)
1426 goto out_fd;
1427
1375 err = security_socket_accept(sock, newsock); 1428 err = security_socket_accept(sock, newsock);
1376 if (err) 1429 if (err)
1377 goto out_release; 1430 goto out_fd;
1378 1431
1379 err = sock->ops->accept(sock, newsock, sock->file->f_flags); 1432 err = sock->ops->accept(sock, newsock, sock->file->f_flags);
1380 if (err < 0) 1433 if (err < 0)
1381 goto out_release; 1434 goto out_fd;
1382 1435
1383 if (upeer_sockaddr) { 1436 if (upeer_sockaddr) {
1384 if(newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 2)<0) { 1437 if(newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 2)<0) {
1385 err = -ECONNABORTED; 1438 err = -ECONNABORTED;
1386 goto out_release; 1439 goto out_fd;
1387 } 1440 }
1388 err = move_addr_to_user(address, len, upeer_sockaddr, upeer_addrlen); 1441 err = move_addr_to_user(address, len, upeer_sockaddr, upeer_addrlen);
1389 if (err < 0) 1442 if (err < 0)
1390 goto out_release; 1443 goto out_fd;
1391 } 1444 }
1392 1445
1393 /* File flags are not inherited via accept() unlike another OSes. */ 1446 /* File flags are not inherited via accept() unlike another OSes. */
1394 1447
1395 if ((err = sock_map_fd(newsock)) < 0) 1448 fd_install(newfd, newfile);
1396 goto out_release; 1449 err = newfd;
1397 1450
1398 security_socket_post_accept(sock, newsock); 1451 security_socket_post_accept(sock, newsock);
1399 1452
1400out_put: 1453out_put:
1401 sockfd_put(sock); 1454 fput_light(sock->file, fput_needed);
1402out: 1455out:
1403 return err; 1456 return err;
1457out_fd:
1458 put_filp(newfile);
1459 put_unused_fd(newfd);
1404out_release: 1460out_release:
1405 sock_release(newsock); 1461 sock_release(newsock);
1406 goto out_put; 1462 goto out_put;
@@ -1423,9 +1479,9 @@ asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrl
1423{ 1479{
1424 struct socket *sock; 1480 struct socket *sock;
1425 char address[MAX_SOCK_ADDR]; 1481 char address[MAX_SOCK_ADDR];
1426 int err; 1482 int err, fput_needed;
1427 1483
1428 sock = sockfd_lookup(fd, &err); 1484 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1429 if (!sock) 1485 if (!sock)
1430 goto out; 1486 goto out;
1431 err = move_addr_to_kernel(uservaddr, addrlen, address); 1487 err = move_addr_to_kernel(uservaddr, addrlen, address);
@@ -1439,7 +1495,7 @@ asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrl
1439 err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen, 1495 err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
1440 sock->file->f_flags); 1496 sock->file->f_flags);
1441out_put: 1497out_put:
1442 sockfd_put(sock); 1498 fput_light(sock->file, fput_needed);
1443out: 1499out:
1444 return err; 1500 return err;
1445} 1501}
@@ -1453,9 +1509,9 @@ asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int _
1453{ 1509{
1454 struct socket *sock; 1510 struct socket *sock;
1455 char address[MAX_SOCK_ADDR]; 1511 char address[MAX_SOCK_ADDR];
1456 int len, err; 1512 int len, err, fput_needed;
1457 1513
1458 sock = sockfd_lookup(fd, &err); 1514 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1459 if (!sock) 1515 if (!sock)
1460 goto out; 1516 goto out;
1461 1517
@@ -1469,7 +1525,7 @@ asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int _
1469 err = move_addr_to_user(address, len, usockaddr, usockaddr_len); 1525 err = move_addr_to_user(address, len, usockaddr, usockaddr_len);
1470 1526
1471out_put: 1527out_put:
1472 sockfd_put(sock); 1528 fput_light(sock->file, fput_needed);
1473out: 1529out:
1474 return err; 1530 return err;
1475} 1531}
@@ -1483,20 +1539,19 @@ asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int _
1483{ 1539{
1484 struct socket *sock; 1540 struct socket *sock;
1485 char address[MAX_SOCK_ADDR]; 1541 char address[MAX_SOCK_ADDR];
1486 int len, err; 1542 int len, err, fput_needed;
1487 1543
1488 if ((sock = sockfd_lookup(fd, &err))!=NULL) 1544 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) {
1489 {
1490 err = security_socket_getpeername(sock); 1545 err = security_socket_getpeername(sock);
1491 if (err) { 1546 if (err) {
1492 sockfd_put(sock); 1547 fput_light(sock->file, fput_needed);
1493 return err; 1548 return err;
1494 } 1549 }
1495 1550
1496 err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1); 1551 err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1);
1497 if (!err) 1552 if (!err)
1498 err=move_addr_to_user(address,len, usockaddr, usockaddr_len); 1553 err=move_addr_to_user(address,len, usockaddr, usockaddr_len);
1499 sockfd_put(sock); 1554 fput_light(sock->file, fput_needed);
1500 } 1555 }
1501 return err; 1556 return err;
1502} 1557}
@@ -1515,10 +1570,16 @@ asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flag
1515 int err; 1570 int err;
1516 struct msghdr msg; 1571 struct msghdr msg;
1517 struct iovec iov; 1572 struct iovec iov;
1518 1573 int fput_needed;
1519 sock = sockfd_lookup(fd, &err); 1574 struct file *sock_file;
1575
1576 sock_file = fget_light(fd, &fput_needed);
1577 if (!sock_file)
1578 return -EBADF;
1579
1580 sock = sock_from_file(sock_file, &err);
1520 if (!sock) 1581 if (!sock)
1521 goto out; 1582 goto out_put;
1522 iov.iov_base=buff; 1583 iov.iov_base=buff;
1523 iov.iov_len=len; 1584 iov.iov_len=len;
1524 msg.msg_name=NULL; 1585 msg.msg_name=NULL;
@@ -1527,8 +1588,7 @@ asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flag
1527 msg.msg_control=NULL; 1588 msg.msg_control=NULL;
1528 msg.msg_controllen=0; 1589 msg.msg_controllen=0;
1529 msg.msg_namelen=0; 1590 msg.msg_namelen=0;
1530 if(addr) 1591 if (addr) {
1531 {
1532 err = move_addr_to_kernel(addr, addr_len, address); 1592 err = move_addr_to_kernel(addr, addr_len, address);
1533 if (err < 0) 1593 if (err < 0)
1534 goto out_put; 1594 goto out_put;
@@ -1541,8 +1601,7 @@ asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flag
1541 err = sock_sendmsg(sock, &msg, len); 1601 err = sock_sendmsg(sock, &msg, len);
1542 1602
1543out_put: 1603out_put:
1544 sockfd_put(sock); 1604 fput_light(sock_file, fput_needed);
1545out:
1546 return err; 1605 return err;
1547} 1606}
1548 1607
@@ -1569,8 +1628,14 @@ asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned f
1569 struct msghdr msg; 1628 struct msghdr msg;
1570 char address[MAX_SOCK_ADDR]; 1629 char address[MAX_SOCK_ADDR];
1571 int err,err2; 1630 int err,err2;
1631 struct file *sock_file;
1632 int fput_needed;
1633
1634 sock_file = fget_light(fd, &fput_needed);
1635 if (!sock_file)
1636 return -EBADF;
1572 1637
1573 sock = sockfd_lookup(fd, &err); 1638 sock = sock_from_file(sock_file, &err);
1574 if (!sock) 1639 if (!sock)
1575 goto out; 1640 goto out;
1576 1641
@@ -1592,8 +1657,8 @@ asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned f
1592 if(err2<0) 1657 if(err2<0)
1593 err=err2; 1658 err=err2;
1594 } 1659 }
1595 sockfd_put(sock);
1596out: 1660out:
1661 fput_light(sock_file, fput_needed);
1597 return err; 1662 return err;
1598} 1663}
1599 1664
@@ -1613,25 +1678,24 @@ asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags
1613 1678
1614asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen) 1679asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen)
1615{ 1680{
1616 int err; 1681 int err, fput_needed;
1617 struct socket *sock; 1682 struct socket *sock;
1618 1683
1619 if (optlen < 0) 1684 if (optlen < 0)
1620 return -EINVAL; 1685 return -EINVAL;
1621 1686
1622 if ((sock = sockfd_lookup(fd, &err))!=NULL) 1687 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL)
1623 { 1688 {
1624 err = security_socket_setsockopt(sock,level,optname); 1689 err = security_socket_setsockopt(sock,level,optname);
1625 if (err) { 1690 if (err)
1626 sockfd_put(sock); 1691 goto out_put;
1627 return err;
1628 }
1629 1692
1630 if (level == SOL_SOCKET) 1693 if (level == SOL_SOCKET)
1631 err=sock_setsockopt(sock,level,optname,optval,optlen); 1694 err=sock_setsockopt(sock,level,optname,optval,optlen);
1632 else 1695 else
1633 err=sock->ops->setsockopt(sock, level, optname, optval, optlen); 1696 err=sock->ops->setsockopt(sock, level, optname, optval, optlen);
1634 sockfd_put(sock); 1697out_put:
1698 fput_light(sock->file, fput_needed);
1635 } 1699 }
1636 return err; 1700 return err;
1637} 1701}
@@ -1643,23 +1707,20 @@ asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optv
1643 1707
1644asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen) 1708asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen)
1645{ 1709{
1646 int err; 1710 int err, fput_needed;
1647 struct socket *sock; 1711 struct socket *sock;
1648 1712
1649 if ((sock = sockfd_lookup(fd, &err))!=NULL) 1713 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) {
1650 { 1714 err = security_socket_getsockopt(sock, level, optname);
1651 err = security_socket_getsockopt(sock, level, 1715 if (err)
1652 optname); 1716 goto out_put;
1653 if (err) {
1654 sockfd_put(sock);
1655 return err;
1656 }
1657 1717
1658 if (level == SOL_SOCKET) 1718 if (level == SOL_SOCKET)
1659 err=sock_getsockopt(sock,level,optname,optval,optlen); 1719 err=sock_getsockopt(sock,level,optname,optval,optlen);
1660 else 1720 else
1661 err=sock->ops->getsockopt(sock, level, optname, optval, optlen); 1721 err=sock->ops->getsockopt(sock, level, optname, optval, optlen);
1662 sockfd_put(sock); 1722out_put:
1723 fput_light(sock->file, fput_needed);
1663 } 1724 }
1664 return err; 1725 return err;
1665} 1726}
@@ -1671,19 +1732,15 @@ asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optv
1671 1732
1672asmlinkage long sys_shutdown(int fd, int how) 1733asmlinkage long sys_shutdown(int fd, int how)
1673{ 1734{
1674 int err; 1735 int err, fput_needed;
1675 struct socket *sock; 1736 struct socket *sock;
1676 1737
1677 if ((sock = sockfd_lookup(fd, &err))!=NULL) 1738 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL)
1678 { 1739 {
1679 err = security_socket_shutdown(sock, how); 1740 err = security_socket_shutdown(sock, how);
1680 if (err) { 1741 if (!err)
1681 sockfd_put(sock); 1742 err = sock->ops->shutdown(sock, how);
1682 return err; 1743 fput_light(sock->file, fput_needed);
1683 }
1684
1685 err=sock->ops->shutdown(sock, how);
1686 sockfd_put(sock);
1687 } 1744 }
1688 return err; 1745 return err;
1689} 1746}
@@ -1712,6 +1769,7 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
1712 unsigned char *ctl_buf = ctl; 1769 unsigned char *ctl_buf = ctl;
1713 struct msghdr msg_sys; 1770 struct msghdr msg_sys;
1714 int err, ctl_len, iov_size, total_len; 1771 int err, ctl_len, iov_size, total_len;
1772 int fput_needed;
1715 1773
1716 err = -EFAULT; 1774 err = -EFAULT;
1717 if (MSG_CMSG_COMPAT & flags) { 1775 if (MSG_CMSG_COMPAT & flags) {
@@ -1720,7 +1778,7 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
1720 } else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr))) 1778 } else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr)))
1721 return -EFAULT; 1779 return -EFAULT;
1722 1780
1723 sock = sockfd_lookup(fd, &err); 1781 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1724 if (!sock) 1782 if (!sock)
1725 goto out; 1783 goto out;
1726 1784
@@ -1788,7 +1846,7 @@ out_freeiov:
1788 if (iov != iovstack) 1846 if (iov != iovstack)
1789 sock_kfree_s(sock->sk, iov, iov_size); 1847 sock_kfree_s(sock->sk, iov, iov_size);
1790out_put: 1848out_put:
1791 sockfd_put(sock); 1849 fput_light(sock->file, fput_needed);
1792out: 1850out:
1793 return err; 1851 return err;
1794} 1852}
@@ -1806,6 +1864,7 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flag
1806 struct msghdr msg_sys; 1864 struct msghdr msg_sys;
1807 unsigned long cmsg_ptr; 1865 unsigned long cmsg_ptr;
1808 int err, iov_size, total_len, len; 1866 int err, iov_size, total_len, len;
1867 int fput_needed;
1809 1868
1810 /* kernel mode address */ 1869 /* kernel mode address */
1811 char addr[MAX_SOCK_ADDR]; 1870 char addr[MAX_SOCK_ADDR];
@@ -1821,7 +1880,7 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flag
1821 if (copy_from_user(&msg_sys,msg,sizeof(struct msghdr))) 1880 if (copy_from_user(&msg_sys,msg,sizeof(struct msghdr)))
1822 return -EFAULT; 1881 return -EFAULT;
1823 1882
1824 sock = sockfd_lookup(fd, &err); 1883 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1825 if (!sock) 1884 if (!sock)
1826 goto out; 1885 goto out;
1827 1886
@@ -1888,7 +1947,7 @@ out_freeiov:
1888 if (iov != iovstack) 1947 if (iov != iovstack)
1889 sock_kfree_s(sock->sk, iov, iov_size); 1948 sock_kfree_s(sock->sk, iov, iov_size);
1890out_put: 1949out_put:
1891 sockfd_put(sock); 1950 fput_light(sock->file, fput_needed);
1892out: 1951out:
1893 return err; 1952 return err;
1894} 1953}
@@ -2089,6 +2148,20 @@ void socket_seq_show(struct seq_file *seq)
2089} 2148}
2090#endif /* CONFIG_PROC_FS */ 2149#endif /* CONFIG_PROC_FS */
2091 2150
2151#ifdef CONFIG_COMPAT
2152static long compat_sock_ioctl(struct file *file, unsigned cmd,
2153 unsigned long arg)
2154{
2155 struct socket *sock = file->private_data;
2156 int ret = -ENOIOCTLCMD;
2157
2158 if (sock->ops->compat_ioctl)
2159 ret = sock->ops->compat_ioctl(sock, cmd, arg);
2160
2161 return ret;
2162}
2163#endif
2164
2092/* ABI emulation layers need these two */ 2165/* ABI emulation layers need these two */
2093EXPORT_SYMBOL(move_addr_to_kernel); 2166EXPORT_SYMBOL(move_addr_to_kernel);
2094EXPORT_SYMBOL(move_addr_to_user); 2167EXPORT_SYMBOL(move_addr_to_user);