diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2010-12-30 00:20:30 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-12-30 00:21:47 -0500 |
commit | d392da5207352f09030e95d9ea335a4225667ec0 (patch) | |
tree | 7d6cd1932afcad0a5619a5c504a6d93ca318187c /net/sctp/socket.c | |
parent | e39d5ef678045d61812c1401f04fe8edb14d6359 (diff) | |
parent | 387c31c7e5c9805b0aef8833d1731a5fe7bdea14 (diff) |
Merge v2.6.37-rc8 into powerpc/next
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 112 |
1 files changed, 77 insertions, 35 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ca44917872d2..fff0926b1111 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -57,6 +57,8 @@ | |||
57 | * be incorporated into the next SCTP release. | 57 | * be incorporated into the next SCTP release. |
58 | */ | 58 | */ |
59 | 59 | ||
60 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
61 | |||
60 | #include <linux/types.h> | 62 | #include <linux/types.h> |
61 | #include <linux/kernel.h> | 63 | #include <linux/kernel.h> |
62 | #include <linux/wait.h> | 64 | #include <linux/wait.h> |
@@ -109,12 +111,12 @@ static void sctp_sock_migrate(struct sock *, struct sock *, | |||
109 | static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; | 111 | static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; |
110 | 112 | ||
111 | extern struct kmem_cache *sctp_bucket_cachep; | 113 | extern struct kmem_cache *sctp_bucket_cachep; |
112 | extern int sysctl_sctp_mem[3]; | 114 | extern long sysctl_sctp_mem[3]; |
113 | extern int sysctl_sctp_rmem[3]; | 115 | extern int sysctl_sctp_rmem[3]; |
114 | extern int sysctl_sctp_wmem[3]; | 116 | extern int sysctl_sctp_wmem[3]; |
115 | 117 | ||
116 | static int sctp_memory_pressure; | 118 | static int sctp_memory_pressure; |
117 | static atomic_t sctp_memory_allocated; | 119 | static atomic_long_t sctp_memory_allocated; |
118 | struct percpu_counter sctp_sockets_allocated; | 120 | struct percpu_counter sctp_sockets_allocated; |
119 | 121 | ||
120 | static void sctp_enter_memory_pressure(struct sock *sk) | 122 | static void sctp_enter_memory_pressure(struct sock *sk) |
@@ -916,6 +918,11 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, | |||
916 | /* Walk through the addrs buffer and count the number of addresses. */ | 918 | /* Walk through the addrs buffer and count the number of addresses. */ |
917 | addr_buf = kaddrs; | 919 | addr_buf = kaddrs; |
918 | while (walk_size < addrs_size) { | 920 | while (walk_size < addrs_size) { |
921 | if (walk_size + sizeof(sa_family_t) > addrs_size) { | ||
922 | kfree(kaddrs); | ||
923 | return -EINVAL; | ||
924 | } | ||
925 | |||
919 | sa_addr = (struct sockaddr *)addr_buf; | 926 | sa_addr = (struct sockaddr *)addr_buf; |
920 | af = sctp_get_af_specific(sa_addr->sa_family); | 927 | af = sctp_get_af_specific(sa_addr->sa_family); |
921 | 928 | ||
@@ -1002,9 +1009,13 @@ static int __sctp_connect(struct sock* sk, | |||
1002 | /* Walk through the addrs buffer and count the number of addresses. */ | 1009 | /* Walk through the addrs buffer and count the number of addresses. */ |
1003 | addr_buf = kaddrs; | 1010 | addr_buf = kaddrs; |
1004 | while (walk_size < addrs_size) { | 1011 | while (walk_size < addrs_size) { |
1012 | if (walk_size + sizeof(sa_family_t) > addrs_size) { | ||
1013 | err = -EINVAL; | ||
1014 | goto out_free; | ||
1015 | } | ||
1016 | |||
1005 | sa_addr = (union sctp_addr *)addr_buf; | 1017 | sa_addr = (union sctp_addr *)addr_buf; |
1006 | af = sctp_get_af_specific(sa_addr->sa.sa_family); | 1018 | af = sctp_get_af_specific(sa_addr->sa.sa_family); |
1007 | port = ntohs(sa_addr->v4.sin_port); | ||
1008 | 1019 | ||
1009 | /* If the address family is not supported or if this address | 1020 | /* If the address family is not supported or if this address |
1010 | * causes the address buffer to overflow return EINVAL. | 1021 | * causes the address buffer to overflow return EINVAL. |
@@ -1014,6 +1025,8 @@ static int __sctp_connect(struct sock* sk, | |||
1014 | goto out_free; | 1025 | goto out_free; |
1015 | } | 1026 | } |
1016 | 1027 | ||
1028 | port = ntohs(sa_addr->v4.sin_port); | ||
1029 | |||
1017 | /* Save current address so we can work with it */ | 1030 | /* Save current address so we can work with it */ |
1018 | memcpy(&to, sa_addr, af->sockaddr_len); | 1031 | memcpy(&to, sa_addr, af->sockaddr_len); |
1019 | 1032 | ||
@@ -2458,9 +2471,8 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk, | |||
2458 | if (params.sack_delay == 0 && params.sack_freq == 0) | 2471 | if (params.sack_delay == 0 && params.sack_freq == 0) |
2459 | return 0; | 2472 | return 0; |
2460 | } else if (optlen == sizeof(struct sctp_assoc_value)) { | 2473 | } else if (optlen == sizeof(struct sctp_assoc_value)) { |
2461 | printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value " | 2474 | pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n"); |
2462 | "in delayed_ack socket option deprecated\n"); | 2475 | pr_warn("Use struct sctp_sack_info instead\n"); |
2463 | printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n"); | ||
2464 | if (copy_from_user(¶ms, optval, optlen)) | 2476 | if (copy_from_user(¶ms, optval, optlen)) |
2465 | return -EFAULT; | 2477 | return -EFAULT; |
2466 | 2478 | ||
@@ -2868,10 +2880,8 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned | |||
2868 | int val; | 2880 | int val; |
2869 | 2881 | ||
2870 | if (optlen == sizeof(int)) { | 2882 | if (optlen == sizeof(int)) { |
2871 | printk(KERN_WARNING | 2883 | pr_warn("Use of int in maxseg socket option deprecated\n"); |
2872 | "SCTP: Use of int in maxseg socket option deprecated\n"); | 2884 | pr_warn("Use struct sctp_assoc_value instead\n"); |
2873 | printk(KERN_WARNING | ||
2874 | "SCTP: Use struct sctp_assoc_value instead\n"); | ||
2875 | if (copy_from_user(&val, optval, optlen)) | 2885 | if (copy_from_user(&val, optval, optlen)) |
2876 | return -EFAULT; | 2886 | return -EFAULT; |
2877 | params.assoc_id = 0; | 2887 | params.assoc_id = 0; |
@@ -2922,6 +2932,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva | |||
2922 | struct sctp_association *asoc = NULL; | 2932 | struct sctp_association *asoc = NULL; |
2923 | struct sctp_setpeerprim prim; | 2933 | struct sctp_setpeerprim prim; |
2924 | struct sctp_chunk *chunk; | 2934 | struct sctp_chunk *chunk; |
2935 | struct sctp_af *af; | ||
2925 | int err; | 2936 | int err; |
2926 | 2937 | ||
2927 | sp = sctp_sk(sk); | 2938 | sp = sctp_sk(sk); |
@@ -2949,6 +2960,13 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva | |||
2949 | if (!sctp_state(asoc, ESTABLISHED)) | 2960 | if (!sctp_state(asoc, ESTABLISHED)) |
2950 | return -ENOTCONN; | 2961 | return -ENOTCONN; |
2951 | 2962 | ||
2963 | af = sctp_get_af_specific(prim.sspp_addr.ss_family); | ||
2964 | if (!af) | ||
2965 | return -EINVAL; | ||
2966 | |||
2967 | if (!af->addr_valid((union sctp_addr *)&prim.sspp_addr, sp, NULL)) | ||
2968 | return -EADDRNOTAVAIL; | ||
2969 | |||
2952 | if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr)) | 2970 | if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr)) |
2953 | return -EADDRNOTAVAIL; | 2971 | return -EADDRNOTAVAIL; |
2954 | 2972 | ||
@@ -3121,10 +3139,8 @@ static int sctp_setsockopt_maxburst(struct sock *sk, | |||
3121 | int assoc_id = 0; | 3139 | int assoc_id = 0; |
3122 | 3140 | ||
3123 | if (optlen == sizeof(int)) { | 3141 | if (optlen == sizeof(int)) { |
3124 | printk(KERN_WARNING | 3142 | pr_warn("Use of int in max_burst socket option deprecated\n"); |
3125 | "SCTP: Use of int in max_burst socket option deprecated\n"); | 3143 | pr_warn("Use struct sctp_assoc_value instead\n"); |
3126 | printk(KERN_WARNING | ||
3127 | "SCTP: Use struct sctp_assoc_value instead\n"); | ||
3128 | if (copy_from_user(&val, optval, optlen)) | 3144 | if (copy_from_user(&val, optval, optlen)) |
3129 | return -EFAULT; | 3145 | return -EFAULT; |
3130 | } else if (optlen == sizeof(struct sctp_assoc_value)) { | 3146 | } else if (optlen == sizeof(struct sctp_assoc_value)) { |
@@ -3595,7 +3611,40 @@ out: | |||
3595 | /* The SCTP ioctl handler. */ | 3611 | /* The SCTP ioctl handler. */ |
3596 | SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg) | 3612 | SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg) |
3597 | { | 3613 | { |
3598 | return -ENOIOCTLCMD; | 3614 | int rc = -ENOTCONN; |
3615 | |||
3616 | sctp_lock_sock(sk); | ||
3617 | |||
3618 | /* | ||
3619 | * SEQPACKET-style sockets in LISTENING state are valid, for | ||
3620 | * SCTP, so only discard TCP-style sockets in LISTENING state. | ||
3621 | */ | ||
3622 | if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) | ||
3623 | goto out; | ||
3624 | |||
3625 | switch (cmd) { | ||
3626 | case SIOCINQ: { | ||
3627 | struct sk_buff *skb; | ||
3628 | unsigned int amount = 0; | ||
3629 | |||
3630 | skb = skb_peek(&sk->sk_receive_queue); | ||
3631 | if (skb != NULL) { | ||
3632 | /* | ||
3633 | * We will only return the amount of this packet since | ||
3634 | * that is all that will be read. | ||
3635 | */ | ||
3636 | amount = skb->len; | ||
3637 | } | ||
3638 | rc = put_user(amount, (int __user *)arg); | ||
3639 | break; | ||
3640 | } | ||
3641 | default: | ||
3642 | rc = -ENOIOCTLCMD; | ||
3643 | break; | ||
3644 | } | ||
3645 | out: | ||
3646 | sctp_release_sock(sk); | ||
3647 | return rc; | ||
3599 | } | 3648 | } |
3600 | 3649 | ||
3601 | /* This is the function which gets called during socket creation to | 3650 | /* This is the function which gets called during socket creation to |
@@ -3854,7 +3903,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, | |||
3854 | } | 3903 | } |
3855 | 3904 | ||
3856 | out: | 3905 | out: |
3857 | return (retval); | 3906 | return retval; |
3858 | } | 3907 | } |
3859 | 3908 | ||
3860 | 3909 | ||
@@ -3910,7 +3959,7 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len, | |||
3910 | } | 3959 | } |
3911 | 3960 | ||
3912 | out: | 3961 | out: |
3913 | return (retval); | 3962 | return retval; |
3914 | } | 3963 | } |
3915 | 3964 | ||
3916 | /* 7.1.12 Enable/Disable message fragmentation (SCTP_DISABLE_FRAGMENTS) | 3965 | /* 7.1.12 Enable/Disable message fragmentation (SCTP_DISABLE_FRAGMENTS) |
@@ -4281,9 +4330,8 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len, | |||
4281 | if (copy_from_user(¶ms, optval, len)) | 4330 | if (copy_from_user(¶ms, optval, len)) |
4282 | return -EFAULT; | 4331 | return -EFAULT; |
4283 | } else if (len == sizeof(struct sctp_assoc_value)) { | 4332 | } else if (len == sizeof(struct sctp_assoc_value)) { |
4284 | printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value " | 4333 | pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n"); |
4285 | "in delayed_ack socket option deprecated\n"); | 4334 | pr_warn("Use struct sctp_sack_info instead\n"); |
4286 | printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n"); | ||
4287 | if (copy_from_user(¶ms, optval, len)) | 4335 | if (copy_from_user(¶ms, optval, len)) |
4288 | return -EFAULT; | 4336 | return -EFAULT; |
4289 | } else | 4337 | } else |
@@ -4929,10 +4977,8 @@ static int sctp_getsockopt_maxseg(struct sock *sk, int len, | |||
4929 | struct sctp_association *asoc; | 4977 | struct sctp_association *asoc; |
4930 | 4978 | ||
4931 | if (len == sizeof(int)) { | 4979 | if (len == sizeof(int)) { |
4932 | printk(KERN_WARNING | 4980 | pr_warn("Use of int in maxseg socket option deprecated\n"); |
4933 | "SCTP: Use of int in maxseg socket option deprecated\n"); | 4981 | pr_warn("Use struct sctp_assoc_value instead\n"); |
4934 | printk(KERN_WARNING | ||
4935 | "SCTP: Use struct sctp_assoc_value instead\n"); | ||
4936 | params.assoc_id = 0; | 4982 | params.assoc_id = 0; |
4937 | } else if (len >= sizeof(struct sctp_assoc_value)) { | 4983 | } else if (len >= sizeof(struct sctp_assoc_value)) { |
4938 | len = sizeof(struct sctp_assoc_value); | 4984 | len = sizeof(struct sctp_assoc_value); |
@@ -5007,7 +5053,7 @@ static int sctp_getsockopt_partial_delivery_point(struct sock *sk, int len, | |||
5007 | if (copy_to_user(optval, &val, len)) | 5053 | if (copy_to_user(optval, &val, len)) |
5008 | return -EFAULT; | 5054 | return -EFAULT; |
5009 | 5055 | ||
5010 | return -ENOTSUPP; | 5056 | return 0; |
5011 | } | 5057 | } |
5012 | 5058 | ||
5013 | /* | 5059 | /* |
@@ -5023,10 +5069,8 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len, | |||
5023 | struct sctp_association *asoc; | 5069 | struct sctp_association *asoc; |
5024 | 5070 | ||
5025 | if (len == sizeof(int)) { | 5071 | if (len == sizeof(int)) { |
5026 | printk(KERN_WARNING | 5072 | pr_warn("Use of int in max_burst socket option deprecated\n"); |
5027 | "SCTP: Use of int in max_burst socket option deprecated\n"); | 5073 | pr_warn("Use struct sctp_assoc_value instead\n"); |
5028 | printk(KERN_WARNING | ||
5029 | "SCTP: Use struct sctp_assoc_value instead\n"); | ||
5030 | params.assoc_id = 0; | 5074 | params.assoc_id = 0; |
5031 | } else if (len >= sizeof(struct sctp_assoc_value)) { | 5075 | } else if (len >= sizeof(struct sctp_assoc_value)) { |
5032 | len = sizeof(struct sctp_assoc_value); | 5076 | len = sizeof(struct sctp_assoc_value); |
@@ -5569,7 +5613,7 @@ static int sctp_get_port(struct sock *sk, unsigned short snum) | |||
5569 | /* Note: sk->sk_num gets filled in if ephemeral port request. */ | 5613 | /* Note: sk->sk_num gets filled in if ephemeral port request. */ |
5570 | ret = sctp_get_port_local(sk, &addr); | 5614 | ret = sctp_get_port_local(sk, &addr); |
5571 | 5615 | ||
5572 | return (ret ? 1 : 0); | 5616 | return ret ? 1 : 0; |
5573 | } | 5617 | } |
5574 | 5618 | ||
5575 | /* | 5619 | /* |
@@ -5586,8 +5630,7 @@ SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog) | |||
5586 | tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); | 5630 | tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); |
5587 | if (IS_ERR(tfm)) { | 5631 | if (IS_ERR(tfm)) { |
5588 | if (net_ratelimit()) { | 5632 | if (net_ratelimit()) { |
5589 | printk(KERN_INFO | 5633 | pr_info("failed to load transform for %s: %ld\n", |
5590 | "SCTP: failed to load transform for %s: %ld\n", | ||
5591 | sctp_hmac_alg, PTR_ERR(tfm)); | 5634 | sctp_hmac_alg, PTR_ERR(tfm)); |
5592 | } | 5635 | } |
5593 | return -ENOSYS; | 5636 | return -ENOSYS; |
@@ -5716,13 +5759,12 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
5716 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) | 5759 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) |
5717 | mask |= POLLERR; | 5760 | mask |= POLLERR; |
5718 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 5761 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
5719 | mask |= POLLRDHUP; | 5762 | mask |= POLLRDHUP | POLLIN | POLLRDNORM; |
5720 | if (sk->sk_shutdown == SHUTDOWN_MASK) | 5763 | if (sk->sk_shutdown == SHUTDOWN_MASK) |
5721 | mask |= POLLHUP; | 5764 | mask |= POLLHUP; |
5722 | 5765 | ||
5723 | /* Is it readable? Reconsider this code with TCP-style support. */ | 5766 | /* Is it readable? Reconsider this code with TCP-style support. */ |
5724 | if (!skb_queue_empty(&sk->sk_receive_queue) || | 5767 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
5725 | (sk->sk_shutdown & RCV_SHUTDOWN)) | ||
5726 | mask |= POLLIN | POLLRDNORM; | 5768 | mask |= POLLIN | POLLRDNORM; |
5727 | 5769 | ||
5728 | /* The association is either gone or not ready. */ | 5770 | /* The association is either gone or not ready. */ |