aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c341
1 files changed, 194 insertions, 147 deletions
diff --git a/net/socket.c b/net/socket.c
index a00851f981db..e3c21d5ec288 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>
@@ -351,8 +349,8 @@ static struct dentry_operations sockfs_dentry_operations = {
351/* 349/*
352 * Obtains the first available file descriptor and sets it up for use. 350 * Obtains the first available file descriptor and sets it up for use.
353 * 351 *
354 * This function creates file structure and maps it to fd space 352 * These functions create file structures and maps them to fd space
355 * of current process. On success it returns file descriptor 353 * of the current process. On success it returns file descriptor
356 * and file struct implicitly stored in sock->file. 354 * and file struct implicitly stored in sock->file.
357 * Note that another thread may close file descriptor before we return 355 * 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 356 * from this function. We use the fact that now we do not refer
@@ -365,53 +363,90 @@ static struct dentry_operations sockfs_dentry_operations = {
365 * but we take care of internal coherence yet. 363 * but we take care of internal coherence yet.
366 */ 364 */
367 365
368int sock_map_fd(struct socket *sock) 366static int sock_alloc_fd(struct file **filep)
369{ 367{
370 int fd; 368 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 369
378 fd = get_unused_fd(); 370 fd = get_unused_fd();
379 if (fd >= 0) { 371 if (likely(fd >= 0)) {
380 struct file *file = get_empty_filp(); 372 struct file *file = get_empty_filp();
381 373
382 if (!file) { 374 *filep = file;
375 if (unlikely(!file)) {
383 put_unused_fd(fd); 376 put_unused_fd(fd);
384 fd = -ENFILE; 377 return -ENFILE;
385 goto out;
386 } 378 }
379 } else
380 *filep = NULL;
381 return fd;
382}
383
384static int sock_attach_fd(struct socket *sock, struct file *file)
385{
386 struct qstr this;
387 char name[32];
387 388
388 this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino); 389 this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
389 this.name = name; 390 this.name = name;
390 this.hash = SOCK_INODE(sock)->i_ino; 391 this.hash = SOCK_INODE(sock)->i_ino;
391 392
392 file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this); 393 file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
393 if (!file->f_dentry) { 394 if (unlikely(!file->f_dentry))
394 put_filp(file); 395 return -ENOMEM;
396
397 file->f_dentry->d_op = &sockfs_dentry_operations;
398 d_add(file->f_dentry, SOCK_INODE(sock));
399 file->f_vfsmnt = mntget(sock_mnt);
400 file->f_mapping = file->f_dentry->d_inode->i_mapping;
401
402 sock->file = file;
403 file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
404 file->f_mode = FMODE_READ | FMODE_WRITE;
405 file->f_flags = O_RDWR;
406 file->f_pos = 0;
407 file->private_data = sock;
408
409 return 0;
410}
411
412int sock_map_fd(struct socket *sock)
413{
414 struct file *newfile;
415 int fd = sock_alloc_fd(&newfile);
416
417 if (likely(fd >= 0)) {
418 int err = sock_attach_fd(sock, newfile);
419
420 if (unlikely(err < 0)) {
421 put_filp(newfile);
395 put_unused_fd(fd); 422 put_unused_fd(fd);
396 fd = -ENOMEM; 423 return err;
397 goto out;
398 } 424 }
399 file->f_dentry->d_op = &sockfs_dentry_operations; 425 fd_install(fd, newfile);
400 d_add(file->f_dentry, SOCK_INODE(sock)); 426 }
401 file->f_vfsmnt = mntget(sock_mnt); 427 return fd;
402 file->f_mapping = file->f_dentry->d_inode->i_mapping; 428}
403 429
404 sock->file = file; 430static struct socket *sock_from_file(struct file *file, int *err)
405 file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops; 431{
406 file->f_mode = FMODE_READ | FMODE_WRITE; 432 struct inode *inode;
407 file->f_flags = O_RDWR; 433 struct socket *sock;
408 file->f_pos = 0; 434
409 file->private_data = sock; 435 if (file->f_op == &socket_file_ops)
410 fd_install(fd, file); 436 return file->private_data; /* set in sock_map_fd */
437
438 inode = file->f_dentry->d_inode;
439 if (!S_ISSOCK(inode->i_mode)) {
440 *err = -ENOTSOCK;
441 return NULL;
411 } 442 }
412 443
413out: 444 sock = SOCKET_I(inode);
414 return fd; 445 if (sock->file != file) {
446 printk(KERN_ERR "socki_lookup: socket file changed!\n");
447 sock->file = file;
448 }
449 return sock;
415} 450}
416 451
417/** 452/**
@@ -430,31 +465,31 @@ out:
430struct socket *sockfd_lookup(int fd, int *err) 465struct socket *sockfd_lookup(int fd, int *err)
431{ 466{
432 struct file *file; 467 struct file *file;
433 struct inode *inode;
434 struct socket *sock; 468 struct socket *sock;
435 469
436 if (!(file = fget(fd))) 470 if (!(file = fget(fd))) {
437 {
438 *err = -EBADF; 471 *err = -EBADF;
439 return NULL; 472 return NULL;
440 } 473 }
441 474 sock = sock_from_file(file, err);
442 if (file->f_op == &socket_file_ops) 475 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); 476 fput(file);
449 return NULL; 477 return sock;
450 } 478}
451 479
452 sock = SOCKET_I(inode); 480static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
453 if (sock->file != file) { 481{
454 printk(KERN_ERR "socki_lookup: socket file changed!\n"); 482 struct file *file;
455 sock->file = file; 483 struct socket *sock;
484
485 file = fget_light(fd, fput_needed);
486 if (file) {
487 sock = sock_from_file(file, err);
488 if (sock)
489 return sock;
490 fput_light(file, *fput_needed);
456 } 491 }
457 return sock; 492 return NULL;
458} 493}
459 494
460/** 495/**
@@ -792,36 +827,36 @@ static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf,
792 * with module unload. 827 * with module unload.
793 */ 828 */
794 829
795static DECLARE_MUTEX(br_ioctl_mutex); 830static DEFINE_MUTEX(br_ioctl_mutex);
796static int (*br_ioctl_hook)(unsigned int cmd, void __user *arg) = NULL; 831static int (*br_ioctl_hook)(unsigned int cmd, void __user *arg) = NULL;
797 832
798void brioctl_set(int (*hook)(unsigned int, void __user *)) 833void brioctl_set(int (*hook)(unsigned int, void __user *))
799{ 834{
800 down(&br_ioctl_mutex); 835 mutex_lock(&br_ioctl_mutex);
801 br_ioctl_hook = hook; 836 br_ioctl_hook = hook;
802 up(&br_ioctl_mutex); 837 mutex_unlock(&br_ioctl_mutex);
803} 838}
804EXPORT_SYMBOL(brioctl_set); 839EXPORT_SYMBOL(brioctl_set);
805 840
806static DECLARE_MUTEX(vlan_ioctl_mutex); 841static DEFINE_MUTEX(vlan_ioctl_mutex);
807static int (*vlan_ioctl_hook)(void __user *arg); 842static int (*vlan_ioctl_hook)(void __user *arg);
808 843
809void vlan_ioctl_set(int (*hook)(void __user *)) 844void vlan_ioctl_set(int (*hook)(void __user *))
810{ 845{
811 down(&vlan_ioctl_mutex); 846 mutex_lock(&vlan_ioctl_mutex);
812 vlan_ioctl_hook = hook; 847 vlan_ioctl_hook = hook;
813 up(&vlan_ioctl_mutex); 848 mutex_unlock(&vlan_ioctl_mutex);
814} 849}
815EXPORT_SYMBOL(vlan_ioctl_set); 850EXPORT_SYMBOL(vlan_ioctl_set);
816 851
817static DECLARE_MUTEX(dlci_ioctl_mutex); 852static DEFINE_MUTEX(dlci_ioctl_mutex);
818static int (*dlci_ioctl_hook)(unsigned int, void __user *); 853static int (*dlci_ioctl_hook)(unsigned int, void __user *);
819 854
820void dlci_ioctl_set(int (*hook)(unsigned int, void __user *)) 855void dlci_ioctl_set(int (*hook)(unsigned int, void __user *))
821{ 856{
822 down(&dlci_ioctl_mutex); 857 mutex_lock(&dlci_ioctl_mutex);
823 dlci_ioctl_hook = hook; 858 dlci_ioctl_hook = hook;
824 up(&dlci_ioctl_mutex); 859 mutex_unlock(&dlci_ioctl_mutex);
825} 860}
826EXPORT_SYMBOL(dlci_ioctl_set); 861EXPORT_SYMBOL(dlci_ioctl_set);
827 862
@@ -840,11 +875,11 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
840 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { 875 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
841 err = dev_ioctl(cmd, argp); 876 err = dev_ioctl(cmd, argp);
842 } else 877 } else
843#ifdef WIRELESS_EXT 878#ifdef CONFIG_WIRELESS_EXT
844 if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { 879 if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
845 err = dev_ioctl(cmd, argp); 880 err = dev_ioctl(cmd, argp);
846 } else 881 } else
847#endif /* WIRELESS_EXT */ 882#endif /* CONFIG_WIRELESS_EXT */
848 switch (cmd) { 883 switch (cmd) {
849 case FIOSETOWN: 884 case FIOSETOWN:
850 case SIOCSPGRP: 885 case SIOCSPGRP:
@@ -865,10 +900,10 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
865 if (!br_ioctl_hook) 900 if (!br_ioctl_hook)
866 request_module("bridge"); 901 request_module("bridge");
867 902
868 down(&br_ioctl_mutex); 903 mutex_lock(&br_ioctl_mutex);
869 if (br_ioctl_hook) 904 if (br_ioctl_hook)
870 err = br_ioctl_hook(cmd, argp); 905 err = br_ioctl_hook(cmd, argp);
871 up(&br_ioctl_mutex); 906 mutex_unlock(&br_ioctl_mutex);
872 break; 907 break;
873 case SIOCGIFVLAN: 908 case SIOCGIFVLAN:
874 case SIOCSIFVLAN: 909 case SIOCSIFVLAN:
@@ -876,10 +911,10 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
876 if (!vlan_ioctl_hook) 911 if (!vlan_ioctl_hook)
877 request_module("8021q"); 912 request_module("8021q");
878 913
879 down(&vlan_ioctl_mutex); 914 mutex_lock(&vlan_ioctl_mutex);
880 if (vlan_ioctl_hook) 915 if (vlan_ioctl_hook)
881 err = vlan_ioctl_hook(argp); 916 err = vlan_ioctl_hook(argp);
882 up(&vlan_ioctl_mutex); 917 mutex_unlock(&vlan_ioctl_mutex);
883 break; 918 break;
884 case SIOCGIFDIVERT: 919 case SIOCGIFDIVERT:
885 case SIOCSIFDIVERT: 920 case SIOCSIFDIVERT:
@@ -893,9 +928,9 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
893 request_module("dlci"); 928 request_module("dlci");
894 929
895 if (dlci_ioctl_hook) { 930 if (dlci_ioctl_hook) {
896 down(&dlci_ioctl_mutex); 931 mutex_lock(&dlci_ioctl_mutex);
897 err = dlci_ioctl_hook(cmd, argp); 932 err = dlci_ioctl_hook(cmd, argp);
898 up(&dlci_ioctl_mutex); 933 mutex_unlock(&dlci_ioctl_mutex);
899 } 934 }
900 break; 935 break;
901 default: 936 default:
@@ -1289,19 +1324,17 @@ asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
1289{ 1324{
1290 struct socket *sock; 1325 struct socket *sock;
1291 char address[MAX_SOCK_ADDR]; 1326 char address[MAX_SOCK_ADDR];
1292 int err; 1327 int err, fput_needed;
1293 1328
1294 if((sock = sockfd_lookup(fd,&err))!=NULL) 1329 if((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL)
1295 { 1330 {
1296 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) { 1331 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
1297 err = security_socket_bind(sock, (struct sockaddr *)address, addrlen); 1332 err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
1298 if (err) { 1333 if (!err)
1299 sockfd_put(sock); 1334 err = sock->ops->bind(sock,
1300 return err; 1335 (struct sockaddr *)address, addrlen);
1301 }
1302 err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen);
1303 } 1336 }
1304 sockfd_put(sock); 1337 fput_light(sock->file, fput_needed);
1305 } 1338 }
1306 return err; 1339 return err;
1307} 1340}
@@ -1318,20 +1351,17 @@ int sysctl_somaxconn = SOMAXCONN;
1318asmlinkage long sys_listen(int fd, int backlog) 1351asmlinkage long sys_listen(int fd, int backlog)
1319{ 1352{
1320 struct socket *sock; 1353 struct socket *sock;
1321 int err; 1354 int err, fput_needed;
1322 1355
1323 if ((sock = sockfd_lookup(fd, &err)) != NULL) { 1356 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) {
1324 if ((unsigned) backlog > sysctl_somaxconn) 1357 if ((unsigned) backlog > sysctl_somaxconn)
1325 backlog = sysctl_somaxconn; 1358 backlog = sysctl_somaxconn;
1326 1359
1327 err = security_socket_listen(sock, backlog); 1360 err = security_socket_listen(sock, backlog);
1328 if (err) { 1361 if (!err)
1329 sockfd_put(sock); 1362 err = sock->ops->listen(sock, backlog);
1330 return err;
1331 }
1332 1363
1333 err=sock->ops->listen(sock, backlog); 1364 fput_light(sock->file, fput_needed);
1334 sockfd_put(sock);
1335 } 1365 }
1336 return err; 1366 return err;
1337} 1367}
@@ -1352,10 +1382,11 @@ asmlinkage long sys_listen(int fd, int backlog)
1352asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen) 1382asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen)
1353{ 1383{
1354 struct socket *sock, *newsock; 1384 struct socket *sock, *newsock;
1355 int err, len; 1385 struct file *newfile;
1386 int err, len, newfd, fput_needed;
1356 char address[MAX_SOCK_ADDR]; 1387 char address[MAX_SOCK_ADDR];
1357 1388
1358 sock = sockfd_lookup(fd, &err); 1389 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1359 if (!sock) 1390 if (!sock)
1360 goto out; 1391 goto out;
1361 1392
@@ -1372,35 +1403,48 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _
1372 */ 1403 */
1373 __module_get(newsock->ops->owner); 1404 __module_get(newsock->ops->owner);
1374 1405
1406 newfd = sock_alloc_fd(&newfile);
1407 if (unlikely(newfd < 0)) {
1408 err = newfd;
1409 goto out_release;
1410 }
1411
1412 err = sock_attach_fd(newsock, newfile);
1413 if (err < 0)
1414 goto out_fd;
1415
1375 err = security_socket_accept(sock, newsock); 1416 err = security_socket_accept(sock, newsock);
1376 if (err) 1417 if (err)
1377 goto out_release; 1418 goto out_fd;
1378 1419
1379 err = sock->ops->accept(sock, newsock, sock->file->f_flags); 1420 err = sock->ops->accept(sock, newsock, sock->file->f_flags);
1380 if (err < 0) 1421 if (err < 0)
1381 goto out_release; 1422 goto out_fd;
1382 1423
1383 if (upeer_sockaddr) { 1424 if (upeer_sockaddr) {
1384 if(newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 2)<0) { 1425 if(newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 2)<0) {
1385 err = -ECONNABORTED; 1426 err = -ECONNABORTED;
1386 goto out_release; 1427 goto out_fd;
1387 } 1428 }
1388 err = move_addr_to_user(address, len, upeer_sockaddr, upeer_addrlen); 1429 err = move_addr_to_user(address, len, upeer_sockaddr, upeer_addrlen);
1389 if (err < 0) 1430 if (err < 0)
1390 goto out_release; 1431 goto out_fd;
1391 } 1432 }
1392 1433
1393 /* File flags are not inherited via accept() unlike another OSes. */ 1434 /* File flags are not inherited via accept() unlike another OSes. */
1394 1435
1395 if ((err = sock_map_fd(newsock)) < 0) 1436 fd_install(newfd, newfile);
1396 goto out_release; 1437 err = newfd;
1397 1438
1398 security_socket_post_accept(sock, newsock); 1439 security_socket_post_accept(sock, newsock);
1399 1440
1400out_put: 1441out_put:
1401 sockfd_put(sock); 1442 fput_light(sock->file, fput_needed);
1402out: 1443out:
1403 return err; 1444 return err;
1445out_fd:
1446 put_filp(newfile);
1447 put_unused_fd(newfd);
1404out_release: 1448out_release:
1405 sock_release(newsock); 1449 sock_release(newsock);
1406 goto out_put; 1450 goto out_put;
@@ -1423,9 +1467,9 @@ asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrl
1423{ 1467{
1424 struct socket *sock; 1468 struct socket *sock;
1425 char address[MAX_SOCK_ADDR]; 1469 char address[MAX_SOCK_ADDR];
1426 int err; 1470 int err, fput_needed;
1427 1471
1428 sock = sockfd_lookup(fd, &err); 1472 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1429 if (!sock) 1473 if (!sock)
1430 goto out; 1474 goto out;
1431 err = move_addr_to_kernel(uservaddr, addrlen, address); 1475 err = move_addr_to_kernel(uservaddr, addrlen, address);
@@ -1439,7 +1483,7 @@ asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrl
1439 err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen, 1483 err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
1440 sock->file->f_flags); 1484 sock->file->f_flags);
1441out_put: 1485out_put:
1442 sockfd_put(sock); 1486 fput_light(sock->file, fput_needed);
1443out: 1487out:
1444 return err; 1488 return err;
1445} 1489}
@@ -1453,9 +1497,9 @@ asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int _
1453{ 1497{
1454 struct socket *sock; 1498 struct socket *sock;
1455 char address[MAX_SOCK_ADDR]; 1499 char address[MAX_SOCK_ADDR];
1456 int len, err; 1500 int len, err, fput_needed;
1457 1501
1458 sock = sockfd_lookup(fd, &err); 1502 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1459 if (!sock) 1503 if (!sock)
1460 goto out; 1504 goto out;
1461 1505
@@ -1469,7 +1513,7 @@ asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int _
1469 err = move_addr_to_user(address, len, usockaddr, usockaddr_len); 1513 err = move_addr_to_user(address, len, usockaddr, usockaddr_len);
1470 1514
1471out_put: 1515out_put:
1472 sockfd_put(sock); 1516 fput_light(sock->file, fput_needed);
1473out: 1517out:
1474 return err; 1518 return err;
1475} 1519}
@@ -1483,20 +1527,19 @@ asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int _
1483{ 1527{
1484 struct socket *sock; 1528 struct socket *sock;
1485 char address[MAX_SOCK_ADDR]; 1529 char address[MAX_SOCK_ADDR];
1486 int len, err; 1530 int len, err, fput_needed;
1487 1531
1488 if ((sock = sockfd_lookup(fd, &err))!=NULL) 1532 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) {
1489 {
1490 err = security_socket_getpeername(sock); 1533 err = security_socket_getpeername(sock);
1491 if (err) { 1534 if (err) {
1492 sockfd_put(sock); 1535 fput_light(sock->file, fput_needed);
1493 return err; 1536 return err;
1494 } 1537 }
1495 1538
1496 err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1); 1539 err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1);
1497 if (!err) 1540 if (!err)
1498 err=move_addr_to_user(address,len, usockaddr, usockaddr_len); 1541 err=move_addr_to_user(address,len, usockaddr, usockaddr_len);
1499 sockfd_put(sock); 1542 fput_light(sock->file, fput_needed);
1500 } 1543 }
1501 return err; 1544 return err;
1502} 1545}
@@ -1515,10 +1558,16 @@ asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flag
1515 int err; 1558 int err;
1516 struct msghdr msg; 1559 struct msghdr msg;
1517 struct iovec iov; 1560 struct iovec iov;
1518 1561 int fput_needed;
1519 sock = sockfd_lookup(fd, &err); 1562 struct file *sock_file;
1563
1564 sock_file = fget_light(fd, &fput_needed);
1565 if (!sock_file)
1566 return -EBADF;
1567
1568 sock = sock_from_file(sock_file, &err);
1520 if (!sock) 1569 if (!sock)
1521 goto out; 1570 goto out_put;
1522 iov.iov_base=buff; 1571 iov.iov_base=buff;
1523 iov.iov_len=len; 1572 iov.iov_len=len;
1524 msg.msg_name=NULL; 1573 msg.msg_name=NULL;
@@ -1527,8 +1576,7 @@ asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flag
1527 msg.msg_control=NULL; 1576 msg.msg_control=NULL;
1528 msg.msg_controllen=0; 1577 msg.msg_controllen=0;
1529 msg.msg_namelen=0; 1578 msg.msg_namelen=0;
1530 if(addr) 1579 if (addr) {
1531 {
1532 err = move_addr_to_kernel(addr, addr_len, address); 1580 err = move_addr_to_kernel(addr, addr_len, address);
1533 if (err < 0) 1581 if (err < 0)
1534 goto out_put; 1582 goto out_put;
@@ -1541,8 +1589,7 @@ asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flag
1541 err = sock_sendmsg(sock, &msg, len); 1589 err = sock_sendmsg(sock, &msg, len);
1542 1590
1543out_put: 1591out_put:
1544 sockfd_put(sock); 1592 fput_light(sock_file, fput_needed);
1545out:
1546 return err; 1593 return err;
1547} 1594}
1548 1595
@@ -1569,8 +1616,14 @@ asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned f
1569 struct msghdr msg; 1616 struct msghdr msg;
1570 char address[MAX_SOCK_ADDR]; 1617 char address[MAX_SOCK_ADDR];
1571 int err,err2; 1618 int err,err2;
1619 struct file *sock_file;
1620 int fput_needed;
1572 1621
1573 sock = sockfd_lookup(fd, &err); 1622 sock_file = fget_light(fd, &fput_needed);
1623 if (!sock_file)
1624 return -EBADF;
1625
1626 sock = sock_from_file(sock_file, &err);
1574 if (!sock) 1627 if (!sock)
1575 goto out; 1628 goto out;
1576 1629
@@ -1592,8 +1645,8 @@ asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned f
1592 if(err2<0) 1645 if(err2<0)
1593 err=err2; 1646 err=err2;
1594 } 1647 }
1595 sockfd_put(sock);
1596out: 1648out:
1649 fput_light(sock_file, fput_needed);
1597 return err; 1650 return err;
1598} 1651}
1599 1652
@@ -1613,25 +1666,24 @@ asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags
1613 1666
1614asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen) 1667asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen)
1615{ 1668{
1616 int err; 1669 int err, fput_needed;
1617 struct socket *sock; 1670 struct socket *sock;
1618 1671
1619 if (optlen < 0) 1672 if (optlen < 0)
1620 return -EINVAL; 1673 return -EINVAL;
1621 1674
1622 if ((sock = sockfd_lookup(fd, &err))!=NULL) 1675 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL)
1623 { 1676 {
1624 err = security_socket_setsockopt(sock,level,optname); 1677 err = security_socket_setsockopt(sock,level,optname);
1625 if (err) { 1678 if (err)
1626 sockfd_put(sock); 1679 goto out_put;
1627 return err;
1628 }
1629 1680
1630 if (level == SOL_SOCKET) 1681 if (level == SOL_SOCKET)
1631 err=sock_setsockopt(sock,level,optname,optval,optlen); 1682 err=sock_setsockopt(sock,level,optname,optval,optlen);
1632 else 1683 else
1633 err=sock->ops->setsockopt(sock, level, optname, optval, optlen); 1684 err=sock->ops->setsockopt(sock, level, optname, optval, optlen);
1634 sockfd_put(sock); 1685out_put:
1686 fput_light(sock->file, fput_needed);
1635 } 1687 }
1636 return err; 1688 return err;
1637} 1689}
@@ -1643,23 +1695,20 @@ asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optv
1643 1695
1644asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen) 1696asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen)
1645{ 1697{
1646 int err; 1698 int err, fput_needed;
1647 struct socket *sock; 1699 struct socket *sock;
1648 1700
1649 if ((sock = sockfd_lookup(fd, &err))!=NULL) 1701 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) {
1650 { 1702 err = security_socket_getsockopt(sock, level, optname);
1651 err = security_socket_getsockopt(sock, level, 1703 if (err)
1652 optname); 1704 goto out_put;
1653 if (err) {
1654 sockfd_put(sock);
1655 return err;
1656 }
1657 1705
1658 if (level == SOL_SOCKET) 1706 if (level == SOL_SOCKET)
1659 err=sock_getsockopt(sock,level,optname,optval,optlen); 1707 err=sock_getsockopt(sock,level,optname,optval,optlen);
1660 else 1708 else
1661 err=sock->ops->getsockopt(sock, level, optname, optval, optlen); 1709 err=sock->ops->getsockopt(sock, level, optname, optval, optlen);
1662 sockfd_put(sock); 1710out_put:
1711 fput_light(sock->file, fput_needed);
1663 } 1712 }
1664 return err; 1713 return err;
1665} 1714}
@@ -1671,19 +1720,15 @@ asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optv
1671 1720
1672asmlinkage long sys_shutdown(int fd, int how) 1721asmlinkage long sys_shutdown(int fd, int how)
1673{ 1722{
1674 int err; 1723 int err, fput_needed;
1675 struct socket *sock; 1724 struct socket *sock;
1676 1725
1677 if ((sock = sockfd_lookup(fd, &err))!=NULL) 1726 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL)
1678 { 1727 {
1679 err = security_socket_shutdown(sock, how); 1728 err = security_socket_shutdown(sock, how);
1680 if (err) { 1729 if (!err)
1681 sockfd_put(sock); 1730 err = sock->ops->shutdown(sock, how);
1682 return err; 1731 fput_light(sock->file, fput_needed);
1683 }
1684
1685 err=sock->ops->shutdown(sock, how);
1686 sockfd_put(sock);
1687 } 1732 }
1688 return err; 1733 return err;
1689} 1734}
@@ -1712,6 +1757,7 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
1712 unsigned char *ctl_buf = ctl; 1757 unsigned char *ctl_buf = ctl;
1713 struct msghdr msg_sys; 1758 struct msghdr msg_sys;
1714 int err, ctl_len, iov_size, total_len; 1759 int err, ctl_len, iov_size, total_len;
1760 int fput_needed;
1715 1761
1716 err = -EFAULT; 1762 err = -EFAULT;
1717 if (MSG_CMSG_COMPAT & flags) { 1763 if (MSG_CMSG_COMPAT & flags) {
@@ -1720,7 +1766,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))) 1766 } else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr)))
1721 return -EFAULT; 1767 return -EFAULT;
1722 1768
1723 sock = sockfd_lookup(fd, &err); 1769 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1724 if (!sock) 1770 if (!sock)
1725 goto out; 1771 goto out;
1726 1772
@@ -1788,7 +1834,7 @@ out_freeiov:
1788 if (iov != iovstack) 1834 if (iov != iovstack)
1789 sock_kfree_s(sock->sk, iov, iov_size); 1835 sock_kfree_s(sock->sk, iov, iov_size);
1790out_put: 1836out_put:
1791 sockfd_put(sock); 1837 fput_light(sock->file, fput_needed);
1792out: 1838out:
1793 return err; 1839 return err;
1794} 1840}
@@ -1806,6 +1852,7 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flag
1806 struct msghdr msg_sys; 1852 struct msghdr msg_sys;
1807 unsigned long cmsg_ptr; 1853 unsigned long cmsg_ptr;
1808 int err, iov_size, total_len, len; 1854 int err, iov_size, total_len, len;
1855 int fput_needed;
1809 1856
1810 /* kernel mode address */ 1857 /* kernel mode address */
1811 char addr[MAX_SOCK_ADDR]; 1858 char addr[MAX_SOCK_ADDR];
@@ -1821,7 +1868,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))) 1868 if (copy_from_user(&msg_sys,msg,sizeof(struct msghdr)))
1822 return -EFAULT; 1869 return -EFAULT;
1823 1870
1824 sock = sockfd_lookup(fd, &err); 1871 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1825 if (!sock) 1872 if (!sock)
1826 goto out; 1873 goto out;
1827 1874
@@ -1888,7 +1935,7 @@ out_freeiov:
1888 if (iov != iovstack) 1935 if (iov != iovstack)
1889 sock_kfree_s(sock->sk, iov, iov_size); 1936 sock_kfree_s(sock->sk, iov, iov_size);
1890out_put: 1937out_put:
1891 sockfd_put(sock); 1938 fput_light(sock->file, fput_needed);
1892out: 1939out:
1893 return err; 1940 return err;
1894} 1941}