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