diff options
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 897c01c029ca..9b6cc6de80d8 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -972,7 +972,7 @@ static int sctp_setsockopt_bindx(struct sock *sk, | |||
972 | return -EFAULT; | 972 | return -EFAULT; |
973 | 973 | ||
974 | /* Alloc space for the address array in kernel memory. */ | 974 | /* Alloc space for the address array in kernel memory. */ |
975 | kaddrs = kmalloc(addrs_size, GFP_KERNEL); | 975 | kaddrs = kmalloc(addrs_size, GFP_USER | __GFP_NOWARN); |
976 | if (unlikely(!kaddrs)) | 976 | if (unlikely(!kaddrs)) |
977 | return -ENOMEM; | 977 | return -ENOMEM; |
978 | 978 | ||
@@ -1952,8 +1952,6 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) | |||
1952 | 1952 | ||
1953 | /* Now send the (possibly) fragmented message. */ | 1953 | /* Now send the (possibly) fragmented message. */ |
1954 | list_for_each_entry(chunk, &datamsg->chunks, frag_list) { | 1954 | list_for_each_entry(chunk, &datamsg->chunks, frag_list) { |
1955 | sctp_chunk_hold(chunk); | ||
1956 | |||
1957 | /* Do accounting for the write space. */ | 1955 | /* Do accounting for the write space. */ |
1958 | sctp_set_owner_w(chunk); | 1956 | sctp_set_owner_w(chunk); |
1959 | 1957 | ||
@@ -1966,15 +1964,13 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) | |||
1966 | * breaks. | 1964 | * breaks. |
1967 | */ | 1965 | */ |
1968 | err = sctp_primitive_SEND(net, asoc, datamsg); | 1966 | err = sctp_primitive_SEND(net, asoc, datamsg); |
1967 | sctp_datamsg_put(datamsg); | ||
1969 | /* Did the lower layer accept the chunk? */ | 1968 | /* Did the lower layer accept the chunk? */ |
1970 | if (err) { | 1969 | if (err) |
1971 | sctp_datamsg_free(datamsg); | ||
1972 | goto out_free; | 1970 | goto out_free; |
1973 | } | ||
1974 | 1971 | ||
1975 | pr_debug("%s: we sent primitively\n", __func__); | 1972 | pr_debug("%s: we sent primitively\n", __func__); |
1976 | 1973 | ||
1977 | sctp_datamsg_put(datamsg); | ||
1978 | err = msg_len; | 1974 | err = msg_len; |
1979 | 1975 | ||
1980 | if (unlikely(wait_connect)) { | 1976 | if (unlikely(wait_connect)) { |
@@ -4928,7 +4924,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4928 | to = optval + offsetof(struct sctp_getaddrs, addrs); | 4924 | to = optval + offsetof(struct sctp_getaddrs, addrs); |
4929 | space_left = len - offsetof(struct sctp_getaddrs, addrs); | 4925 | space_left = len - offsetof(struct sctp_getaddrs, addrs); |
4930 | 4926 | ||
4931 | addrs = kmalloc(space_left, GFP_KERNEL); | 4927 | addrs = kmalloc(space_left, GFP_USER | __GFP_NOWARN); |
4932 | if (!addrs) | 4928 | if (!addrs) |
4933 | return -ENOMEM; | 4929 | return -ENOMEM; |
4934 | 4930 | ||
@@ -6458,7 +6454,7 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
6458 | if (sctp_writeable(sk)) { | 6454 | if (sctp_writeable(sk)) { |
6459 | mask |= POLLOUT | POLLWRNORM; | 6455 | mask |= POLLOUT | POLLWRNORM; |
6460 | } else { | 6456 | } else { |
6461 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 6457 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); |
6462 | /* | 6458 | /* |
6463 | * Since the socket is not locked, the buffer | 6459 | * Since the socket is not locked, the buffer |
6464 | * might be made available after the writeable check and | 6460 | * might be made available after the writeable check and |
@@ -6801,26 +6797,30 @@ no_packet: | |||
6801 | static void __sctp_write_space(struct sctp_association *asoc) | 6797 | static void __sctp_write_space(struct sctp_association *asoc) |
6802 | { | 6798 | { |
6803 | struct sock *sk = asoc->base.sk; | 6799 | struct sock *sk = asoc->base.sk; |
6804 | struct socket *sock = sk->sk_socket; | ||
6805 | 6800 | ||
6806 | if ((sctp_wspace(asoc) > 0) && sock) { | 6801 | if (sctp_wspace(asoc) <= 0) |
6807 | if (waitqueue_active(&asoc->wait)) | 6802 | return; |
6808 | wake_up_interruptible(&asoc->wait); | 6803 | |
6804 | if (waitqueue_active(&asoc->wait)) | ||
6805 | wake_up_interruptible(&asoc->wait); | ||
6809 | 6806 | ||
6810 | if (sctp_writeable(sk)) { | 6807 | if (sctp_writeable(sk)) { |
6811 | wait_queue_head_t *wq = sk_sleep(sk); | 6808 | struct socket_wq *wq; |
6812 | 6809 | ||
6813 | if (wq && waitqueue_active(wq)) | 6810 | rcu_read_lock(); |
6814 | wake_up_interruptible(wq); | 6811 | wq = rcu_dereference(sk->sk_wq); |
6812 | if (wq) { | ||
6813 | if (waitqueue_active(&wq->wait)) | ||
6814 | wake_up_interruptible(&wq->wait); | ||
6815 | 6815 | ||
6816 | /* Note that we try to include the Async I/O support | 6816 | /* Note that we try to include the Async I/O support |
6817 | * here by modeling from the current TCP/UDP code. | 6817 | * here by modeling from the current TCP/UDP code. |
6818 | * We have not tested with it yet. | 6818 | * We have not tested with it yet. |
6819 | */ | 6819 | */ |
6820 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) | 6820 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) |
6821 | sock_wake_async(sock, | 6821 | sock_wake_async(wq, SOCK_WAKE_SPACE, POLL_OUT); |
6822 | SOCK_WAKE_SPACE, POLL_OUT); | ||
6823 | } | 6822 | } |
6823 | rcu_read_unlock(); | ||
6824 | } | 6824 | } |
6825 | } | 6825 | } |
6826 | 6826 | ||
@@ -7163,6 +7163,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk, | |||
7163 | newsk->sk_type = sk->sk_type; | 7163 | newsk->sk_type = sk->sk_type; |
7164 | newsk->sk_bound_dev_if = sk->sk_bound_dev_if; | 7164 | newsk->sk_bound_dev_if = sk->sk_bound_dev_if; |
7165 | newsk->sk_flags = sk->sk_flags; | 7165 | newsk->sk_flags = sk->sk_flags; |
7166 | newsk->sk_tsflags = sk->sk_tsflags; | ||
7166 | newsk->sk_no_check_tx = sk->sk_no_check_tx; | 7167 | newsk->sk_no_check_tx = sk->sk_no_check_tx; |
7167 | newsk->sk_no_check_rx = sk->sk_no_check_rx; | 7168 | newsk->sk_no_check_rx = sk->sk_no_check_rx; |
7168 | newsk->sk_reuse = sk->sk_reuse; | 7169 | newsk->sk_reuse = sk->sk_reuse; |
@@ -7195,6 +7196,9 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk, | |||
7195 | newinet->mc_ttl = 1; | 7196 | newinet->mc_ttl = 1; |
7196 | newinet->mc_index = 0; | 7197 | newinet->mc_index = 0; |
7197 | newinet->mc_list = NULL; | 7198 | newinet->mc_list = NULL; |
7199 | |||
7200 | if (newsk->sk_flags & SK_FLAGS_TIMESTAMP) | ||
7201 | net_enable_timestamp(); | ||
7198 | } | 7202 | } |
7199 | 7203 | ||
7200 | static inline void sctp_copy_descendant(struct sock *sk_to, | 7204 | static inline void sctp_copy_descendant(struct sock *sk_to, |
@@ -7375,6 +7379,13 @@ struct proto sctp_prot = { | |||
7375 | 7379 | ||
7376 | #if IS_ENABLED(CONFIG_IPV6) | 7380 | #if IS_ENABLED(CONFIG_IPV6) |
7377 | 7381 | ||
7382 | #include <net/transp_v6.h> | ||
7383 | static void sctp_v6_destroy_sock(struct sock *sk) | ||
7384 | { | ||
7385 | sctp_destroy_sock(sk); | ||
7386 | inet6_destroy_sock(sk); | ||
7387 | } | ||
7388 | |||
7378 | struct proto sctpv6_prot = { | 7389 | struct proto sctpv6_prot = { |
7379 | .name = "SCTPv6", | 7390 | .name = "SCTPv6", |
7380 | .owner = THIS_MODULE, | 7391 | .owner = THIS_MODULE, |
@@ -7384,7 +7395,7 @@ struct proto sctpv6_prot = { | |||
7384 | .accept = sctp_accept, | 7395 | .accept = sctp_accept, |
7385 | .ioctl = sctp_ioctl, | 7396 | .ioctl = sctp_ioctl, |
7386 | .init = sctp_init_sock, | 7397 | .init = sctp_init_sock, |
7387 | .destroy = sctp_destroy_sock, | 7398 | .destroy = sctp_v6_destroy_sock, |
7388 | .shutdown = sctp_shutdown, | 7399 | .shutdown = sctp_shutdown, |
7389 | .setsockopt = sctp_setsockopt, | 7400 | .setsockopt = sctp_setsockopt, |
7390 | .getsockopt = sctp_getsockopt, | 7401 | .getsockopt = sctp_getsockopt, |