aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-03-21 12:31:48 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-21 12:31:48 -0500
commit3d1f337b3e7378923c89f37afb573a918ef40be5 (patch)
tree386798378567a10d1c7b24f599cb50f70298694c /net/socket.c
parent2bf2154c6bb5599e3ec3f73c34861a0b12aa839e (diff)
parent5e35941d990123f155b02d5663e51a24f816b6f3 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (235 commits) [NETFILTER]: Add H.323 conntrack/NAT helper [TG3]: Don't mark tg3_test_registers() as returning const. [IPV6]: Cleanups for net/ipv6/addrconf.c (kzalloc, early exit) v2 [IPV6]: Nearly complete kzalloc cleanup for net/ipv6 [IPV6]: Cleanup of net/ipv6/reassambly.c [BRIDGE]: Remove duplicate const from is_link_local() argument type. [DECNET]: net/decnet/dn_route.c: fix inconsequent NULL checking [TG3]: make drivers/net/tg3.c:tg3_request_irq() static [BRIDGE]: use LLC to send STP [LLC]: llc_mac_hdr_init const arguments [BRIDGE]: allow show/store of group multicast address [BRIDGE]: use llc for receiving STP packets [BRIDGE]: stp timer to jiffies cleanup [BRIDGE]: forwarding remove unneeded preempt and bh diasables [BRIDGE]: netfilter inline cleanup [BRIDGE]: netfilter VLAN macro cleanup [BRIDGE]: netfilter dont use __constant_htons [BRIDGE]: netfilter whitespace [BRIDGE]: optimize frame pass up [BRIDGE]: use kzalloc ...
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c332
1 files changed, 191 insertions, 141 deletions
diff --git a/net/socket.c b/net/socket.c
index 7e1bdef8b09e..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>
@@ -348,8 +349,8 @@ static struct dentry_operations sockfs_dentry_operations = {
348/* 349/*
349 * 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.
350 * 351 *
351 * This function creates file structure and maps it to fd space 352 * These functions create file structures and maps them to fd space
352 * of current process. On success it returns file descriptor 353 * of the current process. On success it returns file descriptor
353 * and file struct implicitly stored in sock->file. 354 * and file struct implicitly stored in sock->file.
354 * Note that another thread may close file descriptor before we return 355 * Note that another thread may close file descriptor before we return
355 * 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
@@ -362,53 +363,90 @@ static struct dentry_operations sockfs_dentry_operations = {
362 * but we take care of internal coherence yet. 363 * but we take care of internal coherence yet.
363 */ 364 */
364 365
365int sock_map_fd(struct socket *sock) 366static int sock_alloc_fd(struct file **filep)
366{ 367{
367 int fd; 368 int fd;
368 struct qstr this;
369 char name[32];
370
371 /*
372 * Find a file descriptor suitable for return to the user.
373 */
374 369
375 fd = get_unused_fd(); 370 fd = get_unused_fd();
376 if (fd >= 0) { 371 if (likely(fd >= 0)) {
377 struct file *file = get_empty_filp(); 372 struct file *file = get_empty_filp();
378 373
379 if (!file) { 374 *filep = file;
375 if (unlikely(!file)) {
380 put_unused_fd(fd); 376 put_unused_fd(fd);
381 fd = -ENFILE; 377 return -ENFILE;
382 goto out;
383 } 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];
388
389 this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
390 this.name = name;
391 this.hash = SOCK_INODE(sock)->i_ino;
384 392
385 this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino); 393 file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
386 this.name = name; 394 if (unlikely(!file->f_dentry))
387 this.hash = SOCK_INODE(sock)->i_ino; 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}
388 411
389 file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this); 412int sock_map_fd(struct socket *sock)
390 if (!file->f_dentry) { 413{
391 put_filp(file); 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);
392 put_unused_fd(fd); 422 put_unused_fd(fd);
393 fd = -ENOMEM; 423 return err;
394 goto out;
395 } 424 }
396 file->f_dentry->d_op = &sockfs_dentry_operations; 425 fd_install(fd, newfile);
397 d_add(file->f_dentry, SOCK_INODE(sock)); 426 }
398 file->f_vfsmnt = mntget(sock_mnt); 427 return fd;
399 file->f_mapping = file->f_dentry->d_inode->i_mapping; 428}
400 429
401 sock->file = file; 430static struct socket *sock_from_file(struct file *file, int *err)
402 file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops; 431{
403 file->f_mode = FMODE_READ | FMODE_WRITE; 432 struct inode *inode;
404 file->f_flags = O_RDWR; 433 struct socket *sock;
405 file->f_pos = 0; 434
406 file->private_data = sock; 435 if (file->f_op == &socket_file_ops)
407 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;
408 } 442 }
409 443
410out: 444 sock = SOCKET_I(inode);
411 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;
412} 450}
413 451
414/** 452/**
@@ -427,31 +465,31 @@ out:
427struct socket *sockfd_lookup(int fd, int *err) 465struct socket *sockfd_lookup(int fd, int *err)
428{ 466{
429 struct file *file; 467 struct file *file;
430 struct inode *inode;
431 struct socket *sock; 468 struct socket *sock;
432 469
433 if (!(file = fget(fd))) 470 if (!(file = fget(fd))) {
434 {
435 *err = -EBADF; 471 *err = -EBADF;
436 return NULL; 472 return NULL;
437 } 473 }
438 474 sock = sock_from_file(file, err);
439 if (file->f_op == &socket_file_ops) 475 if (!sock)
440 return file->private_data; /* set in sock_map_fd */
441
442 inode = file->f_dentry->d_inode;
443 if (!S_ISSOCK(inode->i_mode)) {
444 *err = -ENOTSOCK;
445 fput(file); 476 fput(file);
446 return NULL; 477 return sock;
447 } 478}
448 479
449 sock = SOCKET_I(inode); 480static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
450 if (sock->file != file) { 481{
451 printk(KERN_ERR "socki_lookup: socket file changed!\n"); 482 struct file *file;
452 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);
453 } 491 }
454 return sock; 492 return NULL;
455} 493}
456 494
457/** 495/**
@@ -789,36 +827,36 @@ static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf,
789 * with module unload. 827 * with module unload.
790 */ 828 */
791 829
792static DECLARE_MUTEX(br_ioctl_mutex); 830static DEFINE_MUTEX(br_ioctl_mutex);
793static int (*br_ioctl_hook)(unsigned int cmd, void __user *arg) = NULL; 831static int (*br_ioctl_hook)(unsigned int cmd, void __user *arg) = NULL;
794 832
795void brioctl_set(int (*hook)(unsigned int, void __user *)) 833void brioctl_set(int (*hook)(unsigned int, void __user *))
796{ 834{
797 down(&br_ioctl_mutex); 835 mutex_lock(&br_ioctl_mutex);
798 br_ioctl_hook = hook; 836 br_ioctl_hook = hook;
799 up(&br_ioctl_mutex); 837 mutex_unlock(&br_ioctl_mutex);
800} 838}
801EXPORT_SYMBOL(brioctl_set); 839EXPORT_SYMBOL(brioctl_set);
802 840
803static DECLARE_MUTEX(vlan_ioctl_mutex); 841static DEFINE_MUTEX(vlan_ioctl_mutex);
804static int (*vlan_ioctl_hook)(void __user *arg); 842static int (*vlan_ioctl_hook)(void __user *arg);
805 843
806void vlan_ioctl_set(int (*hook)(void __user *)) 844void vlan_ioctl_set(int (*hook)(void __user *))
807{ 845{
808 down(&vlan_ioctl_mutex); 846 mutex_lock(&vlan_ioctl_mutex);
809 vlan_ioctl_hook = hook; 847 vlan_ioctl_hook = hook;
810 up(&vlan_ioctl_mutex); 848 mutex_unlock(&vlan_ioctl_mutex);
811} 849}
812EXPORT_SYMBOL(vlan_ioctl_set); 850EXPORT_SYMBOL(vlan_ioctl_set);
813 851
814static DECLARE_MUTEX(dlci_ioctl_mutex); 852static DEFINE_MUTEX(dlci_ioctl_mutex);
815static int (*dlci_ioctl_hook)(unsigned int, void __user *); 853static int (*dlci_ioctl_hook)(unsigned int, void __user *);
816 854
817void dlci_ioctl_set(int (*hook)(unsigned int, void __user *)) 855void dlci_ioctl_set(int (*hook)(unsigned int, void __user *))
818{ 856{
819 down(&dlci_ioctl_mutex); 857 mutex_lock(&dlci_ioctl_mutex);
820 dlci_ioctl_hook = hook; 858 dlci_ioctl_hook = hook;
821 up(&dlci_ioctl_mutex); 859 mutex_unlock(&dlci_ioctl_mutex);
822} 860}
823EXPORT_SYMBOL(dlci_ioctl_set); 861EXPORT_SYMBOL(dlci_ioctl_set);
824 862
@@ -862,10 +900,10 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
862 if (!br_ioctl_hook) 900 if (!br_ioctl_hook)
863 request_module("bridge"); 901 request_module("bridge");
864 902
865 down(&br_ioctl_mutex); 903 mutex_lock(&br_ioctl_mutex);
866 if (br_ioctl_hook) 904 if (br_ioctl_hook)
867 err = br_ioctl_hook(cmd, argp); 905 err = br_ioctl_hook(cmd, argp);
868 up(&br_ioctl_mutex); 906 mutex_unlock(&br_ioctl_mutex);
869 break; 907 break;
870 case SIOCGIFVLAN: 908 case SIOCGIFVLAN:
871 case SIOCSIFVLAN: 909 case SIOCSIFVLAN:
@@ -873,10 +911,10 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
873 if (!vlan_ioctl_hook) 911 if (!vlan_ioctl_hook)
874 request_module("8021q"); 912 request_module("8021q");
875 913
876 down(&vlan_ioctl_mutex); 914 mutex_lock(&vlan_ioctl_mutex);
877 if (vlan_ioctl_hook) 915 if (vlan_ioctl_hook)
878 err = vlan_ioctl_hook(argp); 916 err = vlan_ioctl_hook(argp);
879 up(&vlan_ioctl_mutex); 917 mutex_unlock(&vlan_ioctl_mutex);
880 break; 918 break;
881 case SIOCGIFDIVERT: 919 case SIOCGIFDIVERT:
882 case SIOCSIFDIVERT: 920 case SIOCSIFDIVERT:
@@ -890,9 +928,9 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
890 request_module("dlci"); 928 request_module("dlci");
891 929
892 if (dlci_ioctl_hook) { 930 if (dlci_ioctl_hook) {
893 down(&dlci_ioctl_mutex); 931 mutex_lock(&dlci_ioctl_mutex);
894 err = dlci_ioctl_hook(cmd, argp); 932 err = dlci_ioctl_hook(cmd, argp);
895 up(&dlci_ioctl_mutex); 933 mutex_unlock(&dlci_ioctl_mutex);
896 } 934 }
897 break; 935 break;
898 default: 936 default:
@@ -1286,19 +1324,17 @@ asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
1286{ 1324{
1287 struct socket *sock; 1325 struct socket *sock;
1288 char address[MAX_SOCK_ADDR]; 1326 char address[MAX_SOCK_ADDR];
1289 int err; 1327 int err, fput_needed;
1290 1328
1291 if((sock = sockfd_lookup(fd,&err))!=NULL) 1329 if((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL)
1292 { 1330 {
1293 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) { 1331 if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
1294 err = security_socket_bind(sock, (struct sockaddr *)address, addrlen); 1332 err = security_socket_bind(sock, (struct sockaddr *)address, addrlen);
1295 if (err) { 1333 if (!err)
1296 sockfd_put(sock); 1334 err = sock->ops->bind(sock,
1297 return err; 1335 (struct sockaddr *)address, addrlen);
1298 }
1299 err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen);
1300 } 1336 }
1301 sockfd_put(sock); 1337 fput_light(sock->file, fput_needed);
1302 } 1338 }
1303 return err; 1339 return err;
1304} 1340}
@@ -1315,20 +1351,17 @@ int sysctl_somaxconn = SOMAXCONN;
1315asmlinkage long sys_listen(int fd, int backlog) 1351asmlinkage long sys_listen(int fd, int backlog)
1316{ 1352{
1317 struct socket *sock; 1353 struct socket *sock;
1318 int err; 1354 int err, fput_needed;
1319 1355
1320 if ((sock = sockfd_lookup(fd, &err)) != NULL) { 1356 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) {
1321 if ((unsigned) backlog > sysctl_somaxconn) 1357 if ((unsigned) backlog > sysctl_somaxconn)
1322 backlog = sysctl_somaxconn; 1358 backlog = sysctl_somaxconn;
1323 1359
1324 err = security_socket_listen(sock, backlog); 1360 err = security_socket_listen(sock, backlog);
1325 if (err) { 1361 if (!err)
1326 sockfd_put(sock); 1362 err = sock->ops->listen(sock, backlog);
1327 return err;
1328 }
1329 1363
1330 err=sock->ops->listen(sock, backlog); 1364 fput_light(sock->file, fput_needed);
1331 sockfd_put(sock);
1332 } 1365 }
1333 return err; 1366 return err;
1334} 1367}
@@ -1349,10 +1382,11 @@ asmlinkage long sys_listen(int fd, int backlog)
1349asmlinkage 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)
1350{ 1383{
1351 struct socket *sock, *newsock; 1384 struct socket *sock, *newsock;
1352 int err, len; 1385 struct file *newfile;
1386 int err, len, newfd, fput_needed;
1353 char address[MAX_SOCK_ADDR]; 1387 char address[MAX_SOCK_ADDR];
1354 1388
1355 sock = sockfd_lookup(fd, &err); 1389 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1356 if (!sock) 1390 if (!sock)
1357 goto out; 1391 goto out;
1358 1392
@@ -1369,35 +1403,48 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int _
1369 */ 1403 */
1370 __module_get(newsock->ops->owner); 1404 __module_get(newsock->ops->owner);
1371 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
1372 err = security_socket_accept(sock, newsock); 1416 err = security_socket_accept(sock, newsock);
1373 if (err) 1417 if (err)
1374 goto out_release; 1418 goto out_fd;
1375 1419
1376 err = sock->ops->accept(sock, newsock, sock->file->f_flags); 1420 err = sock->ops->accept(sock, newsock, sock->file->f_flags);
1377 if (err < 0) 1421 if (err < 0)
1378 goto out_release; 1422 goto out_fd;
1379 1423
1380 if (upeer_sockaddr) { 1424 if (upeer_sockaddr) {
1381 if(newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 2)<0) { 1425 if(newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 2)<0) {
1382 err = -ECONNABORTED; 1426 err = -ECONNABORTED;
1383 goto out_release; 1427 goto out_fd;
1384 } 1428 }
1385 err = move_addr_to_user(address, len, upeer_sockaddr, upeer_addrlen); 1429 err = move_addr_to_user(address, len, upeer_sockaddr, upeer_addrlen);
1386 if (err < 0) 1430 if (err < 0)
1387 goto out_release; 1431 goto out_fd;
1388 } 1432 }
1389 1433
1390 /* File flags are not inherited via accept() unlike another OSes. */ 1434 /* File flags are not inherited via accept() unlike another OSes. */
1391 1435
1392 if ((err = sock_map_fd(newsock)) < 0) 1436 fd_install(newfd, newfile);
1393 goto out_release; 1437 err = newfd;
1394 1438
1395 security_socket_post_accept(sock, newsock); 1439 security_socket_post_accept(sock, newsock);
1396 1440
1397out_put: 1441out_put:
1398 sockfd_put(sock); 1442 fput_light(sock->file, fput_needed);
1399out: 1443out:
1400 return err; 1444 return err;
1445out_fd:
1446 put_filp(newfile);
1447 put_unused_fd(newfd);
1401out_release: 1448out_release:
1402 sock_release(newsock); 1449 sock_release(newsock);
1403 goto out_put; 1450 goto out_put;
@@ -1420,9 +1467,9 @@ asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrl
1420{ 1467{
1421 struct socket *sock; 1468 struct socket *sock;
1422 char address[MAX_SOCK_ADDR]; 1469 char address[MAX_SOCK_ADDR];
1423 int err; 1470 int err, fput_needed;
1424 1471
1425 sock = sockfd_lookup(fd, &err); 1472 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1426 if (!sock) 1473 if (!sock)
1427 goto out; 1474 goto out;
1428 err = move_addr_to_kernel(uservaddr, addrlen, address); 1475 err = move_addr_to_kernel(uservaddr, addrlen, address);
@@ -1436,7 +1483,7 @@ asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrl
1436 err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen, 1483 err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
1437 sock->file->f_flags); 1484 sock->file->f_flags);
1438out_put: 1485out_put:
1439 sockfd_put(sock); 1486 fput_light(sock->file, fput_needed);
1440out: 1487out:
1441 return err; 1488 return err;
1442} 1489}
@@ -1450,9 +1497,9 @@ asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int _
1450{ 1497{
1451 struct socket *sock; 1498 struct socket *sock;
1452 char address[MAX_SOCK_ADDR]; 1499 char address[MAX_SOCK_ADDR];
1453 int len, err; 1500 int len, err, fput_needed;
1454 1501
1455 sock = sockfd_lookup(fd, &err); 1502 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1456 if (!sock) 1503 if (!sock)
1457 goto out; 1504 goto out;
1458 1505
@@ -1466,7 +1513,7 @@ asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int _
1466 err = move_addr_to_user(address, len, usockaddr, usockaddr_len); 1513 err = move_addr_to_user(address, len, usockaddr, usockaddr_len);
1467 1514
1468out_put: 1515out_put:
1469 sockfd_put(sock); 1516 fput_light(sock->file, fput_needed);
1470out: 1517out:
1471 return err; 1518 return err;
1472} 1519}
@@ -1480,20 +1527,19 @@ asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int _
1480{ 1527{
1481 struct socket *sock; 1528 struct socket *sock;
1482 char address[MAX_SOCK_ADDR]; 1529 char address[MAX_SOCK_ADDR];
1483 int len, err; 1530 int len, err, fput_needed;
1484 1531
1485 if ((sock = sockfd_lookup(fd, &err))!=NULL) 1532 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) {
1486 {
1487 err = security_socket_getpeername(sock); 1533 err = security_socket_getpeername(sock);
1488 if (err) { 1534 if (err) {
1489 sockfd_put(sock); 1535 fput_light(sock->file, fput_needed);
1490 return err; 1536 return err;
1491 } 1537 }
1492 1538
1493 err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1); 1539 err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1);
1494 if (!err) 1540 if (!err)
1495 err=move_addr_to_user(address,len, usockaddr, usockaddr_len); 1541 err=move_addr_to_user(address,len, usockaddr, usockaddr_len);
1496 sockfd_put(sock); 1542 fput_light(sock->file, fput_needed);
1497 } 1543 }
1498 return err; 1544 return err;
1499} 1545}
@@ -1512,10 +1558,16 @@ asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flag
1512 int err; 1558 int err;
1513 struct msghdr msg; 1559 struct msghdr msg;
1514 struct iovec iov; 1560 struct iovec iov;
1515 1561 int fput_needed;
1516 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);
1517 if (!sock) 1569 if (!sock)
1518 goto out; 1570 goto out_put;
1519 iov.iov_base=buff; 1571 iov.iov_base=buff;
1520 iov.iov_len=len; 1572 iov.iov_len=len;
1521 msg.msg_name=NULL; 1573 msg.msg_name=NULL;
@@ -1524,8 +1576,7 @@ asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flag
1524 msg.msg_control=NULL; 1576 msg.msg_control=NULL;
1525 msg.msg_controllen=0; 1577 msg.msg_controllen=0;
1526 msg.msg_namelen=0; 1578 msg.msg_namelen=0;
1527 if(addr) 1579 if (addr) {
1528 {
1529 err = move_addr_to_kernel(addr, addr_len, address); 1580 err = move_addr_to_kernel(addr, addr_len, address);
1530 if (err < 0) 1581 if (err < 0)
1531 goto out_put; 1582 goto out_put;
@@ -1538,8 +1589,7 @@ asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flag
1538 err = sock_sendmsg(sock, &msg, len); 1589 err = sock_sendmsg(sock, &msg, len);
1539 1590
1540out_put: 1591out_put:
1541 sockfd_put(sock); 1592 fput_light(sock_file, fput_needed);
1542out:
1543 return err; 1593 return err;
1544} 1594}
1545 1595
@@ -1566,8 +1616,14 @@ asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned f
1566 struct msghdr msg; 1616 struct msghdr msg;
1567 char address[MAX_SOCK_ADDR]; 1617 char address[MAX_SOCK_ADDR];
1568 int err,err2; 1618 int err,err2;
1619 struct file *sock_file;
1620 int fput_needed;
1569 1621
1570 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);
1571 if (!sock) 1627 if (!sock)
1572 goto out; 1628 goto out;
1573 1629
@@ -1589,8 +1645,8 @@ asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned f
1589 if(err2<0) 1645 if(err2<0)
1590 err=err2; 1646 err=err2;
1591 } 1647 }
1592 sockfd_put(sock);
1593out: 1648out:
1649 fput_light(sock_file, fput_needed);
1594 return err; 1650 return err;
1595} 1651}
1596 1652
@@ -1610,25 +1666,24 @@ asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags
1610 1666
1611asmlinkage 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)
1612{ 1668{
1613 int err; 1669 int err, fput_needed;
1614 struct socket *sock; 1670 struct socket *sock;
1615 1671
1616 if (optlen < 0) 1672 if (optlen < 0)
1617 return -EINVAL; 1673 return -EINVAL;
1618 1674
1619 if ((sock = sockfd_lookup(fd, &err))!=NULL) 1675 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL)
1620 { 1676 {
1621 err = security_socket_setsockopt(sock,level,optname); 1677 err = security_socket_setsockopt(sock,level,optname);
1622 if (err) { 1678 if (err)
1623 sockfd_put(sock); 1679 goto out_put;
1624 return err;
1625 }
1626 1680
1627 if (level == SOL_SOCKET) 1681 if (level == SOL_SOCKET)
1628 err=sock_setsockopt(sock,level,optname,optval,optlen); 1682 err=sock_setsockopt(sock,level,optname,optval,optlen);
1629 else 1683 else
1630 err=sock->ops->setsockopt(sock, level, optname, optval, optlen); 1684 err=sock->ops->setsockopt(sock, level, optname, optval, optlen);
1631 sockfd_put(sock); 1685out_put:
1686 fput_light(sock->file, fput_needed);
1632 } 1687 }
1633 return err; 1688 return err;
1634} 1689}
@@ -1640,23 +1695,20 @@ asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optv
1640 1695
1641asmlinkage 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)
1642{ 1697{
1643 int err; 1698 int err, fput_needed;
1644 struct socket *sock; 1699 struct socket *sock;
1645 1700
1646 if ((sock = sockfd_lookup(fd, &err))!=NULL) 1701 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed)) != NULL) {
1647 { 1702 err = security_socket_getsockopt(sock, level, optname);
1648 err = security_socket_getsockopt(sock, level, 1703 if (err)
1649 optname); 1704 goto out_put;
1650 if (err) {
1651 sockfd_put(sock);
1652 return err;
1653 }
1654 1705
1655 if (level == SOL_SOCKET) 1706 if (level == SOL_SOCKET)
1656 err=sock_getsockopt(sock,level,optname,optval,optlen); 1707 err=sock_getsockopt(sock,level,optname,optval,optlen);
1657 else 1708 else
1658 err=sock->ops->getsockopt(sock, level, optname, optval, optlen); 1709 err=sock->ops->getsockopt(sock, level, optname, optval, optlen);
1659 sockfd_put(sock); 1710out_put:
1711 fput_light(sock->file, fput_needed);
1660 } 1712 }
1661 return err; 1713 return err;
1662} 1714}
@@ -1668,19 +1720,15 @@ asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optv
1668 1720
1669asmlinkage long sys_shutdown(int fd, int how) 1721asmlinkage long sys_shutdown(int fd, int how)
1670{ 1722{
1671 int err; 1723 int err, fput_needed;
1672 struct socket *sock; 1724 struct socket *sock;
1673 1725
1674 if ((sock = sockfd_lookup(fd, &err))!=NULL) 1726 if ((sock = sockfd_lookup_light(fd, &err, &fput_needed))!=NULL)
1675 { 1727 {
1676 err = security_socket_shutdown(sock, how); 1728 err = security_socket_shutdown(sock, how);
1677 if (err) { 1729 if (!err)
1678 sockfd_put(sock); 1730 err = sock->ops->shutdown(sock, how);
1679 return err; 1731 fput_light(sock->file, fput_needed);
1680 }
1681
1682 err=sock->ops->shutdown(sock, how);
1683 sockfd_put(sock);
1684 } 1732 }
1685 return err; 1733 return err;
1686} 1734}
@@ -1709,6 +1757,7 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
1709 unsigned char *ctl_buf = ctl; 1757 unsigned char *ctl_buf = ctl;
1710 struct msghdr msg_sys; 1758 struct msghdr msg_sys;
1711 int err, ctl_len, iov_size, total_len; 1759 int err, ctl_len, iov_size, total_len;
1760 int fput_needed;
1712 1761
1713 err = -EFAULT; 1762 err = -EFAULT;
1714 if (MSG_CMSG_COMPAT & flags) { 1763 if (MSG_CMSG_COMPAT & flags) {
@@ -1717,7 +1766,7 @@ asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
1717 } else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr))) 1766 } else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr)))
1718 return -EFAULT; 1767 return -EFAULT;
1719 1768
1720 sock = sockfd_lookup(fd, &err); 1769 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1721 if (!sock) 1770 if (!sock)
1722 goto out; 1771 goto out;
1723 1772
@@ -1785,7 +1834,7 @@ out_freeiov:
1785 if (iov != iovstack) 1834 if (iov != iovstack)
1786 sock_kfree_s(sock->sk, iov, iov_size); 1835 sock_kfree_s(sock->sk, iov, iov_size);
1787out_put: 1836out_put:
1788 sockfd_put(sock); 1837 fput_light(sock->file, fput_needed);
1789out: 1838out:
1790 return err; 1839 return err;
1791} 1840}
@@ -1803,6 +1852,7 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flag
1803 struct msghdr msg_sys; 1852 struct msghdr msg_sys;
1804 unsigned long cmsg_ptr; 1853 unsigned long cmsg_ptr;
1805 int err, iov_size, total_len, len; 1854 int err, iov_size, total_len, len;
1855 int fput_needed;
1806 1856
1807 /* kernel mode address */ 1857 /* kernel mode address */
1808 char addr[MAX_SOCK_ADDR]; 1858 char addr[MAX_SOCK_ADDR];
@@ -1818,7 +1868,7 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flag
1818 if (copy_from_user(&msg_sys,msg,sizeof(struct msghdr))) 1868 if (copy_from_user(&msg_sys,msg,sizeof(struct msghdr)))
1819 return -EFAULT; 1869 return -EFAULT;
1820 1870
1821 sock = sockfd_lookup(fd, &err); 1871 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1822 if (!sock) 1872 if (!sock)
1823 goto out; 1873 goto out;
1824 1874
@@ -1885,7 +1935,7 @@ out_freeiov:
1885 if (iov != iovstack) 1935 if (iov != iovstack)
1886 sock_kfree_s(sock->sk, iov, iov_size); 1936 sock_kfree_s(sock->sk, iov, iov_size);
1887out_put: 1937out_put:
1888 sockfd_put(sock); 1938 fput_light(sock->file, fput_needed);
1889out: 1939out:
1890 return err; 1940 return err;
1891} 1941}