diff options
Diffstat (limited to 'net/sctp/socket.c')
| -rw-r--r-- | net/sctp/socket.c | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 67fdac9d2d33..fbb70770ad05 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -67,6 +67,7 @@ | |||
| 67 | #include <linux/poll.h> | 67 | #include <linux/poll.h> |
| 68 | #include <linux/init.h> | 68 | #include <linux/init.h> |
| 69 | #include <linux/crypto.h> | 69 | #include <linux/crypto.h> |
| 70 | #include <linux/slab.h> | ||
| 70 | 71 | ||
| 71 | #include <net/ip.h> | 72 | #include <net/ip.h> |
| 72 | #include <net/icmp.h> | 73 | #include <net/icmp.h> |
| @@ -915,6 +916,11 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, | |||
| 915 | /* Walk through the addrs buffer and count the number of addresses. */ | 916 | /* Walk through the addrs buffer and count the number of addresses. */ |
| 916 | addr_buf = kaddrs; | 917 | addr_buf = kaddrs; |
| 917 | while (walk_size < addrs_size) { | 918 | while (walk_size < addrs_size) { |
| 919 | if (walk_size + sizeof(sa_family_t) > addrs_size) { | ||
| 920 | kfree(kaddrs); | ||
| 921 | return -EINVAL; | ||
| 922 | } | ||
| 923 | |||
| 918 | sa_addr = (struct sockaddr *)addr_buf; | 924 | sa_addr = (struct sockaddr *)addr_buf; |
| 919 | af = sctp_get_af_specific(sa_addr->sa_family); | 925 | af = sctp_get_af_specific(sa_addr->sa_family); |
| 920 | 926 | ||
| @@ -1001,9 +1007,13 @@ static int __sctp_connect(struct sock* sk, | |||
| 1001 | /* Walk through the addrs buffer and count the number of addresses. */ | 1007 | /* Walk through the addrs buffer and count the number of addresses. */ |
| 1002 | addr_buf = kaddrs; | 1008 | addr_buf = kaddrs; |
| 1003 | while (walk_size < addrs_size) { | 1009 | while (walk_size < addrs_size) { |
| 1010 | if (walk_size + sizeof(sa_family_t) > addrs_size) { | ||
| 1011 | err = -EINVAL; | ||
| 1012 | goto out_free; | ||
| 1013 | } | ||
| 1014 | |||
| 1004 | sa_addr = (union sctp_addr *)addr_buf; | 1015 | sa_addr = (union sctp_addr *)addr_buf; |
| 1005 | af = sctp_get_af_specific(sa_addr->sa.sa_family); | 1016 | af = sctp_get_af_specific(sa_addr->sa.sa_family); |
| 1006 | port = ntohs(sa_addr->v4.sin_port); | ||
| 1007 | 1017 | ||
| 1008 | /* If the address family is not supported or if this address | 1018 | /* If the address family is not supported or if this address |
| 1009 | * causes the address buffer to overflow return EINVAL. | 1019 | * causes the address buffer to overflow return EINVAL. |
| @@ -1013,6 +1023,8 @@ static int __sctp_connect(struct sock* sk, | |||
| 1013 | goto out_free; | 1023 | goto out_free; |
| 1014 | } | 1024 | } |
| 1015 | 1025 | ||
| 1026 | port = ntohs(sa_addr->v4.sin_port); | ||
| 1027 | |||
| 1016 | /* Save current address so we can work with it */ | 1028 | /* Save current address so we can work with it */ |
| 1017 | memcpy(&to, sa_addr, af->sockaddr_len); | 1029 | memcpy(&to, sa_addr, af->sockaddr_len); |
| 1018 | 1030 | ||
| @@ -3718,9 +3730,9 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
| 3718 | sp->hmac = NULL; | 3730 | sp->hmac = NULL; |
| 3719 | 3731 | ||
| 3720 | SCTP_DBG_OBJCNT_INC(sock); | 3732 | SCTP_DBG_OBJCNT_INC(sock); |
| 3721 | percpu_counter_inc(&sctp_sockets_allocated); | ||
| 3722 | 3733 | ||
| 3723 | local_bh_disable(); | 3734 | local_bh_disable(); |
| 3735 | percpu_counter_inc(&sctp_sockets_allocated); | ||
| 3724 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); | 3736 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); |
| 3725 | local_bh_enable(); | 3737 | local_bh_enable(); |
| 3726 | 3738 | ||
| @@ -3737,8 +3749,8 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk) | |||
| 3737 | /* Release our hold on the endpoint. */ | 3749 | /* Release our hold on the endpoint. */ |
| 3738 | ep = sctp_sk(sk)->ep; | 3750 | ep = sctp_sk(sk)->ep; |
| 3739 | sctp_endpoint_free(ep); | 3751 | sctp_endpoint_free(ep); |
| 3740 | percpu_counter_dec(&sctp_sockets_allocated); | ||
| 3741 | local_bh_disable(); | 3752 | local_bh_disable(); |
| 3753 | percpu_counter_dec(&sctp_sockets_allocated); | ||
| 3742 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); | 3754 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); |
| 3743 | local_bh_enable(); | 3755 | local_bh_enable(); |
| 3744 | } | 3756 | } |
| @@ -4383,7 +4395,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, | |||
| 4383 | transports) { | 4395 | transports) { |
| 4384 | memcpy(&temp, &from->ipaddr, sizeof(temp)); | 4396 | memcpy(&temp, &from->ipaddr, sizeof(temp)); |
| 4385 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); | 4397 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); |
| 4386 | addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len; | 4398 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; |
| 4387 | if (space_left < addrlen) | 4399 | if (space_left < addrlen) |
| 4388 | return -ENOMEM; | 4400 | return -ENOMEM; |
| 4389 | if (copy_to_user(to, &temp, addrlen)) | 4401 | if (copy_to_user(to, &temp, addrlen)) |
| @@ -5432,6 +5444,8 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) | |||
| 5432 | rover++; | 5444 | rover++; |
| 5433 | if ((rover < low) || (rover > high)) | 5445 | if ((rover < low) || (rover > high)) |
| 5434 | rover = low; | 5446 | rover = low; |
| 5447 | if (inet_is_reserved_local_port(rover)) | ||
| 5448 | continue; | ||
| 5435 | index = sctp_phashfn(rover); | 5449 | index = sctp_phashfn(rover); |
| 5436 | head = &sctp_port_hashtable[index]; | 5450 | head = &sctp_port_hashtable[index]; |
| 5437 | sctp_spin_lock(&head->lock); | 5451 | sctp_spin_lock(&head->lock); |
| @@ -5478,7 +5492,6 @@ pp_found: | |||
| 5478 | */ | 5492 | */ |
| 5479 | int reuse = sk->sk_reuse; | 5493 | int reuse = sk->sk_reuse; |
| 5480 | struct sock *sk2; | 5494 | struct sock *sk2; |
| 5481 | struct hlist_node *node; | ||
| 5482 | 5495 | ||
| 5483 | SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n"); | 5496 | SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n"); |
| 5484 | if (pp->fastreuse && sk->sk_reuse && | 5497 | if (pp->fastreuse && sk->sk_reuse && |
| @@ -5699,7 +5712,7 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
| 5699 | struct sctp_sock *sp = sctp_sk(sk); | 5712 | struct sctp_sock *sp = sctp_sk(sk); |
| 5700 | unsigned int mask; | 5713 | unsigned int mask; |
| 5701 | 5714 | ||
| 5702 | poll_wait(file, sk->sk_sleep, wait); | 5715 | poll_wait(file, sk_sleep(sk), wait); |
| 5703 | 5716 | ||
| 5704 | /* A TCP-style listening socket becomes readable when the accept queue | 5717 | /* A TCP-style listening socket becomes readable when the accept queue |
| 5705 | * is not empty. | 5718 | * is not empty. |
| @@ -5940,7 +5953,7 @@ static int sctp_wait_for_packet(struct sock * sk, int *err, long *timeo_p) | |||
| 5940 | int error; | 5953 | int error; |
| 5941 | DEFINE_WAIT(wait); | 5954 | DEFINE_WAIT(wait); |
| 5942 | 5955 | ||
| 5943 | prepare_to_wait_exclusive(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 5956 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
| 5944 | 5957 | ||
| 5945 | /* Socket errors? */ | 5958 | /* Socket errors? */ |
| 5946 | error = sock_error(sk); | 5959 | error = sock_error(sk); |
| @@ -5977,14 +5990,14 @@ static int sctp_wait_for_packet(struct sock * sk, int *err, long *timeo_p) | |||
| 5977 | sctp_lock_sock(sk); | 5990 | sctp_lock_sock(sk); |
| 5978 | 5991 | ||
| 5979 | ready: | 5992 | ready: |
| 5980 | finish_wait(sk->sk_sleep, &wait); | 5993 | finish_wait(sk_sleep(sk), &wait); |
| 5981 | return 0; | 5994 | return 0; |
| 5982 | 5995 | ||
| 5983 | interrupted: | 5996 | interrupted: |
| 5984 | error = sock_intr_errno(*timeo_p); | 5997 | error = sock_intr_errno(*timeo_p); |
| 5985 | 5998 | ||
| 5986 | out: | 5999 | out: |
| 5987 | finish_wait(sk->sk_sleep, &wait); | 6000 | finish_wait(sk_sleep(sk), &wait); |
| 5988 | *err = error; | 6001 | *err = error; |
| 5989 | return error; | 6002 | return error; |
| 5990 | } | 6003 | } |
| @@ -6058,14 +6071,14 @@ static void __sctp_write_space(struct sctp_association *asoc) | |||
| 6058 | wake_up_interruptible(&asoc->wait); | 6071 | wake_up_interruptible(&asoc->wait); |
| 6059 | 6072 | ||
| 6060 | if (sctp_writeable(sk)) { | 6073 | if (sctp_writeable(sk)) { |
| 6061 | if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) | 6074 | if (sk_sleep(sk) && waitqueue_active(sk_sleep(sk))) |
| 6062 | wake_up_interruptible(sk->sk_sleep); | 6075 | wake_up_interruptible(sk_sleep(sk)); |
| 6063 | 6076 | ||
| 6064 | /* Note that we try to include the Async I/O support | 6077 | /* Note that we try to include the Async I/O support |
| 6065 | * here by modeling from the current TCP/UDP code. | 6078 | * here by modeling from the current TCP/UDP code. |
| 6066 | * We have not tested with it yet. | 6079 | * We have not tested with it yet. |
| 6067 | */ | 6080 | */ |
| 6068 | if (sock->fasync_list && | 6081 | if (sock->wq->fasync_list && |
| 6069 | !(sk->sk_shutdown & SEND_SHUTDOWN)) | 6082 | !(sk->sk_shutdown & SEND_SHUTDOWN)) |
| 6070 | sock_wake_async(sock, | 6083 | sock_wake_async(sock, |
| 6071 | SOCK_WAKE_SPACE, POLL_OUT); | 6084 | SOCK_WAKE_SPACE, POLL_OUT); |
| @@ -6185,6 +6198,19 @@ do_nonblock: | |||
| 6185 | goto out; | 6198 | goto out; |
| 6186 | } | 6199 | } |
| 6187 | 6200 | ||
| 6201 | void sctp_data_ready(struct sock *sk, int len) | ||
| 6202 | { | ||
| 6203 | struct socket_wq *wq; | ||
| 6204 | |||
| 6205 | rcu_read_lock(); | ||
| 6206 | wq = rcu_dereference(sk->sk_wq); | ||
| 6207 | if (wq_has_sleeper(wq)) | ||
| 6208 | wake_up_interruptible_sync_poll(&wq->wait, POLLIN | | ||
| 6209 | POLLRDNORM | POLLRDBAND); | ||
| 6210 | sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); | ||
| 6211 | rcu_read_unlock(); | ||
| 6212 | } | ||
| 6213 | |||
| 6188 | /* If socket sndbuf has changed, wake up all per association waiters. */ | 6214 | /* If socket sndbuf has changed, wake up all per association waiters. */ |
| 6189 | void sctp_write_space(struct sock *sk) | 6215 | void sctp_write_space(struct sock *sk) |
| 6190 | { | 6216 | { |
| @@ -6293,7 +6319,7 @@ static int sctp_wait_for_accept(struct sock *sk, long timeo) | |||
| 6293 | 6319 | ||
| 6294 | 6320 | ||
| 6295 | for (;;) { | 6321 | for (;;) { |
| 6296 | prepare_to_wait_exclusive(sk->sk_sleep, &wait, | 6322 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, |
| 6297 | TASK_INTERRUPTIBLE); | 6323 | TASK_INTERRUPTIBLE); |
| 6298 | 6324 | ||
| 6299 | if (list_empty(&ep->asocs)) { | 6325 | if (list_empty(&ep->asocs)) { |
| @@ -6319,7 +6345,7 @@ static int sctp_wait_for_accept(struct sock *sk, long timeo) | |||
| 6319 | break; | 6345 | break; |
| 6320 | } | 6346 | } |
| 6321 | 6347 | ||
| 6322 | finish_wait(sk->sk_sleep, &wait); | 6348 | finish_wait(sk_sleep(sk), &wait); |
| 6323 | 6349 | ||
| 6324 | return err; | 6350 | return err; |
| 6325 | } | 6351 | } |
| @@ -6329,7 +6355,7 @@ static void sctp_wait_for_close(struct sock *sk, long timeout) | |||
| 6329 | DEFINE_WAIT(wait); | 6355 | DEFINE_WAIT(wait); |
| 6330 | 6356 | ||
| 6331 | do { | 6357 | do { |
| 6332 | prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); | 6358 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
| 6333 | if (list_empty(&sctp_sk(sk)->ep->asocs)) | 6359 | if (list_empty(&sctp_sk(sk)->ep->asocs)) |
| 6334 | break; | 6360 | break; |
| 6335 | sctp_release_sock(sk); | 6361 | sctp_release_sock(sk); |
| @@ -6337,7 +6363,7 @@ static void sctp_wait_for_close(struct sock *sk, long timeout) | |||
| 6337 | sctp_lock_sock(sk); | 6363 | sctp_lock_sock(sk); |
| 6338 | } while (!signal_pending(current) && timeout); | 6364 | } while (!signal_pending(current) && timeout); |
| 6339 | 6365 | ||
| 6340 | finish_wait(sk->sk_sleep, &wait); | 6366 | finish_wait(sk_sleep(sk), &wait); |
| 6341 | } | 6367 | } |
| 6342 | 6368 | ||
| 6343 | static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) | 6369 | static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) |
| @@ -6359,7 +6385,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk, | |||
| 6359 | struct sctp_association *asoc) | 6385 | struct sctp_association *asoc) |
| 6360 | { | 6386 | { |
| 6361 | struct inet_sock *inet = inet_sk(sk); | 6387 | struct inet_sock *inet = inet_sk(sk); |
| 6362 | struct inet_sock *newinet = inet_sk(newsk); | 6388 | struct inet_sock *newinet; |
| 6363 | 6389 | ||
| 6364 | newsk->sk_type = sk->sk_type; | 6390 | newsk->sk_type = sk->sk_type; |
| 6365 | newsk->sk_bound_dev_if = sk->sk_bound_dev_if; | 6391 | newsk->sk_bound_dev_if = sk->sk_bound_dev_if; |
