diff options
-rw-r--r-- | include/net/sctp/sctp.h | 10 | ||||
-rw-r--r-- | net/sctp/input.c | 2 | ||||
-rw-r--r-- | net/sctp/ipv6.c | 2 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 6 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 103 | ||||
-rw-r--r-- | net/sctp/socket.c | 45 | ||||
-rw-r--r-- | net/sctp/tsnmap.c | 14 |
7 files changed, 123 insertions, 59 deletions
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 16baef4dab7e..d529045c1679 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h | |||
@@ -190,6 +190,16 @@ void sctp_assocs_proc_exit(void); | |||
190 | 190 | ||
191 | 191 | ||
192 | /* | 192 | /* |
193 | * Module global variables | ||
194 | */ | ||
195 | |||
196 | /* | ||
197 | * sctp/protocol.c | ||
198 | */ | ||
199 | extern struct kmem_cache *sctp_chunk_cachep __read_mostly; | ||
200 | extern struct kmem_cache *sctp_bucket_cachep __read_mostly; | ||
201 | |||
202 | /* | ||
193 | * Section: Macros, externs, and inlines | 203 | * Section: Macros, externs, and inlines |
194 | */ | 204 | */ |
195 | 205 | ||
diff --git a/net/sctp/input.c b/net/sctp/input.c index d57ff7f3c576..47e56017f4ce 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -590,7 +590,7 @@ out_unlock: | |||
590 | * Return 0 - If further processing is needed. | 590 | * Return 0 - If further processing is needed. |
591 | * Return 1 - If the packet can be discarded right away. | 591 | * Return 1 - If the packet can be discarded right away. |
592 | */ | 592 | */ |
593 | int sctp_rcv_ootb(struct sk_buff *skb) | 593 | static int sctp_rcv_ootb(struct sk_buff *skb) |
594 | { | 594 | { |
595 | sctp_chunkhdr_t *ch; | 595 | sctp_chunkhdr_t *ch; |
596 | __u8 *ch_end; | 596 | __u8 *ch_end; |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 2c29394fd92e..f8aa23dda1c1 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -641,6 +641,8 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk, | |||
641 | newsctp6sk = (struct sctp6_sock *)newsk; | 641 | newsctp6sk = (struct sctp6_sock *)newsk; |
642 | inet_sk(newsk)->pinet6 = &newsctp6sk->inet6; | 642 | inet_sk(newsk)->pinet6 = &newsctp6sk->inet6; |
643 | 643 | ||
644 | sctp_sk(newsk)->v4mapped = sctp_sk(sk)->v4mapped; | ||
645 | |||
644 | newinet = inet_sk(newsk); | 646 | newinet = inet_sk(newsk); |
645 | newnp = inet6_sk(newsk); | 647 | newnp = inet6_sk(newsk); |
646 | 648 | ||
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 8d18f570c2e6..51c4d7fef1d2 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -65,8 +65,6 @@ | |||
65 | #include <net/sctp/sctp.h> | 65 | #include <net/sctp/sctp.h> |
66 | #include <net/sctp/sm.h> | 66 | #include <net/sctp/sm.h> |
67 | 67 | ||
68 | extern struct kmem_cache *sctp_chunk_cachep; | ||
69 | |||
70 | SCTP_STATIC | 68 | SCTP_STATIC |
71 | struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc, | 69 | struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc, |
72 | __u8 type, __u8 flags, int paylen); | 70 | __u8 type, __u8 flags, int paylen); |
@@ -115,15 +113,12 @@ void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, | |||
115 | const void *payload, size_t paylen) | 113 | const void *payload, size_t paylen) |
116 | { | 114 | { |
117 | sctp_errhdr_t err; | 115 | sctp_errhdr_t err; |
118 | int padlen; | ||
119 | __u16 len; | 116 | __u16 len; |
120 | 117 | ||
121 | /* Cause code constants are now defined in network order. */ | 118 | /* Cause code constants are now defined in network order. */ |
122 | err.cause = cause_code; | 119 | err.cause = cause_code; |
123 | len = sizeof(sctp_errhdr_t) + paylen; | 120 | len = sizeof(sctp_errhdr_t) + paylen; |
124 | padlen = len % 4; | ||
125 | err.length = htons(len); | 121 | err.length = htons(len); |
126 | len += padlen; | ||
127 | chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); | 122 | chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); |
128 | sctp_addto_chunk(chunk, paylen, payload); | 123 | sctp_addto_chunk(chunk, paylen, payload); |
129 | } | 124 | } |
@@ -1454,7 +1449,6 @@ no_hmac: | |||
1454 | do_gettimeofday(&tv); | 1449 | do_gettimeofday(&tv); |
1455 | 1450 | ||
1456 | if (!asoc && tv_lt(bear_cookie->expiration, tv)) { | 1451 | if (!asoc && tv_lt(bear_cookie->expiration, tv)) { |
1457 | __u16 len; | ||
1458 | /* | 1452 | /* |
1459 | * Section 3.3.10.3 Stale Cookie Error (3) | 1453 | * Section 3.3.10.3 Stale Cookie Error (3) |
1460 | * | 1454 | * |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index fd2dfdd7d7fd..71cad56dd73f 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -97,6 +97,13 @@ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, | |||
97 | const struct sctp_association *asoc, | 97 | const struct sctp_association *asoc, |
98 | struct sctp_transport *transport); | 98 | struct sctp_transport *transport); |
99 | 99 | ||
100 | static sctp_disposition_t sctp_sf_abort_violation( | ||
101 | const struct sctp_association *asoc, | ||
102 | void *arg, | ||
103 | sctp_cmd_seq_t *commands, | ||
104 | const __u8 *payload, | ||
105 | const size_t paylen); | ||
106 | |||
100 | static sctp_disposition_t sctp_sf_violation_chunklen( | 107 | static sctp_disposition_t sctp_sf_violation_chunklen( |
101 | const struct sctp_endpoint *ep, | 108 | const struct sctp_endpoint *ep, |
102 | const struct sctp_association *asoc, | 109 | const struct sctp_association *asoc, |
@@ -104,6 +111,13 @@ static sctp_disposition_t sctp_sf_violation_chunklen( | |||
104 | void *arg, | 111 | void *arg, |
105 | sctp_cmd_seq_t *commands); | 112 | sctp_cmd_seq_t *commands); |
106 | 113 | ||
114 | static sctp_disposition_t sctp_sf_violation_ctsn( | ||
115 | const struct sctp_endpoint *ep, | ||
116 | const struct sctp_association *asoc, | ||
117 | const sctp_subtype_t type, | ||
118 | void *arg, | ||
119 | sctp_cmd_seq_t *commands); | ||
120 | |||
107 | /* Small helper function that checks if the chunk length | 121 | /* Small helper function that checks if the chunk length |
108 | * is of the appropriate length. The 'required_length' argument | 122 | * is of the appropriate length. The 'required_length' argument |
109 | * is set to be the size of a specific chunk we are testing. | 123 | * is set to be the size of a specific chunk we are testing. |
@@ -2880,6 +2894,13 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep, | |||
2880 | return SCTP_DISPOSITION_DISCARD; | 2894 | return SCTP_DISPOSITION_DISCARD; |
2881 | } | 2895 | } |
2882 | 2896 | ||
2897 | /* If Cumulative TSN Ack beyond the max tsn currently | ||
2898 | * send, terminating the association and respond to the | ||
2899 | * sender with an ABORT. | ||
2900 | */ | ||
2901 | if (!TSN_lt(ctsn, asoc->next_tsn)) | ||
2902 | return sctp_sf_violation_ctsn(ep, asoc, type, arg, commands); | ||
2903 | |||
2883 | /* Return this SACK for further processing. */ | 2904 | /* Return this SACK for further processing. */ |
2884 | sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_SACKH(sackh)); | 2905 | sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, SCTP_SACKH(sackh)); |
2885 | 2906 | ||
@@ -3691,40 +3712,21 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep, | |||
3691 | return SCTP_DISPOSITION_VIOLATION; | 3712 | return SCTP_DISPOSITION_VIOLATION; |
3692 | } | 3713 | } |
3693 | 3714 | ||
3694 | |||
3695 | /* | 3715 | /* |
3696 | * Handle a protocol violation when the chunk length is invalid. | 3716 | * Common function to handle a protocol violation. |
3697 | * "Invalid" length is identified as smaller then the minimal length a | ||
3698 | * given chunk can be. For example, a SACK chunk has invalid length | ||
3699 | * if it's length is set to be smaller then the size of sctp_sack_chunk_t. | ||
3700 | * | ||
3701 | * We inform the other end by sending an ABORT with a Protocol Violation | ||
3702 | * error code. | ||
3703 | * | ||
3704 | * Section: Not specified | ||
3705 | * Verification Tag: Nothing to do | ||
3706 | * Inputs | ||
3707 | * (endpoint, asoc, chunk) | ||
3708 | * | ||
3709 | * Outputs | ||
3710 | * (reply_msg, msg_up, counters) | ||
3711 | * | ||
3712 | * Generate an ABORT chunk and terminate the association. | ||
3713 | */ | 3717 | */ |
3714 | static sctp_disposition_t sctp_sf_violation_chunklen( | 3718 | static sctp_disposition_t sctp_sf_abort_violation( |
3715 | const struct sctp_endpoint *ep, | ||
3716 | const struct sctp_association *asoc, | 3719 | const struct sctp_association *asoc, |
3717 | const sctp_subtype_t type, | ||
3718 | void *arg, | 3720 | void *arg, |
3719 | sctp_cmd_seq_t *commands) | 3721 | sctp_cmd_seq_t *commands, |
3722 | const __u8 *payload, | ||
3723 | const size_t paylen) | ||
3720 | { | 3724 | { |
3721 | struct sctp_chunk *chunk = arg; | 3725 | struct sctp_chunk *chunk = arg; |
3722 | struct sctp_chunk *abort = NULL; | 3726 | struct sctp_chunk *abort = NULL; |
3723 | char err_str[]="The following chunk had invalid length:"; | ||
3724 | 3727 | ||
3725 | /* Make the abort chunk. */ | 3728 | /* Make the abort chunk. */ |
3726 | abort = sctp_make_abort_violation(asoc, chunk, err_str, | 3729 | abort = sctp_make_abort_violation(asoc, chunk, payload, paylen); |
3727 | sizeof(err_str)); | ||
3728 | if (!abort) | 3730 | if (!abort) |
3729 | goto nomem; | 3731 | goto nomem; |
3730 | 3732 | ||
@@ -3756,6 +3758,57 @@ nomem: | |||
3756 | return SCTP_DISPOSITION_NOMEM; | 3758 | return SCTP_DISPOSITION_NOMEM; |
3757 | } | 3759 | } |
3758 | 3760 | ||
3761 | /* | ||
3762 | * Handle a protocol violation when the chunk length is invalid. | ||
3763 | * "Invalid" length is identified as smaller then the minimal length a | ||
3764 | * given chunk can be. For example, a SACK chunk has invalid length | ||
3765 | * if it's length is set to be smaller then the size of sctp_sack_chunk_t. | ||
3766 | * | ||
3767 | * We inform the other end by sending an ABORT with a Protocol Violation | ||
3768 | * error code. | ||
3769 | * | ||
3770 | * Section: Not specified | ||
3771 | * Verification Tag: Nothing to do | ||
3772 | * Inputs | ||
3773 | * (endpoint, asoc, chunk) | ||
3774 | * | ||
3775 | * Outputs | ||
3776 | * (reply_msg, msg_up, counters) | ||
3777 | * | ||
3778 | * Generate an ABORT chunk and terminate the association. | ||
3779 | */ | ||
3780 | static sctp_disposition_t sctp_sf_violation_chunklen( | ||
3781 | const struct sctp_endpoint *ep, | ||
3782 | const struct sctp_association *asoc, | ||
3783 | const sctp_subtype_t type, | ||
3784 | void *arg, | ||
3785 | sctp_cmd_seq_t *commands) | ||
3786 | { | ||
3787 | char err_str[]="The following chunk had invalid length:"; | ||
3788 | |||
3789 | return sctp_sf_abort_violation(asoc, arg, commands, err_str, | ||
3790 | sizeof(err_str)); | ||
3791 | } | ||
3792 | |||
3793 | /* Handle a protocol violation when the peer trying to advance the | ||
3794 | * cumulative tsn ack to a point beyond the max tsn currently sent. | ||
3795 | * | ||
3796 | * We inform the other end by sending an ABORT with a Protocol Violation | ||
3797 | * error code. | ||
3798 | */ | ||
3799 | static sctp_disposition_t sctp_sf_violation_ctsn( | ||
3800 | const struct sctp_endpoint *ep, | ||
3801 | const struct sctp_association *asoc, | ||
3802 | const sctp_subtype_t type, | ||
3803 | void *arg, | ||
3804 | sctp_cmd_seq_t *commands) | ||
3805 | { | ||
3806 | char err_str[]="The cumulative tsn ack beyond the max tsn currently sent:"; | ||
3807 | |||
3808 | return sctp_sf_abort_violation(asoc, arg, commands, err_str, | ||
3809 | sizeof(err_str)); | ||
3810 | } | ||
3811 | |||
3759 | /*************************************************************************** | 3812 | /*************************************************************************** |
3760 | * These are the state functions for handling primitive (Section 10) events. | 3813 | * These are the state functions for handling primitive (Section 10) events. |
3761 | ***************************************************************************/ | 3814 | ***************************************************************************/ |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ee88f2ea5101..01c6364245b7 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -107,8 +107,6 @@ static void sctp_sock_migrate(struct sock *, struct sock *, | |||
107 | struct sctp_association *, sctp_socket_type_t); | 107 | struct sctp_association *, sctp_socket_type_t); |
108 | static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; | 108 | static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; |
109 | 109 | ||
110 | extern struct kmem_cache *sctp_bucket_cachep; | ||
111 | |||
112 | /* Get the sndbuf space available at the time on the association. */ | 110 | /* Get the sndbuf space available at the time on the association. */ |
113 | static inline int sctp_wspace(struct sctp_association *asoc) | 111 | static inline int sctp_wspace(struct sctp_association *asoc) |
114 | { | 112 | { |
@@ -433,7 +431,7 @@ out: | |||
433 | * | 431 | * |
434 | * Only sctp_setsockopt_bindx() is supposed to call this function. | 432 | * Only sctp_setsockopt_bindx() is supposed to call this function. |
435 | */ | 433 | */ |
436 | int sctp_bindx_add(struct sock *sk, struct sockaddr *addrs, int addrcnt) | 434 | static int sctp_bindx_add(struct sock *sk, struct sockaddr *addrs, int addrcnt) |
437 | { | 435 | { |
438 | int cnt; | 436 | int cnt; |
439 | int retval = 0; | 437 | int retval = 0; |
@@ -602,7 +600,7 @@ out: | |||
602 | * | 600 | * |
603 | * Only sctp_setsockopt_bindx() is supposed to call this function. | 601 | * Only sctp_setsockopt_bindx() is supposed to call this function. |
604 | */ | 602 | */ |
605 | int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt) | 603 | static int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt) |
606 | { | 604 | { |
607 | struct sctp_sock *sp = sctp_sk(sk); | 605 | struct sctp_sock *sp = sctp_sk(sk); |
608 | struct sctp_endpoint *ep = sp->ep; | 606 | struct sctp_endpoint *ep = sp->ep; |
@@ -977,7 +975,7 @@ static int __sctp_connect(struct sock* sk, | |||
977 | int err = 0; | 975 | int err = 0; |
978 | int addrcnt = 0; | 976 | int addrcnt = 0; |
979 | int walk_size = 0; | 977 | int walk_size = 0; |
980 | union sctp_addr *sa_addr; | 978 | union sctp_addr *sa_addr = NULL; |
981 | void *addr_buf; | 979 | void *addr_buf; |
982 | unsigned short port; | 980 | unsigned short port; |
983 | unsigned int f_flags = 0; | 981 | unsigned int f_flags = 0; |
@@ -1011,7 +1009,10 @@ static int __sctp_connect(struct sock* sk, | |||
1011 | goto out_free; | 1009 | goto out_free; |
1012 | } | 1010 | } |
1013 | 1011 | ||
1014 | err = sctp_verify_addr(sk, sa_addr, af->sockaddr_len); | 1012 | /* Save current address so we can work with it */ |
1013 | memcpy(&to, sa_addr, af->sockaddr_len); | ||
1014 | |||
1015 | err = sctp_verify_addr(sk, &to, af->sockaddr_len); | ||
1015 | if (err) | 1016 | if (err) |
1016 | goto out_free; | 1017 | goto out_free; |
1017 | 1018 | ||
@@ -1021,12 +1022,11 @@ static int __sctp_connect(struct sock* sk, | |||
1021 | if (asoc && asoc->peer.port && asoc->peer.port != port) | 1022 | if (asoc && asoc->peer.port && asoc->peer.port != port) |
1022 | goto out_free; | 1023 | goto out_free; |
1023 | 1024 | ||
1024 | memcpy(&to, sa_addr, af->sockaddr_len); | ||
1025 | 1025 | ||
1026 | /* Check if there already is a matching association on the | 1026 | /* Check if there already is a matching association on the |
1027 | * endpoint (other than the one created here). | 1027 | * endpoint (other than the one created here). |
1028 | */ | 1028 | */ |
1029 | asoc2 = sctp_endpoint_lookup_assoc(ep, sa_addr, &transport); | 1029 | asoc2 = sctp_endpoint_lookup_assoc(ep, &to, &transport); |
1030 | if (asoc2 && asoc2 != asoc) { | 1030 | if (asoc2 && asoc2 != asoc) { |
1031 | if (asoc2->state >= SCTP_STATE_ESTABLISHED) | 1031 | if (asoc2->state >= SCTP_STATE_ESTABLISHED) |
1032 | err = -EISCONN; | 1032 | err = -EISCONN; |
@@ -1039,7 +1039,7 @@ static int __sctp_connect(struct sock* sk, | |||
1039 | * make sure that there is no peeled-off association matching | 1039 | * make sure that there is no peeled-off association matching |
1040 | * the peer address even on another socket. | 1040 | * the peer address even on another socket. |
1041 | */ | 1041 | */ |
1042 | if (sctp_endpoint_is_peeled_off(ep, sa_addr)) { | 1042 | if (sctp_endpoint_is_peeled_off(ep, &to)) { |
1043 | err = -EADDRNOTAVAIL; | 1043 | err = -EADDRNOTAVAIL; |
1044 | goto out_free; | 1044 | goto out_free; |
1045 | } | 1045 | } |
@@ -1070,7 +1070,7 @@ static int __sctp_connect(struct sock* sk, | |||
1070 | } | 1070 | } |
1071 | } | 1071 | } |
1072 | 1072 | ||
1073 | scope = sctp_scope(sa_addr); | 1073 | scope = sctp_scope(&to); |
1074 | asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL); | 1074 | asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL); |
1075 | if (!asoc) { | 1075 | if (!asoc) { |
1076 | err = -ENOMEM; | 1076 | err = -ENOMEM; |
@@ -1079,7 +1079,7 @@ static int __sctp_connect(struct sock* sk, | |||
1079 | } | 1079 | } |
1080 | 1080 | ||
1081 | /* Prime the peer's transport structures. */ | 1081 | /* Prime the peer's transport structures. */ |
1082 | transport = sctp_assoc_add_peer(asoc, sa_addr, GFP_KERNEL, | 1082 | transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL, |
1083 | SCTP_UNKNOWN); | 1083 | SCTP_UNKNOWN); |
1084 | if (!transport) { | 1084 | if (!transport) { |
1085 | err = -ENOMEM; | 1085 | err = -ENOMEM; |
@@ -1103,8 +1103,8 @@ static int __sctp_connect(struct sock* sk, | |||
1103 | 1103 | ||
1104 | /* Initialize sk's dport and daddr for getpeername() */ | 1104 | /* Initialize sk's dport and daddr for getpeername() */ |
1105 | inet_sk(sk)->dport = htons(asoc->peer.port); | 1105 | inet_sk(sk)->dport = htons(asoc->peer.port); |
1106 | af = sctp_get_af_specific(to.sa.sa_family); | 1106 | af = sctp_get_af_specific(sa_addr->sa.sa_family); |
1107 | af->to_sk_daddr(&to, sk); | 1107 | af->to_sk_daddr(sa_addr, sk); |
1108 | sk->sk_err = 0; | 1108 | sk->sk_err = 0; |
1109 | 1109 | ||
1110 | /* in-kernel sockets don't generally have a file allocated to them | 1110 | /* in-kernel sockets don't generally have a file allocated to them |
@@ -1531,7 +1531,6 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1531 | goto out_unlock; | 1531 | goto out_unlock; |
1532 | } | 1532 | } |
1533 | if (sinfo_flags & SCTP_ABORT) { | 1533 | if (sinfo_flags & SCTP_ABORT) { |
1534 | struct sctp_chunk *chunk; | ||
1535 | 1534 | ||
1536 | chunk = sctp_make_abort_user(asoc, msg, msg_len); | 1535 | chunk = sctp_make_abort_user(asoc, msg, msg_len); |
1537 | if (!chunk) { | 1536 | if (!chunk) { |
@@ -4353,7 +4352,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4353 | space_left, &bytes_copied); | 4352 | space_left, &bytes_copied); |
4354 | if (cnt < 0) { | 4353 | if (cnt < 0) { |
4355 | err = cnt; | 4354 | err = cnt; |
4356 | goto error; | 4355 | goto error_lock; |
4357 | } | 4356 | } |
4358 | goto copy_getaddrs; | 4357 | goto copy_getaddrs; |
4359 | } | 4358 | } |
@@ -4367,7 +4366,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4367 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4366 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; |
4368 | if (space_left < addrlen) { | 4367 | if (space_left < addrlen) { |
4369 | err = -ENOMEM; /*fixme: right error?*/ | 4368 | err = -ENOMEM; /*fixme: right error?*/ |
4370 | goto error; | 4369 | goto error_lock; |
4371 | } | 4370 | } |
4372 | memcpy(buf, &temp, addrlen); | 4371 | memcpy(buf, &temp, addrlen); |
4373 | buf += addrlen; | 4372 | buf += addrlen; |
@@ -4381,15 +4380,21 @@ copy_getaddrs: | |||
4381 | 4380 | ||
4382 | if (copy_to_user(to, addrs, bytes_copied)) { | 4381 | if (copy_to_user(to, addrs, bytes_copied)) { |
4383 | err = -EFAULT; | 4382 | err = -EFAULT; |
4384 | goto error; | 4383 | goto out; |
4385 | } | 4384 | } |
4386 | if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) { | 4385 | if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) { |
4387 | err = -EFAULT; | 4386 | err = -EFAULT; |
4388 | goto error; | 4387 | goto out; |
4389 | } | 4388 | } |
4390 | if (put_user(bytes_copied, optlen)) | 4389 | if (put_user(bytes_copied, optlen)) |
4391 | err = -EFAULT; | 4390 | err = -EFAULT; |
4392 | error: | 4391 | |
4392 | goto out; | ||
4393 | |||
4394 | error_lock: | ||
4395 | sctp_read_unlock(addr_lock); | ||
4396 | |||
4397 | out: | ||
4393 | kfree(addrs); | 4398 | kfree(addrs); |
4394 | return err; | 4399 | return err; |
4395 | } | 4400 | } |
@@ -5964,7 +5969,7 @@ static int sctp_wait_for_accept(struct sock *sk, long timeo) | |||
5964 | return err; | 5969 | return err; |
5965 | } | 5970 | } |
5966 | 5971 | ||
5967 | void sctp_wait_for_close(struct sock *sk, long timeout) | 5972 | static void sctp_wait_for_close(struct sock *sk, long timeout) |
5968 | { | 5973 | { |
5969 | DEFINE_WAIT(wait); | 5974 | DEFINE_WAIT(wait); |
5970 | 5975 | ||
diff --git a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c index d3192a1babcc..1ff0daade304 100644 --- a/net/sctp/tsnmap.c +++ b/net/sctp/tsnmap.c | |||
@@ -161,7 +161,7 @@ SCTP_STATIC int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map, | |||
161 | __u16 *start, __u16 *end) | 161 | __u16 *start, __u16 *end) |
162 | { | 162 | { |
163 | int started, ended; | 163 | int started, ended; |
164 | __u16 _start, _end, offset; | 164 | __u16 start_, end_, offset; |
165 | 165 | ||
166 | /* We haven't found a gap yet. */ | 166 | /* We haven't found a gap yet. */ |
167 | started = ended = 0; | 167 | started = ended = 0; |
@@ -175,7 +175,7 @@ SCTP_STATIC int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map, | |||
175 | 175 | ||
176 | offset = iter->start - map->base_tsn; | 176 | offset = iter->start - map->base_tsn; |
177 | sctp_tsnmap_find_gap_ack(map->tsn_map, offset, map->len, 0, | 177 | sctp_tsnmap_find_gap_ack(map->tsn_map, offset, map->len, 0, |
178 | &started, &_start, &ended, &_end); | 178 | &started, &start_, &ended, &end_); |
179 | } | 179 | } |
180 | 180 | ||
181 | /* Do we need to check the overflow map? */ | 181 | /* Do we need to check the overflow map? */ |
@@ -193,8 +193,8 @@ SCTP_STATIC int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map, | |||
193 | offset, | 193 | offset, |
194 | map->len, | 194 | map->len, |
195 | map->len, | 195 | map->len, |
196 | &started, &_start, | 196 | &started, &start_, |
197 | &ended, &_end); | 197 | &ended, &end_); |
198 | } | 198 | } |
199 | 199 | ||
200 | /* The Gap Ack Block happens to end at the end of the | 200 | /* The Gap Ack Block happens to end at the end of the |
@@ -202,7 +202,7 @@ SCTP_STATIC int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map, | |||
202 | */ | 202 | */ |
203 | if (started && !ended) { | 203 | if (started && !ended) { |
204 | ended++; | 204 | ended++; |
205 | _end = map->len + map->len - 1; | 205 | end_ = map->len + map->len - 1; |
206 | } | 206 | } |
207 | 207 | ||
208 | /* If we found a Gap Ack Block, return the start and end and | 208 | /* If we found a Gap Ack Block, return the start and end and |
@@ -215,8 +215,8 @@ SCTP_STATIC int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map, | |||
215 | int gap = map->cumulative_tsn_ack_point - | 215 | int gap = map->cumulative_tsn_ack_point - |
216 | map->base_tsn; | 216 | map->base_tsn; |
217 | 217 | ||
218 | *start = _start - gap; | 218 | *start = start_ - gap; |
219 | *end = _end - gap; | 219 | *end = end_ - gap; |
220 | 220 | ||
221 | /* Move the iterator forward. */ | 221 | /* Move the iterator forward. */ |
222 | iter->start = map->cumulative_tsn_ack_point + *end + 1; | 222 | iter->start = map->cumulative_tsn_ack_point + *end + 1; |