From b90a137d30a6322d76023d879d40fc31f3edf0a6 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Thu, 14 Feb 2008 10:18:20 -0500 Subject: [SCTP]: Correctly set the length of sctp_assoc_change notification sctp_assoc_change notification may contain the data from a received ABORT chunk. Set the length correctly to account for that. Signed-off-by: Vlad Yasevich --- net/sctp/ulpevent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/sctp') diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index e27b11f18b7..b43f1f110f8 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -206,7 +206,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_assoc_change( * This field is the total length of the notification data, including * the notification header. */ - sac->sac_length = sizeof(struct sctp_assoc_change); + sac->sac_length = skb->len; /* Socket Extensions for SCTP * 5.3.1.1 SCTP_ASSOC_CHANGE -- cgit v1.2.3 From 15efbe763978d7cc327d824d9e8f8f9e525dd40d Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 15 Feb 2008 09:53:59 -0500 Subject: [SCTP]: Clean up naming conventions of sctp protocol/address family registration I noticed while looking into some odd behavior in sctp, that the variable name sctp_pf_inet6_specific was used twice to represent two different pieces of data (its both a structure name and a pointer to that type of structure), which is confusing to say the least, and potentially dangerous depending on the variable scope. This patch cleans that up, and makes the protocol and address family registration names in SCTP more regular, increasing readability. Signed-off-by: Neil Horman Signed-off-by: Vlad Yasevich ipv6.c | 12 ++++++------ protocol.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) --- net/sctp/ipv6.c | 12 ++++++------ net/sctp/protocol.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'net/sctp') diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 4d7ec961ae1..87f940587d5 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -966,7 +966,7 @@ static struct inet6_protocol sctpv6_protocol = { .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL, }; -static struct sctp_af sctp_ipv6_specific = { +static struct sctp_af sctp_af_inet6 = { .sa_family = AF_INET6, .sctp_xmit = sctp_v6_xmit, .setsockopt = ipv6_setsockopt, @@ -998,7 +998,7 @@ static struct sctp_af sctp_ipv6_specific = { #endif }; -static struct sctp_pf sctp_pf_inet6_specific = { +static struct sctp_pf sctp_pf_inet6 = { .event_msgname = sctp_inet6_event_msgname, .skb_msgname = sctp_inet6_skb_msgname, .af_supported = sctp_inet6_af_supported, @@ -1008,7 +1008,7 @@ static struct sctp_pf sctp_pf_inet6_specific = { .supported_addrs = sctp_inet6_supported_addrs, .create_accept_sk = sctp_v6_create_accept_sk, .addr_v4map = sctp_v6_addr_v4map, - .af = &sctp_ipv6_specific, + .af = &sctp_af_inet6, }; /* Initialize IPv6 support and register with socket layer. */ @@ -1017,10 +1017,10 @@ int sctp_v6_init(void) int rc; /* Register the SCTP specific PF_INET6 functions. */ - sctp_register_pf(&sctp_pf_inet6_specific, PF_INET6); + sctp_register_pf(&sctp_pf_inet6, PF_INET6); /* Register the SCTP specific AF_INET6 functions. */ - sctp_register_af(&sctp_ipv6_specific); + sctp_register_af(&sctp_af_inet6); rc = proto_register(&sctpv6_prot, 1); if (rc) @@ -1051,7 +1051,7 @@ void sctp_v6_exit(void) inet6_unregister_protosw(&sctpv6_seqpacket_protosw); inet6_unregister_protosw(&sctpv6_stream_protosw); proto_unregister(&sctpv6_prot); - list_del(&sctp_ipv6_specific.list); + list_del(&sctp_af_inet6.list); } /* Unregister with inet6 layer. */ diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 22a16571499..688546dccd8 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -832,7 +832,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, return ip_queue_xmit(skb, ipfragok); } -static struct sctp_af sctp_ipv4_specific; +static struct sctp_af sctp_af_inet; static struct sctp_pf sctp_pf_inet = { .event_msgname = sctp_inet_event_msgname, @@ -844,7 +844,7 @@ static struct sctp_pf sctp_pf_inet = { .supported_addrs = sctp_inet_supported_addrs, .create_accept_sk = sctp_v4_create_accept_sk, .addr_v4map = sctp_v4_addr_v4map, - .af = &sctp_ipv4_specific, + .af = &sctp_af_inet }; /* Notifier for inetaddr addition/deletion events. */ @@ -906,7 +906,7 @@ static struct net_protocol sctp_protocol = { }; /* IPv4 address related functions. */ -static struct sctp_af sctp_ipv4_specific = { +static struct sctp_af sctp_af_inet = { .sa_family = AF_INET, .sctp_xmit = sctp_v4_xmit, .setsockopt = ip_setsockopt, @@ -1192,7 +1192,7 @@ SCTP_STATIC __init int sctp_init(void) sctp_sysctl_register(); INIT_LIST_HEAD(&sctp_address_families); - sctp_register_af(&sctp_ipv4_specific); + sctp_register_af(&sctp_af_inet); status = proto_register(&sctp_prot, 1); if (status) @@ -1249,7 +1249,7 @@ err_v6_init: proto_unregister(&sctp_prot); err_proto_register: sctp_sysctl_unregister(); - list_del(&sctp_ipv4_specific.list); + list_del(&sctp_af_inet.list); free_pages((unsigned long)sctp_port_hashtable, get_order(sctp_port_hashsize * sizeof(struct sctp_bind_hashbucket))); @@ -1299,7 +1299,7 @@ SCTP_STATIC __exit void sctp_exit(void) inet_unregister_protosw(&sctp_seqpacket_protosw); sctp_sysctl_unregister(); - list_del(&sctp_ipv4_specific.list); + list_del(&sctp_af_inet.list); free_pages((unsigned long)sctp_assoc_hashtable, get_order(sctp_assoc_hashsize * -- cgit v1.2.3 From b40db6846847e82daf175641987df29324c425fa Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Wed, 27 Feb 2008 14:40:37 -0500 Subject: [SCTP]: Incorrect length was used in SCTP_*_AUTH_CHUNKS socket option The chunks are stored inside a parameter structure in the kernel and when we copy them to the user, we need to account for the parameter header. Signed-off-by: Vlad Yasevich --- net/sctp/socket.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'net/sctp') diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 44797ad88a0..848df21dc6c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -5070,6 +5070,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, struct sctp_authchunks val; struct sctp_association *asoc; struct sctp_chunks_param *ch; + u32 num_chunks; char __user *to; if (len <= sizeof(struct sctp_authchunks)) @@ -5086,10 +5087,11 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, ch = asoc->peer.peer_chunks; /* See if the user provided enough room for all the data */ - if (len < ntohs(ch->param_hdr.length)) + num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); + if (len < num_chunks) return -EINVAL; - len = ntohs(ch->param_hdr.length); + len = num_chunks; if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(to, ch->chunks, len)) @@ -5105,6 +5107,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, struct sctp_authchunks val; struct sctp_association *asoc; struct sctp_chunks_param *ch; + u32 num_chunks; char __user *to; if (len <= sizeof(struct sctp_authchunks)) @@ -5123,10 +5126,11 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, else ch = sctp_sk(sk)->ep->auth_chunk_list; - if (len < ntohs(ch->param_hdr.length)) + num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t); + if (len < num_chunks) return -EINVAL; - len = ntohs(ch->param_hdr.length); + len = num_chunks; if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(to, ch->chunks, len)) -- cgit v1.2.3 From 7e8616d8e7731b026019d9af7cc9914b8bb42bc7 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Wed, 27 Feb 2008 16:04:52 -0500 Subject: [SCTP]: Update AUTH structures to match declarations in draft-16. The new SCTP socket api (draft 16) updates the AUTH API structures. We never exported these since we knew they would change. Update the rest to match the draft. Signed-off-by: Vlad Yasevich --- net/sctp/auth.c | 4 ++-- net/sctp/socket.c | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'net/sctp') diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 8bb79f28177..675a5c3e68a 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -838,11 +838,11 @@ int sctp_auth_set_key(struct sctp_endpoint *ep, } /* Create a new key data based on the info passed in */ - key = sctp_auth_create_key(auth_key->sca_keylen, GFP_KERNEL); + key = sctp_auth_create_key(auth_key->sca_keylength, GFP_KERNEL); if (!key) goto nomem; - memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylen); + memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylength); /* If we are replacing, remove the old keys data from the * key id. If we are adding new key id, add it to the diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 848df21dc6c..939892691a2 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1964,7 +1964,7 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk, static int sctp_setsockopt_events(struct sock *sk, char __user *optval, int optlen) { - if (optlen != sizeof(struct sctp_event_subscribe)) + if (optlen > sizeof(struct sctp_event_subscribe)) return -EINVAL; if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) return -EFAULT; @@ -5094,6 +5094,8 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, len = num_chunks; if (put_user(len, optlen)) return -EFAULT; + if (put_user(num_chunks, &p->gauth_number_of_chunks)) + return -EFAULT; if (copy_to_user(to, ch->chunks, len)) return -EFAULT; @@ -5133,6 +5135,8 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, len = num_chunks; if (put_user(len, optlen)) return -EFAULT; + if (put_user(num_chunks, &p->gauth_number_of_chunks)) + return -EFAULT; if (copy_to_user(to, ch->chunks, len)) return -EFAULT; -- cgit v1.2.3