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