File: | net/sctp/socket.c |
Warning: | line 5141, column 7 Copies out a struct with a union element with different sizes |
1 | /* SCTP kernel implementation | |||
2 | * (C) Copyright IBM Corp. 2001, 2004 | |||
3 | * Copyright (c) 1999-2000 Cisco, Inc. | |||
4 | * Copyright (c) 1999-2001 Motorola, Inc. | |||
5 | * Copyright (c) 2001-2003 Intel Corp. | |||
6 | * Copyright (c) 2001-2002 Nokia, Inc. | |||
7 | * Copyright (c) 2001 La Monte H.P. Yarroll | |||
8 | * | |||
9 | * This file is part of the SCTP kernel implementation | |||
10 | * | |||
11 | * These functions interface with the sockets layer to implement the | |||
12 | * SCTP Extensions for the Sockets API. | |||
13 | * | |||
14 | * Note that the descriptions from the specification are USER level | |||
15 | * functions--this file is the functions which populate the struct proto | |||
16 | * for SCTP which is the BOTTOM of the sockets interface. | |||
17 | * | |||
18 | * This SCTP implementation is free software; | |||
19 | * you can redistribute it and/or modify it under the terms of | |||
20 | * the GNU General Public License as published by | |||
21 | * the Free Software Foundation; either version 2, or (at your option) | |||
22 | * any later version. | |||
23 | * | |||
24 | * This SCTP implementation is distributed in the hope that it | |||
25 | * will be useful, but WITHOUT ANY WARRANTY; without even the implied | |||
26 | * ************************ | |||
27 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |||
28 | * See the GNU General Public License for more details. | |||
29 | * | |||
30 | * You should have received a copy of the GNU General Public License | |||
31 | * along with GNU CC; see the file COPYING. If not, see | |||
32 | * <http://www.gnu.org/licenses/>. | |||
33 | * | |||
34 | * Please send any bug reports or fixes you make to the | |||
35 | * email address(es): | |||
36 | * lksctp developers <[email protected]> | |||
37 | * | |||
38 | * Written or modified by: | |||
39 | * La Monte H.P. Yarroll <[email protected]> | |||
40 | * Narasimha Budihal <[email protected]> | |||
41 | * Karl Knutson <[email protected]> | |||
42 | * Jon Grimm <[email protected]> | |||
43 | * Xingang Guo <[email protected]> | |||
44 | * Daisy Chang <[email protected]> | |||
45 | * Sridhar Samudrala <[email protected]> | |||
46 | * Inaky Perez-Gonzalez <[email protected]> | |||
47 | * Ardelle Fan <[email protected]> | |||
48 | * Ryan Layer <[email protected]> | |||
49 | * Anup Pemmaiah <[email protected]> | |||
50 | * Kevin Gao <[email protected]> | |||
51 | */ | |||
52 | ||||
53 | #define pr_fmt(fmt)"sctp" ": " fmt KBUILD_MODNAME"sctp" ": " fmt | |||
54 | ||||
55 | #include <crypto/hash.h> | |||
56 | #include <linux1/types.h> | |||
57 | #include <linux1/kernel.h> | |||
58 | #include <linux1/wait.h> | |||
59 | #include <linux1/time.h> | |||
60 | #include <linux1/ip.h> | |||
61 | #include <linux1/capability.h> | |||
62 | #include <linux1/fcntl.h> | |||
63 | #include <linux1/poll.h> | |||
64 | #include <linux1/init.h> | |||
65 | #include <linux1/slab.h> | |||
66 | #include <linux1/file.h> | |||
67 | #include <linux1/compat.h> | |||
68 | ||||
69 | #include <net/ip.h> | |||
70 | #include <net/icmp.h> | |||
71 | #include <net/route.h> | |||
72 | #include <net/ipv6.h> | |||
73 | #include <net/inet_common.h> | |||
74 | #include <net/busy_poll.h> | |||
75 | ||||
76 | #include <linux1/socket.h> /* for sa_family_t */ | |||
77 | #include <linux1/export.h> | |||
78 | #include <net/sock.h> | |||
79 | #include <net/sctp/sctp.h> | |||
80 | #include <net/sctp/sm.h> | |||
81 | ||||
82 | /* Forward declarations for internal helper functions. */ | |||
83 | static int sctp_writeable(struct sock *sk); | |||
84 | static void sctp_wfree(struct sk_buff *skb); | |||
85 | static int sctp_wait_for_sndbuf(struct sctp_association *, long *timeo_p, | |||
86 | size_t msg_len); | |||
87 | static int sctp_wait_for_packet(struct sock *sk, int *err, long *timeo_p); | |||
88 | static int sctp_wait_for_connect(struct sctp_association *, long *timeo_p); | |||
89 | static int sctp_wait_for_accept(struct sock *sk, long timeo); | |||
90 | static void sctp_wait_for_close(struct sock *sk, long timeo); | |||
91 | static void sctp_destruct_sock(struct sock *sk); | |||
92 | static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt, | |||
93 | union sctp_addr *addr, int len); | |||
94 | static int sctp_bindx_add(struct sock *, struct sockaddr *, int); | |||
95 | static int sctp_bindx_rem(struct sock *, struct sockaddr *, int); | |||
96 | static int sctp_send_asconf_add_ip(struct sock *, struct sockaddr *, int); | |||
97 | static int sctp_send_asconf_del_ip(struct sock *, struct sockaddr *, int); | |||
98 | static int sctp_send_asconf(struct sctp_association *asoc, | |||
99 | struct sctp_chunk *chunk); | |||
100 | static int sctp_do_bind(struct sock *, union sctp_addr *, int); | |||
101 | static int sctp_autobind(struct sock *sk); | |||
102 | static void sctp_sock_migrate(struct sock *, struct sock *, | |||
103 | struct sctp_association *, sctp_socket_type_t); | |||
104 | ||||
105 | static int sctp_memory_pressure; | |||
106 | static atomic_long_t sctp_memory_allocated; | |||
107 | struct percpu_counter sctp_sockets_allocated; | |||
108 | ||||
109 | static void sctp_enter_memory_pressure(struct sock *sk) | |||
110 | { | |||
111 | sctp_memory_pressure = 1; | |||
112 | } | |||
113 | ||||
114 | ||||
115 | /* Get the sndbuf space available at the time on the association. */ | |||
116 | static inlineinline __attribute__((no_instrument_function)) int sctp_wspace(struct sctp_association *asoc) | |||
117 | { | |||
118 | int amt; | |||
119 | ||||
120 | if (asoc->ep->sndbuf_policy) | |||
121 | amt = asoc->sndbuf_used; | |||
122 | else | |||
123 | amt = sk_wmem_alloc_get(asoc->base.sk); | |||
124 | ||||
125 | if (amt >= asoc->base.sk->sk_sndbuf) { | |||
126 | if (asoc->base.sk->sk_userlocks & SOCK_SNDBUF_LOCK1) | |||
127 | amt = 0; | |||
128 | else { | |||
129 | amt = sk_stream_wspace(asoc->base.sk); | |||
130 | if (amt < 0) | |||
131 | amt = 0; | |||
132 | } | |||
133 | } else { | |||
134 | amt = asoc->base.sk->sk_sndbuf - amt; | |||
135 | } | |||
136 | return amt; | |||
137 | } | |||
138 | ||||
139 | /* Increment the used sndbuf space count of the corresponding association by | |||
140 | * the size of the outgoing data chunk. | |||
141 | * Also, set the skb destructor for sndbuf accounting later. | |||
142 | * | |||
143 | * Since it is always 1-1 between chunk and skb, and also a new skb is always | |||
144 | * allocated for chunk bundling in sctp_packet_transmit(), we can use the | |||
145 | * destructor in the data chunk skb for the purpose of the sndbuf space | |||
146 | * tracking. | |||
147 | */ | |||
148 | static inlineinline __attribute__((no_instrument_function)) void sctp_set_owner_w(struct sctp_chunk *chunk) | |||
149 | { | |||
150 | struct sctp_association *asoc = chunk->asoc; | |||
151 | struct sock *sk = asoc->base.sk; | |||
152 | ||||
153 | /* The sndbuf space is tracked per association. */ | |||
154 | sctp_association_hold(asoc); | |||
155 | ||||
156 | skb_set_owner_w(chunk->skb, sk); | |||
157 | ||||
158 | chunk->skb->destructor = sctp_wfree; | |||
159 | /* Save the chunk pointer in skb for sctp_wfree to use later. */ | |||
160 | skb_shinfo(chunk->skb)((struct skb_shared_info *)(skb_end_pointer(chunk->skb)))->destructor_arg = chunk; | |||
161 | ||||
162 | asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk)((int)((unsigned long)(chunk->chunk_end) - (unsigned long) (chunk->chunk_hdr) - sizeof(sctp_data_chunk_t))) + | |||
163 | sizeof(struct sk_buff) + | |||
164 | sizeof(struct sctp_chunk); | |||
165 | ||||
166 | atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); | |||
167 | sk->sk_wmem_queued += chunk->skb->truesize; | |||
168 | sk_mem_charge(sk, chunk->skb->truesize); | |||
169 | } | |||
170 | ||||
171 | /* Verify that this is a valid address. */ | |||
172 | static inlineinline __attribute__((no_instrument_function)) int sctp_verify_addr(struct sock *sk, union sctp_addr *addr, | |||
173 | int len) | |||
174 | { | |||
175 | struct sctp_af *af; | |||
176 | ||||
177 | /* Verify basic sockaddr. */ | |||
178 | af = sctp_sockaddr_af(sctp_sk(sk), addr, len); | |||
179 | if (!af) | |||
180 | return -EINVAL22; | |||
181 | ||||
182 | /* Is this a valid SCTP address? */ | |||
183 | if (!af->addr_valid(addr, sctp_sk(sk), NULL((void *)0))) | |||
184 | return -EINVAL22; | |||
185 | ||||
186 | if (!sctp_sk(sk)->pf->send_verify(sctp_sk(sk), (addr))) | |||
187 | return -EINVAL22; | |||
188 | ||||
189 | return 0; | |||
190 | } | |||
191 | ||||
192 | /* Look up the association by its id. If this is not a UDP-style | |||
193 | * socket, the ID field is always ignored. | |||
194 | */ | |||
195 | struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id) | |||
196 | { | |||
197 | struct sctp_association *asoc = NULL((void *)0); | |||
198 | ||||
199 | /* If this is not a UDP-style socket, assoc id should be ignored. */ | |||
200 | if (!sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) { | |||
201 | /* Return NULL if the socket state is not ESTABLISHED. It | |||
202 | * could be a TCP-style listening socket or a socket which | |||
203 | * hasn't yet called connect() to establish an association. | |||
204 | */ | |||
205 | if (!sctp_sstate(sk, ESTABLISHED)__sctp_sstate((sk), (SCTP_SS_ESTABLISHED)) && !sctp_sstate(sk, CLOSING)__sctp_sstate((sk), (SCTP_SS_CLOSING))) | |||
206 | return NULL((void *)0); | |||
207 | ||||
208 | /* Get the first and the only association from the list. */ | |||
209 | if (!list_empty(&sctp_sk(sk)->ep->asocs)) | |||
210 | asoc = list_entry(sctp_sk(sk)->ep->asocs.next,({ const typeof( ((struct sctp_association *)0)->asocs ) * __mptr = (sctp_sk(sk)->ep->asocs.next); (struct sctp_association *)( (char *)__mptr - __builtin_offsetof(struct sctp_association , asocs) );}) | |||
211 | struct sctp_association, asocs)({ const typeof( ((struct sctp_association *)0)->asocs ) * __mptr = (sctp_sk(sk)->ep->asocs.next); (struct sctp_association *)( (char *)__mptr - __builtin_offsetof(struct sctp_association , asocs) );}); | |||
212 | return asoc; | |||
213 | } | |||
214 | ||||
215 | /* Otherwise this is a UDP-style socket. */ | |||
216 | if (!id || (id == (sctp_assoc_t)-1)) | |||
217 | return NULL((void *)0); | |||
218 | ||||
219 | spin_lock_bh(&sctp_assocs_id_lock); | |||
220 | asoc = (struct sctp_association *)idr_find(&sctp_assocs_id, (int)id); | |||
221 | spin_unlock_bh(&sctp_assocs_id_lock); | |||
222 | ||||
223 | if (!asoc || (asoc->base.sk != sk) || asoc->base.dead) | |||
224 | return NULL((void *)0); | |||
225 | ||||
226 | return asoc; | |||
227 | } | |||
228 | ||||
229 | /* Look up the transport from an address and an assoc id. If both address and | |||
230 | * id are specified, the associations matching the address and the id should be | |||
231 | * the same. | |||
232 | */ | |||
233 | static struct sctp_transport *sctp_addr_id2transport(struct sock *sk, | |||
234 | struct sockaddr_storage__kernel_sockaddr_storage *addr, | |||
235 | sctp_assoc_t id) | |||
236 | { | |||
237 | struct sctp_association *addr_asoc = NULL((void *)0), *id_asoc = NULL((void *)0); | |||
238 | struct sctp_transport *transport; | |||
239 | union sctp_addr *laddr = (union sctp_addr *)addr; | |||
240 | ||||
241 | addr_asoc = sctp_endpoint_lookup_assoc(sctp_sk(sk)->ep, | |||
242 | laddr, | |||
243 | &transport); | |||
244 | ||||
245 | if (!addr_asoc) | |||
246 | return NULL((void *)0); | |||
247 | ||||
248 | id_asoc = sctp_id2assoc(sk, id); | |||
249 | if (id_asoc && (id_asoc != addr_asoc)) | |||
250 | return NULL((void *)0); | |||
251 | ||||
252 | sctp_get_pf_specific(sk->sk_family__sk_common.skc_family)->addr_to_user(sctp_sk(sk), | |||
253 | (union sctp_addr *)addr); | |||
254 | ||||
255 | return transport; | |||
256 | } | |||
257 | ||||
258 | /* API 3.1.2 bind() - UDP Style Syntax | |||
259 | * The syntax of bind() is, | |||
260 | * | |||
261 | * ret = bind(int sd, struct sockaddr *addr, int addrlen); | |||
262 | * | |||
263 | * sd - the socket descriptor returned by socket(). | |||
264 | * addr - the address structure (struct sockaddr_in or struct | |||
265 | * sockaddr_in6 [RFC 2553]), | |||
266 | * addr_len - the size of the address structure. | |||
267 | */ | |||
268 | static int sctp_bind(struct sock *sk, struct sockaddr *addr, int addr_len) | |||
269 | { | |||
270 | int retval = 0; | |||
271 | ||||
272 | lock_sock(sk); | |||
273 | ||||
274 | pr_debug("%s: sk:%p, addr:%p, addr_len:%d\n", __func__, sk,do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, addr:%p, addr_len:%d\n" ), .lineno = 275, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, addr:%p, addr_len:%d\n", __func__, sk, addr, addr_len ); } while (0) | |||
275 | addr, addr_len)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, addr:%p, addr_len:%d\n" ), .lineno = 275, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, addr:%p, addr_len:%d\n", __func__, sk, addr, addr_len ); } while (0); | |||
276 | ||||
277 | /* Disallow binding twice. */ | |||
278 | if (!sctp_sk(sk)->ep->base.bind_addr.port) | |||
279 | retval = sctp_do_bind(sk, (union sctp_addr *)addr, | |||
280 | addr_len); | |||
281 | else | |||
282 | retval = -EINVAL22; | |||
283 | ||||
284 | release_sock(sk); | |||
285 | ||||
286 | return retval; | |||
287 | } | |||
288 | ||||
289 | static long sctp_get_port_local(struct sock *, union sctp_addr *); | |||
290 | ||||
291 | /* Verify this is a valid sockaddr. */ | |||
292 | static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt, | |||
293 | union sctp_addr *addr, int len) | |||
294 | { | |||
295 | struct sctp_af *af; | |||
296 | ||||
297 | /* Check minimum size. */ | |||
298 | if (len < sizeof (struct sockaddr)) | |||
299 | return NULL((void *)0); | |||
300 | ||||
301 | /* V4 mapped address are really of AF_INET family */ | |||
302 | if (addr->sa.sa_family == AF_INET610 && | |||
303 | ipv6_addr_v4mapped(&addr->v6.sin6_addr)) { | |||
304 | if (!opt->pf->af_supported(AF_INET2, opt)) | |||
305 | return NULL((void *)0); | |||
306 | } else { | |||
307 | /* Does this PF support this AF? */ | |||
308 | if (!opt->pf->af_supported(addr->sa.sa_family, opt)) | |||
309 | return NULL((void *)0); | |||
310 | } | |||
311 | ||||
312 | /* If we get this far, af is valid. */ | |||
313 | af = sctp_get_af_specific(addr->sa.sa_family); | |||
314 | ||||
315 | if (len < af->sockaddr_len) | |||
316 | return NULL((void *)0); | |||
317 | ||||
318 | return af; | |||
319 | } | |||
320 | ||||
321 | /* Bind a local address either to an endpoint or to an association. */ | |||
322 | static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) | |||
323 | { | |||
324 | struct net *net = sock_net(sk); | |||
325 | struct sctp_sock *sp = sctp_sk(sk); | |||
326 | struct sctp_endpoint *ep = sp->ep; | |||
327 | struct sctp_bind_addr *bp = &ep->base.bind_addr; | |||
328 | struct sctp_af *af; | |||
329 | unsigned short snum; | |||
330 | int ret = 0; | |||
331 | ||||
332 | /* Common sockaddr verification. */ | |||
333 | af = sctp_sockaddr_af(sp, addr, len); | |||
334 | if (!af) { | |||
335 | pr_debug("%s: sk:%p, newaddr:%p, len:%d EINVAL\n",do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, newaddr:%p, len:%d EINVAL\n" ), .lineno = 336, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, newaddr:%p, len:%d EINVAL\n", __func__, sk, addr , len); } while (0) | |||
336 | __func__, sk, addr, len)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, newaddr:%p, len:%d EINVAL\n" ), .lineno = 336, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, newaddr:%p, len:%d EINVAL\n", __func__, sk, addr , len); } while (0); | |||
337 | return -EINVAL22; | |||
338 | } | |||
339 | ||||
340 | snum = ntohs(addr->v4.sin_port)(__builtin_constant_p((__u16)(( __u16)(__be16)(addr->v4.sin_port ))) ? ((__u16)( (((__u16)(( __u16)(__be16)(addr->v4.sin_port )) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16)(__be16 )(addr->v4.sin_port)) & (__u16)0xff00U) >> 8))) : __fswab16(( __u16)(__be16)(addr->v4.sin_port))); | |||
341 | ||||
342 | pr_debug("%s: sk:%p, new addr:%pISc, port:%d, new port:%d, len:%d\n",do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, new addr:%pISc, port:%d, new port:%d, len:%d\n" ), .lineno = 343, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, new addr:%pISc, port:%d, new port:%d, len:%d\n", __func__, sk, &addr->sa, bp->port, snum, len); } while (0) | |||
343 | __func__, sk, &addr->sa, bp->port, snum, len)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, new addr:%pISc, port:%d, new port:%d, len:%d\n" ), .lineno = 343, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, new addr:%pISc, port:%d, new port:%d, len:%d\n", __func__, sk, &addr->sa, bp->port, snum, len); } while (0); | |||
344 | ||||
345 | /* PF specific bind() address verification. */ | |||
346 | if (!sp->pf->bind_verify(sp, addr)) | |||
347 | return -EADDRNOTAVAIL99; | |||
348 | ||||
349 | /* We must either be unbound, or bind to the same port. | |||
350 | * It's OK to allow 0 ports if we are already bound. | |||
351 | * We'll just inhert an already bound port in this case | |||
352 | */ | |||
353 | if (bp->port) { | |||
354 | if (!snum) | |||
355 | snum = bp->port; | |||
356 | else if (snum != bp->port) { | |||
357 | pr_debug("%s: new port %d doesn't match existing port "do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: new port %d doesn't match existing port " "%d\n"), .lineno = 358, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: new port %d doesn't match existing port " "%d\n", __func__ , snum, bp->port); } while (0) | |||
358 | "%d\n", __func__, snum, bp->port)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: new port %d doesn't match existing port " "%d\n"), .lineno = 358, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: new port %d doesn't match existing port " "%d\n", __func__ , snum, bp->port); } while (0); | |||
359 | return -EINVAL22; | |||
360 | } | |||
361 | } | |||
362 | ||||
363 | if (snum && snum < PROT_SOCK1024 && | |||
364 | !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE10)) | |||
365 | return -EACCES13; | |||
366 | ||||
367 | /* See if the address matches any of the addresses we may have | |||
368 | * already bound before checking against other endpoints. | |||
369 | */ | |||
370 | if (sctp_bind_addr_match(bp, addr, sp)) | |||
371 | return -EINVAL22; | |||
372 | ||||
373 | /* Make sure we are allowed to bind here. | |||
374 | * The function sctp_get_port_local() does duplicate address | |||
375 | * detection. | |||
376 | */ | |||
377 | addr->v4.sin_port = htons(snum)(( __be16)(__builtin_constant_p((__u16)((snum))) ? ((__u16)( ( ((__u16)((snum)) & (__u16)0x00ffU) << 8) | (((__u16 )((snum)) & (__u16)0xff00U) >> 8))) : __fswab16((snum )))); | |||
378 | if ((ret = sctp_get_port_local(sk, addr))) { | |||
379 | return -EADDRINUSE98; | |||
380 | } | |||
381 | ||||
382 | /* Refresh ephemeral port. */ | |||
383 | if (!bp->port) | |||
384 | bp->port = inet_sk(sk)->inet_numsk.__sk_common.skc_num; | |||
385 | ||||
386 | /* Add the address to the bind address list. | |||
387 | * Use GFP_ATOMIC since BHs will be disabled. | |||
388 | */ | |||
389 | ret = sctp_add_bind_addr(bp, addr, af->sockaddr_len, | |||
390 | SCTP_ADDR_SRC, GFP_ATOMIC((( gfp_t)0x20u)|(( gfp_t)0x80000u)|(( gfp_t)0x2000000u))); | |||
391 | ||||
392 | /* Copy back into socket for getsockname() use. */ | |||
393 | if (!ret) { | |||
394 | inet_sk(sk)->inet_sport = htons(inet_sk(sk)->inet_num)(( __be16)(__builtin_constant_p((__u16)((inet_sk(sk)->sk.__sk_common .skc_num))) ? ((__u16)( (((__u16)((inet_sk(sk)->sk.__sk_common .skc_num)) & (__u16)0x00ffU) << 8) | (((__u16)((inet_sk (sk)->sk.__sk_common.skc_num)) & (__u16)0xff00U) >> 8))) : __fswab16((inet_sk(sk)->sk.__sk_common.skc_num)))); | |||
395 | sp->pf->to_sk_saddr(addr, sk); | |||
396 | } | |||
397 | ||||
398 | return ret; | |||
399 | } | |||
400 | ||||
401 | /* ADDIP Section 4.1.1 Congestion Control of ASCONF Chunks | |||
402 | * | |||
403 | * R1) One and only one ASCONF Chunk MAY be in transit and unacknowledged | |||
404 | * at any one time. If a sender, after sending an ASCONF chunk, decides | |||
405 | * it needs to transfer another ASCONF Chunk, it MUST wait until the | |||
406 | * ASCONF-ACK Chunk returns from the previous ASCONF Chunk before sending a | |||
407 | * subsequent ASCONF. Note this restriction binds each side, so at any | |||
408 | * time two ASCONF may be in-transit on any given association (one sent | |||
409 | * from each endpoint). | |||
410 | */ | |||
411 | static int sctp_send_asconf(struct sctp_association *asoc, | |||
412 | struct sctp_chunk *chunk) | |||
413 | { | |||
414 | struct net *net = sock_net(asoc->base.sk); | |||
415 | int retval = 0; | |||
416 | ||||
417 | /* If there is an outstanding ASCONF chunk, queue it for later | |||
418 | * transmission. | |||
419 | */ | |||
420 | if (asoc->addip_last_asconf) { | |||
421 | list_add_tail(&chunk->list, &asoc->addip_chunk_list); | |||
422 | goto out; | |||
423 | } | |||
424 | ||||
425 | /* Hold the chunk until an ASCONF_ACK is received. */ | |||
426 | sctp_chunk_hold(chunk); | |||
427 | retval = sctp_primitive_ASCONF(net, asoc, chunk); | |||
428 | if (retval) | |||
429 | sctp_chunk_free(chunk); | |||
430 | else | |||
431 | asoc->addip_last_asconf = chunk; | |||
432 | ||||
433 | out: | |||
434 | return retval; | |||
435 | } | |||
436 | ||||
437 | /* Add a list of addresses as bind addresses to local endpoint or | |||
438 | * association. | |||
439 | * | |||
440 | * Basically run through each address specified in the addrs/addrcnt | |||
441 | * array/length pair, determine if it is IPv6 or IPv4 and call | |||
442 | * sctp_do_bind() on it. | |||
443 | * | |||
444 | * If any of them fails, then the operation will be reversed and the | |||
445 | * ones that were added will be removed. | |||
446 | * | |||
447 | * Only sctp_setsockopt_bindx() is supposed to call this function. | |||
448 | */ | |||
449 | static int sctp_bindx_add(struct sock *sk, struct sockaddr *addrs, int addrcnt) | |||
450 | { | |||
451 | int cnt; | |||
452 | int retval = 0; | |||
453 | void *addr_buf; | |||
454 | struct sockaddr *sa_addr; | |||
455 | struct sctp_af *af; | |||
456 | ||||
457 | pr_debug("%s: sk:%p, addrs:%p, addrcnt:%d\n", __func__, sk,do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, addrs:%p, addrcnt:%d\n" ), .lineno = 458, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, addrs:%p, addrcnt:%d\n", __func__, sk, addrs, addrcnt ); } while (0) | |||
458 | addrs, addrcnt)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, addrs:%p, addrcnt:%d\n" ), .lineno = 458, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, addrs:%p, addrcnt:%d\n", __func__, sk, addrs, addrcnt ); } while (0); | |||
459 | ||||
460 | addr_buf = addrs; | |||
461 | for (cnt = 0; cnt < addrcnt; cnt++) { | |||
462 | /* The list may contain either IPv4 or IPv6 address; | |||
463 | * determine the address length for walking thru the list. | |||
464 | */ | |||
465 | sa_addr = addr_buf; | |||
466 | af = sctp_get_af_specific(sa_addr->sa_family); | |||
467 | if (!af) { | |||
468 | retval = -EINVAL22; | |||
469 | goto err_bindx_add; | |||
470 | } | |||
471 | ||||
472 | retval = sctp_do_bind(sk, (union sctp_addr *)sa_addr, | |||
473 | af->sockaddr_len); | |||
474 | ||||
475 | addr_buf += af->sockaddr_len; | |||
476 | ||||
477 | err_bindx_add: | |||
478 | if (retval < 0) { | |||
479 | /* Failed. Cleanup the ones that have been added */ | |||
480 | if (cnt > 0) | |||
481 | sctp_bindx_rem(sk, addrs, cnt); | |||
482 | return retval; | |||
483 | } | |||
484 | } | |||
485 | ||||
486 | return retval; | |||
487 | } | |||
488 | ||||
489 | /* Send an ASCONF chunk with Add IP address parameters to all the peers of the | |||
490 | * associations that are part of the endpoint indicating that a list of local | |||
491 | * addresses are added to the endpoint. | |||
492 | * | |||
493 | * If any of the addresses is already in the bind address list of the | |||
494 | * association, we do not send the chunk for that association. But it will not | |||
495 | * affect other associations. | |||
496 | * | |||
497 | * Only sctp_setsockopt_bindx() is supposed to call this function. | |||
498 | */ | |||
499 | static int sctp_send_asconf_add_ip(struct sock *sk, | |||
500 | struct sockaddr *addrs, | |||
501 | int addrcnt) | |||
502 | { | |||
503 | struct net *net = sock_net(sk); | |||
504 | struct sctp_sock *sp; | |||
505 | struct sctp_endpoint *ep; | |||
506 | struct sctp_association *asoc; | |||
507 | struct sctp_bind_addr *bp; | |||
508 | struct sctp_chunk *chunk; | |||
509 | struct sctp_sockaddr_entry *laddr; | |||
510 | union sctp_addr *addr; | |||
511 | union sctp_addr saveaddr; | |||
512 | void *addr_buf; | |||
513 | struct sctp_af *af; | |||
514 | struct list_head *p; | |||
515 | int i; | |||
516 | int retval = 0; | |||
517 | ||||
518 | if (!net->sctp.addip_enable) | |||
519 | return retval; | |||
520 | ||||
521 | sp = sctp_sk(sk); | |||
522 | ep = sp->ep; | |||
523 | ||||
524 | pr_debug("%s: sk:%p, addrs:%p, addrcnt:%d\n",do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, addrs:%p, addrcnt:%d\n" ), .lineno = 525, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, addrs:%p, addrcnt:%d\n", __func__, sk, addrs, addrcnt ); } while (0) | |||
525 | __func__, sk, addrs, addrcnt)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, addrs:%p, addrcnt:%d\n" ), .lineno = 525, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, addrs:%p, addrcnt:%d\n", __func__, sk, addrs, addrcnt ); } while (0); | |||
526 | ||||
527 | list_for_each_entry(asoc, &ep->asocs, asocs)for (asoc = ({ const typeof( ((typeof(*asoc) *)0)->asocs ) *__mptr = ((&ep->asocs)->next); (typeof(*asoc) *)( (char *)__mptr - __builtin_offsetof(typeof(*asoc), asocs) ); }); &asoc->asocs != (&ep->asocs); asoc = ({ const typeof( ((typeof(*(asoc)) *)0)->asocs ) *__mptr = ((asoc) ->asocs.next); (typeof(*(asoc)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(asoc)), asocs) );})) { | |||
528 | if (!asoc->peer.asconf_capable) | |||
529 | continue; | |||
530 | ||||
531 | if (asoc->peer.addip_disabled_mask & SCTP_PARAM_ADD_IP) | |||
532 | continue; | |||
533 | ||||
534 | if (!sctp_state(asoc, ESTABLISHED)__sctp_state((asoc), (SCTP_STATE_ESTABLISHED))) | |||
535 | continue; | |||
536 | ||||
537 | /* Check if any address in the packed array of addresses is | |||
538 | * in the bind address list of the association. If so, | |||
539 | * do not send the asconf chunk to its peer, but continue with | |||
540 | * other associations. | |||
541 | */ | |||
542 | addr_buf = addrs; | |||
543 | for (i = 0; i < addrcnt; i++) { | |||
544 | addr = addr_buf; | |||
545 | af = sctp_get_af_specific(addr->v4.sin_family); | |||
546 | if (!af) { | |||
547 | retval = -EINVAL22; | |||
548 | goto out; | |||
549 | } | |||
550 | ||||
551 | if (sctp_assoc_lookup_laddr(asoc, addr)) | |||
552 | break; | |||
553 | ||||
554 | addr_buf += af->sockaddr_len; | |||
555 | } | |||
556 | if (i < addrcnt) | |||
557 | continue; | |||
558 | ||||
559 | /* Use the first valid address in bind addr list of | |||
560 | * association as Address Parameter of ASCONF CHUNK. | |||
561 | */ | |||
562 | bp = &asoc->base.bind_addr; | |||
563 | p = bp->address_list.next; | |||
564 | laddr = list_entry(p, struct sctp_sockaddr_entry, list)({ const typeof( ((struct sctp_sockaddr_entry *)0)->list ) *__mptr = (p); (struct sctp_sockaddr_entry *)( (char *)__mptr - __builtin_offsetof(struct sctp_sockaddr_entry, list) );}); | |||
565 | chunk = sctp_make_asconf_update_ip(asoc, &laddr->a, addrs, | |||
566 | addrcnt, SCTP_PARAM_ADD_IP); | |||
567 | if (!chunk) { | |||
568 | retval = -ENOMEM12; | |||
569 | goto out; | |||
570 | } | |||
571 | ||||
572 | /* Add the new addresses to the bind address list with | |||
573 | * use_as_src set to 0. | |||
574 | */ | |||
575 | addr_buf = addrs; | |||
576 | for (i = 0; i < addrcnt; i++) { | |||
577 | addr = addr_buf; | |||
578 | af = sctp_get_af_specific(addr->v4.sin_family); | |||
579 | memcpy(&saveaddr, addr, af->sockaddr_len)({ size_t __len = (af->sockaddr_len); void *__ret; if (__builtin_constant_p (af->sockaddr_len) && __len >= 64) __ret = __memcpy ((&saveaddr), (addr), __len); else __ret = __builtin_memcpy ((&saveaddr), (addr), __len); __ret; }); | |||
580 | retval = sctp_add_bind_addr(bp, &saveaddr, | |||
581 | sizeof(saveaddr), | |||
582 | SCTP_ADDR_NEW, GFP_ATOMIC((( gfp_t)0x20u)|(( gfp_t)0x80000u)|(( gfp_t)0x2000000u))); | |||
583 | addr_buf += af->sockaddr_len; | |||
584 | } | |||
585 | if (asoc->src_out_of_asoc_ok) { | |||
586 | struct sctp_transport *trans; | |||
587 | ||||
588 | list_for_each_entry(trans,for (trans = ({ const typeof( ((typeof(*trans) *)0)->transports ) *__mptr = ((&asoc->peer.transport_addr_list)->next ); (typeof(*trans) *)( (char *)__mptr - __builtin_offsetof(typeof (*trans), transports) );}); &trans->transports != (& asoc->peer.transport_addr_list); trans = ({ const typeof( ( (typeof(*(trans)) *)0)->transports ) *__mptr = ((trans)-> transports.next); (typeof(*(trans)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(trans)), transports) );})) | |||
589 | &asoc->peer.transport_addr_list, transports)for (trans = ({ const typeof( ((typeof(*trans) *)0)->transports ) *__mptr = ((&asoc->peer.transport_addr_list)->next ); (typeof(*trans) *)( (char *)__mptr - __builtin_offsetof(typeof (*trans), transports) );}); &trans->transports != (& asoc->peer.transport_addr_list); trans = ({ const typeof( ( (typeof(*(trans)) *)0)->transports ) *__mptr = ((trans)-> transports.next); (typeof(*(trans)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(trans)), transports) );})) { | |||
590 | /* Clear the source and route cache */ | |||
591 | dst_release(trans->dst); | |||
592 | trans->cwnd = min(4*asoc->pathmtu, max_t(__u32,({ typeof(4*asoc->pathmtu) __UNIQUE_ID_min1_68 = (4*asoc-> pathmtu); typeof(({ __u32 __UNIQUE_ID_min1_66 = (2*asoc->pathmtu ); __u32 __UNIQUE_ID_min2_67 = (4380); (void) (&__UNIQUE_ID_min1_66 == &__UNIQUE_ID_min2_67); __UNIQUE_ID_min1_66 > __UNIQUE_ID_min2_67 ? __UNIQUE_ID_min1_66 : __UNIQUE_ID_min2_67; })) __UNIQUE_ID_min2_69 = (({ __u32 __UNIQUE_ID_min1_66 = (2*asoc->pathmtu); __u32 __UNIQUE_ID_min2_67 = (4380); (void) (&__UNIQUE_ID_min1_66 == &__UNIQUE_ID_min2_67); __UNIQUE_ID_min1_66 > __UNIQUE_ID_min2_67 ? __UNIQUE_ID_min1_66 : __UNIQUE_ID_min2_67; })); (void) (& __UNIQUE_ID_min1_68 == &__UNIQUE_ID_min2_69); __UNIQUE_ID_min1_68 < __UNIQUE_ID_min2_69 ? __UNIQUE_ID_min1_68 : __UNIQUE_ID_min2_69 ; }) | |||
593 | 2*asoc->pathmtu, 4380))({ typeof(4*asoc->pathmtu) __UNIQUE_ID_min1_68 = (4*asoc-> pathmtu); typeof(({ __u32 __UNIQUE_ID_min1_66 = (2*asoc->pathmtu ); __u32 __UNIQUE_ID_min2_67 = (4380); (void) (&__UNIQUE_ID_min1_66 == &__UNIQUE_ID_min2_67); __UNIQUE_ID_min1_66 > __UNIQUE_ID_min2_67 ? __UNIQUE_ID_min1_66 : __UNIQUE_ID_min2_67; })) __UNIQUE_ID_min2_69 = (({ __u32 __UNIQUE_ID_min1_66 = (2*asoc->pathmtu); __u32 __UNIQUE_ID_min2_67 = (4380); (void) (&__UNIQUE_ID_min1_66 == &__UNIQUE_ID_min2_67); __UNIQUE_ID_min1_66 > __UNIQUE_ID_min2_67 ? __UNIQUE_ID_min1_66 : __UNIQUE_ID_min2_67; })); (void) (& __UNIQUE_ID_min1_68 == &__UNIQUE_ID_min2_69); __UNIQUE_ID_min1_68 < __UNIQUE_ID_min2_69 ? __UNIQUE_ID_min1_68 : __UNIQUE_ID_min2_69 ; }); | |||
594 | trans->ssthresh = asoc->peer.i.a_rwnd; | |||
595 | trans->rto = asoc->rto_initial; | |||
596 | sctp_max_rto(asoc, trans); | |||
597 | trans->rtt = trans->srtt = trans->rttvar = 0; | |||
598 | sctp_transport_route(trans, NULL((void *)0), | |||
599 | sctp_sk(asoc->base.sk)); | |||
600 | } | |||
601 | } | |||
602 | retval = sctp_send_asconf(asoc, chunk); | |||
603 | } | |||
604 | ||||
605 | out: | |||
606 | return retval; | |||
607 | } | |||
608 | ||||
609 | /* Remove a list of addresses from bind addresses list. Do not remove the | |||
610 | * last address. | |||
611 | * | |||
612 | * Basically run through each address specified in the addrs/addrcnt | |||
613 | * array/length pair, determine if it is IPv6 or IPv4 and call | |||
614 | * sctp_del_bind() on it. | |||
615 | * | |||
616 | * If any of them fails, then the operation will be reversed and the | |||
617 | * ones that were removed will be added back. | |||
618 | * | |||
619 | * At least one address has to be left; if only one address is | |||
620 | * available, the operation will return -EBUSY. | |||
621 | * | |||
622 | * Only sctp_setsockopt_bindx() is supposed to call this function. | |||
623 | */ | |||
624 | static int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt) | |||
625 | { | |||
626 | struct sctp_sock *sp = sctp_sk(sk); | |||
627 | struct sctp_endpoint *ep = sp->ep; | |||
628 | int cnt; | |||
629 | struct sctp_bind_addr *bp = &ep->base.bind_addr; | |||
630 | int retval = 0; | |||
631 | void *addr_buf; | |||
632 | union sctp_addr *sa_addr; | |||
633 | struct sctp_af *af; | |||
634 | ||||
635 | pr_debug("%s: sk:%p, addrs:%p, addrcnt:%d\n",do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, addrs:%p, addrcnt:%d\n" ), .lineno = 636, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, addrs:%p, addrcnt:%d\n", __func__, sk, addrs, addrcnt ); } while (0) | |||
636 | __func__, sk, addrs, addrcnt)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, addrs:%p, addrcnt:%d\n" ), .lineno = 636, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, addrs:%p, addrcnt:%d\n", __func__, sk, addrs, addrcnt ); } while (0); | |||
637 | ||||
638 | addr_buf = addrs; | |||
639 | for (cnt = 0; cnt < addrcnt; cnt++) { | |||
640 | /* If the bind address list is empty or if there is only one | |||
641 | * bind address, there is nothing more to be removed (we need | |||
642 | * at least one address here). | |||
643 | */ | |||
644 | if (list_empty(&bp->address_list) || | |||
645 | (sctp_list_single_entry(&bp->address_list))) { | |||
646 | retval = -EBUSY16; | |||
647 | goto err_bindx_rem; | |||
648 | } | |||
649 | ||||
650 | sa_addr = addr_buf; | |||
651 | af = sctp_get_af_specific(sa_addr->sa.sa_family); | |||
652 | if (!af) { | |||
653 | retval = -EINVAL22; | |||
654 | goto err_bindx_rem; | |||
655 | } | |||
656 | ||||
657 | if (!af->addr_valid(sa_addr, sp, NULL((void *)0))) { | |||
658 | retval = -EADDRNOTAVAIL99; | |||
659 | goto err_bindx_rem; | |||
660 | } | |||
661 | ||||
662 | if (sa_addr->v4.sin_port && | |||
663 | sa_addr->v4.sin_port != htons(bp->port)(( __be16)(__builtin_constant_p((__u16)((bp->port))) ? ((__u16 )( (((__u16)((bp->port)) & (__u16)0x00ffU) << 8) | (((__u16)((bp->port)) & (__u16)0xff00U) >> 8) )) : __fswab16((bp->port))))) { | |||
664 | retval = -EINVAL22; | |||
665 | goto err_bindx_rem; | |||
666 | } | |||
667 | ||||
668 | if (!sa_addr->v4.sin_port) | |||
669 | sa_addr->v4.sin_port = htons(bp->port)(( __be16)(__builtin_constant_p((__u16)((bp->port))) ? ((__u16 )( (((__u16)((bp->port)) & (__u16)0x00ffU) << 8) | (((__u16)((bp->port)) & (__u16)0xff00U) >> 8) )) : __fswab16((bp->port)))); | |||
670 | ||||
671 | /* FIXME - There is probably a need to check if sk->sk_saddr and | |||
672 | * sk->sk_rcv_addr are currently set to one of the addresses to | |||
673 | * be removed. This is something which needs to be looked into | |||
674 | * when we are fixing the outstanding issues with multi-homing | |||
675 | * socket routing and failover schemes. Refer to comments in | |||
676 | * sctp_do_bind(). -daisy | |||
677 | */ | |||
678 | retval = sctp_del_bind_addr(bp, sa_addr); | |||
679 | ||||
680 | addr_buf += af->sockaddr_len; | |||
681 | err_bindx_rem: | |||
682 | if (retval < 0) { | |||
683 | /* Failed. Add the ones that has been removed back */ | |||
684 | if (cnt > 0) | |||
685 | sctp_bindx_add(sk, addrs, cnt); | |||
686 | return retval; | |||
687 | } | |||
688 | } | |||
689 | ||||
690 | return retval; | |||
691 | } | |||
692 | ||||
693 | /* Send an ASCONF chunk with Delete IP address parameters to all the peers of | |||
694 | * the associations that are part of the endpoint indicating that a list of | |||
695 | * local addresses are removed from the endpoint. | |||
696 | * | |||
697 | * If any of the addresses is already in the bind address list of the | |||
698 | * association, we do not send the chunk for that association. But it will not | |||
699 | * affect other associations. | |||
700 | * | |||
701 | * Only sctp_setsockopt_bindx() is supposed to call this function. | |||
702 | */ | |||
703 | static int sctp_send_asconf_del_ip(struct sock *sk, | |||
704 | struct sockaddr *addrs, | |||
705 | int addrcnt) | |||
706 | { | |||
707 | struct net *net = sock_net(sk); | |||
708 | struct sctp_sock *sp; | |||
709 | struct sctp_endpoint *ep; | |||
710 | struct sctp_association *asoc; | |||
711 | struct sctp_transport *transport; | |||
712 | struct sctp_bind_addr *bp; | |||
713 | struct sctp_chunk *chunk; | |||
714 | union sctp_addr *laddr; | |||
715 | void *addr_buf; | |||
716 | struct sctp_af *af; | |||
717 | struct sctp_sockaddr_entry *saddr; | |||
718 | int i; | |||
719 | int retval = 0; | |||
720 | int stored = 0; | |||
721 | ||||
722 | chunk = NULL((void *)0); | |||
723 | if (!net->sctp.addip_enable) | |||
724 | return retval; | |||
725 | ||||
726 | sp = sctp_sk(sk); | |||
727 | ep = sp->ep; | |||
728 | ||||
729 | pr_debug("%s: sk:%p, addrs:%p, addrcnt:%d\n",do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, addrs:%p, addrcnt:%d\n" ), .lineno = 730, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, addrs:%p, addrcnt:%d\n", __func__, sk, addrs, addrcnt ); } while (0) | |||
730 | __func__, sk, addrs, addrcnt)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, addrs:%p, addrcnt:%d\n" ), .lineno = 730, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, addrs:%p, addrcnt:%d\n", __func__, sk, addrs, addrcnt ); } while (0); | |||
731 | ||||
732 | list_for_each_entry(asoc, &ep->asocs, asocs)for (asoc = ({ const typeof( ((typeof(*asoc) *)0)->asocs ) *__mptr = ((&ep->asocs)->next); (typeof(*asoc) *)( (char *)__mptr - __builtin_offsetof(typeof(*asoc), asocs) ); }); &asoc->asocs != (&ep->asocs); asoc = ({ const typeof( ((typeof(*(asoc)) *)0)->asocs ) *__mptr = ((asoc) ->asocs.next); (typeof(*(asoc)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(asoc)), asocs) );})) { | |||
733 | ||||
734 | if (!asoc->peer.asconf_capable) | |||
735 | continue; | |||
736 | ||||
737 | if (asoc->peer.addip_disabled_mask & SCTP_PARAM_DEL_IP) | |||
738 | continue; | |||
739 | ||||
740 | if (!sctp_state(asoc, ESTABLISHED)__sctp_state((asoc), (SCTP_STATE_ESTABLISHED))) | |||
741 | continue; | |||
742 | ||||
743 | /* Check if any address in the packed array of addresses is | |||
744 | * not present in the bind address list of the association. | |||
745 | * If so, do not send the asconf chunk to its peer, but | |||
746 | * continue with other associations. | |||
747 | */ | |||
748 | addr_buf = addrs; | |||
749 | for (i = 0; i < addrcnt; i++) { | |||
750 | laddr = addr_buf; | |||
751 | af = sctp_get_af_specific(laddr->v4.sin_family); | |||
752 | if (!af) { | |||
753 | retval = -EINVAL22; | |||
754 | goto out; | |||
755 | } | |||
756 | ||||
757 | if (!sctp_assoc_lookup_laddr(asoc, laddr)) | |||
758 | break; | |||
759 | ||||
760 | addr_buf += af->sockaddr_len; | |||
761 | } | |||
762 | if (i < addrcnt) | |||
763 | continue; | |||
764 | ||||
765 | /* Find one address in the association's bind address list | |||
766 | * that is not in the packed array of addresses. This is to | |||
767 | * make sure that we do not delete all the addresses in the | |||
768 | * association. | |||
769 | */ | |||
770 | bp = &asoc->base.bind_addr; | |||
771 | laddr = sctp_find_unmatch_addr(bp, (union sctp_addr *)addrs, | |||
772 | addrcnt, sp); | |||
773 | if ((laddr == NULL((void *)0)) && (addrcnt == 1)) { | |||
774 | if (asoc->asconf_addr_del_pending) | |||
775 | continue; | |||
776 | asoc->asconf_addr_del_pending = | |||
777 | kzalloc(sizeof(union sctp_addr), GFP_ATOMIC((( gfp_t)0x20u)|(( gfp_t)0x80000u)|(( gfp_t)0x2000000u))); | |||
778 | if (asoc->asconf_addr_del_pending == NULL((void *)0)) { | |||
779 | retval = -ENOMEM12; | |||
780 | goto out; | |||
781 | } | |||
782 | asoc->asconf_addr_del_pending->sa.sa_family = | |||
783 | addrs->sa_family; | |||
784 | asoc->asconf_addr_del_pending->v4.sin_port = | |||
785 | htons(bp->port)(( __be16)(__builtin_constant_p((__u16)((bp->port))) ? ((__u16 )( (((__u16)((bp->port)) & (__u16)0x00ffU) << 8) | (((__u16)((bp->port)) & (__u16)0xff00U) >> 8) )) : __fswab16((bp->port)))); | |||
786 | if (addrs->sa_family == AF_INET2) { | |||
787 | struct sockaddr_in *sin; | |||
788 | ||||
789 | sin = (struct sockaddr_in *)addrs; | |||
790 | asoc->asconf_addr_del_pending->v4.sin_addr.s_addr = sin->sin_addr.s_addr; | |||
791 | } else if (addrs->sa_family == AF_INET610) { | |||
792 | struct sockaddr_in6 *sin6; | |||
793 | ||||
794 | sin6 = (struct sockaddr_in6 *)addrs; | |||
795 | asoc->asconf_addr_del_pending->v6.sin6_addr = sin6->sin6_addr; | |||
796 | } | |||
797 | ||||
798 | pr_debug("%s: keep the last address asoc:%p %pISc at %p\n",do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: keep the last address asoc:%p %pISc at %p\n" ), .lineno = 800, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: keep the last address asoc:%p %pISc at %p\n", __func__, asoc, &asoc->asconf_addr_del_pending->sa, asoc-> asconf_addr_del_pending); } while (0) | |||
799 | __func__, asoc, &asoc->asconf_addr_del_pending->sa,do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: keep the last address asoc:%p %pISc at %p\n" ), .lineno = 800, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: keep the last address asoc:%p %pISc at %p\n", __func__, asoc, &asoc->asconf_addr_del_pending->sa, asoc-> asconf_addr_del_pending); } while (0) | |||
800 | asoc->asconf_addr_del_pending)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: keep the last address asoc:%p %pISc at %p\n" ), .lineno = 800, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: keep the last address asoc:%p %pISc at %p\n", __func__, asoc, &asoc->asconf_addr_del_pending->sa, asoc-> asconf_addr_del_pending); } while (0); | |||
801 | ||||
802 | asoc->src_out_of_asoc_ok = 1; | |||
803 | stored = 1; | |||
804 | goto skip_mkasconf; | |||
805 | } | |||
806 | ||||
807 | if (laddr == NULL((void *)0)) | |||
808 | return -EINVAL22; | |||
809 | ||||
810 | /* We do not need RCU protection throughout this loop | |||
811 | * because this is done under a socket lock from the | |||
812 | * setsockopt call. | |||
813 | */ | |||
814 | chunk = sctp_make_asconf_update_ip(asoc, laddr, addrs, addrcnt, | |||
815 | SCTP_PARAM_DEL_IP); | |||
816 | if (!chunk) { | |||
817 | retval = -ENOMEM12; | |||
818 | goto out; | |||
819 | } | |||
820 | ||||
821 | skip_mkasconf: | |||
822 | /* Reset use_as_src flag for the addresses in the bind address | |||
823 | * list that are to be deleted. | |||
824 | */ | |||
825 | addr_buf = addrs; | |||
826 | for (i = 0; i < addrcnt; i++) { | |||
827 | laddr = addr_buf; | |||
828 | af = sctp_get_af_specific(laddr->v4.sin_family); | |||
829 | list_for_each_entry(saddr, &bp->address_list, list)for (saddr = ({ const typeof( ((typeof(*saddr) *)0)->list ) *__mptr = ((&bp->address_list)->next); (typeof(*saddr ) *)( (char *)__mptr - __builtin_offsetof(typeof(*saddr), list ) );}); &saddr->list != (&bp->address_list); saddr = ({ const typeof( ((typeof(*(saddr)) *)0)->list ) *__mptr = ((saddr)->list.next); (typeof(*(saddr)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(saddr)), list) );})) { | |||
830 | if (sctp_cmp_addr_exact(&saddr->a, laddr)) | |||
831 | saddr->state = SCTP_ADDR_DEL; | |||
832 | } | |||
833 | addr_buf += af->sockaddr_len; | |||
834 | } | |||
835 | ||||
836 | /* Update the route and saddr entries for all the transports | |||
837 | * as some of the addresses in the bind address list are | |||
838 | * about to be deleted and cannot be used as source addresses. | |||
839 | */ | |||
840 | list_for_each_entry(transport, &asoc->peer.transport_addr_list,for (transport = ({ const typeof( ((typeof(*transport) *)0)-> transports ) *__mptr = ((&asoc->peer.transport_addr_list )->next); (typeof(*transport) *)( (char *)__mptr - __builtin_offsetof (typeof(*transport), transports) );}); &transport->transports != (&asoc->peer.transport_addr_list); transport = ({ const typeof( ((typeof(*(transport)) *)0)->transports ) *__mptr = ((transport)->transports.next); (typeof(*(transport)) * )( (char *)__mptr - __builtin_offsetof(typeof(*(transport)), transports ) );})) | |||
841 | transports)for (transport = ({ const typeof( ((typeof(*transport) *)0)-> transports ) *__mptr = ((&asoc->peer.transport_addr_list )->next); (typeof(*transport) *)( (char *)__mptr - __builtin_offsetof (typeof(*transport), transports) );}); &transport->transports != (&asoc->peer.transport_addr_list); transport = ({ const typeof( ((typeof(*(transport)) *)0)->transports ) *__mptr = ((transport)->transports.next); (typeof(*(transport)) * )( (char *)__mptr - __builtin_offsetof(typeof(*(transport)), transports ) );})) { | |||
842 | dst_release(transport->dst); | |||
843 | sctp_transport_route(transport, NULL((void *)0), | |||
844 | sctp_sk(asoc->base.sk)); | |||
845 | } | |||
846 | ||||
847 | if (stored) | |||
848 | /* We don't need to transmit ASCONF */ | |||
849 | continue; | |||
850 | retval = sctp_send_asconf(asoc, chunk); | |||
851 | } | |||
852 | out: | |||
853 | return retval; | |||
854 | } | |||
855 | ||||
856 | /* set addr events to assocs in the endpoint. ep and addr_wq must be locked */ | |||
857 | int sctp_asconf_mgmt(struct sctp_sock *sp, struct sctp_sockaddr_entry *addrw) | |||
858 | { | |||
859 | struct sock *sk = sctp_opt2sk(sp); | |||
860 | union sctp_addr *addr; | |||
861 | struct sctp_af *af; | |||
862 | ||||
863 | /* It is safe to write port space in caller. */ | |||
864 | addr = &addrw->a; | |||
865 | addr->v4.sin_port = htons(sp->ep->base.bind_addr.port)(( __be16)(__builtin_constant_p((__u16)((sp->ep->base.bind_addr .port))) ? ((__u16)( (((__u16)((sp->ep->base.bind_addr. port)) & (__u16)0x00ffU) << 8) | (((__u16)((sp-> ep->base.bind_addr.port)) & (__u16)0xff00U) >> 8 ))) : __fswab16((sp->ep->base.bind_addr.port)))); | |||
866 | af = sctp_get_af_specific(addr->sa.sa_family); | |||
867 | if (!af) | |||
868 | return -EINVAL22; | |||
869 | if (sctp_verify_addr(sk, addr, af->sockaddr_len)) | |||
870 | return -EINVAL22; | |||
871 | ||||
872 | if (addrw->state == SCTP_ADDR_NEW) | |||
873 | return sctp_send_asconf_add_ip(sk, (struct sockaddr *)addr, 1); | |||
874 | else | |||
875 | return sctp_send_asconf_del_ip(sk, (struct sockaddr *)addr, 1); | |||
876 | } | |||
877 | ||||
878 | /* Helper for tunneling sctp_bindx() requests through sctp_setsockopt() | |||
879 | * | |||
880 | * API 8.1 | |||
881 | * int sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, | |||
882 | * int flags); | |||
883 | * | |||
884 | * If sd is an IPv4 socket, the addresses passed must be IPv4 addresses. | |||
885 | * If the sd is an IPv6 socket, the addresses passed can either be IPv4 | |||
886 | * or IPv6 addresses. | |||
887 | * | |||
888 | * A single address may be specified as INADDR_ANY or IN6ADDR_ANY, see | |||
889 | * Section 3.1.2 for this usage. | |||
890 | * | |||
891 | * addrs is a pointer to an array of one or more socket addresses. Each | |||
892 | * address is contained in its appropriate structure (i.e. struct | |||
893 | * sockaddr_in or struct sockaddr_in6) the family of the address type | |||
894 | * must be used to distinguish the address length (note that this | |||
895 | * representation is termed a "packed array" of addresses). The caller | |||
896 | * specifies the number of addresses in the array with addrcnt. | |||
897 | * | |||
898 | * On success, sctp_bindx() returns 0. On failure, sctp_bindx() returns | |||
899 | * -1, and sets errno to the appropriate error code. | |||
900 | * | |||
901 | * For SCTP, the port given in each socket address must be the same, or | |||
902 | * sctp_bindx() will fail, setting errno to EINVAL. | |||
903 | * | |||
904 | * The flags parameter is formed from the bitwise OR of zero or more of | |||
905 | * the following currently defined flags: | |||
906 | * | |||
907 | * SCTP_BINDX_ADD_ADDR | |||
908 | * | |||
909 | * SCTP_BINDX_REM_ADDR | |||
910 | * | |||
911 | * SCTP_BINDX_ADD_ADDR directs SCTP to add the given addresses to the | |||
912 | * association, and SCTP_BINDX_REM_ADDR directs SCTP to remove the given | |||
913 | * addresses from the association. The two flags are mutually exclusive; | |||
914 | * if both are given, sctp_bindx() will fail with EINVAL. A caller may | |||
915 | * not remove all addresses from an association; sctp_bindx() will | |||
916 | * reject such an attempt with EINVAL. | |||
917 | * | |||
918 | * An application can use sctp_bindx(SCTP_BINDX_ADD_ADDR) to associate | |||
919 | * additional addresses with an endpoint after calling bind(). Or use | |||
920 | * sctp_bindx(SCTP_BINDX_REM_ADDR) to remove some addresses a listening | |||
921 | * socket is associated with so that no new association accepted will be | |||
922 | * associated with those addresses. If the endpoint supports dynamic | |||
923 | * address a SCTP_BINDX_REM_ADDR or SCTP_BINDX_ADD_ADDR may cause a | |||
924 | * endpoint to send the appropriate message to the peer to change the | |||
925 | * peers address lists. | |||
926 | * | |||
927 | * Adding and removing addresses from a connected association is | |||
928 | * optional functionality. Implementations that do not support this | |||
929 | * functionality should return EOPNOTSUPP. | |||
930 | * | |||
931 | * Basically do nothing but copying the addresses from user to kernel | |||
932 | * land and invoking either sctp_bindx_add() or sctp_bindx_rem() on the sk. | |||
933 | * This is used for tunneling the sctp_bindx() request through sctp_setsockopt() | |||
934 | * from userspace. | |||
935 | * | |||
936 | * We don't use copy_from_user() for optimization: we first do the | |||
937 | * sanity checks (buffer size -fast- and access check-healthy | |||
938 | * pointer); if all of those succeed, then we can alloc the memory | |||
939 | * (expensive operation) needed to copy the data to kernel. Then we do | |||
940 | * the copying without checking the user space area | |||
941 | * (__copy_from_user()). | |||
942 | * | |||
943 | * On exit there is no need to do sockfd_put(), sys_setsockopt() does | |||
944 | * it. | |||
945 | * | |||
946 | * sk The sk of the socket | |||
947 | * addrs The pointer to the addresses in user land | |||
948 | * addrssize Size of the addrs buffer | |||
949 | * op Operation to perform (add or remove, see the flags of | |||
950 | * sctp_bindx) | |||
951 | * | |||
952 | * Returns 0 if ok, <0 errno code on error. | |||
953 | */ | |||
954 | static int sctp_setsockopt_bindx(struct sock *sk, | |||
955 | struct sockaddr __user *addrs, | |||
956 | int addrs_size, int op) | |||
957 | { | |||
958 | struct sockaddr *kaddrs; | |||
959 | int err; | |||
960 | int addrcnt = 0; | |||
961 | int walk_size = 0; | |||
962 | struct sockaddr *sa_addr; | |||
963 | void *addr_buf; | |||
964 | struct sctp_af *af; | |||
965 | ||||
966 | pr_debug("%s: sk:%p addrs:%p addrs_size:%d opt:%d\n",do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p addrs:%p addrs_size:%d opt:%d\n" ), .lineno = 967, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p addrs:%p addrs_size:%d opt:%d\n", __func__, sk, addrs , addrs_size, op); } while (0) | |||
967 | __func__, sk, addrs, addrs_size, op)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p addrs:%p addrs_size:%d opt:%d\n" ), .lineno = 967, .flags = 0, }; if ((descriptor.flags & ( 1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p addrs:%p addrs_size:%d opt:%d\n", __func__, sk, addrs , addrs_size, op); } while (0); | |||
968 | ||||
969 | if (unlikely(addrs_size <= 0)(addrs_size <= 0)) | |||
970 | return -EINVAL22; | |||
971 | ||||
972 | /* Check the user passed a healthy pointer. */ | |||
973 | if (unlikely(!access_ok(VERIFY_READ, addrs, addrs_size))(!(!({ (void)0; __chk_range_not_ok((unsigned long )(addrs), addrs_size , (get_current()->thread.addr_limit.seg)); })))) | |||
974 | return -EFAULT14; | |||
975 | ||||
976 | /* Alloc space for the address array in kernel memory. */ | |||
977 | kaddrs = kmalloc(addrs_size, GFP_USER((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u) | (( gfp_t)0x20000u)) | __GFP_NOWARN(( gfp_t)0x200u)); | |||
978 | if (unlikely(!kaddrs)(!kaddrs)) | |||
979 | return -ENOMEM12; | |||
980 | ||||
981 | if (__copy_from_user(kaddrs, addrs, addrs_size)) { | |||
982 | kfree(kaddrs); | |||
983 | return -EFAULT14; | |||
984 | } | |||
985 | ||||
986 | /* Walk through the addrs buffer and count the number of addresses. */ | |||
987 | addr_buf = kaddrs; | |||
988 | while (walk_size < addrs_size) { | |||
989 | if (walk_size + sizeof(sa_family_t) > addrs_size) { | |||
990 | kfree(kaddrs); | |||
991 | return -EINVAL22; | |||
992 | } | |||
993 | ||||
994 | sa_addr = addr_buf; | |||
995 | af = sctp_get_af_specific(sa_addr->sa_family); | |||
996 | ||||
997 | /* If the address family is not supported or if this address | |||
998 | * causes the address buffer to overflow return EINVAL. | |||
999 | */ | |||
1000 | if (!af || (walk_size + af->sockaddr_len) > addrs_size) { | |||
1001 | kfree(kaddrs); | |||
1002 | return -EINVAL22; | |||
1003 | } | |||
1004 | addrcnt++; | |||
1005 | addr_buf += af->sockaddr_len; | |||
1006 | walk_size += af->sockaddr_len; | |||
1007 | } | |||
1008 | ||||
1009 | /* Do the work. */ | |||
1010 | switch (op) { | |||
1011 | case SCTP_BINDX_ADD_ADDR0x01: | |||
1012 | err = sctp_bindx_add(sk, kaddrs, addrcnt); | |||
1013 | if (err) | |||
1014 | goto out; | |||
1015 | err = sctp_send_asconf_add_ip(sk, kaddrs, addrcnt); | |||
1016 | break; | |||
1017 | ||||
1018 | case SCTP_BINDX_REM_ADDR0x02: | |||
1019 | err = sctp_bindx_rem(sk, kaddrs, addrcnt); | |||
1020 | if (err) | |||
1021 | goto out; | |||
1022 | err = sctp_send_asconf_del_ip(sk, kaddrs, addrcnt); | |||
1023 | break; | |||
1024 | ||||
1025 | default: | |||
1026 | err = -EINVAL22; | |||
1027 | break; | |||
1028 | } | |||
1029 | ||||
1030 | out: | |||
1031 | kfree(kaddrs); | |||
1032 | ||||
1033 | return err; | |||
1034 | } | |||
1035 | ||||
1036 | /* __sctp_connect(struct sock* sk, struct sockaddr *kaddrs, int addrs_size) | |||
1037 | * | |||
1038 | * Common routine for handling connect() and sctp_connectx(). | |||
1039 | * Connect will come in with just a single address. | |||
1040 | */ | |||
1041 | static int __sctp_connect(struct sock *sk, | |||
1042 | struct sockaddr *kaddrs, | |||
1043 | int addrs_size, | |||
1044 | sctp_assoc_t *assoc_id) | |||
1045 | { | |||
1046 | struct net *net = sock_net(sk); | |||
1047 | struct sctp_sock *sp; | |||
1048 | struct sctp_endpoint *ep; | |||
1049 | struct sctp_association *asoc = NULL((void *)0); | |||
1050 | struct sctp_association *asoc2; | |||
1051 | struct sctp_transport *transport; | |||
1052 | union sctp_addr to; | |||
1053 | sctp_scope_t scope; | |||
1054 | long timeo; | |||
1055 | int err = 0; | |||
1056 | int addrcnt = 0; | |||
1057 | int walk_size = 0; | |||
1058 | union sctp_addr *sa_addr = NULL((void *)0); | |||
1059 | void *addr_buf; | |||
1060 | unsigned short port; | |||
1061 | unsigned int f_flags = 0; | |||
1062 | ||||
1063 | sp = sctp_sk(sk); | |||
1064 | ep = sp->ep; | |||
1065 | ||||
1066 | /* connect() cannot be done on a socket that is already in ESTABLISHED | |||
1067 | * state - UDP-style peeled off socket or a TCP-style socket that | |||
1068 | * is already connected. | |||
1069 | * It cannot be done even on a TCP-style listening socket. | |||
1070 | */ | |||
1071 | if (sctp_sstate(sk, ESTABLISHED)__sctp_sstate((sk), (SCTP_SS_ESTABLISHED)) || sctp_sstate(sk, CLOSING)__sctp_sstate((sk), (SCTP_SS_CLOSING)) || | |||
1072 | (sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP)) && sctp_sstate(sk, LISTENING)__sctp_sstate((sk), (SCTP_SS_LISTENING)))) { | |||
1073 | err = -EISCONN106; | |||
1074 | goto out_free; | |||
1075 | } | |||
1076 | ||||
1077 | /* Walk through the addrs buffer and count the number of addresses. */ | |||
1078 | addr_buf = kaddrs; | |||
1079 | while (walk_size < addrs_size) { | |||
1080 | struct sctp_af *af; | |||
1081 | ||||
1082 | if (walk_size + sizeof(sa_family_t) > addrs_size) { | |||
1083 | err = -EINVAL22; | |||
1084 | goto out_free; | |||
1085 | } | |||
1086 | ||||
1087 | sa_addr = addr_buf; | |||
1088 | af = sctp_get_af_specific(sa_addr->sa.sa_family); | |||
1089 | ||||
1090 | /* If the address family is not supported or if this address | |||
1091 | * causes the address buffer to overflow return EINVAL. | |||
1092 | */ | |||
1093 | if (!af || (walk_size + af->sockaddr_len) > addrs_size) { | |||
1094 | err = -EINVAL22; | |||
1095 | goto out_free; | |||
1096 | } | |||
1097 | ||||
1098 | port = ntohs(sa_addr->v4.sin_port)(__builtin_constant_p((__u16)(( __u16)(__be16)(sa_addr->v4 .sin_port))) ? ((__u16)( (((__u16)(( __u16)(__be16)(sa_addr-> v4.sin_port)) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16)(__be16)(sa_addr->v4.sin_port)) & (__u16)0xff00U ) >> 8))) : __fswab16(( __u16)(__be16)(sa_addr->v4.sin_port ))); | |||
1099 | ||||
1100 | /* Save current address so we can work with it */ | |||
1101 | memcpy(&to, sa_addr, af->sockaddr_len)({ size_t __len = (af->sockaddr_len); void *__ret; if (__builtin_constant_p (af->sockaddr_len) && __len >= 64) __ret = __memcpy ((&to), (sa_addr), __len); else __ret = __builtin_memcpy( (&to), (sa_addr), __len); __ret; }); | |||
1102 | ||||
1103 | err = sctp_verify_addr(sk, &to, af->sockaddr_len); | |||
1104 | if (err) | |||
1105 | goto out_free; | |||
1106 | ||||
1107 | /* Make sure the destination port is correctly set | |||
1108 | * in all addresses. | |||
1109 | */ | |||
1110 | if (asoc && asoc->peer.port && asoc->peer.port != port) { | |||
1111 | err = -EINVAL22; | |||
1112 | goto out_free; | |||
1113 | } | |||
1114 | ||||
1115 | /* Check if there already is a matching association on the | |||
1116 | * endpoint (other than the one created here). | |||
1117 | */ | |||
1118 | asoc2 = sctp_endpoint_lookup_assoc(ep, &to, &transport); | |||
1119 | if (asoc2 && asoc2 != asoc) { | |||
1120 | if (asoc2->state >= SCTP_STATE_ESTABLISHED) | |||
1121 | err = -EISCONN106; | |||
1122 | else | |||
1123 | err = -EALREADY114; | |||
1124 | goto out_free; | |||
1125 | } | |||
1126 | ||||
1127 | /* If we could not find a matching association on the endpoint, | |||
1128 | * make sure that there is no peeled-off association matching | |||
1129 | * the peer address even on another socket. | |||
1130 | */ | |||
1131 | if (sctp_endpoint_is_peeled_off(ep, &to)) { | |||
1132 | err = -EADDRNOTAVAIL99; | |||
1133 | goto out_free; | |||
1134 | } | |||
1135 | ||||
1136 | if (!asoc) { | |||
1137 | /* If a bind() or sctp_bindx() is not called prior to | |||
1138 | * an sctp_connectx() call, the system picks an | |||
1139 | * ephemeral port and will choose an address set | |||
1140 | * equivalent to binding with a wildcard address. | |||
1141 | */ | |||
1142 | if (!ep->base.bind_addr.port) { | |||
1143 | if (sctp_autobind(sk)) { | |||
1144 | err = -EAGAIN11; | |||
1145 | goto out_free; | |||
1146 | } | |||
1147 | } else { | |||
1148 | /* | |||
1149 | * If an unprivileged user inherits a 1-many | |||
1150 | * style socket with open associations on a | |||
1151 | * privileged port, it MAY be permitted to | |||
1152 | * accept new associations, but it SHOULD NOT | |||
1153 | * be permitted to open new associations. | |||
1154 | */ | |||
1155 | if (ep->base.bind_addr.port < PROT_SOCK1024 && | |||
1156 | !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE10)) { | |||
1157 | err = -EACCES13; | |||
1158 | goto out_free; | |||
1159 | } | |||
1160 | } | |||
1161 | ||||
1162 | scope = sctp_scope(&to); | |||
1163 | asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u))); | |||
1164 | if (!asoc) { | |||
1165 | err = -ENOMEM12; | |||
1166 | goto out_free; | |||
1167 | } | |||
1168 | ||||
1169 | err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, | |||
1170 | GFP_KERNEL((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u))); | |||
1171 | if (err < 0) { | |||
1172 | goto out_free; | |||
1173 | } | |||
1174 | ||||
1175 | } | |||
1176 | ||||
1177 | /* Prime the peer's transport structures. */ | |||
1178 | transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u)), | |||
1179 | SCTP_UNKNOWN); | |||
1180 | if (!transport) { | |||
1181 | err = -ENOMEM12; | |||
1182 | goto out_free; | |||
1183 | } | |||
1184 | ||||
1185 | addrcnt++; | |||
1186 | addr_buf += af->sockaddr_len; | |||
1187 | walk_size += af->sockaddr_len; | |||
1188 | } | |||
1189 | ||||
1190 | /* In case the user of sctp_connectx() wants an association | |||
1191 | * id back, assign one now. | |||
1192 | */ | |||
1193 | if (assoc_id) { | |||
1194 | err = sctp_assoc_set_id(asoc, GFP_KERNEL((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u))); | |||
1195 | if (err < 0) | |||
1196 | goto out_free; | |||
1197 | } | |||
1198 | ||||
1199 | err = sctp_primitive_ASSOCIATE(net, asoc, NULL((void *)0)); | |||
1200 | if (err < 0) { | |||
1201 | goto out_free; | |||
1202 | } | |||
1203 | ||||
1204 | /* Initialize sk's dport and daddr for getpeername() */ | |||
1205 | inet_sk(sk)->inet_dportsk.__sk_common.skc_dport = htons(asoc->peer.port)(( __be16)(__builtin_constant_p((__u16)((asoc->peer.port)) ) ? ((__u16)( (((__u16)((asoc->peer.port)) & (__u16)0x00ffU ) << 8) | (((__u16)((asoc->peer.port)) & (__u16) 0xff00U) >> 8))) : __fswab16((asoc->peer.port)))); | |||
1206 | sp->pf->to_sk_daddr(sa_addr, sk); | |||
1207 | sk->sk_err = 0; | |||
1208 | ||||
1209 | /* in-kernel sockets don't generally have a file allocated to them | |||
1210 | * if all they do is call sock_create_kern(). | |||
1211 | */ | |||
1212 | if (sk->sk_socket->file) | |||
1213 | f_flags = sk->sk_socket->file->f_flags; | |||
1214 | ||||
1215 | timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK00004000); | |||
1216 | ||||
1217 | if (assoc_id) | |||
1218 | *assoc_id = asoc->assoc_id; | |||
1219 | err = sctp_wait_for_connect(asoc, &timeo); | |||
1220 | /* Note: the asoc may be freed after the return of | |||
1221 | * sctp_wait_for_connect. | |||
1222 | */ | |||
1223 | ||||
1224 | /* Don't free association on exit. */ | |||
1225 | asoc = NULL((void *)0); | |||
1226 | ||||
1227 | out_free: | |||
1228 | pr_debug("%s: took out_free path with asoc:%p kaddrs:%p err:%d\n",do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: took out_free path with asoc:%p kaddrs:%p err:%d\n" ), .lineno = 1229, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: took out_free path with asoc:%p kaddrs:%p err:%d\n", __func__ , asoc, kaddrs, err); } while (0) | |||
1229 | __func__, asoc, kaddrs, err)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: took out_free path with asoc:%p kaddrs:%p err:%d\n" ), .lineno = 1229, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: took out_free path with asoc:%p kaddrs:%p err:%d\n", __func__ , asoc, kaddrs, err); } while (0); | |||
1230 | ||||
1231 | if (asoc) { | |||
1232 | /* sctp_primitive_ASSOCIATE may have added this association | |||
1233 | * To the hash table, try to unhash it, just in case, its a noop | |||
1234 | * if it wasn't hashed so we're safe | |||
1235 | */ | |||
1236 | sctp_association_free(asoc); | |||
1237 | } | |||
1238 | return err; | |||
1239 | } | |||
1240 | ||||
1241 | /* Helper for tunneling sctp_connectx() requests through sctp_setsockopt() | |||
1242 | * | |||
1243 | * API 8.9 | |||
1244 | * int sctp_connectx(int sd, struct sockaddr *addrs, int addrcnt, | |||
1245 | * sctp_assoc_t *asoc); | |||
1246 | * | |||
1247 | * If sd is an IPv4 socket, the addresses passed must be IPv4 addresses. | |||
1248 | * If the sd is an IPv6 socket, the addresses passed can either be IPv4 | |||
1249 | * or IPv6 addresses. | |||
1250 | * | |||
1251 | * A single address may be specified as INADDR_ANY or IN6ADDR_ANY, see | |||
1252 | * Section 3.1.2 for this usage. | |||
1253 | * | |||
1254 | * addrs is a pointer to an array of one or more socket addresses. Each | |||
1255 | * address is contained in its appropriate structure (i.e. struct | |||
1256 | * sockaddr_in or struct sockaddr_in6) the family of the address type | |||
1257 | * must be used to distengish the address length (note that this | |||
1258 | * representation is termed a "packed array" of addresses). The caller | |||
1259 | * specifies the number of addresses in the array with addrcnt. | |||
1260 | * | |||
1261 | * On success, sctp_connectx() returns 0. It also sets the assoc_id to | |||
1262 | * the association id of the new association. On failure, sctp_connectx() | |||
1263 | * returns -1, and sets errno to the appropriate error code. The assoc_id | |||
1264 | * is not touched by the kernel. | |||
1265 | * | |||
1266 | * For SCTP, the port given in each socket address must be the same, or | |||
1267 | * sctp_connectx() will fail, setting errno to EINVAL. | |||
1268 | * | |||
1269 | * An application can use sctp_connectx to initiate an association with | |||
1270 | * an endpoint that is multi-homed. Much like sctp_bindx() this call | |||
1271 | * allows a caller to specify multiple addresses at which a peer can be | |||
1272 | * reached. The way the SCTP stack uses the list of addresses to set up | |||
1273 | * the association is implementation dependent. This function only | |||
1274 | * specifies that the stack will try to make use of all the addresses in | |||
1275 | * the list when needed. | |||
1276 | * | |||
1277 | * Note that the list of addresses passed in is only used for setting up | |||
1278 | * the association. It does not necessarily equal the set of addresses | |||
1279 | * the peer uses for the resulting association. If the caller wants to | |||
1280 | * find out the set of peer addresses, it must use sctp_getpaddrs() to | |||
1281 | * retrieve them after the association has been set up. | |||
1282 | * | |||
1283 | * Basically do nothing but copying the addresses from user to kernel | |||
1284 | * land and invoking either sctp_connectx(). This is used for tunneling | |||
1285 | * the sctp_connectx() request through sctp_setsockopt() from userspace. | |||
1286 | * | |||
1287 | * We don't use copy_from_user() for optimization: we first do the | |||
1288 | * sanity checks (buffer size -fast- and access check-healthy | |||
1289 | * pointer); if all of those succeed, then we can alloc the memory | |||
1290 | * (expensive operation) needed to copy the data to kernel. Then we do | |||
1291 | * the copying without checking the user space area | |||
1292 | * (__copy_from_user()). | |||
1293 | * | |||
1294 | * On exit there is no need to do sockfd_put(), sys_setsockopt() does | |||
1295 | * it. | |||
1296 | * | |||
1297 | * sk The sk of the socket | |||
1298 | * addrs The pointer to the addresses in user land | |||
1299 | * addrssize Size of the addrs buffer | |||
1300 | * | |||
1301 | * Returns >=0 if ok, <0 errno code on error. | |||
1302 | */ | |||
1303 | static int __sctp_setsockopt_connectx(struct sock *sk, | |||
1304 | struct sockaddr __user *addrs, | |||
1305 | int addrs_size, | |||
1306 | sctp_assoc_t *assoc_id) | |||
1307 | { | |||
1308 | struct sockaddr *kaddrs; | |||
1309 | gfp_t gfp = GFP_KERNEL((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u)); | |||
1310 | int err = 0; | |||
1311 | ||||
1312 | pr_debug("%s: sk:%p addrs:%p addrs_size:%d\n",do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p addrs:%p addrs_size:%d\n" ), .lineno = 1313, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p addrs:%p addrs_size:%d\n", __func__, sk, addrs, addrs_size ); } while (0) | |||
1313 | __func__, sk, addrs, addrs_size)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p addrs:%p addrs_size:%d\n" ), .lineno = 1313, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p addrs:%p addrs_size:%d\n", __func__, sk, addrs, addrs_size ); } while (0); | |||
1314 | ||||
1315 | if (unlikely(addrs_size <= 0)(addrs_size <= 0)) | |||
1316 | return -EINVAL22; | |||
1317 | ||||
1318 | /* Check the user passed a healthy pointer. */ | |||
1319 | if (unlikely(!access_ok(VERIFY_READ, addrs, addrs_size))(!(!({ (void)0; __chk_range_not_ok((unsigned long )(addrs), addrs_size , (get_current()->thread.addr_limit.seg)); })))) | |||
1320 | return -EFAULT14; | |||
1321 | ||||
1322 | /* Alloc space for the address array in kernel memory. */ | |||
1323 | if (sk->sk_socket->file) | |||
1324 | gfp = GFP_USER((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u) | (( gfp_t)0x20000u)) | __GFP_NOWARN(( gfp_t)0x200u); | |||
1325 | kaddrs = kmalloc(addrs_size, gfp); | |||
1326 | if (unlikely(!kaddrs)(!kaddrs)) | |||
1327 | return -ENOMEM12; | |||
1328 | ||||
1329 | if (__copy_from_user(kaddrs, addrs, addrs_size)) { | |||
1330 | err = -EFAULT14; | |||
1331 | } else { | |||
1332 | err = __sctp_connect(sk, kaddrs, addrs_size, assoc_id); | |||
1333 | } | |||
1334 | ||||
1335 | kfree(kaddrs); | |||
1336 | ||||
1337 | return err; | |||
1338 | } | |||
1339 | ||||
1340 | /* | |||
1341 | * This is an older interface. It's kept for backward compatibility | |||
1342 | * to the option that doesn't provide association id. | |||
1343 | */ | |||
1344 | static int sctp_setsockopt_connectx_old(struct sock *sk, | |||
1345 | struct sockaddr __user *addrs, | |||
1346 | int addrs_size) | |||
1347 | { | |||
1348 | return __sctp_setsockopt_connectx(sk, addrs, addrs_size, NULL((void *)0)); | |||
1349 | } | |||
1350 | ||||
1351 | /* | |||
1352 | * New interface for the API. The since the API is done with a socket | |||
1353 | * option, to make it simple we feed back the association id is as a return | |||
1354 | * indication to the call. Error is always negative and association id is | |||
1355 | * always positive. | |||
1356 | */ | |||
1357 | static int sctp_setsockopt_connectx(struct sock *sk, | |||
1358 | struct sockaddr __user *addrs, | |||
1359 | int addrs_size) | |||
1360 | { | |||
1361 | sctp_assoc_t assoc_id = 0; | |||
1362 | int err = 0; | |||
1363 | ||||
1364 | err = __sctp_setsockopt_connectx(sk, addrs, addrs_size, &assoc_id); | |||
1365 | ||||
1366 | if (err) | |||
1367 | return err; | |||
1368 | else | |||
1369 | return assoc_id; | |||
1370 | } | |||
1371 | ||||
1372 | /* | |||
1373 | * New (hopefully final) interface for the API. | |||
1374 | * We use the sctp_getaddrs_old structure so that use-space library | |||
1375 | * can avoid any unnecessary allocations. The only different part | |||
1376 | * is that we store the actual length of the address buffer into the | |||
1377 | * addrs_num structure member. That way we can re-use the existing | |||
1378 | * code. | |||
1379 | */ | |||
1380 | #ifdef CONFIG_COMPAT1 | |||
1381 | struct compat_sctp_getaddrs_old { | |||
1382 | sctp_assoc_t assoc_id; | |||
1383 | s32 addr_num; | |||
1384 | compat_uptr_t addrs; /* struct sockaddr * */ | |||
1385 | }; | |||
1386 | #endif | |||
1387 | ||||
1388 | static int sctp_getsockopt_connectx3(struct sock *sk, int len, | |||
1389 | char __user *optval, | |||
1390 | int __user *optlen) | |||
1391 | { | |||
1392 | struct sctp_getaddrs_old param; | |||
1393 | sctp_assoc_t assoc_id = 0; | |||
1394 | int err = 0; | |||
1395 | ||||
1396 | #ifdef CONFIG_COMPAT1 | |||
1397 | if (in_compat_syscallin_compat_syscall()) { | |||
1398 | struct compat_sctp_getaddrs_old param32; | |||
1399 | ||||
1400 | if (len < sizeof(param32)) | |||
1401 | return -EINVAL22; | |||
1402 | if (copy_from_user(¶m32, optval, sizeof(param32))) | |||
1403 | return -EFAULT14; | |||
1404 | ||||
1405 | param.assoc_id = param32.assoc_id; | |||
1406 | param.addr_num = param32.addr_num; | |||
1407 | param.addrs = compat_ptr(param32.addrs); | |||
1408 | } else | |||
1409 | #endif | |||
1410 | { | |||
1411 | if (len < sizeof(param)) | |||
1412 | return -EINVAL22; | |||
1413 | if (copy_from_user(¶m, optval, sizeof(param))) | |||
1414 | return -EFAULT14; | |||
1415 | } | |||
1416 | ||||
1417 | err = __sctp_setsockopt_connectx(sk, (struct sockaddr __user *) | |||
1418 | param.addrs, param.addr_num, | |||
1419 | &assoc_id); | |||
1420 | if (err == 0 || err == -EINPROGRESS115) { | |||
1421 | if (copy_to_user(optval, &assoc_id, sizeof(assoc_id))) | |||
1422 | return -EFAULT14; | |||
1423 | if (put_user(sizeof(assoc_id), optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 1423); __pu_val = sizeof(assoc_id); switch (sizeof(*(optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
1424 | return -EFAULT14; | |||
1425 | } | |||
1426 | ||||
1427 | return err; | |||
1428 | } | |||
1429 | ||||
1430 | /* API 3.1.4 close() - UDP Style Syntax | |||
1431 | * Applications use close() to perform graceful shutdown (as described in | |||
1432 | * Section 10.1 of [SCTP]) on ALL the associations currently represented | |||
1433 | * by a UDP-style socket. | |||
1434 | * | |||
1435 | * The syntax is | |||
1436 | * | |||
1437 | * ret = close(int sd); | |||
1438 | * | |||
1439 | * sd - the socket descriptor of the associations to be closed. | |||
1440 | * | |||
1441 | * To gracefully shutdown a specific association represented by the | |||
1442 | * UDP-style socket, an application should use the sendmsg() call, | |||
1443 | * passing no user data, but including the appropriate flag in the | |||
1444 | * ancillary data (see Section xxxx). | |||
1445 | * | |||
1446 | * If sd in the close() call is a branched-off socket representing only | |||
1447 | * one association, the shutdown is performed on that association only. | |||
1448 | * | |||
1449 | * 4.1.6 close() - TCP Style Syntax | |||
1450 | * | |||
1451 | * Applications use close() to gracefully close down an association. | |||
1452 | * | |||
1453 | * The syntax is: | |||
1454 | * | |||
1455 | * int close(int sd); | |||
1456 | * | |||
1457 | * sd - the socket descriptor of the association to be closed. | |||
1458 | * | |||
1459 | * After an application calls close() on a socket descriptor, no further | |||
1460 | * socket operations will succeed on that descriptor. | |||
1461 | * | |||
1462 | * API 7.1.4 SO_LINGER | |||
1463 | * | |||
1464 | * An application using the TCP-style socket can use this option to | |||
1465 | * perform the SCTP ABORT primitive. The linger option structure is: | |||
1466 | * | |||
1467 | * struct linger { | |||
1468 | * int l_onoff; // option on/off | |||
1469 | * int l_linger; // linger time | |||
1470 | * }; | |||
1471 | * | |||
1472 | * To enable the option, set l_onoff to 1. If the l_linger value is set | |||
1473 | * to 0, calling close() is the same as the ABORT primitive. If the | |||
1474 | * value is set to a negative value, the setsockopt() call will return | |||
1475 | * an error. If the value is set to a positive value linger_time, the | |||
1476 | * close() can be blocked for at most linger_time ms. If the graceful | |||
1477 | * shutdown phase does not finish during this period, close() will | |||
1478 | * return but the graceful shutdown phase continues in the system. | |||
1479 | */ | |||
1480 | static void sctp_close(struct sock *sk, long timeout) | |||
1481 | { | |||
1482 | struct net *net = sock_net(sk); | |||
1483 | struct sctp_endpoint *ep; | |||
1484 | struct sctp_association *asoc; | |||
1485 | struct list_head *pos, *temp; | |||
1486 | unsigned int data_was_unread; | |||
1487 | ||||
1488 | pr_debug("%s: sk:%p, timeout:%ld\n", __func__, sk, timeout)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, timeout:%ld\n" ), .lineno = 1488, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, timeout:%ld\n", __func__, sk, timeout); } while ( 0); | |||
1489 | ||||
1490 | lock_sock(sk); | |||
1491 | sk->sk_shutdown = SHUTDOWN_MASK3; | |||
1492 | sk->sk_state__sk_common.skc_state = SCTP_SS_CLOSING; | |||
1493 | ||||
1494 | ep = sctp_sk(sk)->ep; | |||
1495 | ||||
1496 | /* Clean up any skbs sitting on the receive queue. */ | |||
1497 | data_was_unread = sctp_queue_purge_ulpevents(&sk->sk_receive_queue); | |||
1498 | data_was_unread += sctp_queue_purge_ulpevents(&sctp_sk(sk)->pd_lobby); | |||
1499 | ||||
1500 | /* Walk all associations on an endpoint. */ | |||
1501 | list_for_each_safe(pos, temp, &ep->asocs)for (pos = (&ep->asocs)->next, temp = pos->next; pos != (&ep->asocs); pos = temp, temp = pos->next) { | |||
1502 | asoc = list_entry(pos, struct sctp_association, asocs)({ const typeof( ((struct sctp_association *)0)->asocs ) * __mptr = (pos); (struct sctp_association *)( (char *)__mptr - __builtin_offsetof(struct sctp_association, asocs) );}); | |||
1503 | ||||
1504 | if (sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP))) { | |||
1505 | /* A closed association can still be in the list if | |||
1506 | * it belongs to a TCP-style listening socket that is | |||
1507 | * not yet accepted. If so, free it. If not, send an | |||
1508 | * ABORT or SHUTDOWN based on the linger options. | |||
1509 | */ | |||
1510 | if (sctp_state(asoc, CLOSED)__sctp_state((asoc), (SCTP_STATE_CLOSED))) { | |||
1511 | sctp_association_free(asoc); | |||
1512 | continue; | |||
1513 | } | |||
1514 | } | |||
1515 | ||||
1516 | if (data_was_unread || !skb_queue_empty(&asoc->ulpq.lobby) || | |||
1517 | !skb_queue_empty(&asoc->ulpq.reasm) || | |||
1518 | (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime)) { | |||
1519 | struct sctp_chunk *chunk; | |||
1520 | ||||
1521 | chunk = sctp_make_abort_user(asoc, NULL((void *)0), 0); | |||
1522 | sctp_primitive_ABORT(net, asoc, chunk); | |||
1523 | } else | |||
1524 | sctp_primitive_SHUTDOWN(net, asoc, NULL((void *)0)); | |||
1525 | } | |||
1526 | ||||
1527 | /* On a TCP-style socket, block for at most linger_time if set. */ | |||
1528 | if (sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP)) && timeout) | |||
1529 | sctp_wait_for_close(sk, timeout); | |||
1530 | ||||
1531 | /* This will run the backlog queue. */ | |||
1532 | release_sock(sk); | |||
1533 | ||||
1534 | /* Supposedly, no process has access to the socket, but | |||
1535 | * the net layers still may. | |||
1536 | * Also, sctp_destroy_sock() needs to be called with addr_wq_lock | |||
1537 | * held and that should be grabbed before socket lock. | |||
1538 | */ | |||
1539 | spin_lock_bh(&net->sctp.addr_wq_lock); | |||
1540 | bh_lock_sock(sk)spin_lock(&((sk)->sk_lock.slock)); | |||
1541 | ||||
1542 | /* Hold the sock, since sk_common_release() will put sock_put() | |||
1543 | * and we have just a little more cleanup. | |||
1544 | */ | |||
1545 | sock_hold(sk); | |||
1546 | sk_common_release(sk); | |||
1547 | ||||
1548 | bh_unlock_sock(sk)spin_unlock(&((sk)->sk_lock.slock)); | |||
1549 | spin_unlock_bh(&net->sctp.addr_wq_lock); | |||
1550 | ||||
1551 | sock_put(sk); | |||
1552 | ||||
1553 | SCTP_DBG_OBJCNT_DEC(sock)atomic_dec(&sctp_dbg_objcnt_sock); | |||
1554 | } | |||
1555 | ||||
1556 | /* Handle EPIPE error. */ | |||
1557 | static int sctp_error(struct sock *sk, int flags, int err) | |||
1558 | { | |||
1559 | if (err == -EPIPE32) | |||
1560 | err = sock_error(sk) ? : -EPIPE32; | |||
1561 | if (err == -EPIPE32 && !(flags & MSG_NOSIGNAL0x4000)) | |||
1562 | send_sig(SIGPIPE13, currentget_current(), 0); | |||
1563 | return err; | |||
1564 | } | |||
1565 | ||||
1566 | /* API 3.1.3 sendmsg() - UDP Style Syntax | |||
1567 | * | |||
1568 | * An application uses sendmsg() and recvmsg() calls to transmit data to | |||
1569 | * and receive data from its peer. | |||
1570 | * | |||
1571 | * ssize_t sendmsg(int socket, const struct msghdr *message, | |||
1572 | * int flags); | |||
1573 | * | |||
1574 | * socket - the socket descriptor of the endpoint. | |||
1575 | * message - pointer to the msghdr structure which contains a single | |||
1576 | * user message and possibly some ancillary data. | |||
1577 | * | |||
1578 | * See Section 5 for complete description of the data | |||
1579 | * structures. | |||
1580 | * | |||
1581 | * flags - flags sent or received with the user message, see Section | |||
1582 | * 5 for complete description of the flags. | |||
1583 | * | |||
1584 | * Note: This function could use a rewrite especially when explicit | |||
1585 | * connect support comes in. | |||
1586 | */ | |||
1587 | /* BUG: We do not implement the equivalent of sk_stream_wait_memory(). */ | |||
1588 | ||||
1589 | static int sctp_msghdr_parse(const struct msghdr *, sctp_cmsgs_t *); | |||
1590 | ||||
1591 | static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) | |||
1592 | { | |||
1593 | struct net *net = sock_net(sk); | |||
1594 | struct sctp_sock *sp; | |||
1595 | struct sctp_endpoint *ep; | |||
1596 | struct sctp_association *new_asoc = NULL((void *)0), *asoc = NULL((void *)0); | |||
1597 | struct sctp_transport *transport, *chunk_tp; | |||
1598 | struct sctp_chunk *chunk; | |||
1599 | union sctp_addr to; | |||
1600 | struct sockaddr *msg_name = NULL((void *)0); | |||
1601 | struct sctp_sndrcvinfo default_sinfo; | |||
1602 | struct sctp_sndrcvinfo *sinfo; | |||
1603 | struct sctp_initmsg *sinit; | |||
1604 | sctp_assoc_t associd = 0; | |||
1605 | sctp_cmsgs_t cmsgs = { NULL((void *)0) }; | |||
1606 | sctp_scope_t scope; | |||
1607 | bool fill_sinfo_ttl = false, wait_connect = false; | |||
1608 | struct sctp_datamsg *datamsg; | |||
1609 | int msg_flags = msg->msg_flags; | |||
1610 | __u16 sinfo_flags = 0; | |||
1611 | long timeo; | |||
1612 | int err; | |||
1613 | ||||
1614 | err = 0; | |||
1615 | sp = sctp_sk(sk); | |||
1616 | ep = sp->ep; | |||
1617 | ||||
1618 | pr_debug("%s: sk:%p, msg:%p, msg_len:%zu ep:%p\n", __func__, sk,do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, msg:%p, msg_len:%zu ep:%p\n" ), .lineno = 1619, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, msg:%p, msg_len:%zu ep:%p\n", __func__, sk, msg, msg_len, ep); } while (0) | |||
1619 | msg, msg_len, ep)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, msg:%p, msg_len:%zu ep:%p\n" ), .lineno = 1619, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, msg:%p, msg_len:%zu ep:%p\n", __func__, sk, msg, msg_len, ep); } while (0); | |||
1620 | ||||
1621 | /* We cannot send a message over a TCP-style listening socket. */ | |||
1622 | if (sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP)) && sctp_sstate(sk, LISTENING)__sctp_sstate((sk), (SCTP_SS_LISTENING))) { | |||
1623 | err = -EPIPE32; | |||
1624 | goto out_nounlock; | |||
1625 | } | |||
1626 | ||||
1627 | /* Parse out the SCTP CMSGs. */ | |||
1628 | err = sctp_msghdr_parse(msg, &cmsgs); | |||
1629 | if (err) { | |||
1630 | pr_debug("%s: msghdr parse err:%x\n", __func__, err)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: msghdr parse err:%x\n" ), .lineno = 1630, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: msghdr parse err:%x\n", __func__, err); } while (0); | |||
1631 | goto out_nounlock; | |||
1632 | } | |||
1633 | ||||
1634 | /* Fetch the destination address for this packet. This | |||
1635 | * address only selects the association--it is not necessarily | |||
1636 | * the address we will send to. | |||
1637 | * For a peeled-off socket, msg_name is ignored. | |||
1638 | */ | |||
1639 | if (!sctp_style(sk, UDP_HIGH_BANDWIDTH)__sctp_style((sk), (SCTP_SOCKET_UDP_HIGH_BANDWIDTH)) && msg->msg_name) { | |||
1640 | int msg_namelen = msg->msg_namelen; | |||
1641 | ||||
1642 | err = sctp_verify_addr(sk, (union sctp_addr *)msg->msg_name, | |||
1643 | msg_namelen); | |||
1644 | if (err) | |||
1645 | return err; | |||
1646 | ||||
1647 | if (msg_namelen > sizeof(to)) | |||
1648 | msg_namelen = sizeof(to); | |||
1649 | memcpy(&to, msg->msg_name, msg_namelen)({ size_t __len = (msg_namelen); void *__ret; if (__builtin_constant_p (msg_namelen) && __len >= 64) __ret = __memcpy((& to), (msg->msg_name), __len); else __ret = __builtin_memcpy ((&to), (msg->msg_name), __len); __ret; }); | |||
1650 | msg_name = msg->msg_name; | |||
1651 | } | |||
1652 | ||||
1653 | sinit = cmsgs.init; | |||
1654 | if (cmsgs.sinfo != NULL((void *)0)) { | |||
1655 | memset(&default_sinfo, 0, sizeof(default_sinfo)); | |||
1656 | default_sinfo.sinfo_stream = cmsgs.sinfo->snd_sid; | |||
1657 | default_sinfo.sinfo_flags = cmsgs.sinfo->snd_flags; | |||
1658 | default_sinfo.sinfo_ppid = cmsgs.sinfo->snd_ppid; | |||
1659 | default_sinfo.sinfo_context = cmsgs.sinfo->snd_context; | |||
1660 | default_sinfo.sinfo_assoc_id = cmsgs.sinfo->snd_assoc_id; | |||
1661 | ||||
1662 | sinfo = &default_sinfo; | |||
1663 | fill_sinfo_ttl = true; | |||
1664 | } else { | |||
1665 | sinfo = cmsgs.srinfo; | |||
1666 | } | |||
1667 | /* Did the user specify SNDINFO/SNDRCVINFO? */ | |||
1668 | if (sinfo) { | |||
1669 | sinfo_flags = sinfo->sinfo_flags; | |||
1670 | associd = sinfo->sinfo_assoc_id; | |||
1671 | } | |||
1672 | ||||
1673 | pr_debug("%s: msg_len:%zu, sinfo_flags:0x%x\n", __func__,do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: msg_len:%zu, sinfo_flags:0x%x\n" ), .lineno = 1674, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: msg_len:%zu, sinfo_flags:0x%x\n", __func__, msg_len, sinfo_flags ); } while (0) | |||
1674 | msg_len, sinfo_flags)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: msg_len:%zu, sinfo_flags:0x%x\n" ), .lineno = 1674, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: msg_len:%zu, sinfo_flags:0x%x\n", __func__, msg_len, sinfo_flags ); } while (0); | |||
1675 | ||||
1676 | /* SCTP_EOF or SCTP_ABORT cannot be set on a TCP-style socket. */ | |||
1677 | if (sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP)) && (sinfo_flags & (SCTP_EOF | SCTP_ABORT))) { | |||
1678 | err = -EINVAL22; | |||
1679 | goto out_nounlock; | |||
1680 | } | |||
1681 | ||||
1682 | /* If SCTP_EOF is set, no data can be sent. Disallow sending zero | |||
1683 | * length messages when SCTP_EOF|SCTP_ABORT is not set. | |||
1684 | * If SCTP_ABORT is set, the message length could be non zero with | |||
1685 | * the msg_iov set to the user abort reason. | |||
1686 | */ | |||
1687 | if (((sinfo_flags & SCTP_EOF) && (msg_len > 0)) || | |||
1688 | (!(sinfo_flags & (SCTP_EOF|SCTP_ABORT)) && (msg_len == 0))) { | |||
1689 | err = -EINVAL22; | |||
1690 | goto out_nounlock; | |||
1691 | } | |||
1692 | ||||
1693 | /* If SCTP_ADDR_OVER is set, there must be an address | |||
1694 | * specified in msg_name. | |||
1695 | */ | |||
1696 | if ((sinfo_flags & SCTP_ADDR_OVER) && (!msg->msg_name)) { | |||
1697 | err = -EINVAL22; | |||
1698 | goto out_nounlock; | |||
1699 | } | |||
1700 | ||||
1701 | transport = NULL((void *)0); | |||
1702 | ||||
1703 | pr_debug("%s: about to look up association\n", __func__)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: about to look up association\n" ), .lineno = 1703, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: about to look up association\n", __func__); } while (0); | |||
1704 | ||||
1705 | lock_sock(sk); | |||
1706 | ||||
1707 | /* If a msg_name has been specified, assume this is to be used. */ | |||
1708 | if (msg_name) { | |||
1709 | /* Look for a matching association on the endpoint. */ | |||
1710 | asoc = sctp_endpoint_lookup_assoc(ep, &to, &transport); | |||
1711 | ||||
1712 | /* If we could not find a matching association on the | |||
1713 | * endpoint, make sure that it is not a TCP-style | |||
1714 | * socket that already has an association or there is | |||
1715 | * no peeled-off association on another socket. | |||
1716 | */ | |||
1717 | if (!asoc && | |||
1718 | ((sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP)) && | |||
1719 | (sctp_sstate(sk, ESTABLISHED)__sctp_sstate((sk), (SCTP_SS_ESTABLISHED)) || | |||
1720 | sctp_sstate(sk, CLOSING)__sctp_sstate((sk), (SCTP_SS_CLOSING)))) || | |||
1721 | sctp_endpoint_is_peeled_off(ep, &to))) { | |||
1722 | err = -EADDRNOTAVAIL99; | |||
1723 | goto out_unlock; | |||
1724 | } | |||
1725 | } else { | |||
1726 | asoc = sctp_id2assoc(sk, associd); | |||
1727 | if (!asoc) { | |||
1728 | err = -EPIPE32; | |||
1729 | goto out_unlock; | |||
1730 | } | |||
1731 | } | |||
1732 | ||||
1733 | if (asoc) { | |||
1734 | pr_debug("%s: just looked up association:%p\n", __func__, asoc)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: just looked up association:%p\n" ), .lineno = 1734, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: just looked up association:%p\n", __func__, asoc); } while (0); | |||
1735 | ||||
1736 | /* We cannot send a message on a TCP-style SCTP_SS_ESTABLISHED | |||
1737 | * socket that has an association in CLOSED state. This can | |||
1738 | * happen when an accepted socket has an association that is | |||
1739 | * already CLOSED. | |||
1740 | */ | |||
1741 | if (sctp_state(asoc, CLOSED)__sctp_state((asoc), (SCTP_STATE_CLOSED)) && sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP))) { | |||
1742 | err = -EPIPE32; | |||
1743 | goto out_unlock; | |||
1744 | } | |||
1745 | ||||
1746 | if (sinfo_flags & SCTP_EOF) { | |||
1747 | pr_debug("%s: shutting down association:%p\n",do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: shutting down association:%p\n" ), .lineno = 1748, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: shutting down association:%p\n", __func__, asoc); } while (0) | |||
1748 | __func__, asoc)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: shutting down association:%p\n" ), .lineno = 1748, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: shutting down association:%p\n", __func__, asoc); } while (0); | |||
1749 | ||||
1750 | sctp_primitive_SHUTDOWN(net, asoc, NULL((void *)0)); | |||
1751 | err = 0; | |||
1752 | goto out_unlock; | |||
1753 | } | |||
1754 | if (sinfo_flags & SCTP_ABORT) { | |||
1755 | ||||
1756 | chunk = sctp_make_abort_user(asoc, msg, msg_len); | |||
1757 | if (!chunk) { | |||
1758 | err = -ENOMEM12; | |||
1759 | goto out_unlock; | |||
1760 | } | |||
1761 | ||||
1762 | pr_debug("%s: aborting association:%p\n",do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: aborting association:%p\n" ), .lineno = 1763, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: aborting association:%p\n", __func__, asoc); } while (0 ) | |||
1763 | __func__, asoc)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: aborting association:%p\n" ), .lineno = 1763, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: aborting association:%p\n", __func__, asoc); } while (0 ); | |||
1764 | ||||
1765 | sctp_primitive_ABORT(net, asoc, chunk); | |||
1766 | err = 0; | |||
1767 | goto out_unlock; | |||
1768 | } | |||
1769 | } | |||
1770 | ||||
1771 | /* Do we need to create the association? */ | |||
1772 | if (!asoc) { | |||
1773 | pr_debug("%s: there is no association yet\n", __func__)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: there is no association yet\n" ), .lineno = 1773, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: there is no association yet\n", __func__); } while (0); | |||
1774 | ||||
1775 | if (sinfo_flags & (SCTP_EOF | SCTP_ABORT)) { | |||
1776 | err = -EINVAL22; | |||
1777 | goto out_unlock; | |||
1778 | } | |||
1779 | ||||
1780 | /* Check for invalid stream against the stream counts, | |||
1781 | * either the default or the user specified stream counts. | |||
1782 | */ | |||
1783 | if (sinfo) { | |||
1784 | if (!sinit || !sinit->sinit_num_ostreams) { | |||
1785 | /* Check against the defaults. */ | |||
1786 | if (sinfo->sinfo_stream >= | |||
1787 | sp->initmsg.sinit_num_ostreams) { | |||
1788 | err = -EINVAL22; | |||
1789 | goto out_unlock; | |||
1790 | } | |||
1791 | } else { | |||
1792 | /* Check against the requested. */ | |||
1793 | if (sinfo->sinfo_stream >= | |||
1794 | sinit->sinit_num_ostreams) { | |||
1795 | err = -EINVAL22; | |||
1796 | goto out_unlock; | |||
1797 | } | |||
1798 | } | |||
1799 | } | |||
1800 | ||||
1801 | /* | |||
1802 | * API 3.1.2 bind() - UDP Style Syntax | |||
1803 | * If a bind() or sctp_bindx() is not called prior to a | |||
1804 | * sendmsg() call that initiates a new association, the | |||
1805 | * system picks an ephemeral port and will choose an address | |||
1806 | * set equivalent to binding with a wildcard address. | |||
1807 | */ | |||
1808 | if (!ep->base.bind_addr.port) { | |||
1809 | if (sctp_autobind(sk)) { | |||
1810 | err = -EAGAIN11; | |||
1811 | goto out_unlock; | |||
1812 | } | |||
1813 | } else { | |||
1814 | /* | |||
1815 | * If an unprivileged user inherits a one-to-many | |||
1816 | * style socket with open associations on a privileged | |||
1817 | * port, it MAY be permitted to accept new associations, | |||
1818 | * but it SHOULD NOT be permitted to open new | |||
1819 | * associations. | |||
1820 | */ | |||
1821 | if (ep->base.bind_addr.port < PROT_SOCK1024 && | |||
1822 | !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE10)) { | |||
1823 | err = -EACCES13; | |||
1824 | goto out_unlock; | |||
1825 | } | |||
1826 | } | |||
1827 | ||||
1828 | scope = sctp_scope(&to); | |||
1829 | new_asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u))); | |||
1830 | if (!new_asoc) { | |||
1831 | err = -ENOMEM12; | |||
1832 | goto out_unlock; | |||
1833 | } | |||
1834 | asoc = new_asoc; | |||
1835 | err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, GFP_KERNEL((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u))); | |||
1836 | if (err < 0) { | |||
1837 | err = -ENOMEM12; | |||
1838 | goto out_free; | |||
1839 | } | |||
1840 | ||||
1841 | /* If the SCTP_INIT ancillary data is specified, set all | |||
1842 | * the association init values accordingly. | |||
1843 | */ | |||
1844 | if (sinit) { | |||
1845 | if (sinit->sinit_num_ostreams) { | |||
1846 | asoc->c.sinit_num_ostreams = | |||
1847 | sinit->sinit_num_ostreams; | |||
1848 | } | |||
1849 | if (sinit->sinit_max_instreams) { | |||
1850 | asoc->c.sinit_max_instreams = | |||
1851 | sinit->sinit_max_instreams; | |||
1852 | } | |||
1853 | if (sinit->sinit_max_attempts) { | |||
1854 | asoc->max_init_attempts | |||
1855 | = sinit->sinit_max_attempts; | |||
1856 | } | |||
1857 | if (sinit->sinit_max_init_timeo) { | |||
1858 | asoc->max_init_timeo = | |||
1859 | msecs_to_jiffies(sinit->sinit_max_init_timeo); | |||
1860 | } | |||
1861 | } | |||
1862 | ||||
1863 | /* Prime the peer's transport structures. */ | |||
1864 | transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u)), SCTP_UNKNOWN); | |||
1865 | if (!transport) { | |||
1866 | err = -ENOMEM12; | |||
1867 | goto out_free; | |||
1868 | } | |||
1869 | } | |||
1870 | ||||
1871 | /* ASSERT: we have a valid association at this point. */ | |||
1872 | pr_debug("%s: we have a valid association\n", __func__)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: we have a valid association\n" ), .lineno = 1872, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: we have a valid association\n", __func__); } while (0); | |||
1873 | ||||
1874 | if (!sinfo) { | |||
1875 | /* If the user didn't specify SNDINFO/SNDRCVINFO, make up | |||
1876 | * one with some defaults. | |||
1877 | */ | |||
1878 | memset(&default_sinfo, 0, sizeof(default_sinfo)); | |||
1879 | default_sinfo.sinfo_stream = asoc->default_stream; | |||
1880 | default_sinfo.sinfo_flags = asoc->default_flags; | |||
1881 | default_sinfo.sinfo_ppid = asoc->default_ppid; | |||
1882 | default_sinfo.sinfo_context = asoc->default_context; | |||
1883 | default_sinfo.sinfo_timetolive = asoc->default_timetolive; | |||
1884 | default_sinfo.sinfo_assoc_id = sctp_assoc2id(asoc); | |||
1885 | ||||
1886 | sinfo = &default_sinfo; | |||
1887 | } else if (fill_sinfo_ttl) { | |||
1888 | /* In case SNDINFO was specified, we still need to fill | |||
1889 | * it with a default ttl from the assoc here. | |||
1890 | */ | |||
1891 | sinfo->sinfo_timetolive = asoc->default_timetolive; | |||
1892 | } | |||
1893 | ||||
1894 | /* API 7.1.7, the sndbuf size per association bounds the | |||
1895 | * maximum size of data that can be sent in a single send call. | |||
1896 | */ | |||
1897 | if (msg_len > sk->sk_sndbuf) { | |||
1898 | err = -EMSGSIZE90; | |||
1899 | goto out_free; | |||
1900 | } | |||
1901 | ||||
1902 | if (asoc->pmtu_pending) | |||
1903 | sctp_assoc_pending_pmtu(sk, asoc); | |||
1904 | ||||
1905 | /* If fragmentation is disabled and the message length exceeds the | |||
1906 | * association fragmentation point, return EMSGSIZE. The I-D | |||
1907 | * does not specify what this error is, but this looks like | |||
1908 | * a great fit. | |||
1909 | */ | |||
1910 | if (sctp_sk(sk)->disable_fragments && (msg_len > asoc->frag_point)) { | |||
1911 | err = -EMSGSIZE90; | |||
1912 | goto out_free; | |||
1913 | } | |||
1914 | ||||
1915 | /* Check for invalid stream. */ | |||
1916 | if (sinfo->sinfo_stream >= asoc->c.sinit_num_ostreams) { | |||
1917 | err = -EINVAL22; | |||
1918 | goto out_free; | |||
1919 | } | |||
1920 | ||||
1921 | if (sctp_wspace(asoc) < msg_len) | |||
1922 | sctp_prsctp_prune(asoc, sinfo, msg_len - sctp_wspace(asoc)); | |||
1923 | ||||
1924 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT0x40); | |||
1925 | if (!sctp_wspace(asoc)) { | |||
1926 | err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len); | |||
1927 | if (err) | |||
1928 | goto out_free; | |||
1929 | } | |||
1930 | ||||
1931 | /* If an address is passed with the sendto/sendmsg call, it is used | |||
1932 | * to override the primary destination address in the TCP model, or | |||
1933 | * when SCTP_ADDR_OVER flag is set in the UDP model. | |||
1934 | */ | |||
1935 | if ((sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP)) && msg_name) || | |||
1936 | (sinfo_flags & SCTP_ADDR_OVER)) { | |||
1937 | chunk_tp = sctp_assoc_lookup_paddr(asoc, &to); | |||
1938 | if (!chunk_tp) { | |||
1939 | err = -EINVAL22; | |||
1940 | goto out_free; | |||
1941 | } | |||
1942 | } else | |||
1943 | chunk_tp = NULL((void *)0); | |||
1944 | ||||
1945 | /* Auto-connect, if we aren't connected already. */ | |||
1946 | if (sctp_state(asoc, CLOSED)__sctp_state((asoc), (SCTP_STATE_CLOSED))) { | |||
1947 | err = sctp_primitive_ASSOCIATE(net, asoc, NULL((void *)0)); | |||
1948 | if (err < 0) | |||
1949 | goto out_free; | |||
1950 | ||||
1951 | wait_connect = true; | |||
1952 | pr_debug("%s: we associated primitively\n", __func__)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: we associated primitively\n" ), .lineno = 1952, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: we associated primitively\n", __func__); } while (0); | |||
1953 | } | |||
1954 | ||||
1955 | /* Break the message into multiple chunks of maximum size. */ | |||
1956 | datamsg = sctp_datamsg_from_user(asoc, sinfo, &msg->msg_iter); | |||
1957 | if (IS_ERR(datamsg)) { | |||
1958 | err = PTR_ERR(datamsg); | |||
1959 | goto out_free; | |||
1960 | } | |||
1961 | ||||
1962 | /* Now send the (possibly) fragmented message. */ | |||
1963 | list_for_each_entry(chunk, &datamsg->chunks, frag_list)for (chunk = ({ const typeof( ((typeof(*chunk) *)0)->frag_list ) *__mptr = ((&datamsg->chunks)->next); (typeof(*chunk ) *)( (char *)__mptr - __builtin_offsetof(typeof(*chunk), frag_list ) );}); &chunk->frag_list != (&datamsg->chunks) ; chunk = ({ const typeof( ((typeof(*(chunk)) *)0)->frag_list ) *__mptr = ((chunk)->frag_list.next); (typeof(*(chunk)) * )( (char *)__mptr - __builtin_offsetof(typeof(*(chunk)), frag_list ) );})) { | |||
1964 | sctp_chunk_hold(chunk); | |||
1965 | ||||
1966 | /* Do accounting for the write space. */ | |||
1967 | sctp_set_owner_w(chunk); | |||
1968 | ||||
1969 | chunk->transport = chunk_tp; | |||
1970 | } | |||
1971 | ||||
1972 | /* Send it to the lower layers. Note: all chunks | |||
1973 | * must either fail or succeed. The lower layer | |||
1974 | * works that way today. Keep it that way or this | |||
1975 | * breaks. | |||
1976 | */ | |||
1977 | err = sctp_primitive_SEND(net, asoc, datamsg); | |||
1978 | /* Did the lower layer accept the chunk? */ | |||
1979 | if (err) { | |||
1980 | sctp_datamsg_free(datamsg); | |||
1981 | goto out_free; | |||
1982 | } | |||
1983 | ||||
1984 | pr_debug("%s: we sent primitively\n", __func__)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: we sent primitively\n" ), .lineno = 1984, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: we sent primitively\n", __func__); } while (0); | |||
1985 | ||||
1986 | sctp_datamsg_put(datamsg); | |||
1987 | err = msg_len; | |||
1988 | ||||
1989 | if (unlikely(wait_connect)(wait_connect)) { | |||
1990 | timeo = sock_sndtimeo(sk, msg_flags & MSG_DONTWAIT0x40); | |||
1991 | sctp_wait_for_connect(asoc, &timeo); | |||
1992 | } | |||
1993 | ||||
1994 | /* If we are already past ASSOCIATE, the lower | |||
1995 | * layers are responsible for association cleanup. | |||
1996 | */ | |||
1997 | goto out_unlock; | |||
1998 | ||||
1999 | out_free: | |||
2000 | if (new_asoc) | |||
2001 | sctp_association_free(asoc); | |||
2002 | out_unlock: | |||
2003 | release_sock(sk); | |||
2004 | ||||
2005 | out_nounlock: | |||
2006 | return sctp_error(sk, msg_flags, err); | |||
2007 | ||||
2008 | #if 0 | |||
2009 | do_sock_err: | |||
2010 | if (msg_len) | |||
2011 | err = msg_len; | |||
2012 | else | |||
2013 | err = sock_error(sk); | |||
2014 | goto out; | |||
2015 | ||||
2016 | do_interrupted: | |||
2017 | if (msg_len) | |||
2018 | err = msg_len; | |||
2019 | goto out; | |||
2020 | #endif /* 0 */ | |||
2021 | } | |||
2022 | ||||
2023 | /* This is an extended version of skb_pull() that removes the data from the | |||
2024 | * start of a skb even when data is spread across the list of skb's in the | |||
2025 | * frag_list. len specifies the total amount of data that needs to be removed. | |||
2026 | * when 'len' bytes could be removed from the skb, it returns 0. | |||
2027 | * If 'len' exceeds the total skb length, it returns the no. of bytes that | |||
2028 | * could not be removed. | |||
2029 | */ | |||
2030 | static int sctp_skb_pull(struct sk_buff *skb, int len) | |||
2031 | { | |||
2032 | struct sk_buff *list; | |||
2033 | int skb_len = skb_headlen(skb); | |||
2034 | int rlen; | |||
2035 | ||||
2036 | if (len <= skb_len) { | |||
2037 | __skb_pull(skb, len); | |||
2038 | return 0; | |||
2039 | } | |||
2040 | len -= skb_len; | |||
2041 | __skb_pull(skb, skb_len); | |||
2042 | ||||
2043 | skb_walk_frags(skb, list)for (list = ((struct skb_shared_info *)(skb_end_pointer(skb)) )->frag_list; list; list = list->next) { | |||
2044 | rlen = sctp_skb_pull(list, len); | |||
2045 | skb->len -= (len-rlen); | |||
2046 | skb->data_len -= (len-rlen); | |||
2047 | ||||
2048 | if (!rlen) | |||
2049 | return 0; | |||
2050 | ||||
2051 | len = rlen; | |||
2052 | } | |||
2053 | ||||
2054 | return len; | |||
2055 | } | |||
2056 | ||||
2057 | /* API 3.1.3 recvmsg() - UDP Style Syntax | |||
2058 | * | |||
2059 | * ssize_t recvmsg(int socket, struct msghdr *message, | |||
2060 | * int flags); | |||
2061 | * | |||
2062 | * socket - the socket descriptor of the endpoint. | |||
2063 | * message - pointer to the msghdr structure which contains a single | |||
2064 | * user message and possibly some ancillary data. | |||
2065 | * | |||
2066 | * See Section 5 for complete description of the data | |||
2067 | * structures. | |||
2068 | * | |||
2069 | * flags - flags sent or received with the user message, see Section | |||
2070 | * 5 for complete description of the flags. | |||
2071 | */ | |||
2072 | static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, | |||
2073 | int noblock, int flags, int *addr_len) | |||
2074 | { | |||
2075 | struct sctp_ulpevent *event = NULL((void *)0); | |||
2076 | struct sctp_sock *sp = sctp_sk(sk); | |||
2077 | struct sk_buff *skb, *head_skb; | |||
2078 | int copied; | |||
2079 | int err = 0; | |||
2080 | int skb_len; | |||
2081 | ||||
2082 | pr_debug("%s: sk:%p, msghdr:%p, len:%zd, noblock:%d, flags:0x%x, "do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, msghdr:%p, len:%zd, noblock:%d, flags:0x%x, " "addr_len:%p)\n"), .lineno = 2084, .flags = 0, }; if ((descriptor .flags & (1<<0))) __dynamic_pr_debug(&descriptor , "sctp" ": " "%s: sk:%p, msghdr:%p, len:%zd, noblock:%d, flags:0x%x, " "addr_len:%p)\n", __func__, sk, msg, len, noblock, flags, addr_len ); } while (0) | |||
2083 | "addr_len:%p)\n", __func__, sk, msg, len, noblock, flags,do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, msghdr:%p, len:%zd, noblock:%d, flags:0x%x, " "addr_len:%p)\n"), .lineno = 2084, .flags = 0, }; if ((descriptor .flags & (1<<0))) __dynamic_pr_debug(&descriptor , "sctp" ": " "%s: sk:%p, msghdr:%p, len:%zd, noblock:%d, flags:0x%x, " "addr_len:%p)\n", __func__, sk, msg, len, noblock, flags, addr_len ); } while (0) | |||
2084 | addr_len)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, msghdr:%p, len:%zd, noblock:%d, flags:0x%x, " "addr_len:%p)\n"), .lineno = 2084, .flags = 0, }; if ((descriptor .flags & (1<<0))) __dynamic_pr_debug(&descriptor , "sctp" ": " "%s: sk:%p, msghdr:%p, len:%zd, noblock:%d, flags:0x%x, " "addr_len:%p)\n", __func__, sk, msg, len, noblock, flags, addr_len ); } while (0); | |||
2085 | ||||
2086 | lock_sock(sk); | |||
2087 | ||||
2088 | if (sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP)) && !sctp_sstate(sk, ESTABLISHED)__sctp_sstate((sk), (SCTP_SS_ESTABLISHED)) && | |||
2089 | !sctp_sstate(sk, CLOSING)__sctp_sstate((sk), (SCTP_SS_CLOSING)) && !sctp_sstate(sk, CLOSED)__sctp_sstate((sk), (SCTP_SS_CLOSED))) { | |||
2090 | err = -ENOTCONN107; | |||
2091 | goto out; | |||
2092 | } | |||
2093 | ||||
2094 | skb = sctp_skb_recv_datagram(sk, flags, noblock, &err); | |||
2095 | if (!skb) | |||
2096 | goto out; | |||
2097 | ||||
2098 | /* Get the total length of the skb including any skb's in the | |||
2099 | * frag_list. | |||
2100 | */ | |||
2101 | skb_len = skb->len; | |||
2102 | ||||
2103 | copied = skb_len; | |||
2104 | if (copied > len) | |||
2105 | copied = len; | |||
2106 | ||||
2107 | err = skb_copy_datagram_msg(skb, 0, msg, copied); | |||
2108 | ||||
2109 | event = sctp_skb2event(skb); | |||
2110 | ||||
2111 | if (err) | |||
2112 | goto out_free; | |||
2113 | ||||
2114 | if (event->chunk && event->chunk->head_skb) | |||
2115 | head_skb = event->chunk->head_skb; | |||
2116 | else | |||
2117 | head_skb = skb; | |||
2118 | sock_recv_ts_and_drops(msg, sk, head_skb); | |||
2119 | if (sctp_ulpevent_is_notification(event)) { | |||
2120 | msg->msg_flags |= MSG_NOTIFICATIONMSG_NOTIFICATION; | |||
2121 | sp->pf->event_msgname(event, msg->msg_name, addr_len); | |||
2122 | } else { | |||
2123 | sp->pf->skb_msgname(head_skb, msg->msg_name, addr_len); | |||
2124 | } | |||
2125 | ||||
2126 | /* Check if we allow SCTP_NXTINFO. */ | |||
2127 | if (sp->recvnxtinfo) | |||
2128 | sctp_ulpevent_read_nxtinfo(event, msg, sk); | |||
2129 | /* Check if we allow SCTP_RCVINFO. */ | |||
2130 | if (sp->recvrcvinfo) | |||
2131 | sctp_ulpevent_read_rcvinfo(event, msg); | |||
2132 | /* Check if we allow SCTP_SNDRCVINFO. */ | |||
2133 | if (sp->subscribe.sctp_data_io_event) | |||
2134 | sctp_ulpevent_read_sndrcvinfo(event, msg); | |||
2135 | ||||
2136 | err = copied; | |||
2137 | ||||
2138 | /* If skb's length exceeds the user's buffer, update the skb and | |||
2139 | * push it back to the receive_queue so that the next call to | |||
2140 | * recvmsg() will return the remaining data. Don't set MSG_EOR. | |||
2141 | */ | |||
2142 | if (skb_len > copied) { | |||
2143 | msg->msg_flags &= ~MSG_EOR0x80; | |||
2144 | if (flags & MSG_PEEK2) | |||
2145 | goto out_free; | |||
2146 | sctp_skb_pull(skb, copied); | |||
2147 | skb_queue_head(&sk->sk_receive_queue, skb); | |||
2148 | ||||
2149 | /* When only partial message is copied to the user, increase | |||
2150 | * rwnd by that amount. If all the data in the skb is read, | |||
2151 | * rwnd is updated when the event is freed. | |||
2152 | */ | |||
2153 | if (!sctp_ulpevent_is_notification(event)) | |||
2154 | sctp_assoc_rwnd_increase(event->asoc, copied); | |||
2155 | goto out; | |||
2156 | } else if ((event->msg_flags & MSG_NOTIFICATIONMSG_NOTIFICATION) || | |||
2157 | (event->msg_flags & MSG_EOR0x80)) | |||
2158 | msg->msg_flags |= MSG_EOR0x80; | |||
2159 | else | |||
2160 | msg->msg_flags &= ~MSG_EOR0x80; | |||
2161 | ||||
2162 | out_free: | |||
2163 | if (flags & MSG_PEEK2) { | |||
2164 | /* Release the skb reference acquired after peeking the skb in | |||
2165 | * sctp_skb_recv_datagram(). | |||
2166 | */ | |||
2167 | kfree_skb(skb); | |||
2168 | } else { | |||
2169 | /* Free the event which includes releasing the reference to | |||
2170 | * the owner of the skb, freeing the skb and updating the | |||
2171 | * rwnd. | |||
2172 | */ | |||
2173 | sctp_ulpevent_free(event); | |||
2174 | } | |||
2175 | out: | |||
2176 | release_sock(sk); | |||
2177 | return err; | |||
2178 | } | |||
2179 | ||||
2180 | /* 7.1.12 Enable/Disable message fragmentation (SCTP_DISABLE_FRAGMENTS) | |||
2181 | * | |||
2182 | * This option is a on/off flag. If enabled no SCTP message | |||
2183 | * fragmentation will be performed. Instead if a message being sent | |||
2184 | * exceeds the current PMTU size, the message will NOT be sent and | |||
2185 | * instead a error will be indicated to the user. | |||
2186 | */ | |||
2187 | static int sctp_setsockopt_disable_fragments(struct sock *sk, | |||
2188 | char __user *optval, | |||
2189 | unsigned int optlen) | |||
2190 | { | |||
2191 | int val; | |||
2192 | ||||
2193 | if (optlen < sizeof(int)) | |||
2194 | return -EINVAL22; | |||
2195 | ||||
2196 | if (get_user(val, (int __user *)optval)({ int __ret_gu; register __typeof__(__builtin_choose_expr(sizeof (*((int *)optval)) > sizeof(0UL), 0ULL, 0UL)) __val_gu asm ("%""rdx"); register void *__sp asm("rsp"); (void)0; __might_fault ("net/sctp/socket.c", 2196); asm volatile("call __get_user_%P4" : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) : "0" ((int * )optval), "i" (sizeof(*((int *)optval)))); (val) = ( __typeof__ (*((int *)optval))) __val_gu; clang_analyzer_taint(&val); __builtin_expect(__ret_gu, 0); })) | |||
2197 | return -EFAULT14; | |||
2198 | ||||
2199 | sctp_sk(sk)->disable_fragments = (val == 0) ? 0 : 1; | |||
2200 | ||||
2201 | return 0; | |||
2202 | } | |||
2203 | ||||
2204 | static int sctp_setsockopt_events(struct sock *sk, char __user *optval, | |||
2205 | unsigned int optlen) | |||
2206 | { | |||
2207 | struct sctp_association *asoc; | |||
2208 | struct sctp_ulpevent *event; | |||
2209 | ||||
2210 | if (optlen > sizeof(struct sctp_event_subscribe)) | |||
2211 | return -EINVAL22; | |||
2212 | if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) | |||
2213 | return -EFAULT14; | |||
2214 | ||||
2215 | /* At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT, | |||
2216 | * if there is no data to be sent or retransmit, the stack will | |||
2217 | * immediately send up this notification. | |||
2218 | */ | |||
2219 | if (sctp_ulpevent_type_enabled(SCTP_SENDER_DRY_EVENTSCTP_SENDER_DRY_EVENT, | |||
2220 | &sctp_sk(sk)->subscribe)) { | |||
2221 | asoc = sctp_id2assoc(sk, 0); | |||
2222 | ||||
2223 | if (asoc && sctp_outq_is_empty(&asoc->outqueue)) { | |||
2224 | event = sctp_ulpevent_make_sender_dry_event(asoc, | |||
2225 | GFP_ATOMIC((( gfp_t)0x20u)|(( gfp_t)0x80000u)|(( gfp_t)0x2000000u))); | |||
2226 | if (!event) | |||
2227 | return -ENOMEM12; | |||
2228 | ||||
2229 | sctp_ulpq_tail_event(&asoc->ulpq, event); | |||
2230 | } | |||
2231 | } | |||
2232 | ||||
2233 | return 0; | |||
2234 | } | |||
2235 | ||||
2236 | /* 7.1.8 Automatic Close of associations (SCTP_AUTOCLOSE) | |||
2237 | * | |||
2238 | * This socket option is applicable to the UDP-style socket only. When | |||
2239 | * set it will cause associations that are idle for more than the | |||
2240 | * specified number of seconds to automatically close. An association | |||
2241 | * being idle is defined an association that has NOT sent or received | |||
2242 | * user data. The special value of '0' indicates that no automatic | |||
2243 | * close of any associations should be performed. The option expects an | |||
2244 | * integer defining the number of seconds of idle time before an | |||
2245 | * association is closed. | |||
2246 | */ | |||
2247 | static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
2248 | unsigned int optlen) | |||
2249 | { | |||
2250 | struct sctp_sock *sp = sctp_sk(sk); | |||
2251 | struct net *net = sock_net(sk); | |||
2252 | ||||
2253 | /* Applicable to UDP-style socket only */ | |||
2254 | if (sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP))) | |||
2255 | return -EOPNOTSUPP95; | |||
2256 | if (optlen != sizeof(int)) | |||
2257 | return -EINVAL22; | |||
2258 | if (copy_from_user(&sp->autoclose, optval, optlen)) | |||
2259 | return -EFAULT14; | |||
2260 | ||||
2261 | if (sp->autoclose > net->sctp.max_autoclose) | |||
2262 | sp->autoclose = net->sctp.max_autoclose; | |||
2263 | ||||
2264 | return 0; | |||
2265 | } | |||
2266 | ||||
2267 | /* 7.1.13 Peer Address Parameters (SCTP_PEER_ADDR_PARAMS) | |||
2268 | * | |||
2269 | * Applications can enable or disable heartbeats for any peer address of | |||
2270 | * an association, modify an address's heartbeat interval, force a | |||
2271 | * heartbeat to be sent immediately, and adjust the address's maximum | |||
2272 | * number of retransmissions sent before an address is considered | |||
2273 | * unreachable. The following structure is used to access and modify an | |||
2274 | * address's parameters: | |||
2275 | * | |||
2276 | * struct sctp_paddrparams { | |||
2277 | * sctp_assoc_t spp_assoc_id; | |||
2278 | * struct sockaddr_storage spp_address; | |||
2279 | * uint32_t spp_hbinterval; | |||
2280 | * uint16_t spp_pathmaxrxt; | |||
2281 | * uint32_t spp_pathmtu; | |||
2282 | * uint32_t spp_sackdelay; | |||
2283 | * uint32_t spp_flags; | |||
2284 | * }; | |||
2285 | * | |||
2286 | * spp_assoc_id - (one-to-many style socket) This is filled in the | |||
2287 | * application, and identifies the association for | |||
2288 | * this query. | |||
2289 | * spp_address - This specifies which address is of interest. | |||
2290 | * spp_hbinterval - This contains the value of the heartbeat interval, | |||
2291 | * in milliseconds. If a value of zero | |||
2292 | * is present in this field then no changes are to | |||
2293 | * be made to this parameter. | |||
2294 | * spp_pathmaxrxt - This contains the maximum number of | |||
2295 | * retransmissions before this address shall be | |||
2296 | * considered unreachable. If a value of zero | |||
2297 | * is present in this field then no changes are to | |||
2298 | * be made to this parameter. | |||
2299 | * spp_pathmtu - When Path MTU discovery is disabled the value | |||
2300 | * specified here will be the "fixed" path mtu. | |||
2301 | * Note that if the spp_address field is empty | |||
2302 | * then all associations on this address will | |||
2303 | * have this fixed path mtu set upon them. | |||
2304 | * | |||
2305 | * spp_sackdelay - When delayed sack is enabled, this value specifies | |||
2306 | * the number of milliseconds that sacks will be delayed | |||
2307 | * for. This value will apply to all addresses of an | |||
2308 | * association if the spp_address field is empty. Note | |||
2309 | * also, that if delayed sack is enabled and this | |||
2310 | * value is set to 0, no change is made to the last | |||
2311 | * recorded delayed sack timer value. | |||
2312 | * | |||
2313 | * spp_flags - These flags are used to control various features | |||
2314 | * on an association. The flag field may contain | |||
2315 | * zero or more of the following options. | |||
2316 | * | |||
2317 | * SPP_HB_ENABLE - Enable heartbeats on the | |||
2318 | * specified address. Note that if the address | |||
2319 | * field is empty all addresses for the association | |||
2320 | * have heartbeats enabled upon them. | |||
2321 | * | |||
2322 | * SPP_HB_DISABLE - Disable heartbeats on the | |||
2323 | * speicifed address. Note that if the address | |||
2324 | * field is empty all addresses for the association | |||
2325 | * will have their heartbeats disabled. Note also | |||
2326 | * that SPP_HB_ENABLE and SPP_HB_DISABLE are | |||
2327 | * mutually exclusive, only one of these two should | |||
2328 | * be specified. Enabling both fields will have | |||
2329 | * undetermined results. | |||
2330 | * | |||
2331 | * SPP_HB_DEMAND - Request a user initiated heartbeat | |||
2332 | * to be made immediately. | |||
2333 | * | |||
2334 | * SPP_HB_TIME_IS_ZERO - Specify's that the time for | |||
2335 | * heartbeat delayis to be set to the value of 0 | |||
2336 | * milliseconds. | |||
2337 | * | |||
2338 | * SPP_PMTUD_ENABLE - This field will enable PMTU | |||
2339 | * discovery upon the specified address. Note that | |||
2340 | * if the address feild is empty then all addresses | |||
2341 | * on the association are effected. | |||
2342 | * | |||
2343 | * SPP_PMTUD_DISABLE - This field will disable PMTU | |||
2344 | * discovery upon the specified address. Note that | |||
2345 | * if the address feild is empty then all addresses | |||
2346 | * on the association are effected. Not also that | |||
2347 | * SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually | |||
2348 | * exclusive. Enabling both will have undetermined | |||
2349 | * results. | |||
2350 | * | |||
2351 | * SPP_SACKDELAY_ENABLE - Setting this flag turns | |||
2352 | * on delayed sack. The time specified in spp_sackdelay | |||
2353 | * is used to specify the sack delay for this address. Note | |||
2354 | * that if spp_address is empty then all addresses will | |||
2355 | * enable delayed sack and take on the sack delay | |||
2356 | * value specified in spp_sackdelay. | |||
2357 | * SPP_SACKDELAY_DISABLE - Setting this flag turns | |||
2358 | * off delayed sack. If the spp_address field is blank then | |||
2359 | * delayed sack is disabled for the entire association. Note | |||
2360 | * also that this field is mutually exclusive to | |||
2361 | * SPP_SACKDELAY_ENABLE, setting both will have undefined | |||
2362 | * results. | |||
2363 | */ | |||
2364 | static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2365 | struct sctp_transport *trans, | |||
2366 | struct sctp_association *asoc, | |||
2367 | struct sctp_sock *sp, | |||
2368 | int hb_change, | |||
2369 | int pmtud_change, | |||
2370 | int sackdelay_change) | |||
2371 | { | |||
2372 | int error; | |||
2373 | ||||
2374 | if (params->spp_flags & SPP_HB_DEMAND && trans) { | |||
2375 | struct net *net = sock_net(trans->asoc->base.sk); | |||
2376 | ||||
2377 | error = sctp_primitive_REQUESTHEARTBEAT(net, trans->asoc, trans); | |||
2378 | if (error) | |||
2379 | return error; | |||
2380 | } | |||
2381 | ||||
2382 | /* Note that unless the spp_flag is set to SPP_HB_ENABLE the value of | |||
2383 | * this field is ignored. Note also that a value of zero indicates | |||
2384 | * the current setting should be left unchanged. | |||
2385 | */ | |||
2386 | if (params->spp_flags & SPP_HB_ENABLE) { | |||
2387 | ||||
2388 | /* Re-zero the interval if the SPP_HB_TIME_IS_ZERO is | |||
2389 | * set. This lets us use 0 value when this flag | |||
2390 | * is set. | |||
2391 | */ | |||
2392 | if (params->spp_flags & SPP_HB_TIME_IS_ZERO) | |||
2393 | params->spp_hbinterval = 0; | |||
2394 | ||||
2395 | if (params->spp_hbinterval || | |||
2396 | (params->spp_flags & SPP_HB_TIME_IS_ZERO)) { | |||
2397 | if (trans) { | |||
2398 | trans->hbinterval = | |||
2399 | msecs_to_jiffies(params->spp_hbinterval); | |||
2400 | } else if (asoc) { | |||
2401 | asoc->hbinterval = | |||
2402 | msecs_to_jiffies(params->spp_hbinterval); | |||
2403 | } else { | |||
2404 | sp->hbinterval = params->spp_hbinterval; | |||
2405 | } | |||
2406 | } | |||
2407 | } | |||
2408 | ||||
2409 | if (hb_change) { | |||
2410 | if (trans) { | |||
2411 | trans->param_flags = | |||
2412 | (trans->param_flags & ~SPP_HB) | hb_change; | |||
2413 | } else if (asoc) { | |||
2414 | asoc->param_flags = | |||
2415 | (asoc->param_flags & ~SPP_HB) | hb_change; | |||
2416 | } else { | |||
2417 | sp->param_flags = | |||
2418 | (sp->param_flags & ~SPP_HB) | hb_change; | |||
2419 | } | |||
2420 | } | |||
2421 | ||||
2422 | /* When Path MTU discovery is disabled the value specified here will | |||
2423 | * be the "fixed" path mtu (i.e. the value of the spp_flags field must | |||
2424 | * include the flag SPP_PMTUD_DISABLE for this field to have any | |||
2425 | * effect). | |||
2426 | */ | |||
2427 | if ((params->spp_flags & SPP_PMTUD_DISABLE) && params->spp_pathmtu) { | |||
2428 | if (trans) { | |||
2429 | trans->pathmtu = params->spp_pathmtu; | |||
2430 | sctp_assoc_sync_pmtu(sctp_opt2sk(sp), asoc); | |||
2431 | } else if (asoc) { | |||
2432 | asoc->pathmtu = params->spp_pathmtu; | |||
2433 | sctp_frag_point(asoc, params->spp_pathmtu); | |||
2434 | } else { | |||
2435 | sp->pathmtu = params->spp_pathmtu; | |||
2436 | } | |||
2437 | } | |||
2438 | ||||
2439 | if (pmtud_change) { | |||
2440 | if (trans) { | |||
2441 | int update = (trans->param_flags & SPP_PMTUD_DISABLE) && | |||
2442 | (params->spp_flags & SPP_PMTUD_ENABLE); | |||
2443 | trans->param_flags = | |||
2444 | (trans->param_flags & ~SPP_PMTUD) | pmtud_change; | |||
2445 | if (update) { | |||
2446 | sctp_transport_pmtu(trans, sctp_opt2sk(sp)); | |||
2447 | sctp_assoc_sync_pmtu(sctp_opt2sk(sp), asoc); | |||
2448 | } | |||
2449 | } else if (asoc) { | |||
2450 | asoc->param_flags = | |||
2451 | (asoc->param_flags & ~SPP_PMTUD) | pmtud_change; | |||
2452 | } else { | |||
2453 | sp->param_flags = | |||
2454 | (sp->param_flags & ~SPP_PMTUD) | pmtud_change; | |||
2455 | } | |||
2456 | } | |||
2457 | ||||
2458 | /* Note that unless the spp_flag is set to SPP_SACKDELAY_ENABLE the | |||
2459 | * value of this field is ignored. Note also that a value of zero | |||
2460 | * indicates the current setting should be left unchanged. | |||
2461 | */ | |||
2462 | if ((params->spp_flags & SPP_SACKDELAY_ENABLE) && params->spp_sackdelay) { | |||
2463 | if (trans) { | |||
2464 | trans->sackdelay = | |||
2465 | msecs_to_jiffies(params->spp_sackdelay); | |||
2466 | } else if (asoc) { | |||
2467 | asoc->sackdelay = | |||
2468 | msecs_to_jiffies(params->spp_sackdelay); | |||
2469 | } else { | |||
2470 | sp->sackdelay = params->spp_sackdelay; | |||
2471 | } | |||
2472 | } | |||
2473 | ||||
2474 | if (sackdelay_change) { | |||
2475 | if (trans) { | |||
2476 | trans->param_flags = | |||
2477 | (trans->param_flags & ~SPP_SACKDELAY) | | |||
2478 | sackdelay_change; | |||
2479 | } else if (asoc) { | |||
2480 | asoc->param_flags = | |||
2481 | (asoc->param_flags & ~SPP_SACKDELAY) | | |||
2482 | sackdelay_change; | |||
2483 | } else { | |||
2484 | sp->param_flags = | |||
2485 | (sp->param_flags & ~SPP_SACKDELAY) | | |||
2486 | sackdelay_change; | |||
2487 | } | |||
2488 | } | |||
2489 | ||||
2490 | /* Note that a value of zero indicates the current setting should be | |||
2491 | left unchanged. | |||
2492 | */ | |||
2493 | if (params->spp_pathmaxrxt) { | |||
2494 | if (trans) { | |||
2495 | trans->pathmaxrxt = params->spp_pathmaxrxt; | |||
2496 | } else if (asoc) { | |||
2497 | asoc->pathmaxrxt = params->spp_pathmaxrxt; | |||
2498 | } else { | |||
2499 | sp->pathmaxrxt = params->spp_pathmaxrxt; | |||
2500 | } | |||
2501 | } | |||
2502 | ||||
2503 | return 0; | |||
2504 | } | |||
2505 | ||||
2506 | static int sctp_setsockopt_peer_addr_params(struct sock *sk, | |||
2507 | char __user *optval, | |||
2508 | unsigned int optlen) | |||
2509 | { | |||
2510 | struct sctp_paddrparams params; | |||
2511 | struct sctp_transport *trans = NULL((void *)0); | |||
2512 | struct sctp_association *asoc = NULL((void *)0); | |||
2513 | struct sctp_sock *sp = sctp_sk(sk); | |||
2514 | int error; | |||
2515 | int hb_change, pmtud_change, sackdelay_change; | |||
2516 | ||||
2517 | if (optlen != sizeof(struct sctp_paddrparams)) | |||
2518 | return -EINVAL22; | |||
2519 | ||||
2520 | if (copy_from_user(¶ms, optval, optlen)) | |||
2521 | return -EFAULT14; | |||
2522 | ||||
2523 | /* Validate flags and value parameters. */ | |||
2524 | hb_change = params.spp_flags & SPP_HB; | |||
2525 | pmtud_change = params.spp_flags & SPP_PMTUD; | |||
2526 | sackdelay_change = params.spp_flags & SPP_SACKDELAY; | |||
2527 | ||||
2528 | if (hb_change == SPP_HB || | |||
2529 | pmtud_change == SPP_PMTUD || | |||
2530 | sackdelay_change == SPP_SACKDELAY || | |||
2531 | params.spp_sackdelay > 500 || | |||
2532 | (params.spp_pathmtu && | |||
2533 | params.spp_pathmtu < SCTP_DEFAULT_MINSEGMENT512)) | |||
2534 | return -EINVAL22; | |||
2535 | ||||
2536 | /* If an address other than INADDR_ANY is specified, and | |||
2537 | * no transport is found, then the request is invalid. | |||
2538 | */ | |||
2539 | if (!sctp_is_any(sk, (union sctp_addr *)¶ms.spp_address)) { | |||
2540 | trans = sctp_addr_id2transport(sk, ¶ms.spp_address, | |||
2541 | params.spp_assoc_id); | |||
2542 | if (!trans) | |||
2543 | return -EINVAL22; | |||
2544 | } | |||
2545 | ||||
2546 | /* Get association, if assoc_id != 0 and the socket is a one | |||
2547 | * to many style socket, and an association was not found, then | |||
2548 | * the id was invalid. | |||
2549 | */ | |||
2550 | asoc = sctp_id2assoc(sk, params.spp_assoc_id); | |||
2551 | if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
2552 | return -EINVAL22; | |||
2553 | ||||
2554 | /* Heartbeat demand can only be sent on a transport or | |||
2555 | * association, but not a socket. | |||
2556 | */ | |||
2557 | if (params.spp_flags & SPP_HB_DEMAND && !trans && !asoc) | |||
2558 | return -EINVAL22; | |||
2559 | ||||
2560 | /* Process parameters. */ | |||
2561 | error = sctp_apply_peer_addr_params(¶ms, trans, asoc, sp, | |||
2562 | hb_change, pmtud_change, | |||
2563 | sackdelay_change); | |||
2564 | ||||
2565 | if (error) | |||
2566 | return error; | |||
2567 | ||||
2568 | /* If changes are for association, also apply parameters to each | |||
2569 | * transport. | |||
2570 | */ | |||
2571 | if (!trans && asoc) { | |||
2572 | list_for_each_entry(trans, &asoc->peer.transport_addr_list,for (trans = ({ const typeof( ((typeof(*trans) *)0)->transports ) *__mptr = ((&asoc->peer.transport_addr_list)->next ); (typeof(*trans) *)( (char *)__mptr - __builtin_offsetof(typeof (*trans), transports) );}); &trans->transports != (& asoc->peer.transport_addr_list); trans = ({ const typeof( ( (typeof(*(trans)) *)0)->transports ) *__mptr = ((trans)-> transports.next); (typeof(*(trans)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(trans)), transports) );})) | |||
2573 | transports)for (trans = ({ const typeof( ((typeof(*trans) *)0)->transports ) *__mptr = ((&asoc->peer.transport_addr_list)->next ); (typeof(*trans) *)( (char *)__mptr - __builtin_offsetof(typeof (*trans), transports) );}); &trans->transports != (& asoc->peer.transport_addr_list); trans = ({ const typeof( ( (typeof(*(trans)) *)0)->transports ) *__mptr = ((trans)-> transports.next); (typeof(*(trans)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(trans)), transports) );})) { | |||
2574 | sctp_apply_peer_addr_params(¶ms, trans, asoc, sp, | |||
2575 | hb_change, pmtud_change, | |||
2576 | sackdelay_change); | |||
2577 | } | |||
2578 | } | |||
2579 | ||||
2580 | return 0; | |||
2581 | } | |||
2582 | ||||
2583 | static inlineinline __attribute__((no_instrument_function)) __u32 sctp_spp_sackdelay_enable(__u32 param_flags) | |||
2584 | { | |||
2585 | return (param_flags & ~SPP_SACKDELAY) | SPP_SACKDELAY_ENABLE; | |||
2586 | } | |||
2587 | ||||
2588 | static inlineinline __attribute__((no_instrument_function)) __u32 sctp_spp_sackdelay_disable(__u32 param_flags) | |||
2589 | { | |||
2590 | return (param_flags & ~SPP_SACKDELAY) | SPP_SACKDELAY_DISABLE; | |||
2591 | } | |||
2592 | ||||
2593 | /* | |||
2594 | * 7.1.23. Get or set delayed ack timer (SCTP_DELAYED_SACK) | |||
2595 | * | |||
2596 | * This option will effect the way delayed acks are performed. This | |||
2597 | * option allows you to get or set the delayed ack time, in | |||
2598 | * milliseconds. It also allows changing the delayed ack frequency. | |||
2599 | * Changing the frequency to 1 disables the delayed sack algorithm. If | |||
2600 | * the assoc_id is 0, then this sets or gets the endpoints default | |||
2601 | * values. If the assoc_id field is non-zero, then the set or get | |||
2602 | * effects the specified association for the one to many model (the | |||
2603 | * assoc_id field is ignored by the one to one model). Note that if | |||
2604 | * sack_delay or sack_freq are 0 when setting this option, then the | |||
2605 | * current values will remain unchanged. | |||
2606 | * | |||
2607 | * struct sctp_sack_info { | |||
2608 | * sctp_assoc_t sack_assoc_id; | |||
2609 | * uint32_t sack_delay; | |||
2610 | * uint32_t sack_freq; | |||
2611 | * }; | |||
2612 | * | |||
2613 | * sack_assoc_id - This parameter, indicates which association the user | |||
2614 | * is performing an action upon. Note that if this field's value is | |||
2615 | * zero then the endpoints default value is changed (effecting future | |||
2616 | * associations only). | |||
2617 | * | |||
2618 | * sack_delay - This parameter contains the number of milliseconds that | |||
2619 | * the user is requesting the delayed ACK timer be set to. Note that | |||
2620 | * this value is defined in the standard to be between 200 and 500 | |||
2621 | * milliseconds. | |||
2622 | * | |||
2623 | * sack_freq - This parameter contains the number of packets that must | |||
2624 | * be received before a sack is sent without waiting for the delay | |||
2625 | * timer to expire. The default value for this is 2, setting this | |||
2626 | * value to 1 will disable the delayed sack algorithm. | |||
2627 | */ | |||
2628 | ||||
2629 | static int sctp_setsockopt_delayed_ack(struct sock *sk, | |||
2630 | char __user *optval, unsigned int optlen) | |||
2631 | { | |||
2632 | struct sctp_sack_info params; | |||
2633 | struct sctp_transport *trans = NULL((void *)0); | |||
2634 | struct sctp_association *asoc = NULL((void *)0); | |||
2635 | struct sctp_sock *sp = sctp_sk(sk); | |||
2636 | ||||
2637 | if (optlen == sizeof(struct sctp_sack_info)) { | |||
2638 | if (copy_from_user(¶ms, optval, optlen)) | |||
2639 | return -EFAULT14; | |||
2640 | ||||
2641 | if (params.sack_delay == 0 && params.sack_freq == 0) | |||
2642 | return 0; | |||
2643 | } else if (optlen == sizeof(struct sctp_assoc_value)) { | |||
2644 | pr_warn_ratelimited(DEPRECATED({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of struct sctp_assoc_value in delayed_ack socket option.\n" "Use struct sctp_sack_info instead\n", get_current()->comm , task_pid_nr(get_current())); }) | |||
2645 | "%s (pid %d) "({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of struct sctp_assoc_value in delayed_ack socket option.\n" "Use struct sctp_sack_info instead\n", get_current()->comm , task_pid_nr(get_current())); }) | |||
2646 | "Use of struct sctp_assoc_value in delayed_ack socket option.\n"({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of struct sctp_assoc_value in delayed_ack socket option.\n" "Use struct sctp_sack_info instead\n", get_current()->comm , task_pid_nr(get_current())); }) | |||
2647 | "Use struct sctp_sack_info instead\n",({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of struct sctp_assoc_value in delayed_ack socket option.\n" "Use struct sctp_sack_info instead\n", get_current()->comm , task_pid_nr(get_current())); }) | |||
2648 | current->comm, task_pid_nr(current))({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of struct sctp_assoc_value in delayed_ack socket option.\n" "Use struct sctp_sack_info instead\n", get_current()->comm , task_pid_nr(get_current())); }); | |||
2649 | if (copy_from_user(¶ms, optval, optlen)) | |||
2650 | return -EFAULT14; | |||
2651 | ||||
2652 | if (params.sack_delay == 0) | |||
2653 | params.sack_freq = 1; | |||
2654 | else | |||
2655 | params.sack_freq = 0; | |||
2656 | } else | |||
2657 | return -EINVAL22; | |||
2658 | ||||
2659 | /* Validate value parameter. */ | |||
2660 | if (params.sack_delay > 500) | |||
2661 | return -EINVAL22; | |||
2662 | ||||
2663 | /* Get association, if sack_assoc_id != 0 and the socket is a one | |||
2664 | * to many style socket, and an association was not found, then | |||
2665 | * the id was invalid. | |||
2666 | */ | |||
2667 | asoc = sctp_id2assoc(sk, params.sack_assoc_id); | |||
2668 | if (!asoc && params.sack_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
2669 | return -EINVAL22; | |||
2670 | ||||
2671 | if (params.sack_delay) { | |||
2672 | if (asoc) { | |||
2673 | asoc->sackdelay = | |||
2674 | msecs_to_jiffies(params.sack_delay); | |||
2675 | asoc->param_flags = | |||
2676 | sctp_spp_sackdelay_enable(asoc->param_flags); | |||
2677 | } else { | |||
2678 | sp->sackdelay = params.sack_delay; | |||
2679 | sp->param_flags = | |||
2680 | sctp_spp_sackdelay_enable(sp->param_flags); | |||
2681 | } | |||
2682 | } | |||
2683 | ||||
2684 | if (params.sack_freq == 1) { | |||
2685 | if (asoc) { | |||
2686 | asoc->param_flags = | |||
2687 | sctp_spp_sackdelay_disable(asoc->param_flags); | |||
2688 | } else { | |||
2689 | sp->param_flags = | |||
2690 | sctp_spp_sackdelay_disable(sp->param_flags); | |||
2691 | } | |||
2692 | } else if (params.sack_freq > 1) { | |||
2693 | if (asoc) { | |||
2694 | asoc->sackfreq = params.sack_freq; | |||
2695 | asoc->param_flags = | |||
2696 | sctp_spp_sackdelay_enable(asoc->param_flags); | |||
2697 | } else { | |||
2698 | sp->sackfreq = params.sack_freq; | |||
2699 | sp->param_flags = | |||
2700 | sctp_spp_sackdelay_enable(sp->param_flags); | |||
2701 | } | |||
2702 | } | |||
2703 | ||||
2704 | /* If change is for association, also apply to each transport. */ | |||
2705 | if (asoc) { | |||
2706 | list_for_each_entry(trans, &asoc->peer.transport_addr_list,for (trans = ({ const typeof( ((typeof(*trans) *)0)->transports ) *__mptr = ((&asoc->peer.transport_addr_list)->next ); (typeof(*trans) *)( (char *)__mptr - __builtin_offsetof(typeof (*trans), transports) );}); &trans->transports != (& asoc->peer.transport_addr_list); trans = ({ const typeof( ( (typeof(*(trans)) *)0)->transports ) *__mptr = ((trans)-> transports.next); (typeof(*(trans)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(trans)), transports) );})) | |||
2707 | transports)for (trans = ({ const typeof( ((typeof(*trans) *)0)->transports ) *__mptr = ((&asoc->peer.transport_addr_list)->next ); (typeof(*trans) *)( (char *)__mptr - __builtin_offsetof(typeof (*trans), transports) );}); &trans->transports != (& asoc->peer.transport_addr_list); trans = ({ const typeof( ( (typeof(*(trans)) *)0)->transports ) *__mptr = ((trans)-> transports.next); (typeof(*(trans)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(trans)), transports) );})) { | |||
2708 | if (params.sack_delay) { | |||
2709 | trans->sackdelay = | |||
2710 | msecs_to_jiffies(params.sack_delay); | |||
2711 | trans->param_flags = | |||
2712 | sctp_spp_sackdelay_enable(trans->param_flags); | |||
2713 | } | |||
2714 | if (params.sack_freq == 1) { | |||
2715 | trans->param_flags = | |||
2716 | sctp_spp_sackdelay_disable(trans->param_flags); | |||
2717 | } else if (params.sack_freq > 1) { | |||
2718 | trans->sackfreq = params.sack_freq; | |||
2719 | trans->param_flags = | |||
2720 | sctp_spp_sackdelay_enable(trans->param_flags); | |||
2721 | } | |||
2722 | } | |||
2723 | } | |||
2724 | ||||
2725 | return 0; | |||
2726 | } | |||
2727 | ||||
2728 | /* 7.1.3 Initialization Parameters (SCTP_INITMSG) | |||
2729 | * | |||
2730 | * Applications can specify protocol parameters for the default association | |||
2731 | * initialization. The option name argument to setsockopt() and getsockopt() | |||
2732 | * is SCTP_INITMSG. | |||
2733 | * | |||
2734 | * Setting initialization parameters is effective only on an unconnected | |||
2735 | * socket (for UDP-style sockets only future associations are effected | |||
2736 | * by the change). With TCP-style sockets, this option is inherited by | |||
2737 | * sockets derived from a listener socket. | |||
2738 | */ | |||
2739 | static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, unsigned int optlen) | |||
2740 | { | |||
2741 | struct sctp_initmsg sinit; | |||
2742 | struct sctp_sock *sp = sctp_sk(sk); | |||
2743 | ||||
2744 | if (optlen != sizeof(struct sctp_initmsg)) | |||
2745 | return -EINVAL22; | |||
2746 | if (copy_from_user(&sinit, optval, optlen)) | |||
2747 | return -EFAULT14; | |||
2748 | ||||
2749 | if (sinit.sinit_num_ostreams) | |||
2750 | sp->initmsg.sinit_num_ostreams = sinit.sinit_num_ostreams; | |||
2751 | if (sinit.sinit_max_instreams) | |||
2752 | sp->initmsg.sinit_max_instreams = sinit.sinit_max_instreams; | |||
2753 | if (sinit.sinit_max_attempts) | |||
2754 | sp->initmsg.sinit_max_attempts = sinit.sinit_max_attempts; | |||
2755 | if (sinit.sinit_max_init_timeo) | |||
2756 | sp->initmsg.sinit_max_init_timeo = sinit.sinit_max_init_timeo; | |||
2757 | ||||
2758 | return 0; | |||
2759 | } | |||
2760 | ||||
2761 | /* | |||
2762 | * 7.1.14 Set default send parameters (SCTP_DEFAULT_SEND_PARAM) | |||
2763 | * | |||
2764 | * Applications that wish to use the sendto() system call may wish to | |||
2765 | * specify a default set of parameters that would normally be supplied | |||
2766 | * through the inclusion of ancillary data. This socket option allows | |||
2767 | * such an application to set the default sctp_sndrcvinfo structure. | |||
2768 | * The application that wishes to use this socket option simply passes | |||
2769 | * in to this call the sctp_sndrcvinfo structure defined in Section | |||
2770 | * 5.2.2) The input parameters accepted by this call include | |||
2771 | * sinfo_stream, sinfo_flags, sinfo_ppid, sinfo_context, | |||
2772 | * sinfo_timetolive. The user must provide the sinfo_assoc_id field in | |||
2773 | * to this call if the caller is using the UDP model. | |||
2774 | */ | |||
2775 | static int sctp_setsockopt_default_send_param(struct sock *sk, | |||
2776 | char __user *optval, | |||
2777 | unsigned int optlen) | |||
2778 | { | |||
2779 | struct sctp_sock *sp = sctp_sk(sk); | |||
2780 | struct sctp_association *asoc; | |||
2781 | struct sctp_sndrcvinfo info; | |||
2782 | ||||
2783 | if (optlen != sizeof(info)) | |||
2784 | return -EINVAL22; | |||
2785 | if (copy_from_user(&info, optval, optlen)) | |||
2786 | return -EFAULT14; | |||
2787 | if (info.sinfo_flags & | |||
2788 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | | |||
2789 | SCTP_ABORT | SCTP_EOF)) | |||
2790 | return -EINVAL22; | |||
2791 | ||||
2792 | asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); | |||
2793 | if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
2794 | return -EINVAL22; | |||
2795 | if (asoc) { | |||
2796 | asoc->default_stream = info.sinfo_stream; | |||
2797 | asoc->default_flags = info.sinfo_flags; | |||
2798 | asoc->default_ppid = info.sinfo_ppid; | |||
2799 | asoc->default_context = info.sinfo_context; | |||
2800 | asoc->default_timetolive = info.sinfo_timetolive; | |||
2801 | } else { | |||
2802 | sp->default_stream = info.sinfo_stream; | |||
2803 | sp->default_flags = info.sinfo_flags; | |||
2804 | sp->default_ppid = info.sinfo_ppid; | |||
2805 | sp->default_context = info.sinfo_context; | |||
2806 | sp->default_timetolive = info.sinfo_timetolive; | |||
2807 | } | |||
2808 | ||||
2809 | return 0; | |||
2810 | } | |||
2811 | ||||
2812 | /* RFC6458, Section 8.1.31. Set/get Default Send Parameters | |||
2813 | * (SCTP_DEFAULT_SNDINFO) | |||
2814 | */ | |||
2815 | static int sctp_setsockopt_default_sndinfo(struct sock *sk, | |||
2816 | char __user *optval, | |||
2817 | unsigned int optlen) | |||
2818 | { | |||
2819 | struct sctp_sock *sp = sctp_sk(sk); | |||
2820 | struct sctp_association *asoc; | |||
2821 | struct sctp_sndinfo info; | |||
2822 | ||||
2823 | if (optlen != sizeof(info)) | |||
2824 | return -EINVAL22; | |||
2825 | if (copy_from_user(&info, optval, optlen)) | |||
2826 | return -EFAULT14; | |||
2827 | if (info.snd_flags & | |||
2828 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | | |||
2829 | SCTP_ABORT | SCTP_EOF)) | |||
2830 | return -EINVAL22; | |||
2831 | ||||
2832 | asoc = sctp_id2assoc(sk, info.snd_assoc_id); | |||
2833 | if (!asoc && info.snd_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
2834 | return -EINVAL22; | |||
2835 | if (asoc) { | |||
2836 | asoc->default_stream = info.snd_sid; | |||
2837 | asoc->default_flags = info.snd_flags; | |||
2838 | asoc->default_ppid = info.snd_ppid; | |||
2839 | asoc->default_context = info.snd_context; | |||
2840 | } else { | |||
2841 | sp->default_stream = info.snd_sid; | |||
2842 | sp->default_flags = info.snd_flags; | |||
2843 | sp->default_ppid = info.snd_ppid; | |||
2844 | sp->default_context = info.snd_context; | |||
2845 | } | |||
2846 | ||||
2847 | return 0; | |||
2848 | } | |||
2849 | ||||
2850 | /* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR) | |||
2851 | * | |||
2852 | * Requests that the local SCTP stack use the enclosed peer address as | |||
2853 | * the association primary. The enclosed address must be one of the | |||
2854 | * association peer's addresses. | |||
2855 | */ | |||
2856 | static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval, | |||
2857 | unsigned int optlen) | |||
2858 | { | |||
2859 | struct sctp_prim prim; | |||
2860 | struct sctp_transport *trans; | |||
2861 | ||||
2862 | if (optlen != sizeof(struct sctp_prim)) | |||
2863 | return -EINVAL22; | |||
2864 | ||||
2865 | if (copy_from_user(&prim, optval, sizeof(struct sctp_prim))) | |||
2866 | return -EFAULT14; | |||
2867 | ||||
2868 | trans = sctp_addr_id2transport(sk, &prim.ssp_addr, prim.ssp_assoc_id); | |||
2869 | if (!trans) | |||
2870 | return -EINVAL22; | |||
2871 | ||||
2872 | sctp_assoc_set_primary(trans->asoc, trans); | |||
2873 | ||||
2874 | return 0; | |||
2875 | } | |||
2876 | ||||
2877 | /* | |||
2878 | * 7.1.5 SCTP_NODELAY | |||
2879 | * | |||
2880 | * Turn on/off any Nagle-like algorithm. This means that packets are | |||
2881 | * generally sent as soon as possible and no unnecessary delays are | |||
2882 | * introduced, at the cost of more packets in the network. Expects an | |||
2883 | * integer boolean flag. | |||
2884 | */ | |||
2885 | static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval, | |||
2886 | unsigned int optlen) | |||
2887 | { | |||
2888 | int val; | |||
2889 | ||||
2890 | if (optlen < sizeof(int)) | |||
2891 | return -EINVAL22; | |||
2892 | if (get_user(val, (int __user *)optval)({ int __ret_gu; register __typeof__(__builtin_choose_expr(sizeof (*((int *)optval)) > sizeof(0UL), 0ULL, 0UL)) __val_gu asm ("%""rdx"); register void *__sp asm("rsp"); (void)0; __might_fault ("net/sctp/socket.c", 2892); asm volatile("call __get_user_%P4" : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) : "0" ((int * )optval), "i" (sizeof(*((int *)optval)))); (val) = ( __typeof__ (*((int *)optval))) __val_gu; clang_analyzer_taint(&val); __builtin_expect(__ret_gu, 0); })) | |||
2893 | return -EFAULT14; | |||
2894 | ||||
2895 | sctp_sk(sk)->nodelay = (val == 0) ? 0 : 1; | |||
2896 | return 0; | |||
2897 | } | |||
2898 | ||||
2899 | /* | |||
2900 | * | |||
2901 | * 7.1.1 SCTP_RTOINFO | |||
2902 | * | |||
2903 | * The protocol parameters used to initialize and bound retransmission | |||
2904 | * timeout (RTO) are tunable. sctp_rtoinfo structure is used to access | |||
2905 | * and modify these parameters. | |||
2906 | * All parameters are time values, in milliseconds. A value of 0, when | |||
2907 | * modifying the parameters, indicates that the current value should not | |||
2908 | * be changed. | |||
2909 | * | |||
2910 | */ | |||
2911 | static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigned int optlen) | |||
2912 | { | |||
2913 | struct sctp_rtoinfo rtoinfo; | |||
2914 | struct sctp_association *asoc; | |||
2915 | unsigned long rto_min, rto_max; | |||
2916 | struct sctp_sock *sp = sctp_sk(sk); | |||
2917 | ||||
2918 | if (optlen != sizeof (struct sctp_rtoinfo)) | |||
2919 | return -EINVAL22; | |||
2920 | ||||
2921 | if (copy_from_user(&rtoinfo, optval, optlen)) | |||
2922 | return -EFAULT14; | |||
2923 | ||||
2924 | asoc = sctp_id2assoc(sk, rtoinfo.srto_assoc_id); | |||
2925 | ||||
2926 | /* Set the values to the specific association */ | |||
2927 | if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
2928 | return -EINVAL22; | |||
2929 | ||||
2930 | rto_max = rtoinfo.srto_max; | |||
2931 | rto_min = rtoinfo.srto_min; | |||
2932 | ||||
2933 | if (rto_max) | |||
2934 | rto_max = asoc ? msecs_to_jiffies(rto_max) : rto_max; | |||
2935 | else | |||
2936 | rto_max = asoc ? asoc->rto_max : sp->rtoinfo.srto_max; | |||
2937 | ||||
2938 | if (rto_min) | |||
2939 | rto_min = asoc ? msecs_to_jiffies(rto_min) : rto_min; | |||
2940 | else | |||
2941 | rto_min = asoc ? asoc->rto_min : sp->rtoinfo.srto_min; | |||
2942 | ||||
2943 | if (rto_min > rto_max) | |||
2944 | return -EINVAL22; | |||
2945 | ||||
2946 | if (asoc) { | |||
2947 | if (rtoinfo.srto_initial != 0) | |||
2948 | asoc->rto_initial = | |||
2949 | msecs_to_jiffies(rtoinfo.srto_initial); | |||
2950 | asoc->rto_max = rto_max; | |||
2951 | asoc->rto_min = rto_min; | |||
2952 | } else { | |||
2953 | /* If there is no association or the association-id = 0 | |||
2954 | * set the values to the endpoint. | |||
2955 | */ | |||
2956 | if (rtoinfo.srto_initial != 0) | |||
2957 | sp->rtoinfo.srto_initial = rtoinfo.srto_initial; | |||
2958 | sp->rtoinfo.srto_max = rto_max; | |||
2959 | sp->rtoinfo.srto_min = rto_min; | |||
2960 | } | |||
2961 | ||||
2962 | return 0; | |||
2963 | } | |||
2964 | ||||
2965 | /* | |||
2966 | * | |||
2967 | * 7.1.2 SCTP_ASSOCINFO | |||
2968 | * | |||
2969 | * This option is used to tune the maximum retransmission attempts | |||
2970 | * of the association. | |||
2971 | * Returns an error if the new association retransmission value is | |||
2972 | * greater than the sum of the retransmission value of the peer. | |||
2973 | * See [SCTP] for more information. | |||
2974 | * | |||
2975 | */ | |||
2976 | static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, unsigned int optlen) | |||
2977 | { | |||
2978 | ||||
2979 | struct sctp_assocparams assocparams; | |||
2980 | struct sctp_association *asoc; | |||
2981 | ||||
2982 | if (optlen != sizeof(struct sctp_assocparams)) | |||
2983 | return -EINVAL22; | |||
2984 | if (copy_from_user(&assocparams, optval, optlen)) | |||
2985 | return -EFAULT14; | |||
2986 | ||||
2987 | asoc = sctp_id2assoc(sk, assocparams.sasoc_assoc_id); | |||
2988 | ||||
2989 | if (!asoc && assocparams.sasoc_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
2990 | return -EINVAL22; | |||
2991 | ||||
2992 | /* Set the values to the specific association */ | |||
2993 | if (asoc) { | |||
2994 | if (assocparams.sasoc_asocmaxrxt != 0) { | |||
2995 | __u32 path_sum = 0; | |||
2996 | int paths = 0; | |||
2997 | struct sctp_transport *peer_addr; | |||
2998 | ||||
2999 | list_for_each_entry(peer_addr, &asoc->peer.transport_addr_list,for (peer_addr = ({ const typeof( ((typeof(*peer_addr) *)0)-> transports ) *__mptr = ((&asoc->peer.transport_addr_list )->next); (typeof(*peer_addr) *)( (char *)__mptr - __builtin_offsetof (typeof(*peer_addr), transports) );}); &peer_addr->transports != (&asoc->peer.transport_addr_list); peer_addr = ({ const typeof( ((typeof(*(peer_addr)) *)0)->transports ) *__mptr = ((peer_addr)->transports.next); (typeof(*(peer_addr)) * )( (char *)__mptr - __builtin_offsetof(typeof(*(peer_addr)), transports ) );})) | |||
3000 | transports)for (peer_addr = ({ const typeof( ((typeof(*peer_addr) *)0)-> transports ) *__mptr = ((&asoc->peer.transport_addr_list )->next); (typeof(*peer_addr) *)( (char *)__mptr - __builtin_offsetof (typeof(*peer_addr), transports) );}); &peer_addr->transports != (&asoc->peer.transport_addr_list); peer_addr = ({ const typeof( ((typeof(*(peer_addr)) *)0)->transports ) *__mptr = ((peer_addr)->transports.next); (typeof(*(peer_addr)) * )( (char *)__mptr - __builtin_offsetof(typeof(*(peer_addr)), transports ) );})) { | |||
3001 | path_sum += peer_addr->pathmaxrxt; | |||
3002 | paths++; | |||
3003 | } | |||
3004 | ||||
3005 | /* Only validate asocmaxrxt if we have more than | |||
3006 | * one path/transport. We do this because path | |||
3007 | * retransmissions are only counted when we have more | |||
3008 | * then one path. | |||
3009 | */ | |||
3010 | if (paths > 1 && | |||
3011 | assocparams.sasoc_asocmaxrxt > path_sum) | |||
3012 | return -EINVAL22; | |||
3013 | ||||
3014 | asoc->max_retrans = assocparams.sasoc_asocmaxrxt; | |||
3015 | } | |||
3016 | ||||
3017 | if (assocparams.sasoc_cookie_life != 0) | |||
3018 | asoc->cookie_life = ms_to_ktime(assocparams.sasoc_cookie_life); | |||
3019 | } else { | |||
3020 | /* Set the values to the endpoint */ | |||
3021 | struct sctp_sock *sp = sctp_sk(sk); | |||
3022 | ||||
3023 | if (assocparams.sasoc_asocmaxrxt != 0) | |||
3024 | sp->assocparams.sasoc_asocmaxrxt = | |||
3025 | assocparams.sasoc_asocmaxrxt; | |||
3026 | if (assocparams.sasoc_cookie_life != 0) | |||
3027 | sp->assocparams.sasoc_cookie_life = | |||
3028 | assocparams.sasoc_cookie_life; | |||
3029 | } | |||
3030 | return 0; | |||
3031 | } | |||
3032 | ||||
3033 | /* | |||
3034 | * 7.1.16 Set/clear IPv4 mapped addresses (SCTP_I_WANT_MAPPED_V4_ADDR) | |||
3035 | * | |||
3036 | * This socket option is a boolean flag which turns on or off mapped V4 | |||
3037 | * addresses. If this option is turned on and the socket is type | |||
3038 | * PF_INET6, then IPv4 addresses will be mapped to V6 representation. | |||
3039 | * If this option is turned off, then no mapping will be done of V4 | |||
3040 | * addresses and a user will receive both PF_INET6 and PF_INET type | |||
3041 | * addresses on the socket. | |||
3042 | */ | |||
3043 | static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, unsigned int optlen) | |||
3044 | { | |||
3045 | int val; | |||
3046 | struct sctp_sock *sp = sctp_sk(sk); | |||
3047 | ||||
3048 | if (optlen < sizeof(int)) | |||
3049 | return -EINVAL22; | |||
3050 | if (get_user(val, (int __user *)optval)({ int __ret_gu; register __typeof__(__builtin_choose_expr(sizeof (*((int *)optval)) > sizeof(0UL), 0ULL, 0UL)) __val_gu asm ("%""rdx"); register void *__sp asm("rsp"); (void)0; __might_fault ("net/sctp/socket.c", 3050); asm volatile("call __get_user_%P4" : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) : "0" ((int * )optval), "i" (sizeof(*((int *)optval)))); (val) = ( __typeof__ (*((int *)optval))) __val_gu; clang_analyzer_taint(&val); __builtin_expect(__ret_gu, 0); })) | |||
3051 | return -EFAULT14; | |||
3052 | if (val) | |||
3053 | sp->v4mapped = 1; | |||
3054 | else | |||
3055 | sp->v4mapped = 0; | |||
3056 | ||||
3057 | return 0; | |||
3058 | } | |||
3059 | ||||
3060 | /* | |||
3061 | * 8.1.16. Get or Set the Maximum Fragmentation Size (SCTP_MAXSEG) | |||
3062 | * This option will get or set the maximum size to put in any outgoing | |||
3063 | * SCTP DATA chunk. If a message is larger than this size it will be | |||
3064 | * fragmented by SCTP into the specified size. Note that the underlying | |||
3065 | * SCTP implementation may fragment into smaller sized chunks when the | |||
3066 | * PMTU of the underlying association is smaller than the value set by | |||
3067 | * the user. The default value for this option is '0' which indicates | |||
3068 | * the user is NOT limiting fragmentation and only the PMTU will effect | |||
3069 | * SCTP's choice of DATA chunk size. Note also that values set larger | |||
3070 | * than the maximum size of an IP datagram will effectively let SCTP | |||
3071 | * control fragmentation (i.e. the same as setting this option to 0). | |||
3072 | * | |||
3073 | * The following structure is used to access and modify this parameter: | |||
3074 | * | |||
3075 | * struct sctp_assoc_value { | |||
3076 | * sctp_assoc_t assoc_id; | |||
3077 | * uint32_t assoc_value; | |||
3078 | * }; | |||
3079 | * | |||
3080 | * assoc_id: This parameter is ignored for one-to-one style sockets. | |||
3081 | * For one-to-many style sockets this parameter indicates which | |||
3082 | * association the user is performing an action upon. Note that if | |||
3083 | * this field's value is zero then the endpoints default value is | |||
3084 | * changed (effecting future associations only). | |||
3085 | * assoc_value: This parameter specifies the maximum size in bytes. | |||
3086 | */ | |||
3087 | static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen) | |||
3088 | { | |||
3089 | struct sctp_assoc_value params; | |||
3090 | struct sctp_association *asoc; | |||
3091 | struct sctp_sock *sp = sctp_sk(sk); | |||
3092 | int val; | |||
3093 | ||||
3094 | if (optlen == sizeof(int)) { | |||
3095 | pr_warn_ratelimited(DEPRECATED({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in maxseg socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }) | |||
3096 | "%s (pid %d) "({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in maxseg socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }) | |||
3097 | "Use of int in maxseg socket option.\n"({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in maxseg socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }) | |||
3098 | "Use struct sctp_assoc_value instead\n",({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in maxseg socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }) | |||
3099 | current->comm, task_pid_nr(current))({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in maxseg socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }); | |||
3100 | if (copy_from_user(&val, optval, optlen)) | |||
3101 | return -EFAULT14; | |||
3102 | params.assoc_id = 0; | |||
3103 | } else if (optlen == sizeof(struct sctp_assoc_value)) { | |||
3104 | if (copy_from_user(¶ms, optval, optlen)) | |||
3105 | return -EFAULT14; | |||
3106 | val = params.assoc_value; | |||
3107 | } else | |||
3108 | return -EINVAL22; | |||
3109 | ||||
3110 | if ((val != 0) && ((val < 8) || (val > SCTP_MAX_CHUNK_LEN))) | |||
3111 | return -EINVAL22; | |||
3112 | ||||
3113 | asoc = sctp_id2assoc(sk, params.assoc_id); | |||
3114 | if (!asoc && params.assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
3115 | return -EINVAL22; | |||
3116 | ||||
3117 | if (asoc) { | |||
3118 | if (val == 0) { | |||
3119 | val = asoc->pathmtu; | |||
3120 | val -= sp->pf->af->net_header_len; | |||
3121 | val -= sizeof(struct sctphdr) + | |||
3122 | sizeof(struct sctp_data_chunk); | |||
3123 | } | |||
3124 | asoc->user_frag = val; | |||
3125 | asoc->frag_point = sctp_frag_point(asoc, asoc->pathmtu); | |||
3126 | } else { | |||
3127 | sp->user_frag = val; | |||
3128 | } | |||
3129 | ||||
3130 | return 0; | |||
3131 | } | |||
3132 | ||||
3133 | ||||
3134 | /* | |||
3135 | * 7.1.9 Set Peer Primary Address (SCTP_SET_PEER_PRIMARY_ADDR) | |||
3136 | * | |||
3137 | * Requests that the peer mark the enclosed address as the association | |||
3138 | * primary. The enclosed address must be one of the association's | |||
3139 | * locally bound addresses. The following structure is used to make a | |||
3140 | * set primary request: | |||
3141 | */ | |||
3142 | static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optval, | |||
3143 | unsigned int optlen) | |||
3144 | { | |||
3145 | struct net *net = sock_net(sk); | |||
3146 | struct sctp_sock *sp; | |||
3147 | struct sctp_association *asoc = NULL((void *)0); | |||
3148 | struct sctp_setpeerprim prim; | |||
3149 | struct sctp_chunk *chunk; | |||
3150 | struct sctp_af *af; | |||
3151 | int err; | |||
3152 | ||||
3153 | sp = sctp_sk(sk); | |||
3154 | ||||
3155 | if (!net->sctp.addip_enable) | |||
3156 | return -EPERM1; | |||
3157 | ||||
3158 | if (optlen != sizeof(struct sctp_setpeerprim)) | |||
3159 | return -EINVAL22; | |||
3160 | ||||
3161 | if (copy_from_user(&prim, optval, optlen)) | |||
3162 | return -EFAULT14; | |||
3163 | ||||
3164 | asoc = sctp_id2assoc(sk, prim.sspp_assoc_id); | |||
3165 | if (!asoc) | |||
3166 | return -EINVAL22; | |||
3167 | ||||
3168 | if (!asoc->peer.asconf_capable) | |||
3169 | return -EPERM1; | |||
3170 | ||||
3171 | if (asoc->peer.addip_disabled_mask & SCTP_PARAM_SET_PRIMARY) | |||
3172 | return -EPERM1; | |||
3173 | ||||
3174 | if (!sctp_state(asoc, ESTABLISHED)__sctp_state((asoc), (SCTP_STATE_ESTABLISHED))) | |||
3175 | return -ENOTCONN107; | |||
3176 | ||||
3177 | af = sctp_get_af_specific(prim.sspp_addr.ss_family); | |||
3178 | if (!af) | |||
3179 | return -EINVAL22; | |||
3180 | ||||
3181 | if (!af->addr_valid((union sctp_addr *)&prim.sspp_addr, sp, NULL((void *)0))) | |||
3182 | return -EADDRNOTAVAIL99; | |||
3183 | ||||
3184 | if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr)) | |||
3185 | return -EADDRNOTAVAIL99; | |||
3186 | ||||
3187 | /* Create an ASCONF chunk with SET_PRIMARY parameter */ | |||
3188 | chunk = sctp_make_asconf_set_prim(asoc, | |||
3189 | (union sctp_addr *)&prim.sspp_addr); | |||
3190 | if (!chunk) | |||
3191 | return -ENOMEM12; | |||
3192 | ||||
3193 | err = sctp_send_asconf(asoc, chunk); | |||
3194 | ||||
3195 | pr_debug("%s: we set peer primary addr primitively\n", __func__)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: we set peer primary addr primitively\n" ), .lineno = 3195, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: we set peer primary addr primitively\n", __func__); } while (0); | |||
3196 | ||||
3197 | return err; | |||
3198 | } | |||
3199 | ||||
3200 | static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval, | |||
3201 | unsigned int optlen) | |||
3202 | { | |||
3203 | struct sctp_setadaptation adaptation; | |||
3204 | ||||
3205 | if (optlen != sizeof(struct sctp_setadaptation)) | |||
3206 | return -EINVAL22; | |||
3207 | if (copy_from_user(&adaptation, optval, optlen)) | |||
3208 | return -EFAULT14; | |||
3209 | ||||
3210 | sctp_sk(sk)->adaptation_ind = adaptation.ssb_adaptation_ind; | |||
3211 | ||||
3212 | return 0; | |||
3213 | } | |||
3214 | ||||
3215 | /* | |||
3216 | * 7.1.29. Set or Get the default context (SCTP_CONTEXT) | |||
3217 | * | |||
3218 | * The context field in the sctp_sndrcvinfo structure is normally only | |||
3219 | * used when a failed message is retrieved holding the value that was | |||
3220 | * sent down on the actual send call. This option allows the setting of | |||
3221 | * a default context on an association basis that will be received on | |||
3222 | * reading messages from the peer. This is especially helpful in the | |||
3223 | * one-2-many model for an application to keep some reference to an | |||
3224 | * internal state machine that is processing messages on the | |||
3225 | * association. Note that the setting of this value only effects | |||
3226 | * received messages from the peer and does not effect the value that is | |||
3227 | * saved with outbound messages. | |||
3228 | */ | |||
3229 | static int sctp_setsockopt_context(struct sock *sk, char __user *optval, | |||
3230 | unsigned int optlen) | |||
3231 | { | |||
3232 | struct sctp_assoc_value params; | |||
3233 | struct sctp_sock *sp; | |||
3234 | struct sctp_association *asoc; | |||
3235 | ||||
3236 | if (optlen != sizeof(struct sctp_assoc_value)) | |||
3237 | return -EINVAL22; | |||
3238 | if (copy_from_user(¶ms, optval, optlen)) | |||
3239 | return -EFAULT14; | |||
3240 | ||||
3241 | sp = sctp_sk(sk); | |||
3242 | ||||
3243 | if (params.assoc_id != 0) { | |||
3244 | asoc = sctp_id2assoc(sk, params.assoc_id); | |||
3245 | if (!asoc) | |||
3246 | return -EINVAL22; | |||
3247 | asoc->default_rcv_context = params.assoc_value; | |||
3248 | } else { | |||
3249 | sp->default_rcv_context = params.assoc_value; | |||
3250 | } | |||
3251 | ||||
3252 | return 0; | |||
3253 | } | |||
3254 | ||||
3255 | /* | |||
3256 | * 7.1.24. Get or set fragmented interleave (SCTP_FRAGMENT_INTERLEAVE) | |||
3257 | * | |||
3258 | * This options will at a minimum specify if the implementation is doing | |||
3259 | * fragmented interleave. Fragmented interleave, for a one to many | |||
3260 | * socket, is when subsequent calls to receive a message may return | |||
3261 | * parts of messages from different associations. Some implementations | |||
3262 | * may allow you to turn this value on or off. If so, when turned off, | |||
3263 | * no fragment interleave will occur (which will cause a head of line | |||
3264 | * blocking amongst multiple associations sharing the same one to many | |||
3265 | * socket). When this option is turned on, then each receive call may | |||
3266 | * come from a different association (thus the user must receive data | |||
3267 | * with the extended calls (e.g. sctp_recvmsg) to keep track of which | |||
3268 | * association each receive belongs to. | |||
3269 | * | |||
3270 | * This option takes a boolean value. A non-zero value indicates that | |||
3271 | * fragmented interleave is on. A value of zero indicates that | |||
3272 | * fragmented interleave is off. | |||
3273 | * | |||
3274 | * Note that it is important that an implementation that allows this | |||
3275 | * option to be turned on, have it off by default. Otherwise an unaware | |||
3276 | * application using the one to many model may become confused and act | |||
3277 | * incorrectly. | |||
3278 | */ | |||
3279 | static int sctp_setsockopt_fragment_interleave(struct sock *sk, | |||
3280 | char __user *optval, | |||
3281 | unsigned int optlen) | |||
3282 | { | |||
3283 | int val; | |||
3284 | ||||
3285 | if (optlen != sizeof(int)) | |||
3286 | return -EINVAL22; | |||
3287 | if (get_user(val, (int __user *)optval)({ int __ret_gu; register __typeof__(__builtin_choose_expr(sizeof (*((int *)optval)) > sizeof(0UL), 0ULL, 0UL)) __val_gu asm ("%""rdx"); register void *__sp asm("rsp"); (void)0; __might_fault ("net/sctp/socket.c", 3287); asm volatile("call __get_user_%P4" : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) : "0" ((int * )optval), "i" (sizeof(*((int *)optval)))); (val) = ( __typeof__ (*((int *)optval))) __val_gu; clang_analyzer_taint(&val); __builtin_expect(__ret_gu, 0); })) | |||
3288 | return -EFAULT14; | |||
3289 | ||||
3290 | sctp_sk(sk)->frag_interleave = (val == 0) ? 0 : 1; | |||
3291 | ||||
3292 | return 0; | |||
3293 | } | |||
3294 | ||||
3295 | /* | |||
3296 | * 8.1.21. Set or Get the SCTP Partial Delivery Point | |||
3297 | * (SCTP_PARTIAL_DELIVERY_POINT) | |||
3298 | * | |||
3299 | * This option will set or get the SCTP partial delivery point. This | |||
3300 | * point is the size of a message where the partial delivery API will be | |||
3301 | * invoked to help free up rwnd space for the peer. Setting this to a | |||
3302 | * lower value will cause partial deliveries to happen more often. The | |||
3303 | * calls argument is an integer that sets or gets the partial delivery | |||
3304 | * point. Note also that the call will fail if the user attempts to set | |||
3305 | * this value larger than the socket receive buffer size. | |||
3306 | * | |||
3307 | * Note that any single message having a length smaller than or equal to | |||
3308 | * the SCTP partial delivery point will be delivered in one single read | |||
3309 | * call as long as the user provided buffer is large enough to hold the | |||
3310 | * message. | |||
3311 | */ | |||
3312 | static int sctp_setsockopt_partial_delivery_point(struct sock *sk, | |||
3313 | char __user *optval, | |||
3314 | unsigned int optlen) | |||
3315 | { | |||
3316 | u32 val; | |||
3317 | ||||
3318 | if (optlen != sizeof(u32)) | |||
3319 | return -EINVAL22; | |||
3320 | if (get_user(val, (int __user *)optval)({ int __ret_gu; register __typeof__(__builtin_choose_expr(sizeof (*((int *)optval)) > sizeof(0UL), 0ULL, 0UL)) __val_gu asm ("%""rdx"); register void *__sp asm("rsp"); (void)0; __might_fault ("net/sctp/socket.c", 3320); asm volatile("call __get_user_%P4" : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) : "0" ((int * )optval), "i" (sizeof(*((int *)optval)))); (val) = ( __typeof__ (*((int *)optval))) __val_gu; clang_analyzer_taint(&val); __builtin_expect(__ret_gu, 0); })) | |||
3321 | return -EFAULT14; | |||
3322 | ||||
3323 | /* Note: We double the receive buffer from what the user sets | |||
3324 | * it to be, also initial rwnd is based on rcvbuf/2. | |||
3325 | */ | |||
3326 | if (val > (sk->sk_rcvbuf >> 1)) | |||
3327 | return -EINVAL22; | |||
3328 | ||||
3329 | sctp_sk(sk)->pd_point = val; | |||
3330 | ||||
3331 | return 0; /* is this the right error code? */ | |||
3332 | } | |||
3333 | ||||
3334 | /* | |||
3335 | * 7.1.28. Set or Get the maximum burst (SCTP_MAX_BURST) | |||
3336 | * | |||
3337 | * This option will allow a user to change the maximum burst of packets | |||
3338 | * that can be emitted by this association. Note that the default value | |||
3339 | * is 4, and some implementations may restrict this setting so that it | |||
3340 | * can only be lowered. | |||
3341 | * | |||
3342 | * NOTE: This text doesn't seem right. Do this on a socket basis with | |||
3343 | * future associations inheriting the socket value. | |||
3344 | */ | |||
3345 | static int sctp_setsockopt_maxburst(struct sock *sk, | |||
3346 | char __user *optval, | |||
3347 | unsigned int optlen) | |||
3348 | { | |||
3349 | struct sctp_assoc_value params; | |||
3350 | struct sctp_sock *sp; | |||
3351 | struct sctp_association *asoc; | |||
3352 | int val; | |||
3353 | int assoc_id = 0; | |||
3354 | ||||
3355 | if (optlen == sizeof(int)) { | |||
3356 | pr_warn_ratelimited(DEPRECATED({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in max_burst socket option deprecated.\n" "Use struct sctp_assoc_value instead\n", get_current()->comm , task_pid_nr(get_current())); }) | |||
3357 | "%s (pid %d) "({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in max_burst socket option deprecated.\n" "Use struct sctp_assoc_value instead\n", get_current()->comm , task_pid_nr(get_current())); }) | |||
3358 | "Use of int in max_burst socket option deprecated.\n"({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in max_burst socket option deprecated.\n" "Use struct sctp_assoc_value instead\n", get_current()->comm , task_pid_nr(get_current())); }) | |||
3359 | "Use struct sctp_assoc_value instead\n",({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in max_burst socket option deprecated.\n" "Use struct sctp_assoc_value instead\n", get_current()->comm , task_pid_nr(get_current())); }) | |||
3360 | current->comm, task_pid_nr(current))({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in max_burst socket option deprecated.\n" "Use struct sctp_assoc_value instead\n", get_current()->comm , task_pid_nr(get_current())); }); | |||
3361 | if (copy_from_user(&val, optval, optlen)) | |||
3362 | return -EFAULT14; | |||
3363 | } else if (optlen == sizeof(struct sctp_assoc_value)) { | |||
3364 | if (copy_from_user(¶ms, optval, optlen)) | |||
3365 | return -EFAULT14; | |||
3366 | val = params.assoc_value; | |||
3367 | assoc_id = params.assoc_id; | |||
3368 | } else | |||
3369 | return -EINVAL22; | |||
3370 | ||||
3371 | sp = sctp_sk(sk); | |||
3372 | ||||
3373 | if (assoc_id != 0) { | |||
3374 | asoc = sctp_id2assoc(sk, assoc_id); | |||
3375 | if (!asoc) | |||
3376 | return -EINVAL22; | |||
3377 | asoc->max_burst = val; | |||
3378 | } else | |||
3379 | sp->max_burst = val; | |||
3380 | ||||
3381 | return 0; | |||
3382 | } | |||
3383 | ||||
3384 | /* | |||
3385 | * 7.1.18. Add a chunk that must be authenticated (SCTP_AUTH_CHUNK) | |||
3386 | * | |||
3387 | * This set option adds a chunk type that the user is requesting to be | |||
3388 | * received only in an authenticated way. Changes to the list of chunks | |||
3389 | * will only effect future associations on the socket. | |||
3390 | */ | |||
3391 | static int sctp_setsockopt_auth_chunk(struct sock *sk, | |||
3392 | char __user *optval, | |||
3393 | unsigned int optlen) | |||
3394 | { | |||
3395 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; | |||
3396 | struct sctp_authchunk val; | |||
3397 | ||||
3398 | if (!ep->auth_enable) | |||
3399 | return -EACCES13; | |||
3400 | ||||
3401 | if (optlen != sizeof(struct sctp_authchunk)) | |||
3402 | return -EINVAL22; | |||
3403 | if (copy_from_user(&val, optval, optlen)) | |||
3404 | return -EFAULT14; | |||
3405 | ||||
3406 | switch (val.sauth_chunk) { | |||
3407 | case SCTP_CID_INIT: | |||
3408 | case SCTP_CID_INIT_ACK: | |||
3409 | case SCTP_CID_SHUTDOWN_COMPLETE: | |||
3410 | case SCTP_CID_AUTH: | |||
3411 | return -EINVAL22; | |||
3412 | } | |||
3413 | ||||
3414 | /* add this chunk id to the endpoint */ | |||
3415 | return sctp_auth_ep_add_chunkid(ep, val.sauth_chunk); | |||
3416 | } | |||
3417 | ||||
3418 | /* | |||
3419 | * 7.1.19. Get or set the list of supported HMAC Identifiers (SCTP_HMAC_IDENT) | |||
3420 | * | |||
3421 | * This option gets or sets the list of HMAC algorithms that the local | |||
3422 | * endpoint requires the peer to use. | |||
3423 | */ | |||
3424 | static int sctp_setsockopt_hmac_ident(struct sock *sk, | |||
3425 | char __user *optval, | |||
3426 | unsigned int optlen) | |||
3427 | { | |||
3428 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; | |||
3429 | struct sctp_hmacalgo *hmacs; | |||
3430 | u32 idents; | |||
3431 | int err; | |||
3432 | ||||
3433 | if (!ep->auth_enable) | |||
3434 | return -EACCES13; | |||
3435 | ||||
3436 | if (optlen < sizeof(struct sctp_hmacalgo)) | |||
3437 | return -EINVAL22; | |||
3438 | ||||
3439 | hmacs = memdup_user(optval, optlen); | |||
3440 | if (IS_ERR(hmacs)) | |||
3441 | return PTR_ERR(hmacs); | |||
3442 | ||||
3443 | idents = hmacs->shmac_num_idents; | |||
3444 | if (idents == 0 || idents > SCTP_AUTH_NUM_HMACS__SCTP_AUTH_HMAC_MAX || | |||
3445 | (idents * sizeof(u16)) > (optlen - sizeof(struct sctp_hmacalgo))) { | |||
3446 | err = -EINVAL22; | |||
3447 | goto out; | |||
3448 | } | |||
3449 | ||||
3450 | err = sctp_auth_ep_set_hmacs(ep, hmacs); | |||
3451 | out: | |||
3452 | kfree(hmacs); | |||
3453 | return err; | |||
3454 | } | |||
3455 | ||||
3456 | /* | |||
3457 | * 7.1.20. Set a shared key (SCTP_AUTH_KEY) | |||
3458 | * | |||
3459 | * This option will set a shared secret key which is used to build an | |||
3460 | * association shared key. | |||
3461 | */ | |||
3462 | static int sctp_setsockopt_auth_key(struct sock *sk, | |||
3463 | char __user *optval, | |||
3464 | unsigned int optlen) | |||
3465 | { | |||
3466 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; | |||
3467 | struct sctp_authkey *authkey; | |||
3468 | struct sctp_association *asoc; | |||
3469 | int ret; | |||
3470 | ||||
3471 | if (!ep->auth_enable) | |||
3472 | return -EACCES13; | |||
3473 | ||||
3474 | if (optlen <= sizeof(struct sctp_authkey)) | |||
3475 | return -EINVAL22; | |||
3476 | ||||
3477 | authkey = memdup_user(optval, optlen); | |||
3478 | if (IS_ERR(authkey)) | |||
3479 | return PTR_ERR(authkey); | |||
3480 | ||||
3481 | if (authkey->sca_keylength > optlen - sizeof(struct sctp_authkey)) { | |||
3482 | ret = -EINVAL22; | |||
3483 | goto out; | |||
3484 | } | |||
3485 | ||||
3486 | asoc = sctp_id2assoc(sk, authkey->sca_assoc_id); | |||
3487 | if (!asoc && authkey->sca_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) { | |||
3488 | ret = -EINVAL22; | |||
3489 | goto out; | |||
3490 | } | |||
3491 | ||||
3492 | ret = sctp_auth_set_key(ep, asoc, authkey); | |||
3493 | out: | |||
3494 | kzfree(authkey); | |||
3495 | return ret; | |||
3496 | } | |||
3497 | ||||
3498 | /* | |||
3499 | * 7.1.21. Get or set the active shared key (SCTP_AUTH_ACTIVE_KEY) | |||
3500 | * | |||
3501 | * This option will get or set the active shared key to be used to build | |||
3502 | * the association shared key. | |||
3503 | */ | |||
3504 | static int sctp_setsockopt_active_key(struct sock *sk, | |||
3505 | char __user *optval, | |||
3506 | unsigned int optlen) | |||
3507 | { | |||
3508 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; | |||
3509 | struct sctp_authkeyid val; | |||
3510 | struct sctp_association *asoc; | |||
3511 | ||||
3512 | if (!ep->auth_enable) | |||
3513 | return -EACCES13; | |||
3514 | ||||
3515 | if (optlen != sizeof(struct sctp_authkeyid)) | |||
3516 | return -EINVAL22; | |||
3517 | if (copy_from_user(&val, optval, optlen)) | |||
3518 | return -EFAULT14; | |||
3519 | ||||
3520 | asoc = sctp_id2assoc(sk, val.scact_assoc_id); | |||
3521 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
3522 | return -EINVAL22; | |||
3523 | ||||
3524 | return sctp_auth_set_active_key(ep, asoc, val.scact_keynumber); | |||
3525 | } | |||
3526 | ||||
3527 | /* | |||
3528 | * 7.1.22. Delete a shared key (SCTP_AUTH_DELETE_KEY) | |||
3529 | * | |||
3530 | * This set option will delete a shared secret key from use. | |||
3531 | */ | |||
3532 | static int sctp_setsockopt_del_key(struct sock *sk, | |||
3533 | char __user *optval, | |||
3534 | unsigned int optlen) | |||
3535 | { | |||
3536 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; | |||
3537 | struct sctp_authkeyid val; | |||
3538 | struct sctp_association *asoc; | |||
3539 | ||||
3540 | if (!ep->auth_enable) | |||
3541 | return -EACCES13; | |||
3542 | ||||
3543 | if (optlen != sizeof(struct sctp_authkeyid)) | |||
3544 | return -EINVAL22; | |||
3545 | if (copy_from_user(&val, optval, optlen)) | |||
3546 | return -EFAULT14; | |||
3547 | ||||
3548 | asoc = sctp_id2assoc(sk, val.scact_assoc_id); | |||
3549 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
3550 | return -EINVAL22; | |||
3551 | ||||
3552 | return sctp_auth_del_key_id(ep, asoc, val.scact_keynumber); | |||
3553 | ||||
3554 | } | |||
3555 | ||||
3556 | /* | |||
3557 | * 8.1.23 SCTP_AUTO_ASCONF | |||
3558 | * | |||
3559 | * This option will enable or disable the use of the automatic generation of | |||
3560 | * ASCONF chunks to add and delete addresses to an existing association. Note | |||
3561 | * that this option has two caveats namely: a) it only affects sockets that | |||
3562 | * are bound to all addresses available to the SCTP stack, and b) the system | |||
3563 | * administrator may have an overriding control that turns the ASCONF feature | |||
3564 | * off no matter what setting the socket option may have. | |||
3565 | * This option expects an integer boolean flag, where a non-zero value turns on | |||
3566 | * the option, and a zero value turns off the option. | |||
3567 | * Note. In this implementation, socket operation overrides default parameter | |||
3568 | * being set by sysctl as well as FreeBSD implementation | |||
3569 | */ | |||
3570 | static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval, | |||
3571 | unsigned int optlen) | |||
3572 | { | |||
3573 | int val; | |||
3574 | struct sctp_sock *sp = sctp_sk(sk); | |||
3575 | ||||
3576 | if (optlen < sizeof(int)) | |||
3577 | return -EINVAL22; | |||
3578 | if (get_user(val, (int __user *)optval)({ int __ret_gu; register __typeof__(__builtin_choose_expr(sizeof (*((int *)optval)) > sizeof(0UL), 0ULL, 0UL)) __val_gu asm ("%""rdx"); register void *__sp asm("rsp"); (void)0; __might_fault ("net/sctp/socket.c", 3578); asm volatile("call __get_user_%P4" : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) : "0" ((int * )optval), "i" (sizeof(*((int *)optval)))); (val) = ( __typeof__ (*((int *)optval))) __val_gu; clang_analyzer_taint(&val); __builtin_expect(__ret_gu, 0); })) | |||
3579 | return -EFAULT14; | |||
3580 | if (!sctp_is_ep_boundall(sk) && val) | |||
3581 | return -EINVAL22; | |||
3582 | if ((val && sp->do_auto_asconf) || (!val && !sp->do_auto_asconf)) | |||
3583 | return 0; | |||
3584 | ||||
3585 | spin_lock_bh(&sock_net(sk)->sctp.addr_wq_lock); | |||
3586 | if (val == 0 && sp->do_auto_asconf) { | |||
3587 | list_del(&sp->auto_asconf_list); | |||
3588 | sp->do_auto_asconf = 0; | |||
3589 | } else if (val && !sp->do_auto_asconf) { | |||
3590 | list_add_tail(&sp->auto_asconf_list, | |||
3591 | &sock_net(sk)->sctp.auto_asconf_splist); | |||
3592 | sp->do_auto_asconf = 1; | |||
3593 | } | |||
3594 | spin_unlock_bh(&sock_net(sk)->sctp.addr_wq_lock); | |||
3595 | return 0; | |||
3596 | } | |||
3597 | ||||
3598 | /* | |||
3599 | * SCTP_PEER_ADDR_THLDS | |||
3600 | * | |||
3601 | * This option allows us to alter the partially failed threshold for one or all | |||
3602 | * transports in an association. See Section 6.1 of: | |||
3603 | * http://www.ietf.org/id/draft-nishida-tsvwg-sctp-failover-05.txt | |||
3604 | */ | |||
3605 | static int sctp_setsockopt_paddr_thresholds(struct sock *sk, | |||
3606 | char __user *optval, | |||
3607 | unsigned int optlen) | |||
3608 | { | |||
3609 | struct sctp_paddrthlds val; | |||
3610 | struct sctp_transport *trans; | |||
3611 | struct sctp_association *asoc; | |||
3612 | ||||
3613 | if (optlen < sizeof(struct sctp_paddrthlds)) | |||
3614 | return -EINVAL22; | |||
3615 | if (copy_from_user(&val, (struct sctp_paddrthlds __user *)optval, | |||
3616 | sizeof(struct sctp_paddrthlds))) | |||
3617 | return -EFAULT14; | |||
3618 | ||||
3619 | ||||
3620 | if (sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) { | |||
3621 | asoc = sctp_id2assoc(sk, val.spt_assoc_id); | |||
3622 | if (!asoc) | |||
3623 | return -ENOENT2; | |||
3624 | list_for_each_entry(trans, &asoc->peer.transport_addr_list,for (trans = ({ const typeof( ((typeof(*trans) *)0)->transports ) *__mptr = ((&asoc->peer.transport_addr_list)->next ); (typeof(*trans) *)( (char *)__mptr - __builtin_offsetof(typeof (*trans), transports) );}); &trans->transports != (& asoc->peer.transport_addr_list); trans = ({ const typeof( ( (typeof(*(trans)) *)0)->transports ) *__mptr = ((trans)-> transports.next); (typeof(*(trans)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(trans)), transports) );})) | |||
3625 | transports)for (trans = ({ const typeof( ((typeof(*trans) *)0)->transports ) *__mptr = ((&asoc->peer.transport_addr_list)->next ); (typeof(*trans) *)( (char *)__mptr - __builtin_offsetof(typeof (*trans), transports) );}); &trans->transports != (& asoc->peer.transport_addr_list); trans = ({ const typeof( ( (typeof(*(trans)) *)0)->transports ) *__mptr = ((trans)-> transports.next); (typeof(*(trans)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(trans)), transports) );})) { | |||
3626 | if (val.spt_pathmaxrxt) | |||
3627 | trans->pathmaxrxt = val.spt_pathmaxrxt; | |||
3628 | trans->pf_retrans = val.spt_pathpfthld; | |||
3629 | } | |||
3630 | ||||
3631 | if (val.spt_pathmaxrxt) | |||
3632 | asoc->pathmaxrxt = val.spt_pathmaxrxt; | |||
3633 | asoc->pf_retrans = val.spt_pathpfthld; | |||
3634 | } else { | |||
3635 | trans = sctp_addr_id2transport(sk, &val.spt_address, | |||
3636 | val.spt_assoc_id); | |||
3637 | if (!trans) | |||
3638 | return -ENOENT2; | |||
3639 | ||||
3640 | if (val.spt_pathmaxrxt) | |||
3641 | trans->pathmaxrxt = val.spt_pathmaxrxt; | |||
3642 | trans->pf_retrans = val.spt_pathpfthld; | |||
3643 | } | |||
3644 | ||||
3645 | return 0; | |||
3646 | } | |||
3647 | ||||
3648 | static int sctp_setsockopt_recvrcvinfo(struct sock *sk, | |||
3649 | char __user *optval, | |||
3650 | unsigned int optlen) | |||
3651 | { | |||
3652 | int val; | |||
3653 | ||||
3654 | if (optlen < sizeof(int)) | |||
3655 | return -EINVAL22; | |||
3656 | if (get_user(val, (int __user *) optval)({ int __ret_gu; register __typeof__(__builtin_choose_expr(sizeof (*((int *) optval)) > sizeof(0UL), 0ULL, 0UL)) __val_gu asm ("%""rdx"); register void *__sp asm("rsp"); (void)0; __might_fault ("net/sctp/socket.c", 3656); asm volatile("call __get_user_%P4" : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) : "0" ((int * ) optval), "i" (sizeof(*((int *) optval)))); (val) = ( __typeof__ (*((int *) optval))) __val_gu; clang_analyzer_taint(&val) ; __builtin_expect(__ret_gu, 0); })) | |||
3657 | return -EFAULT14; | |||
3658 | ||||
3659 | sctp_sk(sk)->recvrcvinfo = (val == 0) ? 0 : 1; | |||
3660 | ||||
3661 | return 0; | |||
3662 | } | |||
3663 | ||||
3664 | static int sctp_setsockopt_recvnxtinfo(struct sock *sk, | |||
3665 | char __user *optval, | |||
3666 | unsigned int optlen) | |||
3667 | { | |||
3668 | int val; | |||
3669 | ||||
3670 | if (optlen < sizeof(int)) | |||
3671 | return -EINVAL22; | |||
3672 | if (get_user(val, (int __user *) optval)({ int __ret_gu; register __typeof__(__builtin_choose_expr(sizeof (*((int *) optval)) > sizeof(0UL), 0ULL, 0UL)) __val_gu asm ("%""rdx"); register void *__sp asm("rsp"); (void)0; __might_fault ("net/sctp/socket.c", 3672); asm volatile("call __get_user_%P4" : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) : "0" ((int * ) optval), "i" (sizeof(*((int *) optval)))); (val) = ( __typeof__ (*((int *) optval))) __val_gu; clang_analyzer_taint(&val) ; __builtin_expect(__ret_gu, 0); })) | |||
3673 | return -EFAULT14; | |||
3674 | ||||
3675 | sctp_sk(sk)->recvnxtinfo = (val == 0) ? 0 : 1; | |||
3676 | ||||
3677 | return 0; | |||
3678 | } | |||
3679 | ||||
3680 | static int sctp_setsockopt_pr_supported(struct sock *sk, | |||
3681 | char __user *optval, | |||
3682 | unsigned int optlen) | |||
3683 | { | |||
3684 | struct sctp_assoc_value params; | |||
3685 | struct sctp_association *asoc; | |||
3686 | int retval = -EINVAL22; | |||
3687 | ||||
3688 | if (optlen != sizeof(params)) | |||
3689 | goto out; | |||
3690 | ||||
3691 | if (copy_from_user(¶ms, optval, optlen)) { | |||
3692 | retval = -EFAULT14; | |||
3693 | goto out; | |||
3694 | } | |||
3695 | ||||
3696 | asoc = sctp_id2assoc(sk, params.assoc_id); | |||
3697 | if (asoc) { | |||
3698 | asoc->prsctp_enable = !!params.assoc_value; | |||
3699 | } else if (!params.assoc_id) { | |||
3700 | struct sctp_sock *sp = sctp_sk(sk); | |||
3701 | ||||
3702 | sp->ep->prsctp_enable = !!params.assoc_value; | |||
3703 | } else { | |||
3704 | goto out; | |||
3705 | } | |||
3706 | ||||
3707 | retval = 0; | |||
3708 | ||||
3709 | out: | |||
3710 | return retval; | |||
3711 | } | |||
3712 | ||||
3713 | static int sctp_setsockopt_default_prinfo(struct sock *sk, | |||
3714 | char __user *optval, | |||
3715 | unsigned int optlen) | |||
3716 | { | |||
3717 | struct sctp_default_prinfo info; | |||
3718 | struct sctp_association *asoc; | |||
3719 | int retval = -EINVAL22; | |||
3720 | ||||
3721 | if (optlen != sizeof(info)) | |||
3722 | goto out; | |||
3723 | ||||
3724 | if (copy_from_user(&info, optval, sizeof(info))) { | |||
3725 | retval = -EFAULT14; | |||
3726 | goto out; | |||
3727 | } | |||
3728 | ||||
3729 | if (info.pr_policy & ~SCTP_PR_SCTP_MASK0x0030) | |||
3730 | goto out; | |||
3731 | ||||
3732 | if (info.pr_policy == SCTP_PR_SCTP_NONE0x0000) | |||
3733 | info.pr_value = 0; | |||
3734 | ||||
3735 | asoc = sctp_id2assoc(sk, info.pr_assoc_id); | |||
3736 | if (asoc) { | |||
3737 | SCTP_PR_SET_POLICY(asoc->default_flags, info.pr_policy)do { asoc->default_flags &= ~0x0030; asoc->default_flags |= info.pr_policy; } while (0); | |||
3738 | asoc->default_timetolive = info.pr_value; | |||
3739 | } else if (!info.pr_assoc_id) { | |||
3740 | struct sctp_sock *sp = sctp_sk(sk); | |||
3741 | ||||
3742 | SCTP_PR_SET_POLICY(sp->default_flags, info.pr_policy)do { sp->default_flags &= ~0x0030; sp->default_flags |= info.pr_policy; } while (0); | |||
3743 | sp->default_timetolive = info.pr_value; | |||
3744 | } else { | |||
3745 | goto out; | |||
3746 | } | |||
3747 | ||||
3748 | retval = 0; | |||
3749 | ||||
3750 | out: | |||
3751 | return retval; | |||
3752 | } | |||
3753 | ||||
3754 | /* API 6.2 setsockopt(), getsockopt() | |||
3755 | * | |||
3756 | * Applications use setsockopt() and getsockopt() to set or retrieve | |||
3757 | * socket options. Socket options are used to change the default | |||
3758 | * behavior of sockets calls. They are described in Section 7. | |||
3759 | * | |||
3760 | * The syntax is: | |||
3761 | * | |||
3762 | * ret = getsockopt(int sd, int level, int optname, void __user *optval, | |||
3763 | * int __user *optlen); | |||
3764 | * ret = setsockopt(int sd, int level, int optname, const void __user *optval, | |||
3765 | * int optlen); | |||
3766 | * | |||
3767 | * sd - the socket descript. | |||
3768 | * level - set to IPPROTO_SCTP for all SCTP options. | |||
3769 | * optname - the option name. | |||
3770 | * optval - the buffer to store the value of the option. | |||
3771 | * optlen - the size of the buffer. | |||
3772 | */ | |||
3773 | static int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
3774 | char __user *optval, unsigned int optlen) | |||
3775 | { | |||
3776 | int retval = 0; | |||
3777 | ||||
3778 | pr_debug("%s: sk:%p, optname:%d\n", __func__, sk, optname)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, optname:%d\n" ), .lineno = 3778, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, optname:%d\n", __func__, sk, optname); } while ( 0); | |||
3779 | ||||
3780 | /* I can hardly begin to describe how wrong this is. This is | |||
3781 | * so broken as to be worse than useless. The API draft | |||
3782 | * REALLY is NOT helpful here... I am not convinced that the | |||
3783 | * semantics of setsockopt() with a level OTHER THAN SOL_SCTP | |||
3784 | * are at all well-founded. | |||
3785 | */ | |||
3786 | if (level != SOL_SCTP132) { | |||
3787 | struct sctp_af *af = sctp_sk(sk)->pf->af; | |||
3788 | retval = af->setsockopt(sk, level, optname, optval, optlen); | |||
3789 | goto out_nounlock; | |||
3790 | } | |||
3791 | ||||
3792 | lock_sock(sk); | |||
3793 | ||||
3794 | switch (optname) { | |||
3795 | case SCTP_SOCKOPT_BINDX_ADD100: | |||
3796 | /* 'optlen' is the size of the addresses buffer. */ | |||
3797 | retval = sctp_setsockopt_bindx(sk, (struct sockaddr __user *)optval, | |||
3798 | optlen, SCTP_BINDX_ADD_ADDR0x01); | |||
3799 | break; | |||
3800 | ||||
3801 | case SCTP_SOCKOPT_BINDX_REM101: | |||
3802 | /* 'optlen' is the size of the addresses buffer. */ | |||
3803 | retval = sctp_setsockopt_bindx(sk, (struct sockaddr __user *)optval, | |||
3804 | optlen, SCTP_BINDX_REM_ADDR0x02); | |||
3805 | break; | |||
3806 | ||||
3807 | case SCTP_SOCKOPT_CONNECTX_OLD107: | |||
3808 | /* 'optlen' is the size of the addresses buffer. */ | |||
3809 | retval = sctp_setsockopt_connectx_old(sk, | |||
3810 | (struct sockaddr __user *)optval, | |||
3811 | optlen); | |||
3812 | break; | |||
3813 | ||||
3814 | case SCTP_SOCKOPT_CONNECTX110: | |||
3815 | /* 'optlen' is the size of the addresses buffer. */ | |||
3816 | retval = sctp_setsockopt_connectx(sk, | |||
3817 | (struct sockaddr __user *)optval, | |||
3818 | optlen); | |||
3819 | break; | |||
3820 | ||||
3821 | case SCTP_DISABLE_FRAGMENTS8: | |||
3822 | retval = sctp_setsockopt_disable_fragments(sk, optval, optlen); | |||
3823 | break; | |||
3824 | ||||
3825 | case SCTP_EVENTS11: | |||
3826 | retval = sctp_setsockopt_events(sk, optval, optlen); | |||
3827 | break; | |||
3828 | ||||
3829 | case SCTP_AUTOCLOSE4: | |||
3830 | retval = sctp_setsockopt_autoclose(sk, optval, optlen); | |||
3831 | break; | |||
3832 | ||||
3833 | case SCTP_PEER_ADDR_PARAMS9: | |||
3834 | retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen); | |||
3835 | break; | |||
3836 | ||||
3837 | case SCTP_DELAYED_SACK16: | |||
3838 | retval = sctp_setsockopt_delayed_ack(sk, optval, optlen); | |||
3839 | break; | |||
3840 | case SCTP_PARTIAL_DELIVERY_POINT19: | |||
3841 | retval = sctp_setsockopt_partial_delivery_point(sk, optval, optlen); | |||
3842 | break; | |||
3843 | ||||
3844 | case SCTP_INITMSG2: | |||
3845 | retval = sctp_setsockopt_initmsg(sk, optval, optlen); | |||
3846 | break; | |||
3847 | case SCTP_DEFAULT_SEND_PARAM10: | |||
3848 | retval = sctp_setsockopt_default_send_param(sk, optval, | |||
3849 | optlen); | |||
3850 | break; | |||
3851 | case SCTP_DEFAULT_SNDINFO34: | |||
3852 | retval = sctp_setsockopt_default_sndinfo(sk, optval, optlen); | |||
3853 | break; | |||
3854 | case SCTP_PRIMARY_ADDR6: | |||
3855 | retval = sctp_setsockopt_primary_addr(sk, optval, optlen); | |||
3856 | break; | |||
3857 | case SCTP_SET_PEER_PRIMARY_ADDR5: | |||
3858 | retval = sctp_setsockopt_peer_primary_addr(sk, optval, optlen); | |||
3859 | break; | |||
3860 | case SCTP_NODELAY3: | |||
3861 | retval = sctp_setsockopt_nodelay(sk, optval, optlen); | |||
3862 | break; | |||
3863 | case SCTP_RTOINFO0: | |||
3864 | retval = sctp_setsockopt_rtoinfo(sk, optval, optlen); | |||
3865 | break; | |||
3866 | case SCTP_ASSOCINFO1: | |||
3867 | retval = sctp_setsockopt_associnfo(sk, optval, optlen); | |||
3868 | break; | |||
3869 | case SCTP_I_WANT_MAPPED_V4_ADDR12: | |||
3870 | retval = sctp_setsockopt_mappedv4(sk, optval, optlen); | |||
3871 | break; | |||
3872 | case SCTP_MAXSEG13: | |||
3873 | retval = sctp_setsockopt_maxseg(sk, optval, optlen); | |||
3874 | break; | |||
3875 | case SCTP_ADAPTATION_LAYER7: | |||
3876 | retval = sctp_setsockopt_adaptation_layer(sk, optval, optlen); | |||
3877 | break; | |||
3878 | case SCTP_CONTEXT17: | |||
3879 | retval = sctp_setsockopt_context(sk, optval, optlen); | |||
3880 | break; | |||
3881 | case SCTP_FRAGMENT_INTERLEAVE18: | |||
3882 | retval = sctp_setsockopt_fragment_interleave(sk, optval, optlen); | |||
3883 | break; | |||
3884 | case SCTP_MAX_BURST20: | |||
3885 | retval = sctp_setsockopt_maxburst(sk, optval, optlen); | |||
3886 | break; | |||
3887 | case SCTP_AUTH_CHUNK21: | |||
3888 | retval = sctp_setsockopt_auth_chunk(sk, optval, optlen); | |||
3889 | break; | |||
3890 | case SCTP_HMAC_IDENT22: | |||
3891 | retval = sctp_setsockopt_hmac_ident(sk, optval, optlen); | |||
3892 | break; | |||
3893 | case SCTP_AUTH_KEY23: | |||
3894 | retval = sctp_setsockopt_auth_key(sk, optval, optlen); | |||
3895 | break; | |||
3896 | case SCTP_AUTH_ACTIVE_KEY24: | |||
3897 | retval = sctp_setsockopt_active_key(sk, optval, optlen); | |||
3898 | break; | |||
3899 | case SCTP_AUTH_DELETE_KEY25: | |||
3900 | retval = sctp_setsockopt_del_key(sk, optval, optlen); | |||
3901 | break; | |||
3902 | case SCTP_AUTO_ASCONF30: | |||
3903 | retval = sctp_setsockopt_auto_asconf(sk, optval, optlen); | |||
3904 | break; | |||
3905 | case SCTP_PEER_ADDR_THLDS31: | |||
3906 | retval = sctp_setsockopt_paddr_thresholds(sk, optval, optlen); | |||
3907 | break; | |||
3908 | case SCTP_RECVRCVINFO32: | |||
3909 | retval = sctp_setsockopt_recvrcvinfo(sk, optval, optlen); | |||
3910 | break; | |||
3911 | case SCTP_RECVNXTINFO33: | |||
3912 | retval = sctp_setsockopt_recvnxtinfo(sk, optval, optlen); | |||
3913 | break; | |||
3914 | case SCTP_PR_SUPPORTED113: | |||
3915 | retval = sctp_setsockopt_pr_supported(sk, optval, optlen); | |||
3916 | break; | |||
3917 | case SCTP_DEFAULT_PRINFO114: | |||
3918 | retval = sctp_setsockopt_default_prinfo(sk, optval, optlen); | |||
3919 | break; | |||
3920 | default: | |||
3921 | retval = -ENOPROTOOPT92; | |||
3922 | break; | |||
3923 | } | |||
3924 | ||||
3925 | release_sock(sk); | |||
3926 | ||||
3927 | out_nounlock: | |||
3928 | return retval; | |||
3929 | } | |||
3930 | ||||
3931 | /* API 3.1.6 connect() - UDP Style Syntax | |||
3932 | * | |||
3933 | * An application may use the connect() call in the UDP model to initiate an | |||
3934 | * association without sending data. | |||
3935 | * | |||
3936 | * The syntax is: | |||
3937 | * | |||
3938 | * ret = connect(int sd, const struct sockaddr *nam, socklen_t len); | |||
3939 | * | |||
3940 | * sd: the socket descriptor to have a new association added to. | |||
3941 | * | |||
3942 | * nam: the address structure (either struct sockaddr_in or struct | |||
3943 | * sockaddr_in6 defined in RFC2553 [7]). | |||
3944 | * | |||
3945 | * len: the size of the address. | |||
3946 | */ | |||
3947 | static int sctp_connect(struct sock *sk, struct sockaddr *addr, | |||
3948 | int addr_len) | |||
3949 | { | |||
3950 | int err = 0; | |||
3951 | struct sctp_af *af; | |||
3952 | ||||
3953 | lock_sock(sk); | |||
3954 | ||||
3955 | pr_debug("%s: sk:%p, sockaddr:%p, addr_len:%d\n", __func__, sk,do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, sockaddr:%p, addr_len:%d\n" ), .lineno = 3956, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, sockaddr:%p, addr_len:%d\n", __func__, sk, addr, addr_len); } while (0) | |||
3956 | addr, addr_len)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, sockaddr:%p, addr_len:%d\n" ), .lineno = 3956, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, sockaddr:%p, addr_len:%d\n", __func__, sk, addr, addr_len); } while (0); | |||
3957 | ||||
3958 | /* Validate addr_len before calling common connect/connectx routine. */ | |||
3959 | af = sctp_get_af_specific(addr->sa_family); | |||
3960 | if (!af || addr_len < af->sockaddr_len) { | |||
3961 | err = -EINVAL22; | |||
3962 | } else { | |||
3963 | /* Pass correct addr len to common routine (so it knows there | |||
3964 | * is only one address being passed. | |||
3965 | */ | |||
3966 | err = __sctp_connect(sk, addr, af->sockaddr_len, NULL((void *)0)); | |||
3967 | } | |||
3968 | ||||
3969 | release_sock(sk); | |||
3970 | return err; | |||
3971 | } | |||
3972 | ||||
3973 | /* FIXME: Write comments. */ | |||
3974 | static int sctp_disconnect(struct sock *sk, int flags) | |||
3975 | { | |||
3976 | return -EOPNOTSUPP95; /* STUB */ | |||
3977 | } | |||
3978 | ||||
3979 | /* 4.1.4 accept() - TCP Style Syntax | |||
3980 | * | |||
3981 | * Applications use accept() call to remove an established SCTP | |||
3982 | * association from the accept queue of the endpoint. A new socket | |||
3983 | * descriptor will be returned from accept() to represent the newly | |||
3984 | * formed association. | |||
3985 | */ | |||
3986 | static struct sock *sctp_accept(struct sock *sk, int flags, int *err) | |||
3987 | { | |||
3988 | struct sctp_sock *sp; | |||
3989 | struct sctp_endpoint *ep; | |||
3990 | struct sock *newsk = NULL((void *)0); | |||
3991 | struct sctp_association *asoc; | |||
3992 | long timeo; | |||
3993 | int error = 0; | |||
3994 | ||||
3995 | lock_sock(sk); | |||
3996 | ||||
3997 | sp = sctp_sk(sk); | |||
3998 | ep = sp->ep; | |||
3999 | ||||
4000 | if (!sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP))) { | |||
4001 | error = -EOPNOTSUPP95; | |||
4002 | goto out; | |||
4003 | } | |||
4004 | ||||
4005 | if (!sctp_sstate(sk, LISTENING)__sctp_sstate((sk), (SCTP_SS_LISTENING))) { | |||
4006 | error = -EINVAL22; | |||
4007 | goto out; | |||
4008 | } | |||
4009 | ||||
4010 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK00004000); | |||
4011 | ||||
4012 | error = sctp_wait_for_accept(sk, timeo); | |||
4013 | if (error) | |||
4014 | goto out; | |||
4015 | ||||
4016 | /* We treat the list of associations on the endpoint as the accept | |||
4017 | * queue and pick the first association on the list. | |||
4018 | */ | |||
4019 | asoc = list_entry(ep->asocs.next, struct sctp_association, asocs)({ const typeof( ((struct sctp_association *)0)->asocs ) * __mptr = (ep->asocs.next); (struct sctp_association *)( (char *)__mptr - __builtin_offsetof(struct sctp_association, asocs ) );}); | |||
4020 | ||||
4021 | newsk = sp->pf->create_accept_sk(sk, asoc); | |||
4022 | if (!newsk) { | |||
4023 | error = -ENOMEM12; | |||
4024 | goto out; | |||
4025 | } | |||
4026 | ||||
4027 | /* Populate the fields of the newsk from the oldsk and migrate the | |||
4028 | * asoc to the newsk. | |||
4029 | */ | |||
4030 | sctp_sock_migrate(sk, newsk, asoc, SCTP_SOCKET_TCP); | |||
4031 | ||||
4032 | out: | |||
4033 | release_sock(sk); | |||
4034 | *err = error; | |||
4035 | return newsk; | |||
4036 | } | |||
4037 | ||||
4038 | /* The SCTP ioctl handler. */ | |||
4039 | static int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
4040 | { | |||
4041 | int rc = -ENOTCONN107; | |||
4042 | ||||
4043 | lock_sock(sk); | |||
4044 | ||||
4045 | /* | |||
4046 | * SEQPACKET-style sockets in LISTENING state are valid, for | |||
4047 | * SCTP, so only discard TCP-style sockets in LISTENING state. | |||
4048 | */ | |||
4049 | if (sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP)) && sctp_sstate(sk, LISTENING)__sctp_sstate((sk), (SCTP_SS_LISTENING))) | |||
4050 | goto out; | |||
4051 | ||||
4052 | switch (cmd) { | |||
4053 | case SIOCINQ0x541B: { | |||
4054 | struct sk_buff *skb; | |||
4055 | unsigned int amount = 0; | |||
4056 | ||||
4057 | skb = skb_peek(&sk->sk_receive_queue); | |||
4058 | if (skb != NULL((void *)0)) { | |||
4059 | /* | |||
4060 | * We will only return the amount of this packet since | |||
4061 | * that is all that will be read. | |||
4062 | */ | |||
4063 | amount = skb->len; | |||
4064 | } | |||
4065 | rc = put_user(amount, (int __user *)arg)({ int __ret_pu; __typeof__(*((int *)arg)) __pu_val; (void)0; __might_fault("net/sctp/socket.c", 4065); __pu_val = amount; switch (sizeof(*((int *)arg))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*((int *)arg)))(__pu_val )), "c" ((int *)arg) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*((int *)arg)))(__pu_val )), "c" ((int *)arg) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*((int *)arg)))(__pu_val )), "c" ((int *)arg) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*((int *)arg)))(__pu_val )), "c" ((int *)arg) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*((int *)arg)))(__pu_val )), "c" ((int *)arg) : "ebx"); break; } __builtin_expect(__ret_pu , 0); }); | |||
4066 | break; | |||
4067 | } | |||
4068 | default: | |||
4069 | rc = -ENOIOCTLCMD515; | |||
4070 | break; | |||
4071 | } | |||
4072 | out: | |||
4073 | release_sock(sk); | |||
4074 | return rc; | |||
4075 | } | |||
4076 | ||||
4077 | /* This is the function which gets called during socket creation to | |||
4078 | * initialized the SCTP-specific portion of the sock. | |||
4079 | * The sock structure should already be zero-filled memory. | |||
4080 | */ | |||
4081 | static int sctp_init_sock(struct sock *sk) | |||
4082 | { | |||
4083 | struct net *net = sock_net(sk); | |||
4084 | struct sctp_sock *sp; | |||
4085 | ||||
4086 | pr_debug("%s: sk:%p\n", __func__, sk)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p\n" ), .lineno = 4086, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p\n", __func__, sk); } while (0); | |||
4087 | ||||
4088 | sp = sctp_sk(sk); | |||
4089 | ||||
4090 | /* Initialize the SCTP per socket area. */ | |||
4091 | switch (sk->sk_type) { | |||
4092 | case SOCK_SEQPACKET: | |||
4093 | sp->type = SCTP_SOCKET_UDP; | |||
4094 | break; | |||
4095 | case SOCK_STREAM: | |||
4096 | sp->type = SCTP_SOCKET_TCP; | |||
4097 | break; | |||
4098 | default: | |||
4099 | return -ESOCKTNOSUPPORT94; | |||
4100 | } | |||
4101 | ||||
4102 | sk->sk_gso_type = SKB_GSO_SCTP; | |||
4103 | ||||
4104 | /* Initialize default send parameters. These parameters can be | |||
4105 | * modified with the SCTP_DEFAULT_SEND_PARAM socket option. | |||
4106 | */ | |||
4107 | sp->default_stream = 0; | |||
4108 | sp->default_ppid = 0; | |||
4109 | sp->default_flags = 0; | |||
4110 | sp->default_context = 0; | |||
4111 | sp->default_timetolive = 0; | |||
4112 | ||||
4113 | sp->default_rcv_context = 0; | |||
4114 | sp->max_burst = net->sctp.max_burst; | |||
4115 | ||||
4116 | sp->sctp_hmac_alg = net->sctp.sctp_hmac_alg; | |||
4117 | ||||
4118 | /* Initialize default setup parameters. These parameters | |||
4119 | * can be modified with the SCTP_INITMSG socket option or | |||
4120 | * overridden by the SCTP_INIT CMSG. | |||
4121 | */ | |||
4122 | sp->initmsg.sinit_num_ostreams = sctp_max_outstreams(sctp_globals.max_outstreams); | |||
4123 | sp->initmsg.sinit_max_instreams = sctp_max_instreams(sctp_globals.max_instreams); | |||
4124 | sp->initmsg.sinit_max_attempts = net->sctp.max_retrans_init; | |||
4125 | sp->initmsg.sinit_max_init_timeo = net->sctp.rto_max; | |||
4126 | ||||
4127 | /* Initialize default RTO related parameters. These parameters can | |||
4128 | * be modified for with the SCTP_RTOINFO socket option. | |||
4129 | */ | |||
4130 | sp->rtoinfo.srto_initial = net->sctp.rto_initial; | |||
4131 | sp->rtoinfo.srto_max = net->sctp.rto_max; | |||
4132 | sp->rtoinfo.srto_min = net->sctp.rto_min; | |||
4133 | ||||
4134 | /* Initialize default association related parameters. These parameters | |||
4135 | * can be modified with the SCTP_ASSOCINFO socket option. | |||
4136 | */ | |||
4137 | sp->assocparams.sasoc_asocmaxrxt = net->sctp.max_retrans_association; | |||
4138 | sp->assocparams.sasoc_number_peer_destinations = 0; | |||
4139 | sp->assocparams.sasoc_peer_rwnd = 0; | |||
4140 | sp->assocparams.sasoc_local_rwnd = 0; | |||
4141 | sp->assocparams.sasoc_cookie_life = net->sctp.valid_cookie_life; | |||
4142 | ||||
4143 | /* Initialize default event subscriptions. By default, all the | |||
4144 | * options are off. | |||
4145 | */ | |||
4146 | memset(&sp->subscribe, 0, sizeof(struct sctp_event_subscribe)); | |||
4147 | ||||
4148 | /* Default Peer Address Parameters. These defaults can | |||
4149 | * be modified via SCTP_PEER_ADDR_PARAMS | |||
4150 | */ | |||
4151 | sp->hbinterval = net->sctp.hb_interval; | |||
4152 | sp->pathmaxrxt = net->sctp.max_retrans_path; | |||
4153 | sp->pathmtu = 0; /* allow default discovery */ | |||
4154 | sp->sackdelay = net->sctp.sack_timeout; | |||
4155 | sp->sackfreq = 2; | |||
4156 | sp->param_flags = SPP_HB_ENABLE | | |||
4157 | SPP_PMTUD_ENABLE | | |||
4158 | SPP_SACKDELAY_ENABLE; | |||
4159 | ||||
4160 | /* If enabled no SCTP message fragmentation will be performed. | |||
4161 | * Configure through SCTP_DISABLE_FRAGMENTS socket option. | |||
4162 | */ | |||
4163 | sp->disable_fragments = 0; | |||
4164 | ||||
4165 | /* Enable Nagle algorithm by default. */ | |||
4166 | sp->nodelay = 0; | |||
4167 | ||||
4168 | sp->recvrcvinfo = 0; | |||
4169 | sp->recvnxtinfo = 0; | |||
4170 | ||||
4171 | /* Enable by default. */ | |||
4172 | sp->v4mapped = 1; | |||
4173 | ||||
4174 | /* Auto-close idle associations after the configured | |||
4175 | * number of seconds. A value of 0 disables this | |||
4176 | * feature. Configure through the SCTP_AUTOCLOSE socket option, | |||
4177 | * for UDP-style sockets only. | |||
4178 | */ | |||
4179 | sp->autoclose = 0; | |||
4180 | ||||
4181 | /* User specified fragmentation limit. */ | |||
4182 | sp->user_frag = 0; | |||
4183 | ||||
4184 | sp->adaptation_ind = 0; | |||
4185 | ||||
4186 | sp->pf = sctp_get_pf_specific(sk->sk_family__sk_common.skc_family); | |||
4187 | ||||
4188 | /* Control variables for partial data delivery. */ | |||
4189 | atomic_set(&sp->pd_mode, 0); | |||
4190 | skb_queue_head_init(&sp->pd_lobby); | |||
4191 | sp->frag_interleave = 0; | |||
4192 | ||||
4193 | /* Create a per socket endpoint structure. Even if we | |||
4194 | * change the data structure relationships, this may still | |||
4195 | * be useful for storing pre-connect address information. | |||
4196 | */ | |||
4197 | sp->ep = sctp_endpoint_new(sk, GFP_KERNEL((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u))); | |||
4198 | if (!sp->ep) | |||
4199 | return -ENOMEM12; | |||
4200 | ||||
4201 | sp->hmac = NULL((void *)0); | |||
4202 | ||||
4203 | sk->sk_destruct = sctp_destruct_sock; | |||
4204 | ||||
4205 | SCTP_DBG_OBJCNT_INC(sock)atomic_inc(&sctp_dbg_objcnt_sock); | |||
4206 | ||||
4207 | local_bh_disable(); | |||
4208 | percpu_counter_inc(&sctp_sockets_allocated); | |||
4209 | sock_prot_inuse_add(net, sk->sk_prot__sk_common.skc_prot, 1); | |||
4210 | ||||
4211 | /* Nothing can fail after this block, otherwise | |||
4212 | * sctp_destroy_sock() will be called without addr_wq_lock held | |||
4213 | */ | |||
4214 | if (net->sctp.default_auto_asconf) { | |||
4215 | spin_lock(&sock_net(sk)->sctp.addr_wq_lock); | |||
4216 | list_add_tail(&sp->auto_asconf_list, | |||
4217 | &net->sctp.auto_asconf_splist); | |||
4218 | sp->do_auto_asconf = 1; | |||
4219 | spin_unlock(&sock_net(sk)->sctp.addr_wq_lock); | |||
4220 | } else { | |||
4221 | sp->do_auto_asconf = 0; | |||
4222 | } | |||
4223 | ||||
4224 | local_bh_enable(); | |||
4225 | ||||
4226 | return 0; | |||
4227 | } | |||
4228 | ||||
4229 | /* Cleanup any SCTP per socket resources. Must be called with | |||
4230 | * sock_net(sk)->sctp.addr_wq_lock held if sp->do_auto_asconf is true | |||
4231 | */ | |||
4232 | static void sctp_destroy_sock(struct sock *sk) | |||
4233 | { | |||
4234 | struct sctp_sock *sp; | |||
4235 | ||||
4236 | pr_debug("%s: sk:%p\n", __func__, sk)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p\n" ), .lineno = 4236, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p\n", __func__, sk); } while (0); | |||
4237 | ||||
4238 | /* Release our hold on the endpoint. */ | |||
4239 | sp = sctp_sk(sk); | |||
4240 | /* This could happen during socket init, thus we bail out | |||
4241 | * early, since the rest of the below is not setup either. | |||
4242 | */ | |||
4243 | if (sp->ep == NULL((void *)0)) | |||
4244 | return; | |||
4245 | ||||
4246 | if (sp->do_auto_asconf) { | |||
4247 | sp->do_auto_asconf = 0; | |||
4248 | list_del(&sp->auto_asconf_list); | |||
4249 | } | |||
4250 | sctp_endpoint_free(sp->ep); | |||
4251 | local_bh_disable(); | |||
4252 | percpu_counter_dec(&sctp_sockets_allocated); | |||
4253 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot__sk_common.skc_prot, -1); | |||
4254 | local_bh_enable(); | |||
4255 | } | |||
4256 | ||||
4257 | /* Triggered when there are no references on the socket anymore */ | |||
4258 | static void sctp_destruct_sock(struct sock *sk) | |||
4259 | { | |||
4260 | struct sctp_sock *sp = sctp_sk(sk); | |||
4261 | ||||
4262 | /* Free up the HMAC transform. */ | |||
4263 | crypto_free_shash(sp->hmac); | |||
4264 | ||||
4265 | inet_sock_destruct(sk); | |||
4266 | } | |||
4267 | ||||
4268 | /* API 4.1.7 shutdown() - TCP Style Syntax | |||
4269 | * int shutdown(int socket, int how); | |||
4270 | * | |||
4271 | * sd - the socket descriptor of the association to be closed. | |||
4272 | * how - Specifies the type of shutdown. The values are | |||
4273 | * as follows: | |||
4274 | * SHUT_RD | |||
4275 | * Disables further receive operations. No SCTP | |||
4276 | * protocol action is taken. | |||
4277 | * SHUT_WR | |||
4278 | * Disables further send operations, and initiates | |||
4279 | * the SCTP shutdown sequence. | |||
4280 | * SHUT_RDWR | |||
4281 | * Disables further send and receive operations | |||
4282 | * and initiates the SCTP shutdown sequence. | |||
4283 | */ | |||
4284 | static void sctp_shutdown(struct sock *sk, int how) | |||
4285 | { | |||
4286 | struct net *net = sock_net(sk); | |||
4287 | struct sctp_endpoint *ep; | |||
4288 | ||||
4289 | if (!sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP))) | |||
4290 | return; | |||
4291 | ||||
4292 | ep = sctp_sk(sk)->ep; | |||
4293 | if (how & SEND_SHUTDOWN2 && !list_empty(&ep->asocs)) { | |||
4294 | struct sctp_association *asoc; | |||
4295 | ||||
4296 | sk->sk_state__sk_common.skc_state = SCTP_SS_CLOSING; | |||
4297 | asoc = list_entry(ep->asocs.next,({ const typeof( ((struct sctp_association *)0)->asocs ) * __mptr = (ep->asocs.next); (struct sctp_association *)( (char *)__mptr - __builtin_offsetof(struct sctp_association, asocs ) );}) | |||
4298 | struct sctp_association, asocs)({ const typeof( ((struct sctp_association *)0)->asocs ) * __mptr = (ep->asocs.next); (struct sctp_association *)( (char *)__mptr - __builtin_offsetof(struct sctp_association, asocs ) );}); | |||
4299 | sctp_primitive_SHUTDOWN(net, asoc, NULL((void *)0)); | |||
4300 | } | |||
4301 | } | |||
4302 | ||||
4303 | int sctp_get_sctp_info(struct sock *sk, struct sctp_association *asoc, | |||
4304 | struct sctp_info *info) | |||
4305 | { | |||
4306 | struct sctp_transport *prim; | |||
4307 | struct list_head *pos; | |||
4308 | int mask; | |||
4309 | ||||
4310 | memset(info, 0, sizeof(*info)); | |||
4311 | if (!asoc) { | |||
4312 | struct sctp_sock *sp = sctp_sk(sk); | |||
4313 | ||||
4314 | info->sctpi_s_autoclose = sp->autoclose; | |||
4315 | info->sctpi_s_adaptation_ind = sp->adaptation_ind; | |||
4316 | info->sctpi_s_pd_point = sp->pd_point; | |||
4317 | info->sctpi_s_nodelay = sp->nodelay; | |||
4318 | info->sctpi_s_disable_fragments = sp->disable_fragments; | |||
4319 | info->sctpi_s_v4mapped = sp->v4mapped; | |||
4320 | info->sctpi_s_frag_interleave = sp->frag_interleave; | |||
4321 | info->sctpi_s_type = sp->type; | |||
4322 | ||||
4323 | return 0; | |||
4324 | } | |||
4325 | ||||
4326 | info->sctpi_tag = asoc->c.my_vtag; | |||
4327 | info->sctpi_state = asoc->state; | |||
4328 | info->sctpi_rwnd = asoc->a_rwnd; | |||
4329 | info->sctpi_unackdata = asoc->unack_data; | |||
4330 | info->sctpi_penddata = sctp_tsnmap_pending(&asoc->peer.tsn_map); | |||
4331 | info->sctpi_instrms = asoc->c.sinit_max_instreams; | |||
4332 | info->sctpi_outstrms = asoc->c.sinit_num_ostreams; | |||
4333 | list_for_each(pos, &asoc->base.inqueue.in_chunk_list)for (pos = (&asoc->base.inqueue.in_chunk_list)->next ; pos != (&asoc->base.inqueue.in_chunk_list); pos = pos ->next) | |||
4334 | info->sctpi_inqueue++; | |||
4335 | list_for_each(pos, &asoc->outqueue.out_chunk_list)for (pos = (&asoc->outqueue.out_chunk_list)->next; pos != (&asoc->outqueue.out_chunk_list); pos = pos->next ) | |||
4336 | info->sctpi_outqueue++; | |||
4337 | info->sctpi_overall_error = asoc->overall_error_count; | |||
4338 | info->sctpi_max_burst = asoc->max_burst; | |||
4339 | info->sctpi_maxseg = asoc->frag_point; | |||
4340 | info->sctpi_peer_rwnd = asoc->peer.rwnd; | |||
4341 | info->sctpi_peer_tag = asoc->c.peer_vtag; | |||
4342 | ||||
4343 | mask = asoc->peer.ecn_capable << 1; | |||
4344 | mask = (mask | asoc->peer.ipv4_address) << 1; | |||
4345 | mask = (mask | asoc->peer.ipv6_address) << 1; | |||
4346 | mask = (mask | asoc->peer.hostname_address) << 1; | |||
4347 | mask = (mask | asoc->peer.asconf_capable) << 1; | |||
4348 | mask = (mask | asoc->peer.prsctp_capable) << 1; | |||
4349 | mask = (mask | asoc->peer.auth_capable); | |||
4350 | info->sctpi_peer_capable = mask; | |||
4351 | mask = asoc->peer.sack_needed << 1; | |||
4352 | mask = (mask | asoc->peer.sack_generation) << 1; | |||
4353 | mask = (mask | asoc->peer.zero_window_announced); | |||
4354 | info->sctpi_peer_sack = mask; | |||
4355 | ||||
4356 | info->sctpi_isacks = asoc->stats.isacks; | |||
4357 | info->sctpi_osacks = asoc->stats.osacks; | |||
4358 | info->sctpi_opackets = asoc->stats.opackets; | |||
4359 | info->sctpi_ipackets = asoc->stats.ipackets; | |||
4360 | info->sctpi_rtxchunks = asoc->stats.rtxchunks; | |||
4361 | info->sctpi_outofseqtsns = asoc->stats.outofseqtsns; | |||
4362 | info->sctpi_idupchunks = asoc->stats.idupchunks; | |||
4363 | info->sctpi_gapcnt = asoc->stats.gapcnt; | |||
4364 | info->sctpi_ouodchunks = asoc->stats.ouodchunks; | |||
4365 | info->sctpi_iuodchunks = asoc->stats.iuodchunks; | |||
4366 | info->sctpi_oodchunks = asoc->stats.oodchunks; | |||
4367 | info->sctpi_iodchunks = asoc->stats.iodchunks; | |||
4368 | info->sctpi_octrlchunks = asoc->stats.octrlchunks; | |||
4369 | info->sctpi_ictrlchunks = asoc->stats.ictrlchunks; | |||
4370 | ||||
4371 | prim = asoc->peer.primary_path; | |||
4372 | memcpy(&info->sctpi_p_address, &prim->ipaddr,({ size_t __len = (sizeof(struct __kernel_sockaddr_storage)); void *__ret; if (__builtin_constant_p(sizeof(struct __kernel_sockaddr_storage )) && __len >= 64) __ret = __memcpy((&info-> sctpi_p_address), (&prim->ipaddr), __len); else __ret = __builtin_memcpy((&info->sctpi_p_address), (&prim ->ipaddr), __len); __ret; }) | |||
4373 | sizeof(struct sockaddr_storage))({ size_t __len = (sizeof(struct __kernel_sockaddr_storage)); void *__ret; if (__builtin_constant_p(sizeof(struct __kernel_sockaddr_storage )) && __len >= 64) __ret = __memcpy((&info-> sctpi_p_address), (&prim->ipaddr), __len); else __ret = __builtin_memcpy((&info->sctpi_p_address), (&prim ->ipaddr), __len); __ret; }); | |||
4374 | info->sctpi_p_state = prim->state; | |||
4375 | info->sctpi_p_cwnd = prim->cwnd; | |||
4376 | info->sctpi_p_srtt = prim->srtt; | |||
4377 | info->sctpi_p_rto = jiffies_to_msecs(prim->rto); | |||
4378 | info->sctpi_p_hbinterval = prim->hbinterval; | |||
4379 | info->sctpi_p_pathmaxrxt = prim->pathmaxrxt; | |||
4380 | info->sctpi_p_sackdelay = jiffies_to_msecs(prim->sackdelay); | |||
4381 | info->sctpi_p_ssthresh = prim->ssthresh; | |||
4382 | info->sctpi_p_partial_bytes_acked = prim->partial_bytes_acked; | |||
4383 | info->sctpi_p_flight_size = prim->flight_size; | |||
4384 | info->sctpi_p_error = prim->error_count; | |||
4385 | ||||
4386 | return 0; | |||
4387 | } | |||
4388 | EXPORT_SYMBOL_GPL(sctp_get_sctp_info)extern typeof(sctp_get_sctp_info) sctp_get_sctp_info; extern void *__crc_sctp_get_sctp_info __attribute__((weak)); static const unsigned long __kcrctab_sctp_get_sctp_info __attribute__((__used__ )) __attribute__((section("___kcrctab" "_gpl" "+" "sctp_get_sctp_info" ), used)) = (unsigned long) &__crc_sctp_get_sctp_info; static const char __kstrtab_sctp_get_sctp_info[] __attribute__((section ("__ksymtab_strings"), aligned(1))) = "sctp_get_sctp_info"; static const struct kernel_symbol __ksymtab_sctp_get_sctp_info __attribute__ ((__used__)) __attribute__((section("___ksymtab" "_gpl" "+" "sctp_get_sctp_info" ), used)) = { (unsigned long)&sctp_get_sctp_info, __kstrtab_sctp_get_sctp_info }; | |||
4389 | ||||
4390 | /* use callback to avoid exporting the core structure */ | |||
4391 | int sctp_transport_walk_start(struct rhashtable_iter *iter) | |||
4392 | { | |||
4393 | int err; | |||
4394 | ||||
4395 | err = rhashtable_walk_init(&sctp_transport_hashtable(sctp_globals.transport_hashtable), iter, | |||
4396 | GFP_KERNEL((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u))); | |||
4397 | if (err) | |||
4398 | return err; | |||
4399 | ||||
4400 | err = rhashtable_walk_start(iter); | |||
4401 | if (err && err != -EAGAIN11) { | |||
4402 | rhashtable_walk_stop(iter); | |||
4403 | rhashtable_walk_exit(iter); | |||
4404 | return err; | |||
4405 | } | |||
4406 | ||||
4407 | return 0; | |||
4408 | } | |||
4409 | ||||
4410 | void sctp_transport_walk_stop(struct rhashtable_iter *iter) | |||
4411 | { | |||
4412 | rhashtable_walk_stop(iter); | |||
4413 | rhashtable_walk_exit(iter); | |||
4414 | } | |||
4415 | ||||
4416 | struct sctp_transport *sctp_transport_get_next(struct net *net, | |||
4417 | struct rhashtable_iter *iter) | |||
4418 | { | |||
4419 | struct sctp_transport *t; | |||
4420 | ||||
4421 | t = rhashtable_walk_next(iter); | |||
4422 | for (; t; t = rhashtable_walk_next(iter)) { | |||
4423 | if (IS_ERR(t)) { | |||
4424 | if (PTR_ERR(t) == -EAGAIN11) | |||
4425 | continue; | |||
4426 | break; | |||
4427 | } | |||
4428 | ||||
4429 | if (net_eq(sock_net(t->asoc->base.sk), net) && | |||
4430 | t->asoc->peer.primary_path == t) | |||
4431 | break; | |||
4432 | } | |||
4433 | ||||
4434 | return t; | |||
4435 | } | |||
4436 | ||||
4437 | struct sctp_transport *sctp_transport_get_idx(struct net *net, | |||
4438 | struct rhashtable_iter *iter, | |||
4439 | int pos) | |||
4440 | { | |||
4441 | void *obj = SEQ_START_TOKEN((void *)1); | |||
4442 | ||||
4443 | while (pos && (obj = sctp_transport_get_next(net, iter)) && | |||
4444 | !IS_ERR(obj)) | |||
4445 | pos--; | |||
4446 | ||||
4447 | return obj; | |||
4448 | } | |||
4449 | ||||
4450 | int sctp_for_each_endpoint(int (*cb)(struct sctp_endpoint *, void *), | |||
4451 | void *p) { | |||
4452 | int err = 0; | |||
4453 | int hash = 0; | |||
4454 | struct sctp_ep_common *epb; | |||
4455 | struct sctp_hashbucket *head; | |||
4456 | ||||
4457 | for (head = sctp_ep_hashtable(sctp_globals.ep_hashtable); hash < sctp_ep_hashsize(sctp_globals.ep_hashsize); | |||
4458 | hash++, head++) { | |||
4459 | read_lock(&head->lock)_raw_read_lock(&head->lock); | |||
4460 | sctp_for_each_hentry(epb, &head->chain)for (epb = ({ typeof((&head->chain)->first) ____ptr = ((&head->chain)->first); ____ptr ? ({ const typeof ( ((typeof(*(epb)) *)0)->node ) *__mptr = (____ptr); (typeof (*(epb)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(epb )), node) );}) : ((void *)0); }); epb; epb = ({ typeof((epb)-> node.next) ____ptr = ((epb)->node.next); ____ptr ? ({ const typeof( ((typeof(*(epb)) *)0)->node ) *__mptr = (____ptr) ; (typeof(*(epb)) *)( (char *)__mptr - __builtin_offsetof(typeof (*(epb)), node) );}) : ((void *)0); })) { | |||
4461 | err = cb(sctp_ep(epb), p); | |||
4462 | if (err) | |||
4463 | break; | |||
4464 | } | |||
4465 | read_unlock(&head->lock)_raw_read_unlock(&head->lock); | |||
4466 | } | |||
4467 | ||||
4468 | return err; | |||
4469 | } | |||
4470 | EXPORT_SYMBOL_GPL(sctp_for_each_endpoint)extern typeof(sctp_for_each_endpoint) sctp_for_each_endpoint; extern void *__crc_sctp_for_each_endpoint __attribute__((weak )); static const unsigned long __kcrctab_sctp_for_each_endpoint __attribute__((__used__)) __attribute__((section("___kcrctab" "_gpl" "+" "sctp_for_each_endpoint"), used)) = (unsigned long ) &__crc_sctp_for_each_endpoint; static const char __kstrtab_sctp_for_each_endpoint [] __attribute__((section("__ksymtab_strings"), aligned(1))) = "sctp_for_each_endpoint"; static const struct kernel_symbol __ksymtab_sctp_for_each_endpoint __attribute__((__used__)) __attribute__((section("___ksymtab" "_gpl" "+" "sctp_for_each_endpoint"), used)) = { (unsigned long )&sctp_for_each_endpoint, __kstrtab_sctp_for_each_endpoint }; | |||
4471 | ||||
4472 | int sctp_transport_lookup_process(int (*cb)(struct sctp_transport *, void *), | |||
4473 | struct net *net, | |||
4474 | const union sctp_addr *laddr, | |||
4475 | const union sctp_addr *paddr, void *p) | |||
4476 | { | |||
4477 | struct sctp_transport *transport; | |||
4478 | int err = -ENOENT2; | |||
4479 | ||||
4480 | rcu_read_lock(); | |||
4481 | transport = sctp_addrs_lookup_transport(net, laddr, paddr); | |||
4482 | if (!transport || !sctp_transport_hold(transport)) | |||
4483 | goto out; | |||
4484 | ||||
4485 | rcu_read_unlock(); | |||
4486 | err = cb(transport, p); | |||
4487 | sctp_transport_put(transport); | |||
4488 | ||||
4489 | out: | |||
4490 | return err; | |||
4491 | } | |||
4492 | EXPORT_SYMBOL_GPL(sctp_transport_lookup_process)extern typeof(sctp_transport_lookup_process) sctp_transport_lookup_process ; extern void *__crc_sctp_transport_lookup_process __attribute__ ((weak)); static const unsigned long __kcrctab_sctp_transport_lookup_process __attribute__((__used__)) __attribute__((section("___kcrctab" "_gpl" "+" "sctp_transport_lookup_process"), used)) = (unsigned long) &__crc_sctp_transport_lookup_process; static const char __kstrtab_sctp_transport_lookup_process[] __attribute__ ((section("__ksymtab_strings"), aligned(1))) = "sctp_transport_lookup_process" ; static const struct kernel_symbol __ksymtab_sctp_transport_lookup_process __attribute__((__used__)) __attribute__((section("___ksymtab" "_gpl" "+" "sctp_transport_lookup_process"), used)) = { (unsigned long)&sctp_transport_lookup_process, __kstrtab_sctp_transport_lookup_process }; | |||
4493 | ||||
4494 | int sctp_for_each_transport(int (*cb)(struct sctp_transport *, void *), | |||
4495 | struct net *net, int pos, void *p) { | |||
4496 | struct rhashtable_iter hti; | |||
4497 | void *obj; | |||
4498 | int err; | |||
4499 | ||||
4500 | err = sctp_transport_walk_start(&hti); | |||
4501 | if (err) | |||
4502 | return err; | |||
4503 | ||||
4504 | sctp_transport_get_idx(net, &hti, pos); | |||
4505 | obj = sctp_transport_get_next(net, &hti); | |||
4506 | for (; obj && !IS_ERR(obj); obj = sctp_transport_get_next(net, &hti)) { | |||
4507 | struct sctp_transport *transport = obj; | |||
4508 | ||||
4509 | if (!sctp_transport_hold(transport)) | |||
4510 | continue; | |||
4511 | err = cb(transport, p); | |||
4512 | sctp_transport_put(transport); | |||
4513 | if (err) | |||
4514 | break; | |||
4515 | } | |||
4516 | sctp_transport_walk_stop(&hti); | |||
4517 | ||||
4518 | return err; | |||
4519 | } | |||
4520 | EXPORT_SYMBOL_GPL(sctp_for_each_transport)extern typeof(sctp_for_each_transport) sctp_for_each_transport ; extern void *__crc_sctp_for_each_transport __attribute__((weak )); static const unsigned long __kcrctab_sctp_for_each_transport __attribute__((__used__)) __attribute__((section("___kcrctab" "_gpl" "+" "sctp_for_each_transport"), used)) = (unsigned long ) &__crc_sctp_for_each_transport; static const char __kstrtab_sctp_for_each_transport [] __attribute__((section("__ksymtab_strings"), aligned(1))) = "sctp_for_each_transport"; static const struct kernel_symbol __ksymtab_sctp_for_each_transport __attribute__((__used__)) __attribute__ ((section("___ksymtab" "_gpl" "+" "sctp_for_each_transport"), used)) = { (unsigned long)&sctp_for_each_transport, __kstrtab_sctp_for_each_transport }; | |||
4521 | ||||
4522 | /* 7.2.1 Association Status (SCTP_STATUS) | |||
4523 | ||||
4524 | * Applications can retrieve current status information about an | |||
4525 | * association, including association state, peer receiver window size, | |||
4526 | * number of unacked data chunks, and number of data chunks pending | |||
4527 | * receipt. This information is read-only. | |||
4528 | */ | |||
4529 | static int sctp_getsockopt_sctp_status(struct sock *sk, int len, | |||
4530 | char __user *optval, | |||
4531 | int __user *optlen) | |||
4532 | { | |||
4533 | struct sctp_status status; | |||
4534 | struct sctp_association *asoc = NULL((void *)0); | |||
4535 | struct sctp_transport *transport; | |||
4536 | sctp_assoc_t associd; | |||
4537 | int retval = 0; | |||
4538 | ||||
4539 | if (len < sizeof(status)) { | |||
4540 | retval = -EINVAL22; | |||
4541 | goto out; | |||
4542 | } | |||
4543 | ||||
4544 | len = sizeof(status); | |||
4545 | if (copy_from_user(&status, optval, len)) { | |||
4546 | retval = -EFAULT14; | |||
4547 | goto out; | |||
4548 | } | |||
4549 | ||||
4550 | associd = status.sstat_assoc_id; | |||
4551 | asoc = sctp_id2assoc(sk, associd); | |||
4552 | if (!asoc) { | |||
4553 | retval = -EINVAL22; | |||
4554 | goto out; | |||
4555 | } | |||
4556 | ||||
4557 | transport = asoc->peer.primary_path; | |||
4558 | ||||
4559 | status.sstat_assoc_id = sctp_assoc2id(asoc); | |||
4560 | status.sstat_state = sctp_assoc_to_state(asoc); | |||
4561 | status.sstat_rwnd = asoc->peer.rwnd; | |||
4562 | status.sstat_unackdata = asoc->unack_data; | |||
4563 | ||||
4564 | status.sstat_penddata = sctp_tsnmap_pending(&asoc->peer.tsn_map); | |||
4565 | status.sstat_instrms = asoc->c.sinit_max_instreams; | |||
4566 | status.sstat_outstrms = asoc->c.sinit_num_ostreams; | |||
4567 | status.sstat_fragmentation_point = asoc->frag_point; | |||
4568 | status.sstat_primary.spinfo_assoc_id = sctp_assoc2id(transport->asoc); | |||
4569 | memcpy(&status.sstat_primary.spinfo_address, &transport->ipaddr,({ size_t __len = (transport->af_specific->sockaddr_len ); void *__ret; if (__builtin_constant_p(transport->af_specific ->sockaddr_len) && __len >= 64) __ret = __memcpy ((&status.sstat_primary.spinfo_address), (&transport-> ipaddr), __len); else __ret = __builtin_memcpy((&status.sstat_primary .spinfo_address), (&transport->ipaddr), __len); __ret; }) | |||
4570 | transport->af_specific->sockaddr_len)({ size_t __len = (transport->af_specific->sockaddr_len ); void *__ret; if (__builtin_constant_p(transport->af_specific ->sockaddr_len) && __len >= 64) __ret = __memcpy ((&status.sstat_primary.spinfo_address), (&transport-> ipaddr), __len); else __ret = __builtin_memcpy((&status.sstat_primary .spinfo_address), (&transport->ipaddr), __len); __ret; }); | |||
4571 | /* Map ipv4 address into v4-mapped-on-v6 address. */ | |||
4572 | sctp_get_pf_specific(sk->sk_family__sk_common.skc_family)->addr_to_user(sctp_sk(sk), | |||
4573 | (union sctp_addr *)&status.sstat_primary.spinfo_address); | |||
4574 | status.sstat_primary.spinfo_state = transport->state; | |||
4575 | status.sstat_primary.spinfo_cwnd = transport->cwnd; | |||
4576 | status.sstat_primary.spinfo_srtt = transport->srtt; | |||
4577 | status.sstat_primary.spinfo_rto = jiffies_to_msecs(transport->rto); | |||
4578 | status.sstat_primary.spinfo_mtu = transport->pathmtu; | |||
4579 | ||||
4580 | if (status.sstat_primary.spinfo_state == SCTP_UNKNOWN) | |||
4581 | status.sstat_primary.spinfo_state = SCTP_ACTIVE; | |||
4582 | ||||
4583 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 4583); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) { | |||
4584 | retval = -EFAULT14; | |||
4585 | goto out; | |||
4586 | } | |||
4587 | ||||
4588 | pr_debug("%s: len:%d, state:%d, rwnd:%d, assoc_id:%d\n",do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: len:%d, state:%d, rwnd:%d, assoc_id:%d\n" ), .lineno = 4590, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: len:%d, state:%d, rwnd:%d, assoc_id:%d\n", __func__, len , status.sstat_state, status.sstat_rwnd, status.sstat_assoc_id ); } while (0) | |||
4589 | __func__, len, status.sstat_state, status.sstat_rwnd,do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: len:%d, state:%d, rwnd:%d, assoc_id:%d\n" ), .lineno = 4590, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: len:%d, state:%d, rwnd:%d, assoc_id:%d\n", __func__, len , status.sstat_state, status.sstat_rwnd, status.sstat_assoc_id ); } while (0) | |||
4590 | status.sstat_assoc_id)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: len:%d, state:%d, rwnd:%d, assoc_id:%d\n" ), .lineno = 4590, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: len:%d, state:%d, rwnd:%d, assoc_id:%d\n", __func__, len , status.sstat_state, status.sstat_rwnd, status.sstat_assoc_id ); } while (0); | |||
4591 | ||||
4592 | if (copy_to_user(optval, &status, len)) { | |||
4593 | retval = -EFAULT14; | |||
4594 | goto out; | |||
4595 | } | |||
4596 | ||||
4597 | out: | |||
4598 | return retval; | |||
4599 | } | |||
4600 | ||||
4601 | ||||
4602 | /* 7.2.2 Peer Address Information (SCTP_GET_PEER_ADDR_INFO) | |||
4603 | * | |||
4604 | * Applications can retrieve information about a specific peer address | |||
4605 | * of an association, including its reachability state, congestion | |||
4606 | * window, and retransmission timer values. This information is | |||
4607 | * read-only. | |||
4608 | */ | |||
4609 | static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len, | |||
4610 | char __user *optval, | |||
4611 | int __user *optlen) | |||
4612 | { | |||
4613 | struct sctp_paddrinfo pinfo; | |||
4614 | struct sctp_transport *transport; | |||
4615 | int retval = 0; | |||
4616 | ||||
4617 | if (len < sizeof(pinfo)) { | |||
4618 | retval = -EINVAL22; | |||
4619 | goto out; | |||
4620 | } | |||
4621 | ||||
4622 | len = sizeof(pinfo); | |||
4623 | if (copy_from_user(&pinfo, optval, len)) { | |||
4624 | retval = -EFAULT14; | |||
4625 | goto out; | |||
4626 | } | |||
4627 | ||||
4628 | transport = sctp_addr_id2transport(sk, &pinfo.spinfo_address, | |||
4629 | pinfo.spinfo_assoc_id); | |||
4630 | if (!transport) | |||
4631 | return -EINVAL22; | |||
4632 | ||||
4633 | pinfo.spinfo_assoc_id = sctp_assoc2id(transport->asoc); | |||
4634 | pinfo.spinfo_state = transport->state; | |||
4635 | pinfo.spinfo_cwnd = transport->cwnd; | |||
4636 | pinfo.spinfo_srtt = transport->srtt; | |||
4637 | pinfo.spinfo_rto = jiffies_to_msecs(transport->rto); | |||
4638 | pinfo.spinfo_mtu = transport->pathmtu; | |||
4639 | ||||
4640 | if (pinfo.spinfo_state == SCTP_UNKNOWN) | |||
4641 | pinfo.spinfo_state = SCTP_ACTIVE; | |||
4642 | ||||
4643 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 4643); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) { | |||
4644 | retval = -EFAULT14; | |||
4645 | goto out; | |||
4646 | } | |||
4647 | ||||
4648 | if (copy_to_user(optval, &pinfo, len)) { | |||
4649 | retval = -EFAULT14; | |||
4650 | goto out; | |||
4651 | } | |||
4652 | ||||
4653 | out: | |||
4654 | return retval; | |||
4655 | } | |||
4656 | ||||
4657 | /* 7.1.12 Enable/Disable message fragmentation (SCTP_DISABLE_FRAGMENTS) | |||
4658 | * | |||
4659 | * This option is a on/off flag. If enabled no SCTP message | |||
4660 | * fragmentation will be performed. Instead if a message being sent | |||
4661 | * exceeds the current PMTU size, the message will NOT be sent and | |||
4662 | * instead a error will be indicated to the user. | |||
4663 | */ | |||
4664 | static int sctp_getsockopt_disable_fragments(struct sock *sk, int len, | |||
4665 | char __user *optval, int __user *optlen) | |||
4666 | { | |||
4667 | int val; | |||
4668 | ||||
4669 | if (len < sizeof(int)) | |||
4670 | return -EINVAL22; | |||
4671 | ||||
4672 | len = sizeof(int); | |||
4673 | val = (sctp_sk(sk)->disable_fragments == 1); | |||
4674 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 4674); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
4675 | return -EFAULT14; | |||
4676 | if (copy_to_user(optval, &val, len)) | |||
4677 | return -EFAULT14; | |||
4678 | return 0; | |||
4679 | } | |||
4680 | ||||
4681 | /* 7.1.15 Set notification and ancillary events (SCTP_EVENTS) | |||
4682 | * | |||
4683 | * This socket option is used to specify various notifications and | |||
4684 | * ancillary data the user wishes to receive. | |||
4685 | */ | |||
4686 | static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, | |||
4687 | int __user *optlen) | |||
4688 | { | |||
4689 | if (len == 0) | |||
4690 | return -EINVAL22; | |||
4691 | if (len > sizeof(struct sctp_event_subscribe)) | |||
4692 | len = sizeof(struct sctp_event_subscribe); | |||
4693 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 4693); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
4694 | return -EFAULT14; | |||
4695 | if (copy_to_user(optval, &sctp_sk(sk)->subscribe, len)) | |||
4696 | return -EFAULT14; | |||
4697 | return 0; | |||
4698 | } | |||
4699 | ||||
4700 | /* 7.1.8 Automatic Close of associations (SCTP_AUTOCLOSE) | |||
4701 | * | |||
4702 | * This socket option is applicable to the UDP-style socket only. When | |||
4703 | * set it will cause associations that are idle for more than the | |||
4704 | * specified number of seconds to automatically close. An association | |||
4705 | * being idle is defined an association that has NOT sent or received | |||
4706 | * user data. The special value of '0' indicates that no automatic | |||
4707 | * close of any associations should be performed. The option expects an | |||
4708 | * integer defining the number of seconds of idle time before an | |||
4709 | * association is closed. | |||
4710 | */ | |||
4711 | static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optval, int __user *optlen) | |||
4712 | { | |||
4713 | /* Applicable to UDP-style socket only */ | |||
4714 | if (sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP))) | |||
4715 | return -EOPNOTSUPP95; | |||
4716 | if (len < sizeof(int)) | |||
4717 | return -EINVAL22; | |||
4718 | len = sizeof(int); | |||
4719 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 4719); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
4720 | return -EFAULT14; | |||
4721 | if (copy_to_user(optval, &sctp_sk(sk)->autoclose, sizeof(int))) | |||
4722 | return -EFAULT14; | |||
4723 | return 0; | |||
4724 | } | |||
4725 | ||||
4726 | /* Helper routine to branch off an association to a new socket. */ | |||
4727 | int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp) | |||
4728 | { | |||
4729 | struct sctp_association *asoc = sctp_id2assoc(sk, id); | |||
4730 | struct sctp_sock *sp = sctp_sk(sk); | |||
4731 | struct socket *sock; | |||
4732 | int err = 0; | |||
4733 | ||||
4734 | if (!asoc) | |||
4735 | return -EINVAL22; | |||
4736 | ||||
4737 | /* An association cannot be branched off from an already peeled-off | |||
4738 | * socket, nor is this supported for tcp style sockets. | |||
4739 | */ | |||
4740 | if (!sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
4741 | return -EINVAL22; | |||
4742 | ||||
4743 | /* Create a new socket. */ | |||
4744 | err = sock_create(sk->sk_family__sk_common.skc_family, SOCK_SEQPACKET, IPPROTO_SCTPIPPROTO_SCTP, &sock); | |||
4745 | if (err < 0) | |||
4746 | return err; | |||
4747 | ||||
4748 | sctp_copy_sock(sock->sk, sk, asoc); | |||
4749 | ||||
4750 | /* Make peeled-off sockets more like 1-1 accepted sockets. | |||
4751 | * Set the daddr and initialize id to something more random | |||
4752 | */ | |||
4753 | sp->pf->to_sk_daddr(&asoc->peer.primary_addr, sk); | |||
4754 | ||||
4755 | /* Populate the fields of the newsk from the oldsk and migrate the | |||
4756 | * asoc to the newsk. | |||
4757 | */ | |||
4758 | sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH); | |||
4759 | ||||
4760 | *sockp = sock; | |||
4761 | ||||
4762 | return err; | |||
4763 | } | |||
4764 | EXPORT_SYMBOL(sctp_do_peeloff)extern typeof(sctp_do_peeloff) sctp_do_peeloff; extern void * __crc_sctp_do_peeloff __attribute__((weak)); static const unsigned long __kcrctab_sctp_do_peeloff __attribute__((__used__)) __attribute__ ((section("___kcrctab" "" "+" "sctp_do_peeloff"), used)) = (unsigned long) &__crc_sctp_do_peeloff; static const char __kstrtab_sctp_do_peeloff [] __attribute__((section("__ksymtab_strings"), aligned(1))) = "sctp_do_peeloff"; static const struct kernel_symbol __ksymtab_sctp_do_peeloff __attribute__((__used__)) __attribute__((section("___ksymtab" "" "+" "sctp_do_peeloff"), used)) = { (unsigned long)&sctp_do_peeloff , __kstrtab_sctp_do_peeloff }; | |||
4765 | ||||
4766 | static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval, int __user *optlen) | |||
4767 | { | |||
4768 | sctp_peeloff_arg_t peeloff; | |||
4769 | struct socket *newsock; | |||
4770 | struct file *newfile; | |||
4771 | int retval = 0; | |||
4772 | ||||
4773 | if (len < sizeof(sctp_peeloff_arg_t)) | |||
4774 | return -EINVAL22; | |||
4775 | len = sizeof(sctp_peeloff_arg_t); | |||
4776 | if (copy_from_user(&peeloff, optval, len)) | |||
4777 | return -EFAULT14; | |||
4778 | ||||
4779 | retval = sctp_do_peeloff(sk, peeloff.associd, &newsock); | |||
4780 | if (retval < 0) | |||
4781 | goto out; | |||
4782 | ||||
4783 | /* Map the socket to an unused fd that can be returned to the user. */ | |||
4784 | retval = get_unused_fd_flags(0); | |||
4785 | if (retval < 0) { | |||
4786 | sock_release(newsock); | |||
4787 | goto out; | |||
4788 | } | |||
4789 | ||||
4790 | newfile = sock_alloc_file(newsock, 0, NULL((void *)0)); | |||
4791 | if (IS_ERR(newfile)) { | |||
4792 | put_unused_fd(retval); | |||
4793 | sock_release(newsock); | |||
4794 | return PTR_ERR(newfile); | |||
4795 | } | |||
4796 | ||||
4797 | pr_debug("%s: sk:%p, newsk:%p, sd:%d\n", __func__, sk, newsock->sk,do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, newsk:%p, sd:%d\n" ), .lineno = 4798, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, newsk:%p, sd:%d\n", __func__, sk, newsock->sk , retval); } while (0) | |||
4798 | retval)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, newsk:%p, sd:%d\n" ), .lineno = 4798, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, newsk:%p, sd:%d\n", __func__, sk, newsock->sk , retval); } while (0); | |||
4799 | ||||
4800 | /* Return the fd mapped to the new socket. */ | |||
4801 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 4801); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) { | |||
4802 | fput(newfile); | |||
4803 | put_unused_fd(retval); | |||
4804 | return -EFAULT14; | |||
4805 | } | |||
4806 | peeloff.sd = retval; | |||
4807 | if (copy_to_user(optval, &peeloff, len)) { | |||
4808 | fput(newfile); | |||
4809 | put_unused_fd(retval); | |||
4810 | return -EFAULT14; | |||
4811 | } | |||
4812 | fd_install(retval, newfile); | |||
4813 | out: | |||
4814 | return retval; | |||
4815 | } | |||
4816 | ||||
4817 | /* 7.1.13 Peer Address Parameters (SCTP_PEER_ADDR_PARAMS) | |||
4818 | * | |||
4819 | * Applications can enable or disable heartbeats for any peer address of | |||
4820 | * an association, modify an address's heartbeat interval, force a | |||
4821 | * heartbeat to be sent immediately, and adjust the address's maximum | |||
4822 | * number of retransmissions sent before an address is considered | |||
4823 | * unreachable. The following structure is used to access and modify an | |||
4824 | * address's parameters: | |||
4825 | * | |||
4826 | * struct sctp_paddrparams { | |||
4827 | * sctp_assoc_t spp_assoc_id; | |||
4828 | * struct sockaddr_storage spp_address; | |||
4829 | * uint32_t spp_hbinterval; | |||
4830 | * uint16_t spp_pathmaxrxt; | |||
4831 | * uint32_t spp_pathmtu; | |||
4832 | * uint32_t spp_sackdelay; | |||
4833 | * uint32_t spp_flags; | |||
4834 | * }; | |||
4835 | * | |||
4836 | * spp_assoc_id - (one-to-many style socket) This is filled in the | |||
4837 | * application, and identifies the association for | |||
4838 | * this query. | |||
4839 | * spp_address - This specifies which address is of interest. | |||
4840 | * spp_hbinterval - This contains the value of the heartbeat interval, | |||
4841 | * in milliseconds. If a value of zero | |||
4842 | * is present in this field then no changes are to | |||
4843 | * be made to this parameter. | |||
4844 | * spp_pathmaxrxt - This contains the maximum number of | |||
4845 | * retransmissions before this address shall be | |||
4846 | * considered unreachable. If a value of zero | |||
4847 | * is present in this field then no changes are to | |||
4848 | * be made to this parameter. | |||
4849 | * spp_pathmtu - When Path MTU discovery is disabled the value | |||
4850 | * specified here will be the "fixed" path mtu. | |||
4851 | * Note that if the spp_address field is empty | |||
4852 | * then all associations on this address will | |||
4853 | * have this fixed path mtu set upon them. | |||
4854 | * | |||
4855 | * spp_sackdelay - When delayed sack is enabled, this value specifies | |||
4856 | * the number of milliseconds that sacks will be delayed | |||
4857 | * for. This value will apply to all addresses of an | |||
4858 | * association if the spp_address field is empty. Note | |||
4859 | * also, that if delayed sack is enabled and this | |||
4860 | * value is set to 0, no change is made to the last | |||
4861 | * recorded delayed sack timer value. | |||
4862 | * | |||
4863 | * spp_flags - These flags are used to control various features | |||
4864 | * on an association. The flag field may contain | |||
4865 | * zero or more of the following options. | |||
4866 | * | |||
4867 | * SPP_HB_ENABLE - Enable heartbeats on the | |||
4868 | * specified address. Note that if the address | |||
4869 | * field is empty all addresses for the association | |||
4870 | * have heartbeats enabled upon them. | |||
4871 | * | |||
4872 | * SPP_HB_DISABLE - Disable heartbeats on the | |||
4873 | * speicifed address. Note that if the address | |||
4874 | * field is empty all addresses for the association | |||
4875 | * will have their heartbeats disabled. Note also | |||
4876 | * that SPP_HB_ENABLE and SPP_HB_DISABLE are | |||
4877 | * mutually exclusive, only one of these two should | |||
4878 | * be specified. Enabling both fields will have | |||
4879 | * undetermined results. | |||
4880 | * | |||
4881 | * SPP_HB_DEMAND - Request a user initiated heartbeat | |||
4882 | * to be made immediately. | |||
4883 | * | |||
4884 | * SPP_PMTUD_ENABLE - This field will enable PMTU | |||
4885 | * discovery upon the specified address. Note that | |||
4886 | * if the address feild is empty then all addresses | |||
4887 | * on the association are effected. | |||
4888 | * | |||
4889 | * SPP_PMTUD_DISABLE - This field will disable PMTU | |||
4890 | * discovery upon the specified address. Note that | |||
4891 | * if the address feild is empty then all addresses | |||
4892 | * on the association are effected. Not also that | |||
4893 | * SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually | |||
4894 | * exclusive. Enabling both will have undetermined | |||
4895 | * results. | |||
4896 | * | |||
4897 | * SPP_SACKDELAY_ENABLE - Setting this flag turns | |||
4898 | * on delayed sack. The time specified in spp_sackdelay | |||
4899 | * is used to specify the sack delay for this address. Note | |||
4900 | * that if spp_address is empty then all addresses will | |||
4901 | * enable delayed sack and take on the sack delay | |||
4902 | * value specified in spp_sackdelay. | |||
4903 | * SPP_SACKDELAY_DISABLE - Setting this flag turns | |||
4904 | * off delayed sack. If the spp_address field is blank then | |||
4905 | * delayed sack is disabled for the entire association. Note | |||
4906 | * also that this field is mutually exclusive to | |||
4907 | * SPP_SACKDELAY_ENABLE, setting both will have undefined | |||
4908 | * results. | |||
4909 | */ | |||
4910 | static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, | |||
4911 | char __user *optval, int __user *optlen) | |||
4912 | { | |||
4913 | struct sctp_paddrparams params; | |||
4914 | struct sctp_transport *trans = NULL((void *)0); | |||
4915 | struct sctp_association *asoc = NULL((void *)0); | |||
4916 | struct sctp_sock *sp = sctp_sk(sk); | |||
4917 | ||||
4918 | if (len < sizeof(struct sctp_paddrparams)) | |||
4919 | return -EINVAL22; | |||
4920 | len = sizeof(struct sctp_paddrparams); | |||
4921 | if (copy_from_user(¶ms, optval, len)) | |||
4922 | return -EFAULT14; | |||
4923 | ||||
4924 | /* If an address other than INADDR_ANY is specified, and | |||
4925 | * no transport is found, then the request is invalid. | |||
4926 | */ | |||
4927 | if (!sctp_is_any(sk, (union sctp_addr *)¶ms.spp_address)) { | |||
4928 | trans = sctp_addr_id2transport(sk, ¶ms.spp_address, | |||
4929 | params.spp_assoc_id); | |||
4930 | if (!trans) { | |||
4931 | pr_debug("%s: failed no transport\n", __func__)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: failed no transport\n" ), .lineno = 4931, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: failed no transport\n", __func__); } while (0); | |||
4932 | return -EINVAL22; | |||
4933 | } | |||
4934 | } | |||
4935 | ||||
4936 | /* Get association, if assoc_id != 0 and the socket is a one | |||
4937 | * to many style socket, and an association was not found, then | |||
4938 | * the id was invalid. | |||
4939 | */ | |||
4940 | asoc = sctp_id2assoc(sk, params.spp_assoc_id); | |||
4941 | if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) { | |||
4942 | pr_debug("%s: failed no association\n", __func__)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: failed no association\n" ), .lineno = 4942, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: failed no association\n", __func__); } while (0); | |||
4943 | return -EINVAL22; | |||
4944 | } | |||
4945 | ||||
4946 | if (trans) { | |||
4947 | /* Fetch transport values. */ | |||
4948 | params.spp_hbinterval = jiffies_to_msecs(trans->hbinterval); | |||
4949 | params.spp_pathmtu = trans->pathmtu; | |||
4950 | params.spp_pathmaxrxt = trans->pathmaxrxt; | |||
4951 | params.spp_sackdelay = jiffies_to_msecs(trans->sackdelay); | |||
4952 | ||||
4953 | /*draft-11 doesn't say what to return in spp_flags*/ | |||
4954 | params.spp_flags = trans->param_flags; | |||
4955 | } else if (asoc) { | |||
4956 | /* Fetch association values. */ | |||
4957 | params.spp_hbinterval = jiffies_to_msecs(asoc->hbinterval); | |||
4958 | params.spp_pathmtu = asoc->pathmtu; | |||
4959 | params.spp_pathmaxrxt = asoc->pathmaxrxt; | |||
4960 | params.spp_sackdelay = jiffies_to_msecs(asoc->sackdelay); | |||
4961 | ||||
4962 | /*draft-11 doesn't say what to return in spp_flags*/ | |||
4963 | params.spp_flags = asoc->param_flags; | |||
4964 | } else { | |||
4965 | /* Fetch socket values. */ | |||
4966 | params.spp_hbinterval = sp->hbinterval; | |||
4967 | params.spp_pathmtu = sp->pathmtu; | |||
4968 | params.spp_sackdelay = sp->sackdelay; | |||
4969 | params.spp_pathmaxrxt = sp->pathmaxrxt; | |||
4970 | ||||
4971 | /*draft-11 doesn't say what to return in spp_flags*/ | |||
4972 | params.spp_flags = sp->param_flags; | |||
4973 | } | |||
4974 | ||||
4975 | if (copy_to_user(optval, ¶ms, len)) | |||
4976 | return -EFAULT14; | |||
4977 | ||||
4978 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 4978); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
4979 | return -EFAULT14; | |||
4980 | ||||
4981 | return 0; | |||
4982 | } | |||
4983 | ||||
4984 | /* | |||
4985 | * 7.1.23. Get or set delayed ack timer (SCTP_DELAYED_SACK) | |||
4986 | * | |||
4987 | * This option will effect the way delayed acks are performed. This | |||
4988 | * option allows you to get or set the delayed ack time, in | |||
4989 | * milliseconds. It also allows changing the delayed ack frequency. | |||
4990 | * Changing the frequency to 1 disables the delayed sack algorithm. If | |||
4991 | * the assoc_id is 0, then this sets or gets the endpoints default | |||
4992 | * values. If the assoc_id field is non-zero, then the set or get | |||
4993 | * effects the specified association for the one to many model (the | |||
4994 | * assoc_id field is ignored by the one to one model). Note that if | |||
4995 | * sack_delay or sack_freq are 0 when setting this option, then the | |||
4996 | * current values will remain unchanged. | |||
4997 | * | |||
4998 | * struct sctp_sack_info { | |||
4999 | * sctp_assoc_t sack_assoc_id; | |||
5000 | * uint32_t sack_delay; | |||
5001 | * uint32_t sack_freq; | |||
5002 | * }; | |||
5003 | * | |||
5004 | * sack_assoc_id - This parameter, indicates which association the user | |||
5005 | * is performing an action upon. Note that if this field's value is | |||
5006 | * zero then the endpoints default value is changed (effecting future | |||
5007 | * associations only). | |||
5008 | * | |||
5009 | * sack_delay - This parameter contains the number of milliseconds that | |||
5010 | * the user is requesting the delayed ACK timer be set to. Note that | |||
5011 | * this value is defined in the standard to be between 200 and 500 | |||
5012 | * milliseconds. | |||
5013 | * | |||
5014 | * sack_freq - This parameter contains the number of packets that must | |||
5015 | * be received before a sack is sent without waiting for the delay | |||
5016 | * timer to expire. The default value for this is 2, setting this | |||
5017 | * value to 1 will disable the delayed sack algorithm. | |||
5018 | */ | |||
5019 | static int sctp_getsockopt_delayed_ack(struct sock *sk, int len, | |||
5020 | char __user *optval, | |||
5021 | int __user *optlen) | |||
5022 | { | |||
5023 | struct sctp_sack_info params; | |||
5024 | struct sctp_association *asoc = NULL((void *)0); | |||
5025 | struct sctp_sock *sp = sctp_sk(sk); | |||
5026 | ||||
5027 | if (len >= sizeof(struct sctp_sack_info)) { | |||
5028 | len = sizeof(struct sctp_sack_info); | |||
5029 | ||||
5030 | if (copy_from_user(¶ms, optval, len)) | |||
5031 | return -EFAULT14; | |||
5032 | } else if (len == sizeof(struct sctp_assoc_value)) { | |||
5033 | pr_warn_ratelimited(DEPRECATED({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of struct sctp_assoc_value in delayed_ack socket option.\n" "Use struct sctp_sack_info instead\n", get_current()->comm , task_pid_nr(get_current())); }) | |||
5034 | "%s (pid %d) "({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of struct sctp_assoc_value in delayed_ack socket option.\n" "Use struct sctp_sack_info instead\n", get_current()->comm , task_pid_nr(get_current())); }) | |||
5035 | "Use of struct sctp_assoc_value in delayed_ack socket option.\n"({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of struct sctp_assoc_value in delayed_ack socket option.\n" "Use struct sctp_sack_info instead\n", get_current()->comm , task_pid_nr(get_current())); }) | |||
5036 | "Use struct sctp_sack_info instead\n",({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of struct sctp_assoc_value in delayed_ack socket option.\n" "Use struct sctp_sack_info instead\n", get_current()->comm , task_pid_nr(get_current())); }) | |||
5037 | current->comm, task_pid_nr(current))({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of struct sctp_assoc_value in delayed_ack socket option.\n" "Use struct sctp_sack_info instead\n", get_current()->comm , task_pid_nr(get_current())); }); | |||
5038 | if (copy_from_user(¶ms, optval, len)) | |||
5039 | return -EFAULT14; | |||
5040 | } else | |||
5041 | return -EINVAL22; | |||
5042 | ||||
5043 | /* Get association, if sack_assoc_id != 0 and the socket is a one | |||
5044 | * to many style socket, and an association was not found, then | |||
5045 | * the id was invalid. | |||
5046 | */ | |||
5047 | asoc = sctp_id2assoc(sk, params.sack_assoc_id); | |||
5048 | if (!asoc && params.sack_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
5049 | return -EINVAL22; | |||
5050 | ||||
5051 | if (asoc) { | |||
5052 | /* Fetch association values. */ | |||
5053 | if (asoc->param_flags & SPP_SACKDELAY_ENABLE) { | |||
5054 | params.sack_delay = jiffies_to_msecs( | |||
5055 | asoc->sackdelay); | |||
5056 | params.sack_freq = asoc->sackfreq; | |||
5057 | ||||
5058 | } else { | |||
5059 | params.sack_delay = 0; | |||
5060 | params.sack_freq = 1; | |||
5061 | } | |||
5062 | } else { | |||
5063 | /* Fetch socket values. */ | |||
5064 | if (sp->param_flags & SPP_SACKDELAY_ENABLE) { | |||
5065 | params.sack_delay = sp->sackdelay; | |||
5066 | params.sack_freq = sp->sackfreq; | |||
5067 | } else { | |||
5068 | params.sack_delay = 0; | |||
5069 | params.sack_freq = 1; | |||
5070 | } | |||
5071 | } | |||
5072 | ||||
5073 | if (copy_to_user(optval, ¶ms, len)) | |||
5074 | return -EFAULT14; | |||
5075 | ||||
5076 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5076); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5077 | return -EFAULT14; | |||
5078 | ||||
5079 | return 0; | |||
5080 | } | |||
5081 | ||||
5082 | /* 7.1.3 Initialization Parameters (SCTP_INITMSG) | |||
5083 | * | |||
5084 | * Applications can specify protocol parameters for the default association | |||
5085 | * initialization. The option name argument to setsockopt() and getsockopt() | |||
5086 | * is SCTP_INITMSG. | |||
5087 | * | |||
5088 | * Setting initialization parameters is effective only on an unconnected | |||
5089 | * socket (for UDP-style sockets only future associations are effected | |||
5090 | * by the change). With TCP-style sockets, this option is inherited by | |||
5091 | * sockets derived from a listener socket. | |||
5092 | */ | |||
5093 | static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval, int __user *optlen) | |||
5094 | { | |||
5095 | if (len < sizeof(struct sctp_initmsg)) | |||
5096 | return -EINVAL22; | |||
5097 | len = sizeof(struct sctp_initmsg); | |||
5098 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5098); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5099 | return -EFAULT14; | |||
5100 | if (copy_to_user(optval, &sctp_sk(sk)->initmsg, len)) | |||
5101 | return -EFAULT14; | |||
5102 | return 0; | |||
5103 | } | |||
5104 | ||||
5105 | ||||
5106 | static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, | |||
5107 | char __user *optval, int __user *optlen) | |||
5108 | { | |||
5109 | struct sctp_association *asoc; | |||
5110 | int cnt = 0; | |||
5111 | struct sctp_getaddrs getaddrs; | |||
5112 | struct sctp_transport *from; | |||
5113 | void __user *to; | |||
5114 | union sctp_addr temp; | |||
5115 | struct sctp_sock *sp = sctp_sk(sk); | |||
5116 | int addrlen; | |||
5117 | size_t space_left; | |||
5118 | int bytes_copied; | |||
5119 | ||||
5120 | if (len < sizeof(struct sctp_getaddrs)) | |||
5121 | return -EINVAL22; | |||
5122 | ||||
5123 | if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs))) | |||
5124 | return -EFAULT14; | |||
5125 | ||||
5126 | /* For UDP-style sockets, id specifies the association to query. */ | |||
5127 | asoc = sctp_id2assoc(sk, getaddrs.assoc_id); | |||
5128 | if (!asoc) | |||
5129 | return -EINVAL22; | |||
5130 | ||||
5131 | to = optval + offsetof(struct sctp_getaddrs, addrs)__builtin_offsetof(struct sctp_getaddrs, addrs); | |||
5132 | space_left = len - offsetof(struct sctp_getaddrs, addrs)__builtin_offsetof(struct sctp_getaddrs, addrs); | |||
5133 | ||||
5134 | list_for_each_entry(from, &asoc->peer.transport_addr_list,for (from = ({ const typeof( ((typeof(*from) *)0)->transports ) *__mptr = ((&asoc->peer.transport_addr_list)->next ); (typeof(*from) *)( (char *)__mptr - __builtin_offsetof(typeof (*from), transports) );}); &from->transports != (& asoc->peer.transport_addr_list); from = ({ const typeof( ( (typeof(*(from)) *)0)->transports ) *__mptr = ((from)-> transports.next); (typeof(*(from)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(from)), transports) );})) | |||
5135 | transports)for (from = ({ const typeof( ((typeof(*from) *)0)->transports ) *__mptr = ((&asoc->peer.transport_addr_list)->next ); (typeof(*from) *)( (char *)__mptr - __builtin_offsetof(typeof (*from), transports) );}); &from->transports != (& asoc->peer.transport_addr_list); from = ({ const typeof( ( (typeof(*(from)) *)0)->transports ) *__mptr = ((from)-> transports.next); (typeof(*(from)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(from)), transports) );})) { | |||
5136 | memcpy(&temp, &from->ipaddr, sizeof(temp))({ size_t __len = (sizeof(temp)); void *__ret; if (__builtin_constant_p (sizeof(temp)) && __len >= 64) __ret = __memcpy((& temp), (&from->ipaddr), __len); else __ret = __builtin_memcpy ((&temp), (&from->ipaddr), __len); __ret; }); | |||
5137 | addrlen = sctp_get_pf_specific(sk->sk_family__sk_common.skc_family) | |||
5138 | ->addr_to_user(sp, &temp); | |||
5139 | if (space_left < addrlen) | |||
5140 | return -ENOMEM12; | |||
5141 | if (copy_to_user(to, &temp, addrlen)) | |||
| ||||
5142 | return -EFAULT14; | |||
5143 | to += addrlen; | |||
5144 | cnt++; | |||
5145 | space_left -= addrlen; | |||
5146 | } | |||
5147 | ||||
5148 | if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)({ int __ret_pu; __typeof__(*(&((struct sctp_getaddrs *)optval )->addr_num)) __pu_val; (void)0; __might_fault("net/sctp/socket.c" , 5148); __pu_val = cnt; switch (sizeof(*(&((struct sctp_getaddrs *)optval)->addr_num))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(&((struct sctp_getaddrs *)optval)->addr_num)))(__pu_val)), "c" (&((struct sctp_getaddrs *)optval)->addr_num) : "ebx"); break; case 2: asm volatile ("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(& ((struct sctp_getaddrs *)optval)->addr_num)))(__pu_val)), "c" (&((struct sctp_getaddrs *)optval)->addr_num) : "ebx" ); break; case 4: asm volatile("call __put_user_" "4" : "=a" ( __ret_pu) : "0" ((typeof(*(&((struct sctp_getaddrs *)optval )->addr_num)))(__pu_val)), "c" (&((struct sctp_getaddrs *)optval)->addr_num) : "ebx"); break; case 8: asm volatile ("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(& ((struct sctp_getaddrs *)optval)->addr_num)))(__pu_val)), "c" (&((struct sctp_getaddrs *)optval)->addr_num) : "ebx" ); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(&((struct sctp_getaddrs *)optval )->addr_num)))(__pu_val)), "c" (&((struct sctp_getaddrs *)optval)->addr_num) : "ebx"); break; } __builtin_expect( __ret_pu, 0); })) | |||
5149 | return -EFAULT14; | |||
5150 | bytes_copied = ((char __user *)to) - optval; | |||
5151 | if (put_user(bytes_copied, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5151); __pu_val = bytes_copied; switch ( sizeof(*(optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5152 | return -EFAULT14; | |||
5153 | ||||
5154 | return 0; | |||
5155 | } | |||
5156 | ||||
5157 | static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to, | |||
5158 | size_t space_left, int *bytes_copied) | |||
5159 | { | |||
5160 | struct sctp_sockaddr_entry *addr; | |||
5161 | union sctp_addr temp; | |||
5162 | int cnt = 0; | |||
5163 | int addrlen; | |||
5164 | struct net *net = sock_net(sk); | |||
5165 | ||||
5166 | rcu_read_lock(); | |||
5167 | list_for_each_entry_rcu(addr, &net->sctp.local_addr_list, list)for (addr = ({ const typeof( ((typeof(*addr) *)0)->list ) * __mptr = (({ typeof((&net->sctp.local_addr_list)->next ) _________p1 = ({ union { typeof((&net->sctp.local_addr_list )->next) __val; char __c[1]; } __u; if (1) __read_once_size (&((&net->sctp.local_addr_list)->next), __u.__c , sizeof((&net->sctp.local_addr_list)->next)); else __read_once_size_nocheck(&((&net->sctp.local_addr_list )->next), __u.__c, sizeof((&net->sctp.local_addr_list )->next)); __u.__val; }); typeof(*((&net->sctp.local_addr_list )->next)) *___typecheck_p __attribute__((unused)); do { } while (0); (_________p1); })); (typeof(*addr) *)( (char *)__mptr - __builtin_offsetof(typeof(*addr), list) );}); &addr-> list != (&net->sctp.local_addr_list); addr = ({ const typeof ( ((typeof(*addr) *)0)->list ) *__mptr = (({ typeof(addr-> list.next) _________p1 = ({ union { typeof(addr->list.next ) __val; char __c[1]; } __u; if (1) __read_once_size(&(addr ->list.next), __u.__c, sizeof(addr->list.next)); else __read_once_size_nocheck (&(addr->list.next), __u.__c, sizeof(addr->list.next )); __u.__val; }); typeof(*(addr->list.next)) *___typecheck_p __attribute__((unused)); do { } while (0); (_________p1); }) ); (typeof(*addr) *)( (char *)__mptr - __builtin_offsetof(typeof (*addr), list) );})) { | |||
5168 | if (!addr->valid) | |||
5169 | continue; | |||
5170 | ||||
5171 | if ((PF_INET2 == sk->sk_family__sk_common.skc_family) && | |||
5172 | (AF_INET610 == addr->a.sa.sa_family)) | |||
5173 | continue; | |||
5174 | if ((PF_INET610 == sk->sk_family__sk_common.skc_family) && | |||
5175 | inet_v6_ipv6only(sk) && | |||
5176 | (AF_INET2 == addr->a.sa.sa_family)) | |||
5177 | continue; | |||
5178 | memcpy(&temp, &addr->a, sizeof(temp))({ size_t __len = (sizeof(temp)); void *__ret; if (__builtin_constant_p (sizeof(temp)) && __len >= 64) __ret = __memcpy((& temp), (&addr->a), __len); else __ret = __builtin_memcpy ((&temp), (&addr->a), __len); __ret; }); | |||
5179 | if (!temp.v4.sin_port) | |||
5180 | temp.v4.sin_port = htons(port)(( __be16)(__builtin_constant_p((__u16)((port))) ? ((__u16)( ( ((__u16)((port)) & (__u16)0x00ffU) << 8) | (((__u16 )((port)) & (__u16)0xff00U) >> 8))) : __fswab16((port )))); | |||
5181 | ||||
5182 | addrlen = sctp_get_pf_specific(sk->sk_family__sk_common.skc_family) | |||
5183 | ->addr_to_user(sctp_sk(sk), &temp); | |||
5184 | ||||
5185 | if (space_left < addrlen) { | |||
5186 | cnt = -ENOMEM12; | |||
5187 | break; | |||
5188 | } | |||
5189 | memcpy(to, &temp, addrlen)({ size_t __len = (addrlen); void *__ret; if (__builtin_constant_p (addrlen) && __len >= 64) __ret = __memcpy((to), ( &temp), __len); else __ret = __builtin_memcpy((to), (& temp), __len); __ret; }); | |||
5190 | ||||
5191 | to += addrlen; | |||
5192 | cnt++; | |||
5193 | space_left -= addrlen; | |||
5194 | *bytes_copied += addrlen; | |||
5195 | } | |||
5196 | rcu_read_unlock(); | |||
5197 | ||||
5198 | return cnt; | |||
5199 | } | |||
5200 | ||||
5201 | ||||
5202 | static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
5203 | char __user *optval, int __user *optlen) | |||
5204 | { | |||
5205 | struct sctp_bind_addr *bp; | |||
5206 | struct sctp_association *asoc; | |||
5207 | int cnt = 0; | |||
5208 | struct sctp_getaddrs getaddrs; | |||
5209 | struct sctp_sockaddr_entry *addr; | |||
5210 | void __user *to; | |||
5211 | union sctp_addr temp; | |||
5212 | struct sctp_sock *sp = sctp_sk(sk); | |||
5213 | int addrlen; | |||
5214 | int err = 0; | |||
5215 | size_t space_left; | |||
5216 | int bytes_copied = 0; | |||
5217 | void *addrs; | |||
5218 | void *buf; | |||
5219 | ||||
5220 | if (len < sizeof(struct sctp_getaddrs)) | |||
5221 | return -EINVAL22; | |||
5222 | ||||
5223 | if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs))) | |||
5224 | return -EFAULT14; | |||
5225 | ||||
5226 | /* | |||
5227 | * For UDP-style sockets, id specifies the association to query. | |||
5228 | * If the id field is set to the value '0' then the locally bound | |||
5229 | * addresses are returned without regard to any particular | |||
5230 | * association. | |||
5231 | */ | |||
5232 | if (0 == getaddrs.assoc_id) { | |||
5233 | bp = &sctp_sk(sk)->ep->base.bind_addr; | |||
5234 | } else { | |||
5235 | asoc = sctp_id2assoc(sk, getaddrs.assoc_id); | |||
5236 | if (!asoc) | |||
5237 | return -EINVAL22; | |||
5238 | bp = &asoc->base.bind_addr; | |||
5239 | } | |||
5240 | ||||
5241 | to = optval + offsetof(struct sctp_getaddrs, addrs)__builtin_offsetof(struct sctp_getaddrs, addrs); | |||
5242 | space_left = len - offsetof(struct sctp_getaddrs, addrs)__builtin_offsetof(struct sctp_getaddrs, addrs); | |||
5243 | ||||
5244 | addrs = kmalloc(space_left, GFP_USER((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u) | (( gfp_t)0x20000u)) | __GFP_NOWARN(( gfp_t)0x200u)); | |||
5245 | if (!addrs) | |||
5246 | return -ENOMEM12; | |||
5247 | ||||
5248 | /* If the endpoint is bound to 0.0.0.0 or ::0, get the valid | |||
5249 | * addresses from the global local address list. | |||
5250 | */ | |||
5251 | if (sctp_list_single_entry(&bp->address_list)) { | |||
5252 | addr = list_entry(bp->address_list.next,({ const typeof( ((struct sctp_sockaddr_entry *)0)->list ) *__mptr = (bp->address_list.next); (struct sctp_sockaddr_entry *)( (char *)__mptr - __builtin_offsetof(struct sctp_sockaddr_entry , list) );}) | |||
5253 | struct sctp_sockaddr_entry, list)({ const typeof( ((struct sctp_sockaddr_entry *)0)->list ) *__mptr = (bp->address_list.next); (struct sctp_sockaddr_entry *)( (char *)__mptr - __builtin_offsetof(struct sctp_sockaddr_entry , list) );}); | |||
5254 | if (sctp_is_any(sk, &addr->a)) { | |||
5255 | cnt = sctp_copy_laddrs(sk, bp->port, addrs, | |||
5256 | space_left, &bytes_copied); | |||
5257 | if (cnt < 0) { | |||
5258 | err = cnt; | |||
5259 | goto out; | |||
5260 | } | |||
5261 | goto copy_getaddrs; | |||
5262 | } | |||
5263 | } | |||
5264 | ||||
5265 | buf = addrs; | |||
5266 | /* Protection on the bound address list is not needed since | |||
5267 | * in the socket option context we hold a socket lock and | |||
5268 | * thus the bound address list can't change. | |||
5269 | */ | |||
5270 | list_for_each_entry(addr, &bp->address_list, list)for (addr = ({ const typeof( ((typeof(*addr) *)0)->list ) * __mptr = ((&bp->address_list)->next); (typeof(*addr ) *)( (char *)__mptr - __builtin_offsetof(typeof(*addr), list ) );}); &addr->list != (&bp->address_list); addr = ({ const typeof( ((typeof(*(addr)) *)0)->list ) *__mptr = ((addr)->list.next); (typeof(*(addr)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(addr)), list) );})) { | |||
5271 | memcpy(&temp, &addr->a, sizeof(temp))({ size_t __len = (sizeof(temp)); void *__ret; if (__builtin_constant_p (sizeof(temp)) && __len >= 64) __ret = __memcpy((& temp), (&addr->a), __len); else __ret = __builtin_memcpy ((&temp), (&addr->a), __len); __ret; }); | |||
5272 | addrlen = sctp_get_pf_specific(sk->sk_family__sk_common.skc_family) | |||
5273 | ->addr_to_user(sp, &temp); | |||
5274 | if (space_left < addrlen) { | |||
5275 | err = -ENOMEM12; /*fixme: right error?*/ | |||
5276 | goto out; | |||
5277 | } | |||
5278 | memcpy(buf, &temp, addrlen)({ size_t __len = (addrlen); void *__ret; if (__builtin_constant_p (addrlen) && __len >= 64) __ret = __memcpy((buf), ( &temp), __len); else __ret = __builtin_memcpy((buf), (& temp), __len); __ret; }); | |||
5279 | buf += addrlen; | |||
5280 | bytes_copied += addrlen; | |||
5281 | cnt++; | |||
5282 | space_left -= addrlen; | |||
5283 | } | |||
5284 | ||||
5285 | copy_getaddrs: | |||
5286 | if (copy_to_user(to, addrs, bytes_copied)) { | |||
5287 | err = -EFAULT14; | |||
5288 | goto out; | |||
5289 | } | |||
5290 | if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)({ int __ret_pu; __typeof__(*(&((struct sctp_getaddrs *)optval )->addr_num)) __pu_val; (void)0; __might_fault("net/sctp/socket.c" , 5290); __pu_val = cnt; switch (sizeof(*(&((struct sctp_getaddrs *)optval)->addr_num))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(&((struct sctp_getaddrs *)optval)->addr_num)))(__pu_val)), "c" (&((struct sctp_getaddrs *)optval)->addr_num) : "ebx"); break; case 2: asm volatile ("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(& ((struct sctp_getaddrs *)optval)->addr_num)))(__pu_val)), "c" (&((struct sctp_getaddrs *)optval)->addr_num) : "ebx" ); break; case 4: asm volatile("call __put_user_" "4" : "=a" ( __ret_pu) : "0" ((typeof(*(&((struct sctp_getaddrs *)optval )->addr_num)))(__pu_val)), "c" (&((struct sctp_getaddrs *)optval)->addr_num) : "ebx"); break; case 8: asm volatile ("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(& ((struct sctp_getaddrs *)optval)->addr_num)))(__pu_val)), "c" (&((struct sctp_getaddrs *)optval)->addr_num) : "ebx" ); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(&((struct sctp_getaddrs *)optval )->addr_num)))(__pu_val)), "c" (&((struct sctp_getaddrs *)optval)->addr_num) : "ebx"); break; } __builtin_expect( __ret_pu, 0); })) { | |||
5291 | err = -EFAULT14; | |||
5292 | goto out; | |||
5293 | } | |||
5294 | if (put_user(bytes_copied, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5294); __pu_val = bytes_copied; switch ( sizeof(*(optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5295 | err = -EFAULT14; | |||
5296 | out: | |||
5297 | kfree(addrs); | |||
5298 | return err; | |||
5299 | } | |||
5300 | ||||
5301 | /* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR) | |||
5302 | * | |||
5303 | * Requests that the local SCTP stack use the enclosed peer address as | |||
5304 | * the association primary. The enclosed address must be one of the | |||
5305 | * association peer's addresses. | |||
5306 | */ | |||
5307 | static int sctp_getsockopt_primary_addr(struct sock *sk, int len, | |||
5308 | char __user *optval, int __user *optlen) | |||
5309 | { | |||
5310 | struct sctp_prim prim; | |||
5311 | struct sctp_association *asoc; | |||
5312 | struct sctp_sock *sp = sctp_sk(sk); | |||
5313 | ||||
5314 | if (len < sizeof(struct sctp_prim)) | |||
5315 | return -EINVAL22; | |||
5316 | ||||
5317 | len = sizeof(struct sctp_prim); | |||
5318 | ||||
5319 | if (copy_from_user(&prim, optval, len)) | |||
5320 | return -EFAULT14; | |||
5321 | ||||
5322 | asoc = sctp_id2assoc(sk, prim.ssp_assoc_id); | |||
5323 | if (!asoc) | |||
5324 | return -EINVAL22; | |||
5325 | ||||
5326 | if (!asoc->peer.primary_path) | |||
5327 | return -ENOTCONN107; | |||
5328 | ||||
5329 | memcpy(&prim.ssp_addr, &asoc->peer.primary_path->ipaddr,({ size_t __len = (asoc->peer.primary_path->af_specific ->sockaddr_len); void *__ret; if (__builtin_constant_p(asoc ->peer.primary_path->af_specific->sockaddr_len) && __len >= 64) __ret = __memcpy((&prim.ssp_addr), (& asoc->peer.primary_path->ipaddr), __len); else __ret = __builtin_memcpy ((&prim.ssp_addr), (&asoc->peer.primary_path->ipaddr ), __len); __ret; }) | |||
5330 | asoc->peer.primary_path->af_specific->sockaddr_len)({ size_t __len = (asoc->peer.primary_path->af_specific ->sockaddr_len); void *__ret; if (__builtin_constant_p(asoc ->peer.primary_path->af_specific->sockaddr_len) && __len >= 64) __ret = __memcpy((&prim.ssp_addr), (& asoc->peer.primary_path->ipaddr), __len); else __ret = __builtin_memcpy ((&prim.ssp_addr), (&asoc->peer.primary_path->ipaddr ), __len); __ret; }); | |||
5331 | ||||
5332 | sctp_get_pf_specific(sk->sk_family__sk_common.skc_family)->addr_to_user(sp, | |||
5333 | (union sctp_addr *)&prim.ssp_addr); | |||
5334 | ||||
5335 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5335); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5336 | return -EFAULT14; | |||
5337 | if (copy_to_user(optval, &prim, len)) | |||
5338 | return -EFAULT14; | |||
5339 | ||||
5340 | return 0; | |||
5341 | } | |||
5342 | ||||
5343 | /* | |||
5344 | * 7.1.11 Set Adaptation Layer Indicator (SCTP_ADAPTATION_LAYER) | |||
5345 | * | |||
5346 | * Requests that the local endpoint set the specified Adaptation Layer | |||
5347 | * Indication parameter for all future INIT and INIT-ACK exchanges. | |||
5348 | */ | |||
5349 | static int sctp_getsockopt_adaptation_layer(struct sock *sk, int len, | |||
5350 | char __user *optval, int __user *optlen) | |||
5351 | { | |||
5352 | struct sctp_setadaptation adaptation; | |||
5353 | ||||
5354 | if (len < sizeof(struct sctp_setadaptation)) | |||
5355 | return -EINVAL22; | |||
5356 | ||||
5357 | len = sizeof(struct sctp_setadaptation); | |||
5358 | ||||
5359 | adaptation.ssb_adaptation_ind = sctp_sk(sk)->adaptation_ind; | |||
5360 | ||||
5361 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5361); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5362 | return -EFAULT14; | |||
5363 | if (copy_to_user(optval, &adaptation, len)) | |||
5364 | return -EFAULT14; | |||
5365 | ||||
5366 | return 0; | |||
5367 | } | |||
5368 | ||||
5369 | /* | |||
5370 | * | |||
5371 | * 7.1.14 Set default send parameters (SCTP_DEFAULT_SEND_PARAM) | |||
5372 | * | |||
5373 | * Applications that wish to use the sendto() system call may wish to | |||
5374 | * specify a default set of parameters that would normally be supplied | |||
5375 | * through the inclusion of ancillary data. This socket option allows | |||
5376 | * such an application to set the default sctp_sndrcvinfo structure. | |||
5377 | ||||
5378 | ||||
5379 | * The application that wishes to use this socket option simply passes | |||
5380 | * in to this call the sctp_sndrcvinfo structure defined in Section | |||
5381 | * 5.2.2) The input parameters accepted by this call include | |||
5382 | * sinfo_stream, sinfo_flags, sinfo_ppid, sinfo_context, | |||
5383 | * sinfo_timetolive. The user must provide the sinfo_assoc_id field in | |||
5384 | * to this call if the caller is using the UDP model. | |||
5385 | * | |||
5386 | * For getsockopt, it get the default sctp_sndrcvinfo structure. | |||
5387 | */ | |||
5388 | static int sctp_getsockopt_default_send_param(struct sock *sk, | |||
5389 | int len, char __user *optval, | |||
5390 | int __user *optlen) | |||
5391 | { | |||
5392 | struct sctp_sock *sp = sctp_sk(sk); | |||
5393 | struct sctp_association *asoc; | |||
5394 | struct sctp_sndrcvinfo info; | |||
5395 | ||||
5396 | if (len < sizeof(info)) | |||
5397 | return -EINVAL22; | |||
5398 | ||||
5399 | len = sizeof(info); | |||
5400 | ||||
5401 | if (copy_from_user(&info, optval, len)) | |||
5402 | return -EFAULT14; | |||
5403 | ||||
5404 | asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); | |||
5405 | if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
5406 | return -EINVAL22; | |||
5407 | if (asoc) { | |||
5408 | info.sinfo_stream = asoc->default_stream; | |||
5409 | info.sinfo_flags = asoc->default_flags; | |||
5410 | info.sinfo_ppid = asoc->default_ppid; | |||
5411 | info.sinfo_context = asoc->default_context; | |||
5412 | info.sinfo_timetolive = asoc->default_timetolive; | |||
5413 | } else { | |||
5414 | info.sinfo_stream = sp->default_stream; | |||
5415 | info.sinfo_flags = sp->default_flags; | |||
5416 | info.sinfo_ppid = sp->default_ppid; | |||
5417 | info.sinfo_context = sp->default_context; | |||
5418 | info.sinfo_timetolive = sp->default_timetolive; | |||
5419 | } | |||
5420 | ||||
5421 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5421); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5422 | return -EFAULT14; | |||
5423 | if (copy_to_user(optval, &info, len)) | |||
5424 | return -EFAULT14; | |||
5425 | ||||
5426 | return 0; | |||
5427 | } | |||
5428 | ||||
5429 | /* RFC6458, Section 8.1.31. Set/get Default Send Parameters | |||
5430 | * (SCTP_DEFAULT_SNDINFO) | |||
5431 | */ | |||
5432 | static int sctp_getsockopt_default_sndinfo(struct sock *sk, int len, | |||
5433 | char __user *optval, | |||
5434 | int __user *optlen) | |||
5435 | { | |||
5436 | struct sctp_sock *sp = sctp_sk(sk); | |||
5437 | struct sctp_association *asoc; | |||
5438 | struct sctp_sndinfo info; | |||
5439 | ||||
5440 | if (len < sizeof(info)) | |||
5441 | return -EINVAL22; | |||
5442 | ||||
5443 | len = sizeof(info); | |||
5444 | ||||
5445 | if (copy_from_user(&info, optval, len)) | |||
5446 | return -EFAULT14; | |||
5447 | ||||
5448 | asoc = sctp_id2assoc(sk, info.snd_assoc_id); | |||
5449 | if (!asoc && info.snd_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
5450 | return -EINVAL22; | |||
5451 | if (asoc) { | |||
5452 | info.snd_sid = asoc->default_stream; | |||
5453 | info.snd_flags = asoc->default_flags; | |||
5454 | info.snd_ppid = asoc->default_ppid; | |||
5455 | info.snd_context = asoc->default_context; | |||
5456 | } else { | |||
5457 | info.snd_sid = sp->default_stream; | |||
5458 | info.snd_flags = sp->default_flags; | |||
5459 | info.snd_ppid = sp->default_ppid; | |||
5460 | info.snd_context = sp->default_context; | |||
5461 | } | |||
5462 | ||||
5463 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5463); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5464 | return -EFAULT14; | |||
5465 | if (copy_to_user(optval, &info, len)) | |||
5466 | return -EFAULT14; | |||
5467 | ||||
5468 | return 0; | |||
5469 | } | |||
5470 | ||||
5471 | /* | |||
5472 | * | |||
5473 | * 7.1.5 SCTP_NODELAY | |||
5474 | * | |||
5475 | * Turn on/off any Nagle-like algorithm. This means that packets are | |||
5476 | * generally sent as soon as possible and no unnecessary delays are | |||
5477 | * introduced, at the cost of more packets in the network. Expects an | |||
5478 | * integer boolean flag. | |||
5479 | */ | |||
5480 | ||||
5481 | static int sctp_getsockopt_nodelay(struct sock *sk, int len, | |||
5482 | char __user *optval, int __user *optlen) | |||
5483 | { | |||
5484 | int val; | |||
5485 | ||||
5486 | if (len < sizeof(int)) | |||
5487 | return -EINVAL22; | |||
5488 | ||||
5489 | len = sizeof(int); | |||
5490 | val = (sctp_sk(sk)->nodelay == 1); | |||
5491 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5491); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5492 | return -EFAULT14; | |||
5493 | if (copy_to_user(optval, &val, len)) | |||
5494 | return -EFAULT14; | |||
5495 | return 0; | |||
5496 | } | |||
5497 | ||||
5498 | /* | |||
5499 | * | |||
5500 | * 7.1.1 SCTP_RTOINFO | |||
5501 | * | |||
5502 | * The protocol parameters used to initialize and bound retransmission | |||
5503 | * timeout (RTO) are tunable. sctp_rtoinfo structure is used to access | |||
5504 | * and modify these parameters. | |||
5505 | * All parameters are time values, in milliseconds. A value of 0, when | |||
5506 | * modifying the parameters, indicates that the current value should not | |||
5507 | * be changed. | |||
5508 | * | |||
5509 | */ | |||
5510 | static int sctp_getsockopt_rtoinfo(struct sock *sk, int len, | |||
5511 | char __user *optval, | |||
5512 | int __user *optlen) { | |||
5513 | struct sctp_rtoinfo rtoinfo; | |||
5514 | struct sctp_association *asoc; | |||
5515 | ||||
5516 | if (len < sizeof (struct sctp_rtoinfo)) | |||
5517 | return -EINVAL22; | |||
5518 | ||||
5519 | len = sizeof(struct sctp_rtoinfo); | |||
5520 | ||||
5521 | if (copy_from_user(&rtoinfo, optval, len)) | |||
5522 | return -EFAULT14; | |||
5523 | ||||
5524 | asoc = sctp_id2assoc(sk, rtoinfo.srto_assoc_id); | |||
5525 | ||||
5526 | if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
5527 | return -EINVAL22; | |||
5528 | ||||
5529 | /* Values corresponding to the specific association. */ | |||
5530 | if (asoc) { | |||
5531 | rtoinfo.srto_initial = jiffies_to_msecs(asoc->rto_initial); | |||
5532 | rtoinfo.srto_max = jiffies_to_msecs(asoc->rto_max); | |||
5533 | rtoinfo.srto_min = jiffies_to_msecs(asoc->rto_min); | |||
5534 | } else { | |||
5535 | /* Values corresponding to the endpoint. */ | |||
5536 | struct sctp_sock *sp = sctp_sk(sk); | |||
5537 | ||||
5538 | rtoinfo.srto_initial = sp->rtoinfo.srto_initial; | |||
5539 | rtoinfo.srto_max = sp->rtoinfo.srto_max; | |||
5540 | rtoinfo.srto_min = sp->rtoinfo.srto_min; | |||
5541 | } | |||
5542 | ||||
5543 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5543); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5544 | return -EFAULT14; | |||
5545 | ||||
5546 | if (copy_to_user(optval, &rtoinfo, len)) | |||
5547 | return -EFAULT14; | |||
5548 | ||||
5549 | return 0; | |||
5550 | } | |||
5551 | ||||
5552 | /* | |||
5553 | * | |||
5554 | * 7.1.2 SCTP_ASSOCINFO | |||
5555 | * | |||
5556 | * This option is used to tune the maximum retransmission attempts | |||
5557 | * of the association. | |||
5558 | * Returns an error if the new association retransmission value is | |||
5559 | * greater than the sum of the retransmission value of the peer. | |||
5560 | * See [SCTP] for more information. | |||
5561 | * | |||
5562 | */ | |||
5563 | static int sctp_getsockopt_associnfo(struct sock *sk, int len, | |||
5564 | char __user *optval, | |||
5565 | int __user *optlen) | |||
5566 | { | |||
5567 | ||||
5568 | struct sctp_assocparams assocparams; | |||
5569 | struct sctp_association *asoc; | |||
5570 | struct list_head *pos; | |||
5571 | int cnt = 0; | |||
5572 | ||||
5573 | if (len < sizeof (struct sctp_assocparams)) | |||
5574 | return -EINVAL22; | |||
5575 | ||||
5576 | len = sizeof(struct sctp_assocparams); | |||
5577 | ||||
5578 | if (copy_from_user(&assocparams, optval, len)) | |||
5579 | return -EFAULT14; | |||
5580 | ||||
5581 | asoc = sctp_id2assoc(sk, assocparams.sasoc_assoc_id); | |||
5582 | ||||
5583 | if (!asoc && assocparams.sasoc_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
5584 | return -EINVAL22; | |||
5585 | ||||
5586 | /* Values correspoinding to the specific association */ | |||
5587 | if (asoc) { | |||
5588 | assocparams.sasoc_asocmaxrxt = asoc->max_retrans; | |||
5589 | assocparams.sasoc_peer_rwnd = asoc->peer.rwnd; | |||
5590 | assocparams.sasoc_local_rwnd = asoc->a_rwnd; | |||
5591 | assocparams.sasoc_cookie_life = ktime_to_ms(asoc->cookie_life); | |||
5592 | ||||
5593 | list_for_each(pos, &asoc->peer.transport_addr_list)for (pos = (&asoc->peer.transport_addr_list)->next; pos != (&asoc->peer.transport_addr_list); pos = pos-> next) { | |||
5594 | cnt++; | |||
5595 | } | |||
5596 | ||||
5597 | assocparams.sasoc_number_peer_destinations = cnt; | |||
5598 | } else { | |||
5599 | /* Values corresponding to the endpoint */ | |||
5600 | struct sctp_sock *sp = sctp_sk(sk); | |||
5601 | ||||
5602 | assocparams.sasoc_asocmaxrxt = sp->assocparams.sasoc_asocmaxrxt; | |||
5603 | assocparams.sasoc_peer_rwnd = sp->assocparams.sasoc_peer_rwnd; | |||
5604 | assocparams.sasoc_local_rwnd = sp->assocparams.sasoc_local_rwnd; | |||
5605 | assocparams.sasoc_cookie_life = | |||
5606 | sp->assocparams.sasoc_cookie_life; | |||
5607 | assocparams.sasoc_number_peer_destinations = | |||
5608 | sp->assocparams. | |||
5609 | sasoc_number_peer_destinations; | |||
5610 | } | |||
5611 | ||||
5612 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5612); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5613 | return -EFAULT14; | |||
5614 | ||||
5615 | if (copy_to_user(optval, &assocparams, len)) | |||
5616 | return -EFAULT14; | |||
5617 | ||||
5618 | return 0; | |||
5619 | } | |||
5620 | ||||
5621 | /* | |||
5622 | * 7.1.16 Set/clear IPv4 mapped addresses (SCTP_I_WANT_MAPPED_V4_ADDR) | |||
5623 | * | |||
5624 | * This socket option is a boolean flag which turns on or off mapped V4 | |||
5625 | * addresses. If this option is turned on and the socket is type | |||
5626 | * PF_INET6, then IPv4 addresses will be mapped to V6 representation. | |||
5627 | * If this option is turned off, then no mapping will be done of V4 | |||
5628 | * addresses and a user will receive both PF_INET6 and PF_INET type | |||
5629 | * addresses on the socket. | |||
5630 | */ | |||
5631 | static int sctp_getsockopt_mappedv4(struct sock *sk, int len, | |||
5632 | char __user *optval, int __user *optlen) | |||
5633 | { | |||
5634 | int val; | |||
5635 | struct sctp_sock *sp = sctp_sk(sk); | |||
5636 | ||||
5637 | if (len < sizeof(int)) | |||
5638 | return -EINVAL22; | |||
5639 | ||||
5640 | len = sizeof(int); | |||
5641 | val = sp->v4mapped; | |||
5642 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5642); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5643 | return -EFAULT14; | |||
5644 | if (copy_to_user(optval, &val, len)) | |||
5645 | return -EFAULT14; | |||
5646 | ||||
5647 | return 0; | |||
5648 | } | |||
5649 | ||||
5650 | /* | |||
5651 | * 7.1.29. Set or Get the default context (SCTP_CONTEXT) | |||
5652 | * (chapter and verse is quoted at sctp_setsockopt_context()) | |||
5653 | */ | |||
5654 | static int sctp_getsockopt_context(struct sock *sk, int len, | |||
5655 | char __user *optval, int __user *optlen) | |||
5656 | { | |||
5657 | struct sctp_assoc_value params; | |||
5658 | struct sctp_sock *sp; | |||
5659 | struct sctp_association *asoc; | |||
5660 | ||||
5661 | if (len < sizeof(struct sctp_assoc_value)) | |||
5662 | return -EINVAL22; | |||
5663 | ||||
5664 | len = sizeof(struct sctp_assoc_value); | |||
5665 | ||||
5666 | if (copy_from_user(¶ms, optval, len)) | |||
5667 | return -EFAULT14; | |||
5668 | ||||
5669 | sp = sctp_sk(sk); | |||
5670 | ||||
5671 | if (params.assoc_id != 0) { | |||
5672 | asoc = sctp_id2assoc(sk, params.assoc_id); | |||
5673 | if (!asoc) | |||
5674 | return -EINVAL22; | |||
5675 | params.assoc_value = asoc->default_rcv_context; | |||
5676 | } else { | |||
5677 | params.assoc_value = sp->default_rcv_context; | |||
5678 | } | |||
5679 | ||||
5680 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5680); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5681 | return -EFAULT14; | |||
5682 | if (copy_to_user(optval, ¶ms, len)) | |||
5683 | return -EFAULT14; | |||
5684 | ||||
5685 | return 0; | |||
5686 | } | |||
5687 | ||||
5688 | /* | |||
5689 | * 8.1.16. Get or Set the Maximum Fragmentation Size (SCTP_MAXSEG) | |||
5690 | * This option will get or set the maximum size to put in any outgoing | |||
5691 | * SCTP DATA chunk. If a message is larger than this size it will be | |||
5692 | * fragmented by SCTP into the specified size. Note that the underlying | |||
5693 | * SCTP implementation may fragment into smaller sized chunks when the | |||
5694 | * PMTU of the underlying association is smaller than the value set by | |||
5695 | * the user. The default value for this option is '0' which indicates | |||
5696 | * the user is NOT limiting fragmentation and only the PMTU will effect | |||
5697 | * SCTP's choice of DATA chunk size. Note also that values set larger | |||
5698 | * than the maximum size of an IP datagram will effectively let SCTP | |||
5699 | * control fragmentation (i.e. the same as setting this option to 0). | |||
5700 | * | |||
5701 | * The following structure is used to access and modify this parameter: | |||
5702 | * | |||
5703 | * struct sctp_assoc_value { | |||
5704 | * sctp_assoc_t assoc_id; | |||
5705 | * uint32_t assoc_value; | |||
5706 | * }; | |||
5707 | * | |||
5708 | * assoc_id: This parameter is ignored for one-to-one style sockets. | |||
5709 | * For one-to-many style sockets this parameter indicates which | |||
5710 | * association the user is performing an action upon. Note that if | |||
5711 | * this field's value is zero then the endpoints default value is | |||
5712 | * changed (effecting future associations only). | |||
5713 | * assoc_value: This parameter specifies the maximum size in bytes. | |||
5714 | */ | |||
5715 | static int sctp_getsockopt_maxseg(struct sock *sk, int len, | |||
5716 | char __user *optval, int __user *optlen) | |||
5717 | { | |||
5718 | struct sctp_assoc_value params; | |||
5719 | struct sctp_association *asoc; | |||
5720 | ||||
5721 | if (len == sizeof(int)) { | |||
5722 | pr_warn_ratelimited(DEPRECATED({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in maxseg socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }) | |||
5723 | "%s (pid %d) "({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in maxseg socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }) | |||
5724 | "Use of int in maxseg socket option.\n"({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in maxseg socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }) | |||
5725 | "Use struct sctp_assoc_value instead\n",({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in maxseg socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }) | |||
5726 | current->comm, task_pid_nr(current))({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in maxseg socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }); | |||
5727 | params.assoc_id = 0; | |||
5728 | } else if (len >= sizeof(struct sctp_assoc_value)) { | |||
5729 | len = sizeof(struct sctp_assoc_value); | |||
5730 | if (copy_from_user(¶ms, optval, sizeof(params))) | |||
5731 | return -EFAULT14; | |||
5732 | } else | |||
5733 | return -EINVAL22; | |||
5734 | ||||
5735 | asoc = sctp_id2assoc(sk, params.assoc_id); | |||
5736 | if (!asoc && params.assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
5737 | return -EINVAL22; | |||
5738 | ||||
5739 | if (asoc) | |||
5740 | params.assoc_value = asoc->frag_point; | |||
5741 | else | |||
5742 | params.assoc_value = sctp_sk(sk)->user_frag; | |||
5743 | ||||
5744 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5744); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5745 | return -EFAULT14; | |||
5746 | if (len == sizeof(int)) { | |||
5747 | if (copy_to_user(optval, ¶ms.assoc_value, len)) | |||
5748 | return -EFAULT14; | |||
5749 | } else { | |||
5750 | if (copy_to_user(optval, ¶ms, len)) | |||
5751 | return -EFAULT14; | |||
5752 | } | |||
5753 | ||||
5754 | return 0; | |||
5755 | } | |||
5756 | ||||
5757 | /* | |||
5758 | * 7.1.24. Get or set fragmented interleave (SCTP_FRAGMENT_INTERLEAVE) | |||
5759 | * (chapter and verse is quoted at sctp_setsockopt_fragment_interleave()) | |||
5760 | */ | |||
5761 | static int sctp_getsockopt_fragment_interleave(struct sock *sk, int len, | |||
5762 | char __user *optval, int __user *optlen) | |||
5763 | { | |||
5764 | int val; | |||
5765 | ||||
5766 | if (len < sizeof(int)) | |||
5767 | return -EINVAL22; | |||
5768 | ||||
5769 | len = sizeof(int); | |||
5770 | ||||
5771 | val = sctp_sk(sk)->frag_interleave; | |||
5772 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5772); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5773 | return -EFAULT14; | |||
5774 | if (copy_to_user(optval, &val, len)) | |||
5775 | return -EFAULT14; | |||
5776 | ||||
5777 | return 0; | |||
5778 | } | |||
5779 | ||||
5780 | /* | |||
5781 | * 7.1.25. Set or Get the sctp partial delivery point | |||
5782 | * (chapter and verse is quoted at sctp_setsockopt_partial_delivery_point()) | |||
5783 | */ | |||
5784 | static int sctp_getsockopt_partial_delivery_point(struct sock *sk, int len, | |||
5785 | char __user *optval, | |||
5786 | int __user *optlen) | |||
5787 | { | |||
5788 | u32 val; | |||
5789 | ||||
5790 | if (len < sizeof(u32)) | |||
5791 | return -EINVAL22; | |||
5792 | ||||
5793 | len = sizeof(u32); | |||
5794 | ||||
5795 | val = sctp_sk(sk)->pd_point; | |||
5796 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5796); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5797 | return -EFAULT14; | |||
5798 | if (copy_to_user(optval, &val, len)) | |||
5799 | return -EFAULT14; | |||
5800 | ||||
5801 | return 0; | |||
5802 | } | |||
5803 | ||||
5804 | /* | |||
5805 | * 7.1.28. Set or Get the maximum burst (SCTP_MAX_BURST) | |||
5806 | * (chapter and verse is quoted at sctp_setsockopt_maxburst()) | |||
5807 | */ | |||
5808 | static int sctp_getsockopt_maxburst(struct sock *sk, int len, | |||
5809 | char __user *optval, | |||
5810 | int __user *optlen) | |||
5811 | { | |||
5812 | struct sctp_assoc_value params; | |||
5813 | struct sctp_sock *sp; | |||
5814 | struct sctp_association *asoc; | |||
5815 | ||||
5816 | if (len == sizeof(int)) { | |||
5817 | pr_warn_ratelimited(DEPRECATED({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in max_burst socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }) | |||
5818 | "%s (pid %d) "({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in max_burst socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }) | |||
5819 | "Use of int in max_burst socket option.\n"({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in max_burst socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }) | |||
5820 | "Use struct sctp_assoc_value instead\n",({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in max_burst socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }) | |||
5821 | current->comm, task_pid_nr(current))({ static struct ratelimit_state _rs = { .lock = (raw_spinlock_t ) { .raw_lock = { { (0) } }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "_rs.lock" } }, .interval = (5 * 250), .burst = 10, }; if (___ratelimit(& _rs, __func__)) printk("\001" "4" "sctp" ": " "[Deprecated]: " "%s (pid %d) " "Use of int in max_burst socket option.\n" "Use struct sctp_assoc_value instead\n" , get_current()->comm, task_pid_nr(get_current())); }); | |||
5822 | params.assoc_id = 0; | |||
5823 | } else if (len >= sizeof(struct sctp_assoc_value)) { | |||
5824 | len = sizeof(struct sctp_assoc_value); | |||
5825 | if (copy_from_user(¶ms, optval, len)) | |||
5826 | return -EFAULT14; | |||
5827 | } else | |||
5828 | return -EINVAL22; | |||
5829 | ||||
5830 | sp = sctp_sk(sk); | |||
5831 | ||||
5832 | if (params.assoc_id != 0) { | |||
5833 | asoc = sctp_id2assoc(sk, params.assoc_id); | |||
5834 | if (!asoc) | |||
5835 | return -EINVAL22; | |||
5836 | params.assoc_value = asoc->max_burst; | |||
5837 | } else | |||
5838 | params.assoc_value = sp->max_burst; | |||
5839 | ||||
5840 | if (len == sizeof(int)) { | |||
5841 | if (copy_to_user(optval, ¶ms.assoc_value, len)) | |||
5842 | return -EFAULT14; | |||
5843 | } else { | |||
5844 | if (copy_to_user(optval, ¶ms, len)) | |||
5845 | return -EFAULT14; | |||
5846 | } | |||
5847 | ||||
5848 | return 0; | |||
5849 | ||||
5850 | } | |||
5851 | ||||
5852 | static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, | |||
5853 | char __user *optval, int __user *optlen) | |||
5854 | { | |||
5855 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; | |||
5856 | struct sctp_hmacalgo __user *p = (void __user *)optval; | |||
5857 | struct sctp_hmac_algo_param *hmacs; | |||
5858 | __u16 data_len = 0; | |||
5859 | u32 num_idents; | |||
5860 | int i; | |||
5861 | ||||
5862 | if (!ep->auth_enable) | |||
5863 | return -EACCES13; | |||
5864 | ||||
5865 | hmacs = ep->auth_hmacs_list; | |||
5866 | data_len = ntohs(hmacs->param_hdr.length)(__builtin_constant_p((__u16)(( __u16)(__be16)(hmacs->param_hdr .length))) ? ((__u16)( (((__u16)(( __u16)(__be16)(hmacs->param_hdr .length)) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16 )(__be16)(hmacs->param_hdr.length)) & (__u16)0xff00U) >> 8))) : __fswab16(( __u16)(__be16)(hmacs->param_hdr.length ))) - sizeof(sctp_paramhdr_t); | |||
5867 | ||||
5868 | if (len < sizeof(struct sctp_hmacalgo) + data_len) | |||
5869 | return -EINVAL22; | |||
5870 | ||||
5871 | len = sizeof(struct sctp_hmacalgo) + data_len; | |||
5872 | num_idents = data_len / sizeof(u16); | |||
5873 | ||||
5874 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5874); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5875 | return -EFAULT14; | |||
5876 | if (put_user(num_idents, &p->shmac_num_idents)({ int __ret_pu; __typeof__(*(&p->shmac_num_idents)) __pu_val ; (void)0; __might_fault("net/sctp/socket.c", 5876); __pu_val = num_idents; switch (sizeof(*(&p->shmac_num_idents)) ) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu ) : "0" ((typeof(*(&p->shmac_num_idents)))(__pu_val)), "c" (&p->shmac_num_idents) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof (*(&p->shmac_num_idents)))(__pu_val)), "c" (&p-> shmac_num_idents) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(&p->shmac_num_idents )))(__pu_val)), "c" (&p->shmac_num_idents) : "ebx"); break ; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu ) : "0" ((typeof(*(&p->shmac_num_idents)))(__pu_val)), "c" (&p->shmac_num_idents) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof (*(&p->shmac_num_idents)))(__pu_val)), "c" (&p-> shmac_num_idents) : "ebx"); break; } __builtin_expect(__ret_pu , 0); })) | |||
5877 | return -EFAULT14; | |||
5878 | for (i = 0; i < num_idents; i++) { | |||
5879 | __u16 hmacid = ntohs(hmacs->hmac_ids[i])(__builtin_constant_p((__u16)(( __u16)(__be16)(hmacs->hmac_ids [i]))) ? ((__u16)( (((__u16)(( __u16)(__be16)(hmacs->hmac_ids [i])) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16)( __be16)(hmacs->hmac_ids[i])) & (__u16)0xff00U) >> 8))) : __fswab16(( __u16)(__be16)(hmacs->hmac_ids[i]))); | |||
5880 | ||||
5881 | if (copy_to_user(&p->shmac_idents[i], &hmacid, sizeof(__u16))) | |||
5882 | return -EFAULT14; | |||
5883 | } | |||
5884 | return 0; | |||
5885 | } | |||
5886 | ||||
5887 | static int sctp_getsockopt_active_key(struct sock *sk, int len, | |||
5888 | char __user *optval, int __user *optlen) | |||
5889 | { | |||
5890 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; | |||
5891 | struct sctp_authkeyid val; | |||
5892 | struct sctp_association *asoc; | |||
5893 | ||||
5894 | if (!ep->auth_enable) | |||
5895 | return -EACCES13; | |||
5896 | ||||
5897 | if (len < sizeof(struct sctp_authkeyid)) | |||
5898 | return -EINVAL22; | |||
5899 | if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid))) | |||
5900 | return -EFAULT14; | |||
5901 | ||||
5902 | asoc = sctp_id2assoc(sk, val.scact_assoc_id); | |||
5903 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
5904 | return -EINVAL22; | |||
5905 | ||||
5906 | if (asoc) | |||
5907 | val.scact_keynumber = asoc->active_key_id; | |||
5908 | else | |||
5909 | val.scact_keynumber = ep->active_key_id; | |||
5910 | ||||
5911 | len = sizeof(struct sctp_authkeyid); | |||
5912 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5912); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5913 | return -EFAULT14; | |||
5914 | if (copy_to_user(optval, &val, len)) | |||
5915 | return -EFAULT14; | |||
5916 | ||||
5917 | return 0; | |||
5918 | } | |||
5919 | ||||
5920 | static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | |||
5921 | char __user *optval, int __user *optlen) | |||
5922 | { | |||
5923 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; | |||
5924 | struct sctp_authchunks __user *p = (void __user *)optval; | |||
5925 | struct sctp_authchunks val; | |||
5926 | struct sctp_association *asoc; | |||
5927 | struct sctp_chunks_param *ch; | |||
5928 | u32 num_chunks = 0; | |||
5929 | char __user *to; | |||
5930 | ||||
5931 | if (!ep->auth_enable) | |||
5932 | return -EACCES13; | |||
5933 | ||||
5934 | if (len < sizeof(struct sctp_authchunks)) | |||
5935 | return -EINVAL22; | |||
5936 | ||||
5937 | if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks))) | |||
5938 | return -EFAULT14; | |||
5939 | ||||
5940 | to = p->gauth_chunks; | |||
5941 | asoc = sctp_id2assoc(sk, val.gauth_assoc_id); | |||
5942 | if (!asoc) | |||
5943 | return -EINVAL22; | |||
5944 | ||||
5945 | ch = asoc->peer.peer_chunks; | |||
5946 | if (!ch) | |||
5947 | goto num; | |||
5948 | ||||
5949 | /* See if the user provided enough room for all the data */ | |||
5950 | num_chunks = ntohs(ch->param_hdr.length)(__builtin_constant_p((__u16)(( __u16)(__be16)(ch->param_hdr .length))) ? ((__u16)( (((__u16)(( __u16)(__be16)(ch->param_hdr .length)) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16 )(__be16)(ch->param_hdr.length)) & (__u16)0xff00U) >> 8))) : __fswab16(( __u16)(__be16)(ch->param_hdr.length))) - sizeof(sctp_paramhdr_t); | |||
5951 | if (len < num_chunks) | |||
5952 | return -EINVAL22; | |||
5953 | ||||
5954 | if (copy_to_user(to, ch->chunks, num_chunks)) | |||
5955 | return -EFAULT14; | |||
5956 | num: | |||
5957 | len = sizeof(struct sctp_authchunks) + num_chunks; | |||
5958 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 5958); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
5959 | return -EFAULT14; | |||
5960 | if (put_user(num_chunks, &p->gauth_number_of_chunks)({ int __ret_pu; __typeof__(*(&p->gauth_number_of_chunks )) __pu_val; (void)0; __might_fault("net/sctp/socket.c", 5960 ); __pu_val = num_chunks; switch (sizeof(*(&p->gauth_number_of_chunks ))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu ) : "0" ((typeof(*(&p->gauth_number_of_chunks)))(__pu_val )), "c" (&p->gauth_number_of_chunks) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(&p->gauth_number_of_chunks)))(__pu_val)), "c" (&p->gauth_number_of_chunks) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ( (typeof(*(&p->gauth_number_of_chunks)))(__pu_val)), "c" (&p->gauth_number_of_chunks) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ( (typeof(*(&p->gauth_number_of_chunks)))(__pu_val)), "c" (&p->gauth_number_of_chunks) : "ebx"); break; default : asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(&p->gauth_number_of_chunks)))(__pu_val)), "c" (&p->gauth_number_of_chunks) : "ebx"); break; } __builtin_expect (__ret_pu, 0); })) | |||
5961 | return -EFAULT14; | |||
5962 | return 0; | |||
5963 | } | |||
5964 | ||||
5965 | static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | |||
5966 | char __user *optval, int __user *optlen) | |||
5967 | { | |||
5968 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; | |||
5969 | struct sctp_authchunks __user *p = (void __user *)optval; | |||
5970 | struct sctp_authchunks val; | |||
5971 | struct sctp_association *asoc; | |||
5972 | struct sctp_chunks_param *ch; | |||
5973 | u32 num_chunks = 0; | |||
5974 | char __user *to; | |||
5975 | ||||
5976 | if (!ep->auth_enable) | |||
5977 | return -EACCES13; | |||
5978 | ||||
5979 | if (len < sizeof(struct sctp_authchunks)) | |||
5980 | return -EINVAL22; | |||
5981 | ||||
5982 | if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks))) | |||
5983 | return -EFAULT14; | |||
5984 | ||||
5985 | to = p->gauth_chunks; | |||
5986 | asoc = sctp_id2assoc(sk, val.gauth_assoc_id); | |||
5987 | if (!asoc && val.gauth_assoc_id && sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP))) | |||
5988 | return -EINVAL22; | |||
5989 | ||||
5990 | if (asoc) | |||
5991 | ch = (struct sctp_chunks_param *)asoc->c.auth_chunks; | |||
5992 | else | |||
5993 | ch = ep->auth_chunk_list; | |||
5994 | ||||
5995 | if (!ch) | |||
5996 | goto num; | |||
5997 | ||||
5998 | num_chunks = ntohs(ch->param_hdr.length)(__builtin_constant_p((__u16)(( __u16)(__be16)(ch->param_hdr .length))) ? ((__u16)( (((__u16)(( __u16)(__be16)(ch->param_hdr .length)) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16 )(__be16)(ch->param_hdr.length)) & (__u16)0xff00U) >> 8))) : __fswab16(( __u16)(__be16)(ch->param_hdr.length))) - sizeof(sctp_paramhdr_t); | |||
5999 | if (len < sizeof(struct sctp_authchunks) + num_chunks) | |||
6000 | return -EINVAL22; | |||
6001 | ||||
6002 | if (copy_to_user(to, ch->chunks, num_chunks)) | |||
6003 | return -EFAULT14; | |||
6004 | num: | |||
6005 | len = sizeof(struct sctp_authchunks) + num_chunks; | |||
6006 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 6006); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
6007 | return -EFAULT14; | |||
6008 | if (put_user(num_chunks, &p->gauth_number_of_chunks)({ int __ret_pu; __typeof__(*(&p->gauth_number_of_chunks )) __pu_val; (void)0; __might_fault("net/sctp/socket.c", 6008 ); __pu_val = num_chunks; switch (sizeof(*(&p->gauth_number_of_chunks ))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu ) : "0" ((typeof(*(&p->gauth_number_of_chunks)))(__pu_val )), "c" (&p->gauth_number_of_chunks) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(&p->gauth_number_of_chunks)))(__pu_val)), "c" (&p->gauth_number_of_chunks) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ( (typeof(*(&p->gauth_number_of_chunks)))(__pu_val)), "c" (&p->gauth_number_of_chunks) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ( (typeof(*(&p->gauth_number_of_chunks)))(__pu_val)), "c" (&p->gauth_number_of_chunks) : "ebx"); break; default : asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(&p->gauth_number_of_chunks)))(__pu_val)), "c" (&p->gauth_number_of_chunks) : "ebx"); break; } __builtin_expect (__ret_pu, 0); })) | |||
6009 | return -EFAULT14; | |||
6010 | ||||
6011 | return 0; | |||
6012 | } | |||
6013 | ||||
6014 | /* | |||
6015 | * 8.2.5. Get the Current Number of Associations (SCTP_GET_ASSOC_NUMBER) | |||
6016 | * This option gets the current number of associations that are attached | |||
6017 | * to a one-to-many style socket. The option value is an uint32_t. | |||
6018 | */ | |||
6019 | static int sctp_getsockopt_assoc_number(struct sock *sk, int len, | |||
6020 | char __user *optval, int __user *optlen) | |||
6021 | { | |||
6022 | struct sctp_sock *sp = sctp_sk(sk); | |||
6023 | struct sctp_association *asoc; | |||
6024 | u32 val = 0; | |||
6025 | ||||
6026 | if (sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP))) | |||
6027 | return -EOPNOTSUPP95; | |||
6028 | ||||
6029 | if (len < sizeof(u32)) | |||
6030 | return -EINVAL22; | |||
6031 | ||||
6032 | len = sizeof(u32); | |||
6033 | ||||
6034 | list_for_each_entry(asoc, &(sp->ep->asocs), asocs)for (asoc = ({ const typeof( ((typeof(*asoc) *)0)->asocs ) *__mptr = ((&(sp->ep->asocs))->next); (typeof(* asoc) *)( (char *)__mptr - __builtin_offsetof(typeof(*asoc), asocs ) );}); &asoc->asocs != (&(sp->ep->asocs)); asoc = ({ const typeof( ((typeof(*(asoc)) *)0)->asocs ) *__mptr = ((asoc)->asocs.next); (typeof(*(asoc)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(asoc)), asocs) );})) { | |||
6035 | val++; | |||
6036 | } | |||
6037 | ||||
6038 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 6038); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
6039 | return -EFAULT14; | |||
6040 | if (copy_to_user(optval, &val, len)) | |||
6041 | return -EFAULT14; | |||
6042 | ||||
6043 | return 0; | |||
6044 | } | |||
6045 | ||||
6046 | /* | |||
6047 | * 8.1.23 SCTP_AUTO_ASCONF | |||
6048 | * See the corresponding setsockopt entry as description | |||
6049 | */ | |||
6050 | static int sctp_getsockopt_auto_asconf(struct sock *sk, int len, | |||
6051 | char __user *optval, int __user *optlen) | |||
6052 | { | |||
6053 | int val = 0; | |||
6054 | ||||
6055 | if (len < sizeof(int)) | |||
6056 | return -EINVAL22; | |||
6057 | ||||
6058 | len = sizeof(int); | |||
6059 | if (sctp_sk(sk)->do_auto_asconf && sctp_is_ep_boundall(sk)) | |||
6060 | val = 1; | |||
6061 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 6061); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
6062 | return -EFAULT14; | |||
6063 | if (copy_to_user(optval, &val, len)) | |||
6064 | return -EFAULT14; | |||
6065 | return 0; | |||
6066 | } | |||
6067 | ||||
6068 | /* | |||
6069 | * 8.2.6. Get the Current Identifiers of Associations | |||
6070 | * (SCTP_GET_ASSOC_ID_LIST) | |||
6071 | * | |||
6072 | * This option gets the current list of SCTP association identifiers of | |||
6073 | * the SCTP associations handled by a one-to-many style socket. | |||
6074 | */ | |||
6075 | static int sctp_getsockopt_assoc_ids(struct sock *sk, int len, | |||
6076 | char __user *optval, int __user *optlen) | |||
6077 | { | |||
6078 | struct sctp_sock *sp = sctp_sk(sk); | |||
6079 | struct sctp_association *asoc; | |||
6080 | struct sctp_assoc_ids *ids; | |||
6081 | u32 num = 0; | |||
6082 | ||||
6083 | if (sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP))) | |||
6084 | return -EOPNOTSUPP95; | |||
6085 | ||||
6086 | if (len < sizeof(struct sctp_assoc_ids)) | |||
6087 | return -EINVAL22; | |||
6088 | ||||
6089 | list_for_each_entry(asoc, &(sp->ep->asocs), asocs)for (asoc = ({ const typeof( ((typeof(*asoc) *)0)->asocs ) *__mptr = ((&(sp->ep->asocs))->next); (typeof(* asoc) *)( (char *)__mptr - __builtin_offsetof(typeof(*asoc), asocs ) );}); &asoc->asocs != (&(sp->ep->asocs)); asoc = ({ const typeof( ((typeof(*(asoc)) *)0)->asocs ) *__mptr = ((asoc)->asocs.next); (typeof(*(asoc)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(asoc)), asocs) );})) { | |||
6090 | num++; | |||
6091 | } | |||
6092 | ||||
6093 | if (len < sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num) | |||
6094 | return -EINVAL22; | |||
6095 | ||||
6096 | len = sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num; | |||
6097 | ||||
6098 | ids = kmalloc(len, GFP_USER((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u) | (( gfp_t)0x20000u)) | __GFP_NOWARN(( gfp_t)0x200u)); | |||
6099 | if (unlikely(!ids)(!ids)) | |||
6100 | return -ENOMEM12; | |||
6101 | ||||
6102 | ids->gaids_number_of_ids = num; | |||
6103 | num = 0; | |||
6104 | list_for_each_entry(asoc, &(sp->ep->asocs), asocs)for (asoc = ({ const typeof( ((typeof(*asoc) *)0)->asocs ) *__mptr = ((&(sp->ep->asocs))->next); (typeof(* asoc) *)( (char *)__mptr - __builtin_offsetof(typeof(*asoc), asocs ) );}); &asoc->asocs != (&(sp->ep->asocs)); asoc = ({ const typeof( ((typeof(*(asoc)) *)0)->asocs ) *__mptr = ((asoc)->asocs.next); (typeof(*(asoc)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(asoc)), asocs) );})) { | |||
6105 | ids->gaids_assoc_id[num++] = asoc->assoc_id; | |||
6106 | } | |||
6107 | ||||
6108 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 6108); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); }) || copy_to_user(optval, ids, len)) { | |||
6109 | kfree(ids); | |||
6110 | return -EFAULT14; | |||
6111 | } | |||
6112 | ||||
6113 | kfree(ids); | |||
6114 | return 0; | |||
6115 | } | |||
6116 | ||||
6117 | /* | |||
6118 | * SCTP_PEER_ADDR_THLDS | |||
6119 | * | |||
6120 | * This option allows us to fetch the partially failed threshold for one or all | |||
6121 | * transports in an association. See Section 6.1 of: | |||
6122 | * http://www.ietf.org/id/draft-nishida-tsvwg-sctp-failover-05.txt | |||
6123 | */ | |||
6124 | static int sctp_getsockopt_paddr_thresholds(struct sock *sk, | |||
6125 | char __user *optval, | |||
6126 | int len, | |||
6127 | int __user *optlen) | |||
6128 | { | |||
6129 | struct sctp_paddrthlds val; | |||
6130 | struct sctp_transport *trans; | |||
6131 | struct sctp_association *asoc; | |||
6132 | ||||
6133 | if (len < sizeof(struct sctp_paddrthlds)) | |||
6134 | return -EINVAL22; | |||
6135 | len = sizeof(struct sctp_paddrthlds); | |||
6136 | if (copy_from_user(&val, (struct sctp_paddrthlds __user *)optval, len)) | |||
6137 | return -EFAULT14; | |||
6138 | ||||
6139 | if (sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) { | |||
6140 | asoc = sctp_id2assoc(sk, val.spt_assoc_id); | |||
6141 | if (!asoc) | |||
6142 | return -ENOENT2; | |||
6143 | ||||
6144 | val.spt_pathpfthld = asoc->pf_retrans; | |||
6145 | val.spt_pathmaxrxt = asoc->pathmaxrxt; | |||
6146 | } else { | |||
6147 | trans = sctp_addr_id2transport(sk, &val.spt_address, | |||
6148 | val.spt_assoc_id); | |||
6149 | if (!trans) | |||
6150 | return -ENOENT2; | |||
6151 | ||||
6152 | val.spt_pathmaxrxt = trans->pathmaxrxt; | |||
6153 | val.spt_pathpfthld = trans->pf_retrans; | |||
6154 | } | |||
6155 | ||||
6156 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 6156); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); }) || copy_to_user(optval, &val, len)) | |||
6157 | return -EFAULT14; | |||
6158 | ||||
6159 | return 0; | |||
6160 | } | |||
6161 | ||||
6162 | /* | |||
6163 | * SCTP_GET_ASSOC_STATS | |||
6164 | * | |||
6165 | * This option retrieves local per endpoint statistics. It is modeled | |||
6166 | * after OpenSolaris' implementation | |||
6167 | */ | |||
6168 | static int sctp_getsockopt_assoc_stats(struct sock *sk, int len, | |||
6169 | char __user *optval, | |||
6170 | int __user *optlen) | |||
6171 | { | |||
6172 | struct sctp_assoc_stats sas; | |||
6173 | struct sctp_association *asoc = NULL((void *)0); | |||
6174 | ||||
6175 | /* User must provide at least the assoc id */ | |||
6176 | if (len < sizeof(sctp_assoc_t)) | |||
6177 | return -EINVAL22; | |||
6178 | ||||
6179 | /* Allow the struct to grow and fill in as much as possible */ | |||
6180 | len = min_t(size_t, len, sizeof(sas))({ size_t __UNIQUE_ID_min1_70 = (len); size_t __UNIQUE_ID_min2_71 = (sizeof(sas)); (void) (&__UNIQUE_ID_min1_70 == &__UNIQUE_ID_min2_71 ); __UNIQUE_ID_min1_70 < __UNIQUE_ID_min2_71 ? __UNIQUE_ID_min1_70 : __UNIQUE_ID_min2_71; }); | |||
6181 | ||||
6182 | if (copy_from_user(&sas, optval, len)) | |||
6183 | return -EFAULT14; | |||
6184 | ||||
6185 | asoc = sctp_id2assoc(sk, sas.sas_assoc_id); | |||
6186 | if (!asoc) | |||
6187 | return -EINVAL22; | |||
6188 | ||||
6189 | sas.sas_rtxchunks = asoc->stats.rtxchunks; | |||
6190 | sas.sas_gapcnt = asoc->stats.gapcnt; | |||
6191 | sas.sas_outofseqtsns = asoc->stats.outofseqtsns; | |||
6192 | sas.sas_osacks = asoc->stats.osacks; | |||
6193 | sas.sas_isacks = asoc->stats.isacks; | |||
6194 | sas.sas_octrlchunks = asoc->stats.octrlchunks; | |||
6195 | sas.sas_ictrlchunks = asoc->stats.ictrlchunks; | |||
6196 | sas.sas_oodchunks = asoc->stats.oodchunks; | |||
6197 | sas.sas_iodchunks = asoc->stats.iodchunks; | |||
6198 | sas.sas_ouodchunks = asoc->stats.ouodchunks; | |||
6199 | sas.sas_iuodchunks = asoc->stats.iuodchunks; | |||
6200 | sas.sas_idupchunks = asoc->stats.idupchunks; | |||
6201 | sas.sas_opackets = asoc->stats.opackets; | |||
6202 | sas.sas_ipackets = asoc->stats.ipackets; | |||
6203 | ||||
6204 | /* New high max rto observed, will return 0 if not a single | |||
6205 | * RTO update took place. obs_rto_ipaddr will be bogus | |||
6206 | * in such a case | |||
6207 | */ | |||
6208 | sas.sas_maxrto = asoc->stats.max_obs_rto; | |||
6209 | memcpy(&sas.sas_obs_rto_ipaddr, &asoc->stats.obs_rto_ipaddr,({ size_t __len = (sizeof(struct __kernel_sockaddr_storage)); void *__ret; if (__builtin_constant_p(sizeof(struct __kernel_sockaddr_storage )) && __len >= 64) __ret = __memcpy((&sas.sas_obs_rto_ipaddr ), (&asoc->stats.obs_rto_ipaddr), __len); else __ret = __builtin_memcpy((&sas.sas_obs_rto_ipaddr), (&asoc-> stats.obs_rto_ipaddr), __len); __ret; }) | |||
6210 | sizeof(struct sockaddr_storage))({ size_t __len = (sizeof(struct __kernel_sockaddr_storage)); void *__ret; if (__builtin_constant_p(sizeof(struct __kernel_sockaddr_storage )) && __len >= 64) __ret = __memcpy((&sas.sas_obs_rto_ipaddr ), (&asoc->stats.obs_rto_ipaddr), __len); else __ret = __builtin_memcpy((&sas.sas_obs_rto_ipaddr), (&asoc-> stats.obs_rto_ipaddr), __len); __ret; }); | |||
6211 | ||||
6212 | /* Mark beginning of a new observation period */ | |||
6213 | asoc->stats.max_obs_rto = asoc->rto_min; | |||
6214 | ||||
6215 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 6215); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
6216 | return -EFAULT14; | |||
6217 | ||||
6218 | pr_debug("%s: len:%d, assoc_id:%d\n", __func__, len, sas.sas_assoc_id)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: len:%d, assoc_id:%d\n" ), .lineno = 6218, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: len:%d, assoc_id:%d\n", __func__, len, sas.sas_assoc_id ); } while (0); | |||
6219 | ||||
6220 | if (copy_to_user(optval, &sas, len)) | |||
6221 | return -EFAULT14; | |||
6222 | ||||
6223 | return 0; | |||
6224 | } | |||
6225 | ||||
6226 | static int sctp_getsockopt_recvrcvinfo(struct sock *sk, int len, | |||
6227 | char __user *optval, | |||
6228 | int __user *optlen) | |||
6229 | { | |||
6230 | int val = 0; | |||
6231 | ||||
6232 | if (len < sizeof(int)) | |||
6233 | return -EINVAL22; | |||
6234 | ||||
6235 | len = sizeof(int); | |||
6236 | if (sctp_sk(sk)->recvrcvinfo) | |||
6237 | val = 1; | |||
6238 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 6238); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
6239 | return -EFAULT14; | |||
6240 | if (copy_to_user(optval, &val, len)) | |||
6241 | return -EFAULT14; | |||
6242 | ||||
6243 | return 0; | |||
6244 | } | |||
6245 | ||||
6246 | static int sctp_getsockopt_recvnxtinfo(struct sock *sk, int len, | |||
6247 | char __user *optval, | |||
6248 | int __user *optlen) | |||
6249 | { | |||
6250 | int val = 0; | |||
6251 | ||||
6252 | if (len < sizeof(int)) | |||
6253 | return -EINVAL22; | |||
6254 | ||||
6255 | len = sizeof(int); | |||
6256 | if (sctp_sk(sk)->recvnxtinfo) | |||
6257 | val = 1; | |||
6258 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 6258); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
6259 | return -EFAULT14; | |||
6260 | if (copy_to_user(optval, &val, len)) | |||
6261 | return -EFAULT14; | |||
6262 | ||||
6263 | return 0; | |||
6264 | } | |||
6265 | ||||
6266 | static int sctp_getsockopt_pr_supported(struct sock *sk, int len, | |||
6267 | char __user *optval, | |||
6268 | int __user *optlen) | |||
6269 | { | |||
6270 | struct sctp_assoc_value params; | |||
6271 | struct sctp_association *asoc; | |||
6272 | int retval = -EFAULT14; | |||
6273 | ||||
6274 | if (len < sizeof(params)) { | |||
6275 | retval = -EINVAL22; | |||
6276 | goto out; | |||
6277 | } | |||
6278 | ||||
6279 | len = sizeof(params); | |||
6280 | if (copy_from_user(¶ms, optval, len)) | |||
6281 | goto out; | |||
6282 | ||||
6283 | asoc = sctp_id2assoc(sk, params.assoc_id); | |||
6284 | if (asoc) { | |||
6285 | params.assoc_value = asoc->prsctp_enable; | |||
6286 | } else if (!params.assoc_id) { | |||
6287 | struct sctp_sock *sp = sctp_sk(sk); | |||
6288 | ||||
6289 | params.assoc_value = sp->ep->prsctp_enable; | |||
6290 | } else { | |||
6291 | retval = -EINVAL22; | |||
6292 | goto out; | |||
6293 | } | |||
6294 | ||||
6295 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 6295); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
6296 | goto out; | |||
6297 | ||||
6298 | if (copy_to_user(optval, ¶ms, len)) | |||
6299 | goto out; | |||
6300 | ||||
6301 | retval = 0; | |||
6302 | ||||
6303 | out: | |||
6304 | return retval; | |||
6305 | } | |||
6306 | ||||
6307 | static int sctp_getsockopt_default_prinfo(struct sock *sk, int len, | |||
6308 | char __user *optval, | |||
6309 | int __user *optlen) | |||
6310 | { | |||
6311 | struct sctp_default_prinfo info; | |||
6312 | struct sctp_association *asoc; | |||
6313 | int retval = -EFAULT14; | |||
6314 | ||||
6315 | if (len < sizeof(info)) { | |||
6316 | retval = -EINVAL22; | |||
6317 | goto out; | |||
6318 | } | |||
6319 | ||||
6320 | len = sizeof(info); | |||
6321 | if (copy_from_user(&info, optval, len)) | |||
6322 | goto out; | |||
6323 | ||||
6324 | asoc = sctp_id2assoc(sk, info.pr_assoc_id); | |||
6325 | if (asoc) { | |||
6326 | info.pr_policy = SCTP_PR_POLICY(asoc->default_flags)((asoc->default_flags) & 0x0030); | |||
6327 | info.pr_value = asoc->default_timetolive; | |||
6328 | } else if (!info.pr_assoc_id) { | |||
6329 | struct sctp_sock *sp = sctp_sk(sk); | |||
6330 | ||||
6331 | info.pr_policy = SCTP_PR_POLICY(sp->default_flags)((sp->default_flags) & 0x0030); | |||
6332 | info.pr_value = sp->default_timetolive; | |||
6333 | } else { | |||
6334 | retval = -EINVAL22; | |||
6335 | goto out; | |||
6336 | } | |||
6337 | ||||
6338 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 6338); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) | |||
6339 | goto out; | |||
6340 | ||||
6341 | if (copy_to_user(optval, &info, len)) | |||
6342 | goto out; | |||
6343 | ||||
6344 | retval = 0; | |||
6345 | ||||
6346 | out: | |||
6347 | return retval; | |||
6348 | } | |||
6349 | ||||
6350 | static int sctp_getsockopt_pr_assocstatus(struct sock *sk, int len, | |||
6351 | char __user *optval, | |||
6352 | int __user *optlen) | |||
6353 | { | |||
6354 | struct sctp_prstatus params; | |||
6355 | struct sctp_association *asoc; | |||
6356 | int policy; | |||
6357 | int retval = -EINVAL22; | |||
6358 | ||||
6359 | if (len < sizeof(params)) | |||
6360 | goto out; | |||
6361 | ||||
6362 | len = sizeof(params); | |||
6363 | if (copy_from_user(¶ms, optval, len)) { | |||
6364 | retval = -EFAULT14; | |||
6365 | goto out; | |||
6366 | } | |||
6367 | ||||
6368 | policy = params.sprstat_policy; | |||
6369 | if (policy & ~SCTP_PR_SCTP_MASK0x0030) | |||
6370 | goto out; | |||
6371 | ||||
6372 | asoc = sctp_id2assoc(sk, params.sprstat_assoc_id); | |||
6373 | if (!asoc) | |||
6374 | goto out; | |||
6375 | ||||
6376 | if (policy == SCTP_PR_SCTP_NONE0x0000) { | |||
6377 | params.sprstat_abandoned_unsent = 0; | |||
6378 | params.sprstat_abandoned_sent = 0; | |||
6379 | for (policy = 0; policy <= SCTP_PR_INDEX(MAX)((0x0030 >> 4) - 1); policy++) { | |||
6380 | params.sprstat_abandoned_unsent += | |||
6381 | asoc->abandoned_unsent[policy]; | |||
6382 | params.sprstat_abandoned_sent += | |||
6383 | asoc->abandoned_sent[policy]; | |||
6384 | } | |||
6385 | } else { | |||
6386 | params.sprstat_abandoned_unsent = | |||
6387 | asoc->abandoned_unsent[__SCTP_PR_INDEX(policy)((policy >> 4) - 1)]; | |||
6388 | params.sprstat_abandoned_sent = | |||
6389 | asoc->abandoned_sent[__SCTP_PR_INDEX(policy)((policy >> 4) - 1)]; | |||
6390 | } | |||
6391 | ||||
6392 | if (put_user(len, optlen)({ int __ret_pu; __typeof__(*(optlen)) __pu_val; (void)0; __might_fault ("net/sctp/socket.c", 6392); __pu_val = len; switch (sizeof(* (optlen))) { case 1: asm volatile("call __put_user_" "1" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen ) : "ebx"); break; case 2: asm volatile("call __put_user_" "2" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 4: asm volatile("call __put_user_" "4" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; case 8: asm volatile("call __put_user_" "8" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; default: asm volatile("call __put_user_" "X" : "=a" (__ret_pu) : "0" ((typeof(*(optlen)))(__pu_val)), "c" (optlen) : "ebx"); break; } __builtin_expect(__ret_pu, 0 ); })) { | |||
6393 | retval = -EFAULT14; | |||
6394 | goto out; | |||
6395 | } | |||
6396 | ||||
6397 | if (copy_to_user(optval, ¶ms, len)) { | |||
6398 | retval = -EFAULT14; | |||
6399 | goto out; | |||
6400 | } | |||
6401 | ||||
6402 | retval = 0; | |||
6403 | ||||
6404 | out: | |||
6405 | return retval; | |||
6406 | } | |||
6407 | ||||
6408 | static int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
6409 | char __user *optval, int __user *optlen) | |||
6410 | { | |||
6411 | int retval = 0; | |||
6412 | int len; | |||
6413 | ||||
6414 | pr_debug("%s: sk:%p, optname:%d\n", __func__, sk, optname)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: sk:%p, optname:%d\n" ), .lineno = 6414, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: sk:%p, optname:%d\n", __func__, sk, optname); } while ( 0); | |||
6415 | ||||
6416 | /* I can hardly begin to describe how wrong this is. This is | |||
6417 | * so broken as to be worse than useless. The API draft | |||
6418 | * REALLY is NOT helpful here... I am not convinced that the | |||
6419 | * semantics of getsockopt() with a level OTHER THAN SOL_SCTP | |||
6420 | * are at all well-founded. | |||
6421 | */ | |||
6422 | if (level != SOL_SCTP132) { | |||
| ||||
6423 | struct sctp_af *af = sctp_sk(sk)->pf->af; | |||
6424 | ||||
6425 | retval = af->getsockopt(sk, level, optname, optval, optlen); | |||
6426 | return retval; | |||
6427 | } | |||
6428 | ||||
6429 | if (get_user(len, optlen)({ int __ret_gu; register __typeof__(__builtin_choose_expr(sizeof (*(optlen)) > sizeof(0UL), 0ULL, 0UL)) __val_gu asm("%""rdx" ); register void *__sp asm("rsp"); (void)0; __might_fault("net/sctp/socket.c" , 6429); asm volatile("call __get_user_%P4" : "=a" (__ret_gu) , "=r" (__val_gu), "+r" (__sp) : "0" (optlen), "i" (sizeof(*( optlen)))); (len) = ( __typeof__(*(optlen))) __val_gu; clang_analyzer_taint (&len); __builtin_expect(__ret_gu, 0); })) | |||
6430 | return -EFAULT14; | |||
6431 | ||||
6432 | if (len < 0) | |||
6433 | return -EINVAL22; | |||
6434 | ||||
6435 | lock_sock(sk); | |||
6436 | ||||
6437 | switch (optname) { | |||
6438 | case SCTP_STATUS14: | |||
6439 | retval = sctp_getsockopt_sctp_status(sk, len, optval, optlen); | |||
6440 | break; | |||
6441 | case SCTP_DISABLE_FRAGMENTS8: | |||
6442 | retval = sctp_getsockopt_disable_fragments(sk, len, optval, | |||
6443 | optlen); | |||
6444 | break; | |||
6445 | case SCTP_EVENTS11: | |||
6446 | retval = sctp_getsockopt_events(sk, len, optval, optlen); | |||
6447 | break; | |||
6448 | case SCTP_AUTOCLOSE4: | |||
6449 | retval = sctp_getsockopt_autoclose(sk, len, optval, optlen); | |||
6450 | break; | |||
6451 | case SCTP_SOCKOPT_PEELOFF102: | |||
6452 | retval = sctp_getsockopt_peeloff(sk, len, optval, optlen); | |||
6453 | break; | |||
6454 | case SCTP_PEER_ADDR_PARAMS9: | |||
6455 | retval = sctp_getsockopt_peer_addr_params(sk, len, optval, | |||
6456 | optlen); | |||
6457 | break; | |||
6458 | case SCTP_DELAYED_SACK16: | |||
6459 | retval = sctp_getsockopt_delayed_ack(sk, len, optval, | |||
6460 | optlen); | |||
6461 | break; | |||
6462 | case SCTP_INITMSG2: | |||
6463 | retval = sctp_getsockopt_initmsg(sk, len, optval, optlen); | |||
6464 | break; | |||
6465 | case SCTP_GET_PEER_ADDRS108: | |||
6466 | retval = sctp_getsockopt_peer_addrs(sk, len, optval, | |||
6467 | optlen); | |||
6468 | break; | |||
6469 | case SCTP_GET_LOCAL_ADDRS109: | |||
6470 | retval = sctp_getsockopt_local_addrs(sk, len, optval, | |||
6471 | optlen); | |||
6472 | break; | |||
6473 | case SCTP_SOCKOPT_CONNECTX3111: | |||
6474 | retval = sctp_getsockopt_connectx3(sk, len, optval, optlen); | |||
6475 | break; | |||
6476 | case SCTP_DEFAULT_SEND_PARAM10: | |||
6477 | retval = sctp_getsockopt_default_send_param(sk, len, | |||
6478 | optval, optlen); | |||
6479 | break; | |||
6480 | case SCTP_DEFAULT_SNDINFO34: | |||
6481 | retval = sctp_getsockopt_default_sndinfo(sk, len, | |||
6482 | optval, optlen); | |||
6483 | break; | |||
6484 | case SCTP_PRIMARY_ADDR6: | |||
6485 | retval = sctp_getsockopt_primary_addr(sk, len, optval, optlen); | |||
6486 | break; | |||
6487 | case SCTP_NODELAY3: | |||
6488 | retval = sctp_getsockopt_nodelay(sk, len, optval, optlen); | |||
6489 | break; | |||
6490 | case SCTP_RTOINFO0: | |||
6491 | retval = sctp_getsockopt_rtoinfo(sk, len, optval, optlen); | |||
6492 | break; | |||
6493 | case SCTP_ASSOCINFO1: | |||
6494 | retval = sctp_getsockopt_associnfo(sk, len, optval, optlen); | |||
6495 | break; | |||
6496 | case SCTP_I_WANT_MAPPED_V4_ADDR12: | |||
6497 | retval = sctp_getsockopt_mappedv4(sk, len, optval, optlen); | |||
6498 | break; | |||
6499 | case SCTP_MAXSEG13: | |||
6500 | retval = sctp_getsockopt_maxseg(sk, len, optval, optlen); | |||
6501 | break; | |||
6502 | case SCTP_GET_PEER_ADDR_INFO15: | |||
6503 | retval = sctp_getsockopt_peer_addr_info(sk, len, optval, | |||
6504 | optlen); | |||
6505 | break; | |||
6506 | case SCTP_ADAPTATION_LAYER7: | |||
6507 | retval = sctp_getsockopt_adaptation_layer(sk, len, optval, | |||
6508 | optlen); | |||
6509 | break; | |||
6510 | case SCTP_CONTEXT17: | |||
6511 | retval = sctp_getsockopt_context(sk, len, optval, optlen); | |||
6512 | break; | |||
6513 | case SCTP_FRAGMENT_INTERLEAVE18: | |||
6514 | retval = sctp_getsockopt_fragment_interleave(sk, len, optval, | |||
6515 | optlen); | |||
6516 | break; | |||
6517 | case SCTP_PARTIAL_DELIVERY_POINT19: | |||
6518 | retval = sctp_getsockopt_partial_delivery_point(sk, len, optval, | |||
6519 | optlen); | |||
6520 | break; | |||
6521 | case SCTP_MAX_BURST20: | |||
6522 | retval = sctp_getsockopt_maxburst(sk, len, optval, optlen); | |||
6523 | break; | |||
6524 | case SCTP_AUTH_KEY23: | |||
6525 | case SCTP_AUTH_CHUNK21: | |||
6526 | case SCTP_AUTH_DELETE_KEY25: | |||
6527 | retval = -EOPNOTSUPP95; | |||
6528 | break; | |||
6529 | case SCTP_HMAC_IDENT22: | |||
6530 | retval = sctp_getsockopt_hmac_ident(sk, len, optval, optlen); | |||
6531 | break; | |||
6532 | case SCTP_AUTH_ACTIVE_KEY24: | |||
6533 | retval = sctp_getsockopt_active_key(sk, len, optval, optlen); | |||
6534 | break; | |||
6535 | case SCTP_PEER_AUTH_CHUNKS26: | |||
6536 | retval = sctp_getsockopt_peer_auth_chunks(sk, len, optval, | |||
6537 | optlen); | |||
6538 | break; | |||
6539 | case SCTP_LOCAL_AUTH_CHUNKS27: | |||
6540 | retval = sctp_getsockopt_local_auth_chunks(sk, len, optval, | |||
6541 | optlen); | |||
6542 | break; | |||
6543 | case SCTP_GET_ASSOC_NUMBER28: | |||
6544 | retval = sctp_getsockopt_assoc_number(sk, len, optval, optlen); | |||
6545 | break; | |||
6546 | case SCTP_GET_ASSOC_ID_LIST29: | |||
6547 | retval = sctp_getsockopt_assoc_ids(sk, len, optval, optlen); | |||
6548 | break; | |||
6549 | case SCTP_AUTO_ASCONF30: | |||
6550 | retval = sctp_getsockopt_auto_asconf(sk, len, optval, optlen); | |||
6551 | break; | |||
6552 | case SCTP_PEER_ADDR_THLDS31: | |||
6553 | retval = sctp_getsockopt_paddr_thresholds(sk, optval, len, optlen); | |||
6554 | break; | |||
6555 | case SCTP_GET_ASSOC_STATS112: | |||
6556 | retval = sctp_getsockopt_assoc_stats(sk, len, optval, optlen); | |||
6557 | break; | |||
6558 | case SCTP_RECVRCVINFO32: | |||
6559 | retval = sctp_getsockopt_recvrcvinfo(sk, len, optval, optlen); | |||
6560 | break; | |||
6561 | case SCTP_RECVNXTINFO33: | |||
6562 | retval = sctp_getsockopt_recvnxtinfo(sk, len, optval, optlen); | |||
6563 | break; | |||
6564 | case SCTP_PR_SUPPORTED113: | |||
6565 | retval = sctp_getsockopt_pr_supported(sk, len, optval, optlen); | |||
6566 | break; | |||
6567 | case SCTP_DEFAULT_PRINFO114: | |||
6568 | retval = sctp_getsockopt_default_prinfo(sk, len, optval, | |||
6569 | optlen); | |||
6570 | break; | |||
6571 | case SCTP_PR_ASSOC_STATUS115: | |||
6572 | retval = sctp_getsockopt_pr_assocstatus(sk, len, optval, | |||
6573 | optlen); | |||
6574 | break; | |||
6575 | default: | |||
6576 | retval = -ENOPROTOOPT92; | |||
6577 | break; | |||
6578 | } | |||
6579 | ||||
6580 | release_sock(sk); | |||
6581 | return retval; | |||
6582 | } | |||
6583 | ||||
6584 | static int sctp_hash(struct sock *sk) | |||
6585 | { | |||
6586 | /* STUB */ | |||
6587 | return 0; | |||
6588 | } | |||
6589 | ||||
6590 | static void sctp_unhash(struct sock *sk) | |||
6591 | { | |||
6592 | /* STUB */ | |||
6593 | } | |||
6594 | ||||
6595 | /* Check if port is acceptable. Possibly find first available port. | |||
6596 | * | |||
6597 | * The port hash table (contained in the 'global' SCTP protocol storage | |||
6598 | * returned by struct sctp_protocol *sctp_get_protocol()). The hash | |||
6599 | * table is an array of 4096 lists (sctp_bind_hashbucket). Each | |||
6600 | * list (the list number is the port number hashed out, so as you | |||
6601 | * would expect from a hash function, all the ports in a given list have | |||
6602 | * such a number that hashes out to the same list number; you were | |||
6603 | * expecting that, right?); so each list has a set of ports, with a | |||
6604 | * link to the socket (struct sock) that uses it, the port number and | |||
6605 | * a fastreuse flag (FIXME: NPI ipg). | |||
6606 | */ | |||
6607 | static struct sctp_bind_bucket *sctp_bucket_create( | |||
6608 | struct sctp_bind_hashbucket *head, struct net *, unsigned short snum); | |||
6609 | ||||
6610 | static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) | |||
6611 | { | |||
6612 | struct sctp_bind_hashbucket *head; /* hash list */ | |||
6613 | struct sctp_bind_bucket *pp; | |||
6614 | unsigned short snum; | |||
6615 | int ret; | |||
6616 | ||||
6617 | snum = ntohs(addr->v4.sin_port)(__builtin_constant_p((__u16)(( __u16)(__be16)(addr->v4.sin_port ))) ? ((__u16)( (((__u16)(( __u16)(__be16)(addr->v4.sin_port )) & (__u16)0x00ffU) << 8) | (((__u16)(( __u16)(__be16 )(addr->v4.sin_port)) & (__u16)0xff00U) >> 8))) : __fswab16(( __u16)(__be16)(addr->v4.sin_port))); | |||
6618 | ||||
6619 | pr_debug("%s: begins, snum:%d\n", __func__, snum)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: begins, snum:%d\n" ), .lineno = 6619, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: begins, snum:%d\n", __func__, snum); } while (0); | |||
6620 | ||||
6621 | local_bh_disable(); | |||
6622 | ||||
6623 | if (snum == 0) { | |||
6624 | /* Search for an available port. */ | |||
6625 | int low, high, remaining, index; | |||
6626 | unsigned int rover; | |||
6627 | struct net *net = sock_net(sk); | |||
6628 | ||||
6629 | inet_get_local_port_range(net, &low, &high); | |||
6630 | remaining = (high - low) + 1; | |||
6631 | rover = prandom_u32() % remaining + low; | |||
6632 | ||||
6633 | do { | |||
6634 | rover++; | |||
6635 | if ((rover < low) || (rover > high)) | |||
6636 | rover = low; | |||
6637 | if (inet_is_local_reserved_port(net, rover)) | |||
6638 | continue; | |||
6639 | index = sctp_phashfn(sock_net(sk), rover); | |||
6640 | head = &sctp_port_hashtable(sctp_globals.port_hashtable)[index]; | |||
6641 | spin_lock(&head->lock); | |||
6642 | sctp_for_each_hentry(pp, &head->chain)for (pp = ({ typeof((&head->chain)->first) ____ptr = ((&head->chain)->first); ____ptr ? ({ const typeof ( ((typeof(*(pp)) *)0)->node ) *__mptr = (____ptr); (typeof (*(pp)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(pp)) , node) );}) : ((void *)0); }); pp; pp = ({ typeof((pp)->node .next) ____ptr = ((pp)->node.next); ____ptr ? ({ const typeof ( ((typeof(*(pp)) *)0)->node ) *__mptr = (____ptr); (typeof (*(pp)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(pp)) , node) );}) : ((void *)0); })) | |||
6643 | if ((pp->port == rover) && | |||
6644 | net_eq(sock_net(sk), pp->net)) | |||
6645 | goto next; | |||
6646 | break; | |||
6647 | next: | |||
6648 | spin_unlock(&head->lock); | |||
6649 | } while (--remaining > 0); | |||
6650 | ||||
6651 | /* Exhausted local port range during search? */ | |||
6652 | ret = 1; | |||
6653 | if (remaining <= 0) | |||
6654 | goto fail; | |||
6655 | ||||
6656 | /* OK, here is the one we will use. HEAD (the port | |||
6657 | * hash table list entry) is non-NULL and we hold it's | |||
6658 | * mutex. | |||
6659 | */ | |||
6660 | snum = rover; | |||
6661 | } else { | |||
6662 | /* We are given an specific port number; we verify | |||
6663 | * that it is not being used. If it is used, we will | |||
6664 | * exahust the search in the hash list corresponding | |||
6665 | * to the port number (snum) - we detect that with the | |||
6666 | * port iterator, pp being NULL. | |||
6667 | */ | |||
6668 | head = &sctp_port_hashtable(sctp_globals.port_hashtable)[sctp_phashfn(sock_net(sk), snum)]; | |||
6669 | spin_lock(&head->lock); | |||
6670 | sctp_for_each_hentry(pp, &head->chain)for (pp = ({ typeof((&head->chain)->first) ____ptr = ((&head->chain)->first); ____ptr ? ({ const typeof ( ((typeof(*(pp)) *)0)->node ) *__mptr = (____ptr); (typeof (*(pp)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(pp)) , node) );}) : ((void *)0); }); pp; pp = ({ typeof((pp)->node .next) ____ptr = ((pp)->node.next); ____ptr ? ({ const typeof ( ((typeof(*(pp)) *)0)->node ) *__mptr = (____ptr); (typeof (*(pp)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(pp)) , node) );}) : ((void *)0); })) { | |||
6671 | if ((pp->port == snum) && net_eq(pp->net, sock_net(sk))) | |||
6672 | goto pp_found; | |||
6673 | } | |||
6674 | } | |||
6675 | pp = NULL((void *)0); | |||
6676 | goto pp_not_found; | |||
6677 | pp_found: | |||
6678 | if (!hlist_empty(&pp->owner)) { | |||
6679 | /* We had a port hash table hit - there is an | |||
6680 | * available port (pp != NULL) and it is being | |||
6681 | * used by other socket (pp->owner not empty); that other | |||
6682 | * socket is going to be sk2. | |||
6683 | */ | |||
6684 | int reuse = sk->sk_reuse__sk_common.skc_reuse; | |||
6685 | struct sock *sk2; | |||
6686 | ||||
6687 | pr_debug("%s: found a possible match\n", __func__)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: found a possible match\n" ), .lineno = 6687, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: found a possible match\n", __func__); } while (0); | |||
6688 | ||||
6689 | if (pp->fastreuse && sk->sk_reuse__sk_common.skc_reuse && | |||
6690 | sk->sk_state__sk_common.skc_state != SCTP_SS_LISTENING) | |||
6691 | goto success; | |||
6692 | ||||
6693 | /* Run through the list of sockets bound to the port | |||
6694 | * (pp->port) [via the pointers bind_next and | |||
6695 | * bind_pprev in the struct sock *sk2 (pp->sk)]. On each one, | |||
6696 | * we get the endpoint they describe and run through | |||
6697 | * the endpoint's list of IP (v4 or v6) addresses, | |||
6698 | * comparing each of the addresses with the address of | |||
6699 | * the socket sk. If we find a match, then that means | |||
6700 | * that this port/socket (sk) combination are already | |||
6701 | * in an endpoint. | |||
6702 | */ | |||
6703 | sk_for_each_bound(sk2, &pp->owner)for (sk2 = ({ typeof((&pp->owner)->first) ____ptr = ((&pp->owner)->first); ____ptr ? ({ const typeof( ( (typeof(*(sk2)) *)0)->__sk_common.skc_bind_node ) *__mptr = (____ptr); (typeof(*(sk2)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(sk2)), __sk_common.skc_bind_node) );}) : ((void *)0 ); }); sk2; sk2 = ({ typeof((sk2)->__sk_common.skc_bind_node .next) ____ptr = ((sk2)->__sk_common.skc_bind_node.next); ____ptr ? ({ const typeof( ((typeof(*(sk2)) *)0)->__sk_common.skc_bind_node ) *__mptr = (____ptr); (typeof(*(sk2)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(sk2)), __sk_common.skc_bind_node) );}) : ((void *)0 ); })) { | |||
6704 | struct sctp_endpoint *ep2; | |||
6705 | ep2 = sctp_sk(sk2)->ep; | |||
6706 | ||||
6707 | if (sk == sk2 || | |||
6708 | (reuse && sk2->sk_reuse__sk_common.skc_reuse && | |||
6709 | sk2->sk_state__sk_common.skc_state != SCTP_SS_LISTENING)) | |||
6710 | continue; | |||
6711 | ||||
6712 | if (sctp_bind_addr_conflict(&ep2->base.bind_addr, addr, | |||
6713 | sctp_sk(sk2), sctp_sk(sk))) { | |||
6714 | ret = (long)sk2; | |||
6715 | goto fail_unlock; | |||
6716 | } | |||
6717 | } | |||
6718 | ||||
6719 | pr_debug("%s: found a match\n", __func__)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: found a match\n" ), .lineno = 6719, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: found a match\n", __func__); } while (0); | |||
6720 | } | |||
6721 | pp_not_found: | |||
6722 | /* If there was a hash table miss, create a new port. */ | |||
6723 | ret = 1; | |||
6724 | if (!pp && !(pp = sctp_bucket_create(head, sock_net(sk), snum))) | |||
6725 | goto fail_unlock; | |||
6726 | ||||
6727 | /* In either case (hit or miss), make sure fastreuse is 1 only | |||
6728 | * if sk->sk_reuse is too (that is, if the caller requested | |||
6729 | * SO_REUSEADDR on this socket -sk-). | |||
6730 | */ | |||
6731 | if (hlist_empty(&pp->owner)) { | |||
6732 | if (sk->sk_reuse__sk_common.skc_reuse && sk->sk_state__sk_common.skc_state != SCTP_SS_LISTENING) | |||
6733 | pp->fastreuse = 1; | |||
6734 | else | |||
6735 | pp->fastreuse = 0; | |||
6736 | } else if (pp->fastreuse && | |||
6737 | (!sk->sk_reuse__sk_common.skc_reuse || sk->sk_state__sk_common.skc_state == SCTP_SS_LISTENING)) | |||
6738 | pp->fastreuse = 0; | |||
6739 | ||||
6740 | /* We are set, so fill up all the data in the hash table | |||
6741 | * entry, tie the socket list information with the rest of the | |||
6742 | * sockets FIXME: Blurry, NPI (ipg). | |||
6743 | */ | |||
6744 | success: | |||
6745 | if (!sctp_sk(sk)->bind_hash) { | |||
6746 | inet_sk(sk)->inet_numsk.__sk_common.skc_num = snum; | |||
6747 | sk_add_bind_node(sk, &pp->owner); | |||
6748 | sctp_sk(sk)->bind_hash = pp; | |||
6749 | } | |||
6750 | ret = 0; | |||
6751 | ||||
6752 | fail_unlock: | |||
6753 | spin_unlock(&head->lock); | |||
6754 | ||||
6755 | fail: | |||
6756 | local_bh_enable(); | |||
6757 | return ret; | |||
6758 | } | |||
6759 | ||||
6760 | /* Assign a 'snum' port to the socket. If snum == 0, an ephemeral | |||
6761 | * port is requested. | |||
6762 | */ | |||
6763 | static int sctp_get_port(struct sock *sk, unsigned short snum) | |||
6764 | { | |||
6765 | union sctp_addr addr; | |||
6766 | struct sctp_af *af = sctp_sk(sk)->pf->af; | |||
6767 | ||||
6768 | /* Set up a dummy address struct from the sk. */ | |||
6769 | af->from_sk(&addr, sk); | |||
6770 | addr.v4.sin_port = htons(snum)(( __be16)(__builtin_constant_p((__u16)((snum))) ? ((__u16)( ( ((__u16)((snum)) & (__u16)0x00ffU) << 8) | (((__u16 )((snum)) & (__u16)0xff00U) >> 8))) : __fswab16((snum )))); | |||
6771 | ||||
6772 | /* Note: sk->sk_num gets filled in if ephemeral port request. */ | |||
6773 | return !!sctp_get_port_local(sk, &addr); | |||
6774 | } | |||
6775 | ||||
6776 | /* | |||
6777 | * Move a socket to LISTENING state. | |||
6778 | */ | |||
6779 | static int sctp_listen_start(struct sock *sk, int backlog) | |||
6780 | { | |||
6781 | struct sctp_sock *sp = sctp_sk(sk); | |||
6782 | struct sctp_endpoint *ep = sp->ep; | |||
6783 | struct crypto_shash *tfm = NULL((void *)0); | |||
6784 | char alg[32]; | |||
6785 | ||||
6786 | /* Allocate HMAC for generating cookie. */ | |||
6787 | if (!sp->hmac && sp->sctp_hmac_alg) { | |||
6788 | sprintf(alg, "hmac(%s)", sp->sctp_hmac_alg); | |||
6789 | tfm = crypto_alloc_shash(alg, 0, 0); | |||
6790 | if (IS_ERR(tfm)) { | |||
6791 | net_info_ratelimited("failed to load transform for %s: %ld\n",do { if (net_ratelimit()) printk("\001" "6" "sctp" ": " "failed to load transform for %s: %ld\n" , sp->sctp_hmac_alg, PTR_ERR(tfm)); } while (0) | |||
6792 | sp->sctp_hmac_alg, PTR_ERR(tfm))do { if (net_ratelimit()) printk("\001" "6" "sctp" ": " "failed to load transform for %s: %ld\n" , sp->sctp_hmac_alg, PTR_ERR(tfm)); } while (0); | |||
6793 | return -ENOSYS38; | |||
6794 | } | |||
6795 | sctp_sk(sk)->hmac = tfm; | |||
6796 | } | |||
6797 | ||||
6798 | /* | |||
6799 | * If a bind() or sctp_bindx() is not called prior to a listen() | |||
6800 | * call that allows new associations to be accepted, the system | |||
6801 | * picks an ephemeral port and will choose an address set equivalent | |||
6802 | * to binding with a wildcard address. | |||
6803 | * | |||
6804 | * This is not currently spelled out in the SCTP sockets | |||
6805 | * extensions draft, but follows the practice as seen in TCP | |||
6806 | * sockets. | |||
6807 | * | |||
6808 | */ | |||
6809 | sk->sk_state__sk_common.skc_state = SCTP_SS_LISTENING; | |||
6810 | if (!ep->base.bind_addr.port) { | |||
6811 | if (sctp_autobind(sk)) | |||
6812 | return -EAGAIN11; | |||
6813 | } else { | |||
6814 | if (sctp_get_port(sk, inet_sk(sk)->inet_numsk.__sk_common.skc_num)) { | |||
6815 | sk->sk_state__sk_common.skc_state = SCTP_SS_CLOSED; | |||
6816 | return -EADDRINUSE98; | |||
6817 | } | |||
6818 | } | |||
6819 | ||||
6820 | sk->sk_max_ack_backlog = backlog; | |||
6821 | sctp_hash_endpoint(ep); | |||
6822 | return 0; | |||
6823 | } | |||
6824 | ||||
6825 | /* | |||
6826 | * 4.1.3 / 5.1.3 listen() | |||
6827 | * | |||
6828 | * By default, new associations are not accepted for UDP style sockets. | |||
6829 | * An application uses listen() to mark a socket as being able to | |||
6830 | * accept new associations. | |||
6831 | * | |||
6832 | * On TCP style sockets, applications use listen() to ready the SCTP | |||
6833 | * endpoint for accepting inbound associations. | |||
6834 | * | |||
6835 | * On both types of endpoints a backlog of '0' disables listening. | |||
6836 | * | |||
6837 | * Move a socket to LISTENING state. | |||
6838 | */ | |||
6839 | int sctp_inet_listen(struct socket *sock, int backlog) | |||
6840 | { | |||
6841 | struct sock *sk = sock->sk; | |||
6842 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; | |||
6843 | int err = -EINVAL22; | |||
6844 | ||||
6845 | if (unlikely(backlog < 0)(backlog < 0)) | |||
6846 | return err; | |||
6847 | ||||
6848 | lock_sock(sk); | |||
6849 | ||||
6850 | /* Peeled-off sockets are not allowed to listen(). */ | |||
6851 | if (sctp_style(sk, UDP_HIGH_BANDWIDTH)__sctp_style((sk), (SCTP_SOCKET_UDP_HIGH_BANDWIDTH))) | |||
6852 | goto out; | |||
6853 | ||||
6854 | if (sock->state != SS_UNCONNECTED) | |||
6855 | goto out; | |||
6856 | ||||
6857 | /* If backlog is zero, disable listening. */ | |||
6858 | if (!backlog) { | |||
6859 | if (sctp_sstate(sk, CLOSED)__sctp_sstate((sk), (SCTP_SS_CLOSED))) | |||
6860 | goto out; | |||
6861 | ||||
6862 | err = 0; | |||
6863 | sctp_unhash_endpoint(ep); | |||
6864 | sk->sk_state__sk_common.skc_state = SCTP_SS_CLOSED; | |||
6865 | if (sk->sk_reuse__sk_common.skc_reuse) | |||
6866 | sctp_sk(sk)->bind_hash->fastreuse = 1; | |||
6867 | goto out; | |||
6868 | } | |||
6869 | ||||
6870 | /* If we are already listening, just update the backlog */ | |||
6871 | if (sctp_sstate(sk, LISTENING)__sctp_sstate((sk), (SCTP_SS_LISTENING))) | |||
6872 | sk->sk_max_ack_backlog = backlog; | |||
6873 | else { | |||
6874 | err = sctp_listen_start(sk, backlog); | |||
6875 | if (err) | |||
6876 | goto out; | |||
6877 | } | |||
6878 | ||||
6879 | err = 0; | |||
6880 | out: | |||
6881 | release_sock(sk); | |||
6882 | return err; | |||
6883 | } | |||
6884 | ||||
6885 | /* | |||
6886 | * This function is done by modeling the current datagram_poll() and the | |||
6887 | * tcp_poll(). Note that, based on these implementations, we don't | |||
6888 | * lock the socket in this function, even though it seems that, | |||
6889 | * ideally, locking or some other mechanisms can be used to ensure | |||
6890 | * the integrity of the counters (sndbuf and wmem_alloc) used | |||
6891 | * in this place. We assume that we don't need locks either until proven | |||
6892 | * otherwise. | |||
6893 | * | |||
6894 | * Another thing to note is that we include the Async I/O support | |||
6895 | * here, again, by modeling the current TCP/UDP code. We don't have | |||
6896 | * a good way to test with it yet. | |||
6897 | */ | |||
6898 | unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
6899 | { | |||
6900 | struct sock *sk = sock->sk; | |||
6901 | struct sctp_sock *sp = sctp_sk(sk); | |||
6902 | unsigned int mask; | |||
6903 | ||||
6904 | poll_wait(file, sk_sleep(sk), wait); | |||
6905 | ||||
6906 | sock_rps_record_flow(sk); | |||
6907 | ||||
6908 | /* A TCP-style listening socket becomes readable when the accept queue | |||
6909 | * is not empty. | |||
6910 | */ | |||
6911 | if (sctp_style(sk, TCP)__sctp_style((sk), (SCTP_SOCKET_TCP)) && sctp_sstate(sk, LISTENING)__sctp_sstate((sk), (SCTP_SS_LISTENING))) | |||
6912 | return (!list_empty(&sp->ep->asocs)) ? | |||
6913 | (POLLIN0x0001 | POLLRDNORM0x0040) : 0; | |||
6914 | ||||
6915 | mask = 0; | |||
6916 | ||||
6917 | /* Is there any exceptional events? */ | |||
6918 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) | |||
6919 | mask |= POLLERR0x0008 | | |||
6920 | (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI0x0002 : 0); | |||
6921 | if (sk->sk_shutdown & RCV_SHUTDOWN1) | |||
6922 | mask |= POLLRDHUP0x2000 | POLLIN0x0001 | POLLRDNORM0x0040; | |||
6923 | if (sk->sk_shutdown == SHUTDOWN_MASK3) | |||
6924 | mask |= POLLHUP0x0010; | |||
6925 | ||||
6926 | /* Is it readable? Reconsider this code with TCP-style support. */ | |||
6927 | if (!skb_queue_empty(&sk->sk_receive_queue)) | |||
6928 | mask |= POLLIN0x0001 | POLLRDNORM0x0040; | |||
6929 | ||||
6930 | /* The association is either gone or not ready. */ | |||
6931 | if (!sctp_style(sk, UDP)__sctp_style((sk), (SCTP_SOCKET_UDP)) && sctp_sstate(sk, CLOSED)__sctp_sstate((sk), (SCTP_SS_CLOSED))) | |||
6932 | return mask; | |||
6933 | ||||
6934 | /* Is it writable? */ | |||
6935 | if (sctp_writeable(sk)) { | |||
6936 | mask |= POLLOUT0x0004 | POLLWRNORM0x0100; | |||
6937 | } else { | |||
6938 | sk_set_bit(SOCKWQ_ASYNC_NOSPACE0, sk); | |||
6939 | /* | |||
6940 | * Since the socket is not locked, the buffer | |||
6941 | * might be made available after the writeable check and | |||
6942 | * before the bit is set. This could cause a lost I/O | |||
6943 | * signal. tcp_poll() has a race breaker for this race | |||
6944 | * condition. Based on their implementation, we put | |||
6945 | * in the following code to cover it as well. | |||
6946 | */ | |||
6947 | if (sctp_writeable(sk)) | |||
6948 | mask |= POLLOUT0x0004 | POLLWRNORM0x0100; | |||
6949 | } | |||
6950 | return mask; | |||
6951 | } | |||
6952 | ||||
6953 | /******************************************************************** | |||
6954 | * 2nd Level Abstractions | |||
6955 | ********************************************************************/ | |||
6956 | ||||
6957 | static struct sctp_bind_bucket *sctp_bucket_create( | |||
6958 | struct sctp_bind_hashbucket *head, struct net *net, unsigned short snum) | |||
6959 | { | |||
6960 | struct sctp_bind_bucket *pp; | |||
6961 | ||||
6962 | pp = kmem_cache_alloc(sctp_bucket_cachep, GFP_ATOMIC((( gfp_t)0x20u)|(( gfp_t)0x80000u)|(( gfp_t)0x2000000u))); | |||
6963 | if (pp) { | |||
6964 | SCTP_DBG_OBJCNT_INC(bind_bucket)atomic_inc(&sctp_dbg_objcnt_bind_bucket); | |||
6965 | pp->port = snum; | |||
6966 | pp->fastreuse = 0; | |||
6967 | INIT_HLIST_HEAD(&pp->owner)((&pp->owner)->first = ((void *)0)); | |||
6968 | pp->net = net; | |||
6969 | hlist_add_head(&pp->node, &head->chain); | |||
6970 | } | |||
6971 | return pp; | |||
6972 | } | |||
6973 | ||||
6974 | /* Caller must hold hashbucket lock for this tb with local BH disabled */ | |||
6975 | static void sctp_bucket_destroy(struct sctp_bind_bucket *pp) | |||
6976 | { | |||
6977 | if (pp && hlist_empty(&pp->owner)) { | |||
6978 | __hlist_del(&pp->node); | |||
6979 | kmem_cache_free(sctp_bucket_cachep, pp); | |||
6980 | SCTP_DBG_OBJCNT_DEC(bind_bucket)atomic_dec(&sctp_dbg_objcnt_bind_bucket); | |||
6981 | } | |||
6982 | } | |||
6983 | ||||
6984 | /* Release this socket's reference to a local port. */ | |||
6985 | static inlineinline __attribute__((no_instrument_function)) void __sctp_put_port(struct sock *sk) | |||
6986 | { | |||
6987 | struct sctp_bind_hashbucket *head = | |||
6988 | &sctp_port_hashtable(sctp_globals.port_hashtable)[sctp_phashfn(sock_net(sk), | |||
6989 | inet_sk(sk)->inet_numsk.__sk_common.skc_num)]; | |||
6990 | struct sctp_bind_bucket *pp; | |||
6991 | ||||
6992 | spin_lock(&head->lock); | |||
6993 | pp = sctp_sk(sk)->bind_hash; | |||
6994 | __sk_del_bind_node(sk); | |||
6995 | sctp_sk(sk)->bind_hash = NULL((void *)0); | |||
6996 | inet_sk(sk)->inet_numsk.__sk_common.skc_num = 0; | |||
6997 | sctp_bucket_destroy(pp); | |||
6998 | spin_unlock(&head->lock); | |||
6999 | } | |||
7000 | ||||
7001 | void sctp_put_port(struct sock *sk) | |||
7002 | { | |||
7003 | local_bh_disable(); | |||
7004 | __sctp_put_port(sk); | |||
7005 | local_bh_enable(); | |||
7006 | } | |||
7007 | ||||
7008 | /* | |||
7009 | * The system picks an ephemeral port and choose an address set equivalent | |||
7010 | * to binding with a wildcard address. | |||
7011 | * One of those addresses will be the primary address for the association. | |||
7012 | * This automatically enables the multihoming capability of SCTP. | |||
7013 | */ | |||
7014 | static int sctp_autobind(struct sock *sk) | |||
7015 | { | |||
7016 | union sctp_addr autoaddr; | |||
7017 | struct sctp_af *af; | |||
7018 | __be16 port; | |||
7019 | ||||
7020 | /* Initialize a local sockaddr structure to INADDR_ANY. */ | |||
7021 | af = sctp_sk(sk)->pf->af; | |||
7022 | ||||
7023 | port = htons(inet_sk(sk)->inet_num)(( __be16)(__builtin_constant_p((__u16)((inet_sk(sk)->sk.__sk_common .skc_num))) ? ((__u16)( (((__u16)((inet_sk(sk)->sk.__sk_common .skc_num)) & (__u16)0x00ffU) << 8) | (((__u16)((inet_sk (sk)->sk.__sk_common.skc_num)) & (__u16)0xff00U) >> 8))) : __fswab16((inet_sk(sk)->sk.__sk_common.skc_num)))); | |||
7024 | af->inaddr_any(&autoaddr, port); | |||
7025 | ||||
7026 | return sctp_do_bind(sk, &autoaddr, af->sockaddr_len); | |||
7027 | } | |||
7028 | ||||
7029 | /* Parse out IPPROTO_SCTP CMSG headers. Perform only minimal validation. | |||
7030 | * | |||
7031 | * From RFC 2292 | |||
7032 | * 4.2 The cmsghdr Structure * | |||
7033 | * | |||
7034 | * When ancillary data is sent or received, any number of ancillary data | |||
7035 | * objects can be specified by the msg_control and msg_controllen members of | |||
7036 | * the msghdr structure, because each object is preceded by | |||
7037 | * a cmsghdr structure defining the object's length (the cmsg_len member). | |||
7038 | * Historically Berkeley-derived implementations have passed only one object | |||
7039 | * at a time, but this API allows multiple objects to be | |||
7040 | * passed in a single call to sendmsg() or recvmsg(). The following example | |||
7041 | * shows two ancillary data objects in a control buffer. | |||
7042 | * | |||
7043 | * |<--------------------------- msg_controllen -------------------------->| | |||
7044 | * | | | |||
7045 | * | |||
7046 | * |<----- ancillary data object ----->|<----- ancillary data object ----->| | |||
7047 | * | |||
7048 | * |<---------- CMSG_SPACE() --------->|<---------- CMSG_SPACE() --------->| | |||
7049 | * | | | | |||
7050 | * | |||
7051 | * |<---------- cmsg_len ---------->| |<--------- cmsg_len ----------->| | | |||
7052 | * | |||
7053 | * |<--------- CMSG_LEN() --------->| |<-------- CMSG_LEN() ---------->| | | |||
7054 | * | | | | | | |||
7055 | * | |||
7056 | * +-----+-----+-----+--+-----------+--+-----+-----+-----+--+-----------+--+ | |||
7057 | * |cmsg_|cmsg_|cmsg_|XX| |XX|cmsg_|cmsg_|cmsg_|XX| |XX| | |||
7058 | * | |||
7059 | * |len |level|type |XX|cmsg_data[]|XX|len |level|type |XX|cmsg_data[]|XX| | |||
7060 | * | |||
7061 | * +-----+-----+-----+--+-----------+--+-----+-----+-----+--+-----------+--+ | |||
7062 | * ^ | |||
7063 | * | | |||
7064 | * | |||
7065 | * msg_control | |||
7066 | * points here | |||
7067 | */ | |||
7068 | static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs) | |||
7069 | { | |||
7070 | struct cmsghdr *cmsg; | |||
7071 | struct msghdr *my_msg = (struct msghdr *)msg; | |||
7072 | ||||
7073 | for_each_cmsghdr(cmsg, my_msg)for (cmsg = (((my_msg)->msg_controllen) >= sizeof(struct cmsghdr) ? (struct cmsghdr *)((my_msg)->msg_control) : (struct cmsghdr *)((void *)0)); cmsg; cmsg = cmsg_nxthdr((my_msg), ( cmsg))) { | |||
7074 | if (!CMSG_OK(my_msg, cmsg)((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && ( cmsg)->cmsg_len <= (unsigned long) ((my_msg)->msg_controllen - ((char *)(cmsg) - (char *)(my_msg)->msg_control)))) | |||
7075 | return -EINVAL22; | |||
7076 | ||||
7077 | /* Should we parse this header or ignore? */ | |||
7078 | if (cmsg->cmsg_level != IPPROTO_SCTPIPPROTO_SCTP) | |||
7079 | continue; | |||
7080 | ||||
7081 | /* Strictly check lengths following example in SCM code. */ | |||
7082 | switch (cmsg->cmsg_type) { | |||
7083 | case SCTP_INITSCTP_INIT: | |||
7084 | /* SCTP Socket API Extension | |||
7085 | * 5.3.1 SCTP Initiation Structure (SCTP_INIT) | |||
7086 | * | |||
7087 | * This cmsghdr structure provides information for | |||
7088 | * initializing new SCTP associations with sendmsg(). | |||
7089 | * The SCTP_INITMSG socket option uses this same data | |||
7090 | * structure. This structure is not used for | |||
7091 | * recvmsg(). | |||
7092 | * | |||
7093 | * cmsg_level cmsg_type cmsg_data[] | |||
7094 | * ------------ ------------ ---------------------- | |||
7095 | * IPPROTO_SCTP SCTP_INIT struct sctp_initmsg | |||
7096 | */ | |||
7097 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_initmsg))(( ((sizeof(struct cmsghdr))+sizeof(long)-1) & ~(sizeof(long )-1) ) + (sizeof(struct sctp_initmsg)))) | |||
7098 | return -EINVAL22; | |||
7099 | ||||
7100 | cmsgs->init = CMSG_DATA(cmsg)((void *)((char *)(cmsg) + ( ((sizeof(struct cmsghdr))+sizeof (long)-1) & ~(sizeof(long)-1) ))); | |||
7101 | break; | |||
7102 | ||||
7103 | case SCTP_SNDRCVSCTP_SNDRCV: | |||
7104 | /* SCTP Socket API Extension | |||
7105 | * 5.3.2 SCTP Header Information Structure(SCTP_SNDRCV) | |||
7106 | * | |||
7107 | * This cmsghdr structure specifies SCTP options for | |||
7108 | * sendmsg() and describes SCTP header information | |||
7109 | * about a received message through recvmsg(). | |||
7110 | * | |||
7111 | * cmsg_level cmsg_type cmsg_data[] | |||
7112 | * ------------ ------------ ---------------------- | |||
7113 | * IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo | |||
7114 | */ | |||
7115 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_sndrcvinfo))(( ((sizeof(struct cmsghdr))+sizeof(long)-1) & ~(sizeof(long )-1) ) + (sizeof(struct sctp_sndrcvinfo)))) | |||
7116 | return -EINVAL22; | |||
7117 | ||||
7118 | cmsgs->srinfo = CMSG_DATA(cmsg)((void *)((char *)(cmsg) + ( ((sizeof(struct cmsghdr))+sizeof (long)-1) & ~(sizeof(long)-1) ))); | |||
7119 | ||||
7120 | if (cmsgs->srinfo->sinfo_flags & | |||
7121 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | | |||
7122 | SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK0x0030 | | |||
7123 | SCTP_ABORT | SCTP_EOF)) | |||
7124 | return -EINVAL22; | |||
7125 | break; | |||
7126 | ||||
7127 | case SCTP_SNDINFOSCTP_SNDINFO: | |||
7128 | /* SCTP Socket API Extension | |||
7129 | * 5.3.4 SCTP Send Information Structure (SCTP_SNDINFO) | |||
7130 | * | |||
7131 | * This cmsghdr structure specifies SCTP options for | |||
7132 | * sendmsg(). This structure and SCTP_RCVINFO replaces | |||
7133 | * SCTP_SNDRCV which has been deprecated. | |||
7134 | * | |||
7135 | * cmsg_level cmsg_type cmsg_data[] | |||
7136 | * ------------ ------------ --------------------- | |||
7137 | * IPPROTO_SCTP SCTP_SNDINFO struct sctp_sndinfo | |||
7138 | */ | |||
7139 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_sndinfo))(( ((sizeof(struct cmsghdr))+sizeof(long)-1) & ~(sizeof(long )-1) ) + (sizeof(struct sctp_sndinfo)))) | |||
7140 | return -EINVAL22; | |||
7141 | ||||
7142 | cmsgs->sinfo = CMSG_DATA(cmsg)((void *)((char *)(cmsg) + ( ((sizeof(struct cmsghdr))+sizeof (long)-1) & ~(sizeof(long)-1) ))); | |||
7143 | ||||
7144 | if (cmsgs->sinfo->snd_flags & | |||
7145 | ~(SCTP_UNORDERED | SCTP_ADDR_OVER | | |||
7146 | SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK0x0030 | | |||
7147 | SCTP_ABORT | SCTP_EOF)) | |||
7148 | return -EINVAL22; | |||
7149 | break; | |||
7150 | default: | |||
7151 | return -EINVAL22; | |||
7152 | } | |||
7153 | } | |||
7154 | ||||
7155 | return 0; | |||
7156 | } | |||
7157 | ||||
7158 | /* | |||
7159 | * Wait for a packet.. | |||
7160 | * Note: This function is the same function as in core/datagram.c | |||
7161 | * with a few modifications to make lksctp work. | |||
7162 | */ | |||
7163 | static int sctp_wait_for_packet(struct sock *sk, int *err, long *timeo_p) | |||
7164 | { | |||
7165 | int error; | |||
7166 | DEFINE_WAIT(wait)wait_queue_t wait = { .private = get_current(), .func = autoremove_wake_function , .task_list = { &((wait).task_list), &((wait).task_list ) }, }; | |||
7167 | ||||
7168 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE1); | |||
7169 | ||||
7170 | /* Socket errors? */ | |||
7171 | error = sock_error(sk); | |||
7172 | if (error) | |||
7173 | goto out; | |||
7174 | ||||
7175 | if (!skb_queue_empty(&sk->sk_receive_queue)) | |||
7176 | goto ready; | |||
7177 | ||||
7178 | /* Socket shut down? */ | |||
7179 | if (sk->sk_shutdown & RCV_SHUTDOWN1) | |||
7180 | goto out; | |||
7181 | ||||
7182 | /* Sequenced packets can come disconnected. If so we report the | |||
7183 | * problem. | |||
7184 | */ | |||
7185 | error = -ENOTCONN107; | |||
7186 | ||||
7187 | /* Is there a good reason to think that we may receive some data? */ | |||
7188 | if (list_empty(&sctp_sk(sk)->ep->asocs) && !sctp_sstate(sk, LISTENING)__sctp_sstate((sk), (SCTP_SS_LISTENING))) | |||
7189 | goto out; | |||
7190 | ||||
7191 | /* Handle signals. */ | |||
7192 | if (signal_pending(currentget_current())) | |||
7193 | goto interrupted; | |||
7194 | ||||
7195 | /* Let another process have a go. Since we are going to sleep | |||
7196 | * anyway. Note: This may cause odd behaviors if the message | |||
7197 | * does not fit in the user's buffer, but this seems to be the | |||
7198 | * only way to honor MSG_DONTWAIT realistically. | |||
7199 | */ | |||
7200 | release_sock(sk); | |||
7201 | *timeo_p = schedule_timeout(*timeo_p); | |||
7202 | lock_sock(sk); | |||
7203 | ||||
7204 | ready: | |||
7205 | finish_wait(sk_sleep(sk), &wait); | |||
7206 | return 0; | |||
7207 | ||||
7208 | interrupted: | |||
7209 | error = sock_intr_errno(*timeo_p); | |||
7210 | ||||
7211 | out: | |||
7212 | finish_wait(sk_sleep(sk), &wait); | |||
7213 | *err = error; | |||
7214 | return error; | |||
7215 | } | |||
7216 | ||||
7217 | /* Receive a datagram. | |||
7218 | * Note: This is pretty much the same routine as in core/datagram.c | |||
7219 | * with a few changes to make lksctp work. | |||
7220 | */ | |||
7221 | struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, | |||
7222 | int noblock, int *err) | |||
7223 | { | |||
7224 | int error; | |||
7225 | struct sk_buff *skb; | |||
7226 | long timeo; | |||
7227 | ||||
7228 | timeo = sock_rcvtimeo(sk, noblock); | |||
7229 | ||||
7230 | pr_debug("%s: timeo:%ld, max:%ld\n", __func__, timeo,do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: timeo:%ld, max:%ld\n" ), .lineno = 7231, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: timeo:%ld, max:%ld\n", __func__, timeo, ((long)(~0UL>> 1))); } while (0) | |||
7231 | MAX_SCHEDULE_TIMEOUT)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: timeo:%ld, max:%ld\n" ), .lineno = 7231, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: timeo:%ld, max:%ld\n", __func__, timeo, ((long)(~0UL>> 1))); } while (0); | |||
7232 | ||||
7233 | do { | |||
7234 | /* Again only user level code calls this function, | |||
7235 | * so nothing interrupt level | |||
7236 | * will suddenly eat the receive_queue. | |||
7237 | * | |||
7238 | * Look at current nfs client by the way... | |||
7239 | * However, this function was correct in any case. 8) | |||
7240 | */ | |||
7241 | if (flags & MSG_PEEK2) { | |||
7242 | skb = skb_peek(&sk->sk_receive_queue); | |||
7243 | if (skb) | |||
7244 | atomic_inc(&skb->users); | |||
7245 | } else { | |||
7246 | skb = __skb_dequeue(&sk->sk_receive_queue); | |||
7247 | } | |||
7248 | ||||
7249 | if (skb) | |||
7250 | return skb; | |||
7251 | ||||
7252 | /* Caller is allowed not to check sk->sk_err before calling. */ | |||
7253 | error = sock_error(sk); | |||
7254 | if (error) | |||
7255 | goto no_packet; | |||
7256 | ||||
7257 | if (sk->sk_shutdown & RCV_SHUTDOWN1) | |||
7258 | break; | |||
7259 | ||||
7260 | if (sk_can_busy_loop(sk) && | |||
7261 | sk_busy_loop(sk, noblock)) | |||
7262 | continue; | |||
7263 | ||||
7264 | /* User doesn't want to wait. */ | |||
7265 | error = -EAGAIN11; | |||
7266 | if (!timeo) | |||
7267 | goto no_packet; | |||
7268 | } while (sctp_wait_for_packet(sk, err, &timeo) == 0); | |||
7269 | ||||
7270 | return NULL((void *)0); | |||
7271 | ||||
7272 | no_packet: | |||
7273 | *err = error; | |||
7274 | return NULL((void *)0); | |||
7275 | } | |||
7276 | ||||
7277 | /* If sndbuf has changed, wake up per association sndbuf waiters. */ | |||
7278 | static void __sctp_write_space(struct sctp_association *asoc) | |||
7279 | { | |||
7280 | struct sock *sk = asoc->base.sk; | |||
7281 | ||||
7282 | if (sctp_wspace(asoc) <= 0) | |||
7283 | return; | |||
7284 | ||||
7285 | if (waitqueue_active(&asoc->wait)) | |||
7286 | wake_up_interruptible(&asoc->wait)__wake_up(&asoc->wait, 1, 1, ((void *)0)); | |||
7287 | ||||
7288 | if (sctp_writeable(sk)) { | |||
7289 | struct socket_wq *wq; | |||
7290 | ||||
7291 | rcu_read_lock(); | |||
7292 | wq = rcu_dereference(sk->sk_wq)({ typeof(*(sk->sk_wq)) *________p1 = (typeof(*(sk->sk_wq )) *)({ typeof((sk->sk_wq)) _________p1 = ({ union { typeof ((sk->sk_wq)) __val; char __c[1]; } __u; if (1) __read_once_size (&((sk->sk_wq)), __u.__c, sizeof((sk->sk_wq))); else __read_once_size_nocheck(&((sk->sk_wq)), __u.__c, sizeof ((sk->sk_wq))); __u.__val; }); typeof(*((sk->sk_wq))) * ___typecheck_p __attribute__((unused)); do { } while (0); (_________p1 ); }); do { static bool __attribute__ ((__section__(".data.unlikely" ))) __warned; if (debug_lockdep_rcu_enabled() && !__warned && (!((0) || rcu_read_lock_held()))) { __warned = true ; lockdep_rcu_suspicious("net/sctp/socket.c", 7292, "suspicious rcu_dereference_check() usage" ); } } while (0); ; ((typeof(*(sk->sk_wq)) *)(________p1)) ; }); | |||
7293 | if (wq) { | |||
7294 | if (waitqueue_active(&wq->wait)) | |||
7295 | wake_up_interruptible(&wq->wait)__wake_up(&wq->wait, 1, 1, ((void *)0)); | |||
7296 | ||||
7297 | /* Note that we try to include the Async I/O support | |||
7298 | * here by modeling from the current TCP/UDP code. | |||
7299 | * We have not tested with it yet. | |||
7300 | */ | |||
7301 | if (!(sk->sk_shutdown & SEND_SHUTDOWN2)) | |||
7302 | sock_wake_async(wq, SOCK_WAKE_SPACE, POLL_OUT((2 << 16)|2)); | |||
7303 | } | |||
7304 | rcu_read_unlock(); | |||
7305 | } | |||
7306 | } | |||
7307 | ||||
7308 | static void sctp_wake_up_waiters(struct sock *sk, | |||
7309 | struct sctp_association *asoc) | |||
7310 | { | |||
7311 | struct sctp_association *tmp = asoc; | |||
7312 | ||||
7313 | /* We do accounting for the sndbuf space per association, | |||
7314 | * so we only need to wake our own association. | |||
7315 | */ | |||
7316 | if (asoc->ep->sndbuf_policy) | |||
7317 | return __sctp_write_space(asoc); | |||
7318 | ||||
7319 | /* If association goes down and is just flushing its | |||
7320 | * outq, then just normally notify others. | |||
7321 | */ | |||
7322 | if (asoc->base.dead) | |||
7323 | return sctp_write_space(sk); | |||
7324 | ||||
7325 | /* Accounting for the sndbuf space is per socket, so we | |||
7326 | * need to wake up others, try to be fair and in case of | |||
7327 | * other associations, let them have a go first instead | |||
7328 | * of just doing a sctp_write_space() call. | |||
7329 | * | |||
7330 | * Note that we reach sctp_wake_up_waiters() only when | |||
7331 | * associations free up queued chunks, thus we are under | |||
7332 | * lock and the list of associations on a socket is | |||
7333 | * guaranteed not to change. | |||
7334 | */ | |||
7335 | for (tmp = list_next_entry(tmp, asocs)({ const typeof( ((typeof(*(tmp)) *)0)->asocs ) *__mptr = ( (tmp)->asocs.next); (typeof(*(tmp)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(tmp)), asocs) );}); 1; | |||
7336 | tmp = list_next_entry(tmp, asocs)({ const typeof( ((typeof(*(tmp)) *)0)->asocs ) *__mptr = ( (tmp)->asocs.next); (typeof(*(tmp)) *)( (char *)__mptr - __builtin_offsetof (typeof(*(tmp)), asocs) );})) { | |||
7337 | /* Manually skip the head element. */ | |||
7338 | if (&tmp->asocs == &((sctp_sk(sk))->ep->asocs)) | |||
7339 | continue; | |||
7340 | /* Wake up association. */ | |||
7341 | __sctp_write_space(tmp); | |||
7342 | /* We've reached the end. */ | |||
7343 | if (tmp == asoc) | |||
7344 | break; | |||
7345 | } | |||
7346 | } | |||
7347 | ||||
7348 | /* Do accounting for the sndbuf space. | |||
7349 | * Decrement the used sndbuf space of the corresponding association by the | |||
7350 | * data size which was just transmitted(freed). | |||
7351 | */ | |||
7352 | static void sctp_wfree(struct sk_buff *skb) | |||
7353 | { | |||
7354 | struct sctp_chunk *chunk = skb_shinfo(skb)((struct skb_shared_info *)(skb_end_pointer(skb)))->destructor_arg; | |||
7355 | struct sctp_association *asoc = chunk->asoc; | |||
7356 | struct sock *sk = asoc->base.sk; | |||
7357 | ||||
7358 | asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk)((int)((unsigned long)(chunk->chunk_end) - (unsigned long) (chunk->chunk_hdr) - sizeof(sctp_data_chunk_t))) + | |||
7359 | sizeof(struct sk_buff) + | |||
7360 | sizeof(struct sctp_chunk); | |||
7361 | ||||
7362 | atomic_sub(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); | |||
7363 | ||||
7364 | /* | |||
7365 | * This undoes what is done via sctp_set_owner_w and sk_mem_charge | |||
7366 | */ | |||
7367 | sk->sk_wmem_queued -= skb->truesize; | |||
7368 | sk_mem_uncharge(sk, skb->truesize); | |||
7369 | ||||
7370 | sock_wfree(skb); | |||
7371 | sctp_wake_up_waiters(sk, asoc); | |||
7372 | ||||
7373 | sctp_association_put(asoc); | |||
7374 | } | |||
7375 | ||||
7376 | /* Do accounting for the receive space on the socket. | |||
7377 | * Accounting for the association is done in ulpevent.c | |||
7378 | * We set this as a destructor for the cloned data skbs so that | |||
7379 | * accounting is done at the correct time. | |||
7380 | */ | |||
7381 | void sctp_sock_rfree(struct sk_buff *skb) | |||
7382 | { | |||
7383 | struct sock *sk = skb->sk; | |||
7384 | struct sctp_ulpevent *event = sctp_skb2event(skb); | |||
7385 | ||||
7386 | atomic_sub(event->rmem_len, &sk->sk_rmem_allocsk_backlog.rmem_alloc); | |||
7387 | ||||
7388 | /* | |||
7389 | * Mimic the behavior of sock_rfree | |||
7390 | */ | |||
7391 | sk_mem_uncharge(sk, event->rmem_len); | |||
7392 | } | |||
7393 | ||||
7394 | ||||
7395 | /* Helper function to wait for space in the sndbuf. */ | |||
7396 | static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, | |||
7397 | size_t msg_len) | |||
7398 | { | |||
7399 | struct sock *sk = asoc->base.sk; | |||
7400 | int err = 0; | |||
7401 | long current_timeo = *timeo_p; | |||
7402 | DEFINE_WAIT(wait)wait_queue_t wait = { .private = get_current(), .func = autoremove_wake_function , .task_list = { &((wait).task_list), &((wait).task_list ) }, }; | |||
7403 | ||||
7404 | pr_debug("%s: asoc:%p, timeo:%ld, msg_len:%zu\n", __func__, asoc,do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: asoc:%p, timeo:%ld, msg_len:%zu\n" ), .lineno = 7405, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: asoc:%p, timeo:%ld, msg_len:%zu\n", __func__, asoc, *timeo_p , msg_len); } while (0) | |||
7405 | *timeo_p, msg_len)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: asoc:%p, timeo:%ld, msg_len:%zu\n" ), .lineno = 7405, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: asoc:%p, timeo:%ld, msg_len:%zu\n", __func__, asoc, *timeo_p , msg_len); } while (0); | |||
7406 | ||||
7407 | /* Increment the association's refcnt. */ | |||
7408 | sctp_association_hold(asoc); | |||
7409 | ||||
7410 | /* Wait on the association specific sndbuf space. */ | |||
7411 | for (;;) { | |||
7412 | prepare_to_wait_exclusive(&asoc->wait, &wait, | |||
7413 | TASK_INTERRUPTIBLE1); | |||
7414 | if (!*timeo_p) | |||
7415 | goto do_nonblock; | |||
7416 | if (sk->sk_err || asoc->state >= SCTP_STATE_SHUTDOWN_PENDING || | |||
7417 | asoc->base.dead) | |||
7418 | goto do_error; | |||
7419 | if (signal_pending(currentget_current())) | |||
7420 | goto do_interrupted; | |||
7421 | if (msg_len <= sctp_wspace(asoc)) | |||
7422 | break; | |||
7423 | ||||
7424 | /* Let another process have a go. Since we are going | |||
7425 | * to sleep anyway. | |||
7426 | */ | |||
7427 | release_sock(sk); | |||
7428 | current_timeo = schedule_timeout(current_timeo); | |||
7429 | BUG_ON(sk != asoc->base.sk)do { if ((sk != asoc->base.sk)) do { asm volatile("1:\tud2\n" ".pushsection __bug_table,\"a\"\n" "2:\t.long 1b - 2b, %c0 - 2b\n" "\t.word %c1, 0\n" "\t.org 2b+%c2\n" ".popsection" : : "i" ( "net/sctp/socket.c"), "i" (7429), "i" (sizeof(struct bug_entry ))); do { } while (1); } while (0); } while (0); | |||
7430 | lock_sock(sk); | |||
7431 | ||||
7432 | *timeo_p = current_timeo; | |||
7433 | } | |||
7434 | ||||
7435 | out: | |||
7436 | finish_wait(&asoc->wait, &wait); | |||
7437 | ||||
7438 | /* Release the association's refcnt. */ | |||
7439 | sctp_association_put(asoc); | |||
7440 | ||||
7441 | return err; | |||
7442 | ||||
7443 | do_error: | |||
7444 | err = -EPIPE32; | |||
7445 | goto out; | |||
7446 | ||||
7447 | do_interrupted: | |||
7448 | err = sock_intr_errno(*timeo_p); | |||
7449 | goto out; | |||
7450 | ||||
7451 | do_nonblock: | |||
7452 | err = -EAGAIN11; | |||
7453 | goto out; | |||
7454 | } | |||
7455 | ||||
7456 | void sctp_data_ready(struct sock *sk) | |||
7457 | { | |||
7458 | struct socket_wq *wq; | |||
7459 | ||||
7460 | rcu_read_lock(); | |||
7461 | wq = rcu_dereference(sk->sk_wq)({ typeof(*(sk->sk_wq)) *________p1 = (typeof(*(sk->sk_wq )) *)({ typeof((sk->sk_wq)) _________p1 = ({ union { typeof ((sk->sk_wq)) __val; char __c[1]; } __u; if (1) __read_once_size (&((sk->sk_wq)), __u.__c, sizeof((sk->sk_wq))); else __read_once_size_nocheck(&((sk->sk_wq)), __u.__c, sizeof ((sk->sk_wq))); __u.__val; }); typeof(*((sk->sk_wq))) * ___typecheck_p __attribute__((unused)); do { } while (0); (_________p1 ); }); do { static bool __attribute__ ((__section__(".data.unlikely" ))) __warned; if (debug_lockdep_rcu_enabled() && !__warned && (!((0) || rcu_read_lock_held()))) { __warned = true ; lockdep_rcu_suspicious("net/sctp/socket.c", 7461, "suspicious rcu_dereference_check() usage" ); } } while (0); ; ((typeof(*(sk->sk_wq)) *)(________p1)) ; }); | |||
7462 | if (skwq_has_sleeper(wq)) | |||
7463 | wake_up_interruptible_sync_poll(&wq->wait, POLLIN |__wake_up_sync_key((&wq->wait), 1, 1, (void *) (0x0001 | 0x0040 | 0x0080)) | |||
7464 | POLLRDNORM | POLLRDBAND)__wake_up_sync_key((&wq->wait), 1, 1, (void *) (0x0001 | 0x0040 | 0x0080)); | |||
7465 | sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN((2 << 16)|1)); | |||
7466 | rcu_read_unlock(); | |||
7467 | } | |||
7468 | ||||
7469 | /* If socket sndbuf has changed, wake up all per association waiters. */ | |||
7470 | void sctp_write_space(struct sock *sk) | |||
7471 | { | |||
7472 | struct sctp_association *asoc; | |||
7473 | ||||
7474 | /* Wake up the tasks in each wait queue. */ | |||
7475 | list_for_each_entry(asoc, &((sctp_sk(sk))->ep->asocs), asocs)for (asoc = ({ const typeof( ((typeof(*asoc) *)0)->asocs ) *__mptr = ((&((sctp_sk(sk))->ep->asocs))->next) ; (typeof(*asoc) *)( (char *)__mptr - __builtin_offsetof(typeof (*asoc), asocs) );}); &asoc->asocs != (&((sctp_sk( sk))->ep->asocs)); asoc = ({ const typeof( ((typeof(*(asoc )) *)0)->asocs ) *__mptr = ((asoc)->asocs.next); (typeof (*(asoc)) *)( (char *)__mptr - __builtin_offsetof(typeof(*(asoc )), asocs) );})) { | |||
7476 | __sctp_write_space(asoc); | |||
7477 | } | |||
7478 | } | |||
7479 | ||||
7480 | /* Is there any sndbuf space available on the socket? | |||
7481 | * | |||
7482 | * Note that sk_wmem_alloc is the sum of the send buffers on all of the | |||
7483 | * associations on the same socket. For a UDP-style socket with | |||
7484 | * multiple associations, it is possible for it to be "unwriteable" | |||
7485 | * prematurely. I assume that this is acceptable because | |||
7486 | * a premature "unwriteable" is better than an accidental "writeable" which | |||
7487 | * would cause an unwanted block under certain circumstances. For the 1-1 | |||
7488 | * UDP-style sockets or TCP-style sockets, this code should work. | |||
7489 | * - Daisy | |||
7490 | */ | |||
7491 | static int sctp_writeable(struct sock *sk) | |||
7492 | { | |||
7493 | int amt = 0; | |||
7494 | ||||
7495 | amt = sk->sk_sndbuf - sk_wmem_alloc_get(sk); | |||
7496 | if (amt < 0) | |||
7497 | amt = 0; | |||
7498 | return amt; | |||
7499 | } | |||
7500 | ||||
7501 | /* Wait for an association to go into ESTABLISHED state. If timeout is 0, | |||
7502 | * returns immediately with EINPROGRESS. | |||
7503 | */ | |||
7504 | static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p) | |||
7505 | { | |||
7506 | struct sock *sk = asoc->base.sk; | |||
7507 | int err = 0; | |||
7508 | long current_timeo = *timeo_p; | |||
7509 | DEFINE_WAIT(wait)wait_queue_t wait = { .private = get_current(), .func = autoremove_wake_function , .task_list = { &((wait).task_list), &((wait).task_list ) }, }; | |||
7510 | ||||
7511 | pr_debug("%s: asoc:%p, timeo:%ld\n", __func__, asoc, *timeo_p)do { static struct _ddebug __attribute__((aligned(8))) __attribute__ ((section("__verbose"))) descriptor = { .modname = "sctp", .function = __func__, .filename = "net/sctp/socket.c", .format = ("%s: asoc:%p, timeo:%ld\n" ), .lineno = 7511, .flags = 0, }; if ((descriptor.flags & (1<<0))) __dynamic_pr_debug(&descriptor, "sctp" ": " "%s: asoc:%p, timeo:%ld\n", __func__, asoc, *timeo_p); } while (0); | |||
7512 | ||||
7513 | /* Increment the association's refcnt. */ | |||
7514 | sctp_association_hold(asoc); | |||
7515 | ||||
7516 | for (;;) { | |||
7517 | prepare_to_wait_exclusive(&asoc->wait, &wait, | |||
7518 | TASK_INTERRUPTIBLE1); | |||
7519 | if (!*timeo_p) | |||
7520 | goto do_nonblock; | |||
7521 | if (sk->sk_shutdown & RCV_SHUTDOWN1) | |||
7522 | break; | |||
7523 | if (sk->sk_err || asoc->state >= SCTP_STATE_SHUTDOWN_PENDING || | |||
7524 | asoc->base.dead) | |||
7525 | goto do_error; | |||
7526 | if (signal_pending(currentget_current())) | |||
7527 | goto do_interrupted; | |||
7528 | ||||
7529 | if (sctp_state(asoc, ESTABLISHED)__sctp_state((asoc), (SCTP_STATE_ESTABLISHED))) | |||
7530 | break; | |||
7531 | ||||
7532 | /* Let another process have a go. Since we are going | |||
7533 | * to sleep anyway. | |||
7534 | */ | |||
7535 | release_sock(sk); | |||
7536 | current_timeo = schedule_timeout(current_timeo); | |||
7537 | lock_sock(sk); | |||
7538 | ||||
7539 | *timeo_p = current_timeo; | |||
7540 | } | |||
7541 | ||||
7542 | out: | |||
7543 | finish_wait(&asoc->wait, &wait); | |||
7544 | ||||
7545 | /* Release the association's refcnt. */ | |||
7546 | sctp_association_put(asoc); | |||
7547 | ||||
7548 | return err; | |||
7549 | ||||
7550 | do_error: | |||
7551 | if (asoc->init_err_counter + 1 > asoc->max_init_attempts) | |||
7552 | err = -ETIMEDOUT110; | |||
7553 | else | |||
7554 | err = -ECONNREFUSED111; | |||
7555 | goto out; | |||
7556 | ||||
7557 | do_interrupted: | |||
7558 | err = sock_intr_errno(*timeo_p); | |||
7559 | goto out; | |||
7560 | ||||
7561 | do_nonblock: | |||
7562 | err = -EINPROGRESS115; | |||
7563 | goto out; | |||
7564 | } | |||
7565 | ||||
7566 | static int sctp_wait_for_accept(struct sock *sk, long timeo) | |||
7567 | { | |||
7568 | struct sctp_endpoint *ep; | |||
7569 | int err = 0; | |||
7570 | DEFINE_WAIT(wait)wait_queue_t wait = { .private = get_current(), .func = autoremove_wake_function , .task_list = { &((wait).task_list), &((wait).task_list ) }, }; | |||
7571 | ||||
7572 | ep = sctp_sk(sk)->ep; | |||
7573 | ||||
7574 | ||||
7575 | for (;;) { | |||
7576 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, | |||
7577 | TASK_INTERRUPTIBLE1); | |||
7578 | ||||
7579 | if (list_empty(&ep->asocs)) { | |||
7580 | release_sock(sk); | |||
7581 | timeo = schedule_timeout(timeo); | |||
7582 | lock_sock(sk); | |||
7583 | } | |||
7584 | ||||
7585 | err = -EINVAL22; | |||
7586 | if (!sctp_sstate(sk, LISTENING)__sctp_sstate((sk), (SCTP_SS_LISTENING))) | |||
7587 | break; | |||
7588 | ||||
7589 | err = 0; | |||
7590 | if (!list_empty(&ep->asocs)) | |||
7591 | break; | |||
7592 | ||||
7593 | err = sock_intr_errno(timeo); | |||
7594 | if (signal_pending(currentget_current())) | |||
7595 | break; | |||
7596 | ||||
7597 | err = -EAGAIN11; | |||
7598 | if (!timeo) | |||
7599 | break; | |||
7600 | } | |||
7601 | ||||
7602 | finish_wait(sk_sleep(sk), &wait); | |||
7603 | ||||
7604 | return err; | |||
7605 | } | |||
7606 | ||||
7607 | static void sctp_wait_for_close(struct sock *sk, long timeout) | |||
7608 | { | |||
7609 | DEFINE_WAIT(wait)wait_queue_t wait = { .private = get_current(), .func = autoremove_wake_function , .task_list = { &((wait).task_list), &((wait).task_list ) }, }; | |||
7610 | ||||
7611 | do { | |||
7612 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE1); | |||
7613 | if (list_empty(&sctp_sk(sk)->ep->asocs)) | |||
7614 | break; | |||
7615 | release_sock(sk); | |||
7616 | timeout = schedule_timeout(timeout); | |||
7617 | lock_sock(sk); | |||
7618 | } while (!signal_pending(currentget_current()) && timeout); | |||
7619 | ||||
7620 | finish_wait(sk_sleep(sk), &wait); | |||
7621 | } | |||
7622 | ||||
7623 | static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) | |||
7624 | { | |||
7625 | struct sk_buff *frag; | |||
7626 | ||||
7627 | if (!skb->data_len) | |||
7628 | goto done; | |||
7629 | ||||
7630 | /* Don't forget the fragments. */ | |||
7631 | skb_walk_frags(skb, frag)for (frag = ((struct skb_shared_info *)(skb_end_pointer(skb)) )->frag_list; frag; frag = frag->next) | |||
7632 | sctp_skb_set_owner_r_frag(frag, sk); | |||
7633 | ||||
7634 | done: | |||
7635 | sctp_skb_set_owner_r(skb, sk); | |||
7636 | } | |||
7637 | ||||
7638 | void sctp_copy_sock(struct sock *newsk, struct sock *sk, | |||
7639 | struct sctp_association *asoc) | |||
7640 | { | |||
7641 | struct inet_sock *inet = inet_sk(sk); | |||
7642 | struct inet_sock *newinet; | |||
7643 | ||||
7644 | newsk->sk_type = sk->sk_type; | |||
7645 | newsk->sk_bound_dev_if__sk_common.skc_bound_dev_if = sk->sk_bound_dev_if__sk_common.skc_bound_dev_if; | |||
7646 | newsk->sk_flags__sk_common.skc_flags = sk->sk_flags__sk_common.skc_flags; | |||
7647 | newsk->sk_tsflags = sk->sk_tsflags; | |||
7648 | newsk->sk_no_check_tx = sk->sk_no_check_tx; | |||
7649 | newsk->sk_no_check_rx = sk->sk_no_check_rx; | |||
7650 | newsk->sk_reuse__sk_common.skc_reuse = sk->sk_reuse__sk_common.skc_reuse; | |||
7651 | ||||
7652 | newsk->sk_shutdown = sk->sk_shutdown; | |||
7653 | newsk->sk_destruct = sctp_destruct_sock; | |||
7654 | newsk->sk_family__sk_common.skc_family = sk->sk_family__sk_common.skc_family; | |||
7655 | newsk->sk_protocol = IPPROTO_SCTPIPPROTO_SCTP; | |||
7656 | newsk->sk_backlog_rcv = sk->sk_prot__sk_common.skc_prot->backlog_rcv; | |||
7657 | newsk->sk_sndbuf = sk->sk_sndbuf; | |||
7658 | newsk->sk_rcvbuf = sk->sk_rcvbuf; | |||
7659 | newsk->sk_lingertime = sk->sk_lingertime; | |||
7660 | newsk->sk_rcvtimeo = sk->sk_rcvtimeo; | |||
7661 | newsk->sk_sndtimeo = sk->sk_sndtimeo; | |||
7662 | newsk->sk_rxhash__sk_common.skc_rxhash = sk->sk_rxhash__sk_common.skc_rxhash; | |||
7663 | ||||
7664 | newinet = inet_sk(newsk); | |||
7665 | ||||
7666 | /* Initialize sk's sport, dport, rcv_saddr and daddr for | |||
7667 | * getsockname() and getpeername() | |||
7668 | */ | |||
7669 | newinet->inet_sport = inet->inet_sport; | |||
7670 | newinet->inet_saddr = inet->inet_saddr; | |||
7671 | newinet->inet_rcv_saddrsk.__sk_common.skc_rcv_saddr = inet->inet_rcv_saddrsk.__sk_common.skc_rcv_saddr; | |||
7672 | newinet->inet_dportsk.__sk_common.skc_dport = htons(asoc->peer.port)(( __be16)(__builtin_constant_p((__u16)((asoc->peer.port)) ) ? ((__u16)( (((__u16)((asoc->peer.port)) & (__u16)0x00ffU ) << 8) | (((__u16)((asoc->peer.port)) & (__u16) 0xff00U) >> 8))) : __fswab16((asoc->peer.port)))); | |||
7673 | newinet->pmtudisc = inet->pmtudisc; | |||
7674 | newinet->inet_id = asoc->next_tsn ^ jiffies; | |||
7675 | ||||
7676 | newinet->uc_ttl = inet->uc_ttl; | |||
7677 | newinet->mc_loop = 1; | |||
7678 | newinet->mc_ttl = 1; | |||
7679 | newinet->mc_index = 0; | |||
7680 | newinet->mc_list = NULL((void *)0); | |||
7681 | ||||
7682 | if (newsk->sk_flags__sk_common.skc_flags & SK_FLAGS_TIMESTAMP((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE ))) | |||
7683 | net_enable_timestamp(); | |||
7684 | ||||
7685 | security_sk_clone(sk, newsk); | |||
7686 | } | |||
7687 | ||||
7688 | static inlineinline __attribute__((no_instrument_function)) void sctp_copy_descendant(struct sock *sk_to, | |||
7689 | const struct sock *sk_from) | |||
7690 | { | |||
7691 | int ancestor_size = sizeof(struct inet_sock) + | |||
7692 | sizeof(struct sctp_sock) - | |||
7693 | offsetof(struct sctp_sock, auto_asconf_list)__builtin_offsetof(struct sctp_sock, auto_asconf_list); | |||
7694 | ||||
7695 | if (sk_from->sk_family__sk_common.skc_family == PF_INET610) | |||
7696 | ancestor_size += sizeof(struct ipv6_pinfo); | |||
7697 | ||||
7698 | __inet_sk_copy_descendant(sk_to, sk_from, ancestor_size); | |||
7699 | } | |||
7700 | ||||
7701 | /* Populate the fields of the newsk from the oldsk and migrate the assoc | |||
7702 | * and its messages to the newsk. | |||
7703 | */ | |||
7704 | static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
7705 | struct sctp_association *assoc, | |||
7706 | sctp_socket_type_t type) | |||
7707 | { | |||
7708 | struct sctp_sock *oldsp = sctp_sk(oldsk); | |||
7709 | struct sctp_sock *newsp = sctp_sk(newsk); | |||
7710 | struct sctp_bind_bucket *pp; /* hash list port iterator */ | |||
7711 | struct sctp_endpoint *newep = newsp->ep; | |||
7712 | struct sk_buff *skb, *tmp; | |||
7713 | struct sctp_ulpevent *event; | |||
7714 | struct sctp_bind_hashbucket *head; | |||
7715 | ||||
7716 | /* Migrate socket buffer sizes and all the socket level options to the | |||
7717 | * new socket. | |||
7718 | */ | |||
7719 | newsk->sk_sndbuf = oldsk->sk_sndbuf; | |||
7720 | newsk->sk_rcvbuf = oldsk->sk_rcvbuf; | |||
7721 | /* Brute force copy old sctp opt. */ | |||
7722 | sctp_copy_descendant(newsk, oldsk); | |||
7723 | ||||
7724 | /* Restore the ep value that was overwritten with the above structure | |||
7725 | * copy. | |||
7726 | */ | |||
7727 | newsp->ep = newep; | |||
7728 | newsp->hmac = NULL((void *)0); | |||
7729 | ||||
7730 | /* Hook this new socket in to the bind_hash list. */ | |||
7731 | head = &sctp_port_hashtable(sctp_globals.port_hashtable)[sctp_phashfn(sock_net(oldsk), | |||
7732 | inet_sk(oldsk)->inet_numsk.__sk_common.skc_num)]; | |||
7733 | spin_lock_bh(&head->lock); | |||
7734 | pp = sctp_sk(oldsk)->bind_hash; | |||
7735 | sk_add_bind_node(newsk, &pp->owner); | |||
7736 | sctp_sk(newsk)->bind_hash = pp; | |||
7737 | inet_sk(newsk)->inet_numsk.__sk_common.skc_num = inet_sk(oldsk)->inet_numsk.__sk_common.skc_num; | |||
7738 | spin_unlock_bh(&head->lock); | |||
7739 | ||||
7740 | /* Copy the bind_addr list from the original endpoint to the new | |||
7741 | * endpoint so that we can handle restarts properly | |||
7742 | */ | |||
7743 | sctp_bind_addr_dup(&newsp->ep->base.bind_addr, | |||
7744 | &oldsp->ep->base.bind_addr, GFP_KERNEL((( gfp_t)(0x400000u|0x2000000u)) | (( gfp_t)0x40u) | (( gfp_t )0x80u))); | |||
7745 | ||||
7746 | /* Move any messages in the old socket's receive queue that are for the | |||
7747 | * peeled off association to the new socket's receive queue. | |||
7748 | */ | |||
7749 | sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp)for (skb = (&oldsk->sk_receive_queue)->next, tmp = skb ->next; skb != (struct sk_buff *)(&oldsk->sk_receive_queue ); skb = tmp, tmp = skb->next) { | |||
7750 | event = sctp_skb2event(skb); | |||
7751 | if (event->asoc == assoc) { | |||
7752 | __skb_unlink(skb, &oldsk->sk_receive_queue); | |||
7753 | __skb_queue_tail(&newsk->sk_receive_queue, skb); | |||
7754 | sctp_skb_set_owner_r_frag(skb, newsk); | |||
7755 | } | |||
7756 | } | |||
7757 | ||||
7758 | /* Clean up any messages pending delivery due to partial | |||
7759 | * delivery. Three cases: | |||
7760 | * 1) No partial deliver; no work. | |||
7761 | * 2) Peeling off partial delivery; keep pd_lobby in new pd_lobby. | |||
7762 | * 3) Peeling off non-partial delivery; move pd_lobby to receive_queue. | |||
7763 | */ | |||
7764 | skb_queue_head_init(&newsp->pd_lobby); | |||
7765 | atomic_set(&sctp_sk(newsk)->pd_mode, assoc->ulpq.pd_mode); | |||
7766 | ||||
7767 | if (atomic_read(&sctp_sk(oldsk)->pd_mode)) { | |||
7768 | struct sk_buff_head *queue; | |||
7769 | ||||
7770 | /* Decide which queue to move pd_lobby skbs to. */ | |||
7771 | if (assoc->ulpq.pd_mode) { | |||
7772 | queue = &newsp->pd_lobby; | |||
7773 | } else | |||
7774 | queue = &newsk->sk_receive_queue; | |||
7775 | ||||
7776 | /* Walk through the pd_lobby, looking for skbs that | |||
7777 | * need moved to the new socket. | |||
7778 | */ | |||
7779 | sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp)for (skb = (&oldsp->pd_lobby)->next, tmp = skb-> next; skb != (struct sk_buff *)(&oldsp->pd_lobby); skb = tmp, tmp = skb->next) { | |||
7780 | event = sctp_skb2event(skb); | |||
7781 | if (event->asoc == assoc) { | |||
7782 | __skb_unlink(skb, &oldsp->pd_lobby); | |||
7783 | __skb_queue_tail(queue, skb); | |||
7784 | sctp_skb_set_owner_r_frag(skb, newsk); | |||
7785 | } | |||
7786 | } | |||
7787 | ||||
7788 | /* Clear up any skbs waiting for the partial | |||
7789 | * delivery to finish. | |||
7790 | */ | |||
7791 | if (assoc->ulpq.pd_mode) | |||
7792 | sctp_clear_pd(oldsk, NULL((void *)0)); | |||
7793 | ||||
7794 | } | |||
7795 | ||||
7796 | sctp_skb_for_each(skb, &assoc->ulpq.reasm, tmp)for (skb = (&assoc->ulpq.reasm)->next, tmp = skb-> next; skb != (struct sk_buff *)(&assoc->ulpq.reasm); skb = tmp, tmp = skb->next) | |||
7797 | sctp_skb_set_owner_r_frag(skb, newsk); | |||
7798 | ||||
7799 | sctp_skb_for_each(skb, &assoc->ulpq.lobby, tmp)for (skb = (&assoc->ulpq.lobby)->next, tmp = skb-> next; skb != (struct sk_buff *)(&assoc->ulpq.lobby); skb = tmp, tmp = skb->next) | |||
7800 | sctp_skb_set_owner_r_frag(skb, newsk); | |||
7801 | ||||
7802 | /* Set the type of socket to indicate that it is peeled off from the | |||
7803 | * original UDP-style socket or created with the accept() call on a | |||
7804 | * TCP-style socket.. | |||
7805 | */ | |||
7806 | newsp->type = type; | |||
7807 | ||||
7808 | /* Mark the new socket "in-use" by the user so that any packets | |||
7809 | * that may arrive on the association after we've moved it are | |||
7810 | * queued to the backlog. This prevents a potential race between | |||
7811 | * backlog processing on the old socket and new-packet processing | |||
7812 | * on the new socket. | |||
7813 | * | |||
7814 | * The caller has just allocated newsk so we can guarantee that other | |||
7815 | * paths won't try to lock it and then oldsk. | |||
7816 | */ | |||
7817 | lock_sock_nested(newsk, SINGLE_DEPTH_NESTING1); | |||
7818 | sctp_assoc_migrate(assoc, newsk); | |||
7819 | ||||
7820 | /* If the association on the newsk is already closed before accept() | |||
7821 | * is called, set RCV_SHUTDOWN flag. | |||
7822 | */ | |||
7823 | if (sctp_state(assoc, CLOSED)__sctp_state((assoc), (SCTP_STATE_CLOSED)) && sctp_style(newsk, TCP)__sctp_style((newsk), (SCTP_SOCKET_TCP))) { | |||
7824 | newsk->sk_state__sk_common.skc_state = SCTP_SS_CLOSED; | |||
7825 | newsk->sk_shutdown |= RCV_SHUTDOWN1; | |||
7826 | } else { | |||
7827 | newsk->sk_state__sk_common.skc_state = SCTP_SS_ESTABLISHED; | |||
7828 | } | |||
7829 | ||||
7830 | release_sock(newsk); | |||
7831 | } | |||
7832 | ||||
7833 | ||||
7834 | /* This proto struct describes the ULP interface for SCTP. */ | |||
7835 | struct proto sctp_prot = { | |||
7836 | .name = "SCTP", | |||
7837 | .owner = THIS_MODULE((struct module *)0), | |||
7838 | .close = sctp_close, | |||
7839 | .connect = sctp_connect, | |||
7840 | .disconnect = sctp_disconnect, | |||
7841 | .accept = sctp_accept, | |||
7842 | .ioctl = sctp_ioctl, | |||
7843 | .init = sctp_init_sock, | |||
7844 | .destroy = sctp_destroy_sock, | |||
7845 | .shutdown = sctp_shutdown, | |||
7846 | .setsockopt = sctp_setsockopt, | |||
7847 | .getsockopt = sctp_getsockopt, | |||
7848 | .sendmsg = sctp_sendmsg, | |||
7849 | .recvmsg = sctp_recvmsg, | |||
7850 | .bind = sctp_bind, | |||
7851 | .backlog_rcv = sctp_backlog_rcv, | |||
7852 | .hash = sctp_hash, | |||
7853 | .unhash = sctp_unhash, | |||
7854 | .get_port = sctp_get_port, | |||
7855 | .obj_size = sizeof(struct sctp_sock), | |||
7856 | .sysctl_mem = sysctl_sctp_mem, | |||
7857 | .sysctl_rmem = sysctl_sctp_rmem, | |||
7858 | .sysctl_wmem = sysctl_sctp_wmem, | |||
7859 | .memory_pressure = &sctp_memory_pressure, | |||
7860 | .enter_memory_pressure = sctp_enter_memory_pressure, | |||
7861 | .memory_allocated = &sctp_memory_allocated, | |||
7862 | .sockets_allocated = &sctp_sockets_allocated, | |||
7863 | }; | |||
7864 | ||||
7865 | #if IS_ENABLED(CONFIG_IPV6)1 | |||
7866 | ||||
7867 | #include <net/transp_v6.h> | |||
7868 | static void sctp_v6_destroy_sock(struct sock *sk) | |||
7869 | { | |||
7870 | sctp_destroy_sock(sk); | |||
7871 | inet6_destroy_sock(sk); | |||
7872 | } | |||
7873 | ||||
7874 | struct proto sctpv6_prot = { | |||
7875 | .name = "SCTPv6", | |||
7876 | .owner = THIS_MODULE((struct module *)0), | |||
7877 | .close = sctp_close, | |||
7878 | .connect = sctp_connect, | |||
7879 | .disconnect = sctp_disconnect, | |||
7880 | .accept = sctp_accept, | |||
7881 | .ioctl = sctp_ioctl, | |||
7882 | .init = sctp_init_sock, | |||
7883 | .destroy = sctp_v6_destroy_sock, | |||
7884 | .shutdown = sctp_shutdown, | |||
7885 | .setsockopt = sctp_setsockopt, | |||
7886 | .getsockopt = sctp_getsockopt, | |||
7887 | .sendmsg = sctp_sendmsg, | |||
7888 | .recvmsg = sctp_recvmsg, | |||
7889 | .bind = sctp_bind, | |||
7890 | .backlog_rcv = sctp_backlog_rcv, | |||
7891 | .hash = sctp_hash, | |||
7892 | .unhash = sctp_unhash, | |||
7893 | .get_port = sctp_get_port, | |||
7894 | .obj_size = sizeof(struct sctp6_sock), | |||
7895 | .sysctl_mem = sysctl_sctp_mem, | |||
7896 | .sysctl_rmem = sysctl_sctp_rmem, | |||
7897 | .sysctl_wmem = sysctl_sctp_wmem, | |||
7898 | .memory_pressure = &sctp_memory_pressure, | |||
7899 | .enter_memory_pressure = sctp_enter_memory_pressure, | |||
7900 | .memory_allocated = &sctp_memory_allocated, | |||
7901 | .sockets_allocated = &sctp_sockets_allocated, | |||
7902 | }; | |||
7903 | #endif /* IS_ENABLED(CONFIG_IPV6) */ |