diff options
Diffstat (limited to 'net/compat.c')
| -rw-r--r-- | net/compat.c | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/net/compat.c b/net/compat.c index a1fb1b079a82..63d260e81472 100644 --- a/net/compat.c +++ b/net/compat.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 15 | #include <linux/gfp.h> | ||
| 15 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
| 16 | #include <linux/types.h> | 17 | #include <linux/types.h> |
| 17 | #include <linux/file.h> | 18 | #include <linux/file.h> |
| @@ -80,7 +81,7 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov, | |||
| 80 | int tot_len; | 81 | int tot_len; |
| 81 | 82 | ||
| 82 | if (kern_msg->msg_namelen) { | 83 | if (kern_msg->msg_namelen) { |
| 83 | if (mode==VERIFY_READ) { | 84 | if (mode == VERIFY_READ) { |
| 84 | int err = move_addr_to_kernel(kern_msg->msg_name, | 85 | int err = move_addr_to_kernel(kern_msg->msg_name, |
| 85 | kern_msg->msg_namelen, | 86 | kern_msg->msg_namelen, |
| 86 | kern_address); | 87 | kern_address); |
| @@ -353,7 +354,7 @@ static int do_set_attach_filter(struct socket *sock, int level, int optname, | |||
| 353 | static int do_set_sock_timeout(struct socket *sock, int level, | 354 | static int do_set_sock_timeout(struct socket *sock, int level, |
| 354 | int optname, char __user *optval, unsigned int optlen) | 355 | int optname, char __user *optval, unsigned int optlen) |
| 355 | { | 356 | { |
| 356 | struct compat_timeval __user *up = (struct compat_timeval __user *) optval; | 357 | struct compat_timeval __user *up = (struct compat_timeval __user *)optval; |
| 357 | struct timeval ktime; | 358 | struct timeval ktime; |
| 358 | mm_segment_t old_fs; | 359 | mm_segment_t old_fs; |
| 359 | int err; | 360 | int err; |
| @@ -366,7 +367,7 @@ static int do_set_sock_timeout(struct socket *sock, int level, | |||
| 366 | return -EFAULT; | 367 | return -EFAULT; |
| 367 | old_fs = get_fs(); | 368 | old_fs = get_fs(); |
| 368 | set_fs(KERNEL_DS); | 369 | set_fs(KERNEL_DS); |
| 369 | err = sock_setsockopt(sock, level, optname, (char *) &ktime, sizeof(ktime)); | 370 | err = sock_setsockopt(sock, level, optname, (char *)&ktime, sizeof(ktime)); |
| 370 | set_fs(old_fs); | 371 | set_fs(old_fs); |
| 371 | 372 | ||
| 372 | return err; | 373 | return err; |
| @@ -388,11 +389,10 @@ asmlinkage long compat_sys_setsockopt(int fd, int level, int optname, | |||
| 388 | char __user *optval, unsigned int optlen) | 389 | char __user *optval, unsigned int optlen) |
| 389 | { | 390 | { |
| 390 | int err; | 391 | int err; |
| 391 | struct socket *sock; | 392 | struct socket *sock = sockfd_lookup(fd, &err); |
| 392 | 393 | ||
| 393 | if ((sock = sockfd_lookup(fd, &err))!=NULL) | 394 | if (sock) { |
| 394 | { | 395 | err = security_socket_setsockopt(sock, level, optname); |
| 395 | err = security_socket_setsockopt(sock,level,optname); | ||
| 396 | if (err) { | 396 | if (err) { |
| 397 | sockfd_put(sock); | 397 | sockfd_put(sock); |
| 398 | return err; | 398 | return err; |
| @@ -452,7 +452,7 @@ static int compat_sock_getsockopt(struct socket *sock, int level, int optname, | |||
| 452 | int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) | 452 | int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) |
| 453 | { | 453 | { |
| 454 | struct compat_timeval __user *ctv = | 454 | struct compat_timeval __user *ctv = |
| 455 | (struct compat_timeval __user*) userstamp; | 455 | (struct compat_timeval __user *) userstamp; |
| 456 | int err = -ENOENT; | 456 | int err = -ENOENT; |
| 457 | struct timeval tv; | 457 | struct timeval tv; |
| 458 | 458 | ||
| @@ -476,7 +476,7 @@ EXPORT_SYMBOL(compat_sock_get_timestamp); | |||
| 476 | int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp) | 476 | int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp) |
| 477 | { | 477 | { |
| 478 | struct compat_timespec __user *ctv = | 478 | struct compat_timespec __user *ctv = |
| 479 | (struct compat_timespec __user*) userstamp; | 479 | (struct compat_timespec __user *) userstamp; |
| 480 | int err = -ENOENT; | 480 | int err = -ENOENT; |
| 481 | struct timespec ts; | 481 | struct timespec ts; |
| 482 | 482 | ||
| @@ -501,12 +501,10 @@ asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, | |||
| 501 | char __user *optval, int __user *optlen) | 501 | char __user *optval, int __user *optlen) |
| 502 | { | 502 | { |
| 503 | int err; | 503 | int err; |
| 504 | struct socket *sock; | 504 | struct socket *sock = sockfd_lookup(fd, &err); |
| 505 | 505 | ||
| 506 | if ((sock = sockfd_lookup(fd, &err))!=NULL) | 506 | if (sock) { |
| 507 | { | 507 | err = security_socket_getsockopt(sock, level, optname); |
| 508 | err = security_socket_getsockopt(sock, level, | ||
| 509 | optname); | ||
| 510 | if (err) { | 508 | if (err) { |
| 511 | sockfd_put(sock); | 509 | sockfd_put(sock); |
| 512 | return err; | 510 | return err; |
| @@ -530,7 +528,7 @@ struct compat_group_req { | |||
| 530 | __u32 gr_interface; | 528 | __u32 gr_interface; |
| 531 | struct __kernel_sockaddr_storage gr_group | 529 | struct __kernel_sockaddr_storage gr_group |
| 532 | __attribute__ ((aligned(4))); | 530 | __attribute__ ((aligned(4))); |
| 533 | } __attribute__ ((packed)); | 531 | } __packed; |
| 534 | 532 | ||
| 535 | struct compat_group_source_req { | 533 | struct compat_group_source_req { |
| 536 | __u32 gsr_interface; | 534 | __u32 gsr_interface; |
| @@ -538,7 +536,7 @@ struct compat_group_source_req { | |||
| 538 | __attribute__ ((aligned(4))); | 536 | __attribute__ ((aligned(4))); |
| 539 | struct __kernel_sockaddr_storage gsr_source | 537 | struct __kernel_sockaddr_storage gsr_source |
| 540 | __attribute__ ((aligned(4))); | 538 | __attribute__ ((aligned(4))); |
| 541 | } __attribute__ ((packed)); | 539 | } __packed; |
| 542 | 540 | ||
| 543 | struct compat_group_filter { | 541 | struct compat_group_filter { |
| 544 | __u32 gf_interface; | 542 | __u32 gf_interface; |
| @@ -548,7 +546,7 @@ struct compat_group_filter { | |||
| 548 | __u32 gf_numsrc; | 546 | __u32 gf_numsrc; |
| 549 | struct __kernel_sockaddr_storage gf_slist[1] | 547 | struct __kernel_sockaddr_storage gf_slist[1] |
| 550 | __attribute__ ((aligned(4))); | 548 | __attribute__ ((aligned(4))); |
| 551 | } __attribute__ ((packed)); | 549 | } __packed; |
| 552 | 550 | ||
| 553 | #define __COMPAT_GF0_SIZE (sizeof(struct compat_group_filter) - \ | 551 | #define __COMPAT_GF0_SIZE (sizeof(struct compat_group_filter) - \ |
| 554 | sizeof(struct __kernel_sockaddr_storage)) | 552 | sizeof(struct __kernel_sockaddr_storage)) |
| @@ -556,7 +554,7 @@ struct compat_group_filter { | |||
| 556 | 554 | ||
| 557 | int compat_mc_setsockopt(struct sock *sock, int level, int optname, | 555 | int compat_mc_setsockopt(struct sock *sock, int level, int optname, |
| 558 | char __user *optval, unsigned int optlen, | 556 | char __user *optval, unsigned int optlen, |
| 559 | int (*setsockopt)(struct sock *,int,int,char __user *,unsigned int)) | 557 | int (*setsockopt)(struct sock *, int, int, char __user *, unsigned int)) |
| 560 | { | 558 | { |
| 561 | char __user *koptval = optval; | 559 | char __user *koptval = optval; |
| 562 | int koptlen = optlen; | 560 | int koptlen = optlen; |
| @@ -639,12 +637,11 @@ int compat_mc_setsockopt(struct sock *sock, int level, int optname, | |||
| 639 | } | 637 | } |
| 640 | return setsockopt(sock, level, optname, koptval, koptlen); | 638 | return setsockopt(sock, level, optname, koptval, koptlen); |
| 641 | } | 639 | } |
| 642 | |||
| 643 | EXPORT_SYMBOL(compat_mc_setsockopt); | 640 | EXPORT_SYMBOL(compat_mc_setsockopt); |
| 644 | 641 | ||
| 645 | int compat_mc_getsockopt(struct sock *sock, int level, int optname, | 642 | int compat_mc_getsockopt(struct sock *sock, int level, int optname, |
| 646 | char __user *optval, int __user *optlen, | 643 | char __user *optval, int __user *optlen, |
| 647 | int (*getsockopt)(struct sock *,int,int,char __user *,int __user *)) | 644 | int (*getsockopt)(struct sock *, int, int, char __user *, int __user *)) |
| 648 | { | 645 | { |
| 649 | struct compat_group_filter __user *gf32 = (void *)optval; | 646 | struct compat_group_filter __user *gf32 = (void *)optval; |
| 650 | struct group_filter __user *kgf; | 647 | struct group_filter __user *kgf; |
| @@ -680,7 +677,7 @@ int compat_mc_getsockopt(struct sock *sock, int level, int optname, | |||
| 680 | __put_user(interface, &kgf->gf_interface) || | 677 | __put_user(interface, &kgf->gf_interface) || |
| 681 | __put_user(fmode, &kgf->gf_fmode) || | 678 | __put_user(fmode, &kgf->gf_fmode) || |
| 682 | __put_user(numsrc, &kgf->gf_numsrc) || | 679 | __put_user(numsrc, &kgf->gf_numsrc) || |
| 683 | copy_in_user(&kgf->gf_group,&gf32->gf_group,sizeof(kgf->gf_group))) | 680 | copy_in_user(&kgf->gf_group, &gf32->gf_group, sizeof(kgf->gf_group))) |
| 684 | return -EFAULT; | 681 | return -EFAULT; |
| 685 | 682 | ||
| 686 | err = getsockopt(sock, level, optname, (char __user *)kgf, koptlen); | 683 | err = getsockopt(sock, level, optname, (char __user *)kgf, koptlen); |
| @@ -713,21 +710,22 @@ int compat_mc_getsockopt(struct sock *sock, int level, int optname, | |||
| 713 | copylen = numsrc * sizeof(gf32->gf_slist[0]); | 710 | copylen = numsrc * sizeof(gf32->gf_slist[0]); |
| 714 | if (copylen > klen) | 711 | if (copylen > klen) |
| 715 | copylen = klen; | 712 | copylen = klen; |
| 716 | if (copy_in_user(gf32->gf_slist, kgf->gf_slist, copylen)) | 713 | if (copy_in_user(gf32->gf_slist, kgf->gf_slist, copylen)) |
| 717 | return -EFAULT; | 714 | return -EFAULT; |
| 718 | } | 715 | } |
| 719 | return err; | 716 | return err; |
| 720 | } | 717 | } |
| 721 | |||
| 722 | EXPORT_SYMBOL(compat_mc_getsockopt); | 718 | EXPORT_SYMBOL(compat_mc_getsockopt); |
| 723 | 719 | ||
| 724 | 720 | ||
| 725 | /* Argument list sizes for compat_sys_socketcall */ | 721 | /* Argument list sizes for compat_sys_socketcall */ |
| 726 | #define AL(x) ((x) * sizeof(u32)) | 722 | #define AL(x) ((x) * sizeof(u32)) |
| 727 | static unsigned char nas[20]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), | 723 | static unsigned char nas[20] = { |
| 728 | AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), | 724 | AL(0), AL(3), AL(3), AL(3), AL(2), AL(3), |
| 729 | AL(6),AL(2),AL(5),AL(5),AL(3),AL(3), | 725 | AL(3), AL(3), AL(4), AL(4), AL(4), AL(6), |
| 730 | AL(4),AL(5)}; | 726 | AL(6), AL(2), AL(5), AL(5), AL(3), AL(3), |
| 727 | AL(4), AL(5) | ||
| 728 | }; | ||
| 731 | #undef AL | 729 | #undef AL |
| 732 | 730 | ||
| 733 | asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned flags) | 731 | asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned flags) |
| @@ -826,7 +824,7 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args) | |||
| 826 | compat_ptr(a[4]), compat_ptr(a[5])); | 824 | compat_ptr(a[4]), compat_ptr(a[5])); |
| 827 | break; | 825 | break; |
| 828 | case SYS_SHUTDOWN: | 826 | case SYS_SHUTDOWN: |
| 829 | ret = sys_shutdown(a0,a1); | 827 | ret = sys_shutdown(a0, a1); |
| 830 | break; | 828 | break; |
| 831 | case SYS_SETSOCKOPT: | 829 | case SYS_SETSOCKOPT: |
| 832 | ret = compat_sys_setsockopt(a0, a1, a[2], | 830 | ret = compat_sys_setsockopt(a0, a1, a[2], |
