.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* AF_RXRPC implementation |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. |
---|
4 | 5 | * Written by David Howells (dhowells@redhat.com) |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or |
---|
7 | | - * modify it under the terms of the GNU General Public License |
---|
8 | | - * as published by the Free Software Foundation; either version |
---|
9 | | - * 2 of the License, or (at your option) any later version. |
---|
10 | 6 | */ |
---|
11 | 7 | |
---|
12 | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
97 | 93 | srx->transport_len > len) |
---|
98 | 94 | return -EINVAL; |
---|
99 | 95 | |
---|
100 | | - if (srx->transport.family != rx->family) |
---|
| 96 | + if (srx->transport.family != rx->family && |
---|
| 97 | + srx->transport.family == AF_INET && rx->family != AF_INET6) |
---|
101 | 98 | return -EAFNOSUPPORT; |
---|
102 | 99 | |
---|
103 | 100 | switch (srx->transport.family) { |
---|
.. | .. |
---|
134 | 131 | struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *)saddr; |
---|
135 | 132 | struct rxrpc_local *local; |
---|
136 | 133 | struct rxrpc_sock *rx = rxrpc_sk(sock->sk); |
---|
137 | | - u16 service_id = srx->srx_service; |
---|
| 134 | + u16 service_id; |
---|
138 | 135 | int ret; |
---|
139 | 136 | |
---|
140 | 137 | _enter("%p,%p,%d", rx, saddr, len); |
---|
.. | .. |
---|
142 | 139 | ret = rxrpc_validate_address(rx, srx, len); |
---|
143 | 140 | if (ret < 0) |
---|
144 | 141 | goto error; |
---|
| 142 | + service_id = srx->srx_service; |
---|
145 | 143 | |
---|
146 | 144 | lock_sock(&rx->sk); |
---|
147 | 145 | |
---|
.. | .. |
---|
248 | 246 | ret = 0; |
---|
249 | 247 | break; |
---|
250 | 248 | } |
---|
251 | | - /* Fall through */ |
---|
| 249 | + fallthrough; |
---|
252 | 250 | default: |
---|
253 | 251 | ret = -EBUSY; |
---|
254 | 252 | break; |
---|
.. | .. |
---|
269 | 267 | * @gfp: The allocation constraints |
---|
270 | 268 | * @notify_rx: Where to send notifications instead of socket queue |
---|
271 | 269 | * @upgrade: Request service upgrade for call |
---|
| 270 | + * @interruptibility: The call is interruptible, or can be canceled. |
---|
272 | 271 | * @debug_id: The debug ID for tracing to be assigned to the call |
---|
273 | 272 | * |
---|
274 | 273 | * Allow a kernel service to begin a call on the nominated socket. This just |
---|
.. | .. |
---|
286 | 285 | gfp_t gfp, |
---|
287 | 286 | rxrpc_notify_rx_t notify_rx, |
---|
288 | 287 | bool upgrade, |
---|
| 288 | + enum rxrpc_interruptibility interruptibility, |
---|
289 | 289 | unsigned int debug_id) |
---|
290 | 290 | { |
---|
291 | 291 | struct rxrpc_conn_parameters cp; |
---|
.. | .. |
---|
308 | 308 | key = NULL; /* a no-security key */ |
---|
309 | 309 | |
---|
310 | 310 | memset(&p, 0, sizeof(p)); |
---|
311 | | - p.user_call_ID = user_call_ID; |
---|
312 | | - p.tx_total_len = tx_total_len; |
---|
| 311 | + p.user_call_ID = user_call_ID; |
---|
| 312 | + p.tx_total_len = tx_total_len; |
---|
| 313 | + p.interruptibility = interruptibility; |
---|
| 314 | + p.kernel = true; |
---|
313 | 315 | |
---|
314 | 316 | memset(&cp, 0, sizeof(cp)); |
---|
315 | 317 | cp.local = rx->local; |
---|
.. | .. |
---|
349 | 351 | */ |
---|
350 | 352 | void rxrpc_kernel_end_call(struct socket *sock, struct rxrpc_call *call) |
---|
351 | 353 | { |
---|
352 | | - _enter("%d{%d}", call->debug_id, atomic_read(&call->usage)); |
---|
| 354 | + _enter("%d{%d}", call->debug_id, refcount_read(&call->ref)); |
---|
353 | 355 | |
---|
354 | 356 | mutex_lock(&call->user_mutex); |
---|
355 | 357 | rxrpc_release_call(rxrpc_sk(sock->sk), call); |
---|
.. | .. |
---|
371 | 373 | * @sock: The socket the call is on |
---|
372 | 374 | * @call: The call to check |
---|
373 | 375 | * |
---|
374 | | - * Allow a kernel service to find out whether a call is still alive - ie. we're |
---|
375 | | - * getting ACKs from the server. Returns a number representing the life state |
---|
376 | | - * which can be compared to that returned by a previous call. |
---|
377 | | - * |
---|
378 | | - * If this is a client call, ping ACKs will be sent to the server to find out |
---|
379 | | - * whether it's still responsive and whether the call is still alive on the |
---|
380 | | - * server. |
---|
| 376 | + * Allow a kernel service to find out whether a call is still alive - |
---|
| 377 | + * ie. whether it has completed. |
---|
381 | 378 | */ |
---|
382 | | -u32 rxrpc_kernel_check_life(struct socket *sock, struct rxrpc_call *call) |
---|
| 379 | +bool rxrpc_kernel_check_life(const struct socket *sock, |
---|
| 380 | + const struct rxrpc_call *call) |
---|
383 | 381 | { |
---|
384 | | - return call->acks_latest; |
---|
| 382 | + return call->state != RXRPC_CALL_COMPLETE; |
---|
385 | 383 | } |
---|
386 | 384 | EXPORT_SYMBOL(rxrpc_kernel_check_life); |
---|
387 | 385 | |
---|
388 | 386 | /** |
---|
389 | | - * rxrpc_kernel_check_call - Check a call's state |
---|
| 387 | + * rxrpc_kernel_get_epoch - Retrieve the epoch value from a call. |
---|
390 | 388 | * @sock: The socket the call is on |
---|
391 | | - * @call: The call to check |
---|
392 | | - * @_compl: Where to store the completion state |
---|
393 | | - * @_abort_code: Where to store any abort code |
---|
| 389 | + * @call: The call to query |
---|
394 | 390 | * |
---|
395 | | - * Allow a kernel service to query the state of a call and find out the manner |
---|
396 | | - * of its termination if it has completed. Returns -EINPROGRESS if the call is |
---|
397 | | - * still going, 0 if the call finished successfully, -ECONNABORTED if the call |
---|
398 | | - * was aborted and an appropriate error if the call failed in some other way. |
---|
| 391 | + * Allow a kernel service to retrieve the epoch value from a service call to |
---|
| 392 | + * see if the client at the other end rebooted. |
---|
399 | 393 | */ |
---|
400 | | -int rxrpc_kernel_check_call(struct socket *sock, struct rxrpc_call *call, |
---|
401 | | - enum rxrpc_call_completion *_compl, u32 *_abort_code) |
---|
| 394 | +u32 rxrpc_kernel_get_epoch(struct socket *sock, struct rxrpc_call *call) |
---|
402 | 395 | { |
---|
403 | | - if (call->state != RXRPC_CALL_COMPLETE) |
---|
404 | | - return -EINPROGRESS; |
---|
405 | | - smp_rmb(); |
---|
406 | | - *_compl = call->completion; |
---|
407 | | - *_abort_code = call->abort_code; |
---|
408 | | - return call->error; |
---|
| 396 | + return call->conn->proto.epoch; |
---|
409 | 397 | } |
---|
410 | | -EXPORT_SYMBOL(rxrpc_kernel_check_call); |
---|
411 | | - |
---|
412 | | -/** |
---|
413 | | - * rxrpc_kernel_retry_call - Allow a kernel service to retry a call |
---|
414 | | - * @sock: The socket the call is on |
---|
415 | | - * @call: The call to retry |
---|
416 | | - * @srx: The address of the peer to contact |
---|
417 | | - * @key: The security context to use (defaults to socket setting) |
---|
418 | | - * |
---|
419 | | - * Allow a kernel service to try resending a client call that failed due to a |
---|
420 | | - * network error to a new address. The Tx queue is maintained intact, thereby |
---|
421 | | - * relieving the need to re-encrypt any request data that has already been |
---|
422 | | - * buffered. |
---|
423 | | - */ |
---|
424 | | -int rxrpc_kernel_retry_call(struct socket *sock, struct rxrpc_call *call, |
---|
425 | | - struct sockaddr_rxrpc *srx, struct key *key) |
---|
426 | | -{ |
---|
427 | | - struct rxrpc_conn_parameters cp; |
---|
428 | | - struct rxrpc_sock *rx = rxrpc_sk(sock->sk); |
---|
429 | | - int ret; |
---|
430 | | - |
---|
431 | | - _enter("%d{%d}", call->debug_id, atomic_read(&call->usage)); |
---|
432 | | - |
---|
433 | | - if (!key) |
---|
434 | | - key = rx->key; |
---|
435 | | - if (key && !key->payload.data[0]) |
---|
436 | | - key = NULL; /* a no-security key */ |
---|
437 | | - |
---|
438 | | - memset(&cp, 0, sizeof(cp)); |
---|
439 | | - cp.local = rx->local; |
---|
440 | | - cp.key = key; |
---|
441 | | - cp.security_level = 0; |
---|
442 | | - cp.exclusive = false; |
---|
443 | | - cp.service_id = srx->srx_service; |
---|
444 | | - |
---|
445 | | - mutex_lock(&call->user_mutex); |
---|
446 | | - |
---|
447 | | - ret = rxrpc_prepare_call_for_retry(rx, call); |
---|
448 | | - if (ret == 0) |
---|
449 | | - ret = rxrpc_retry_client_call(rx, call, &cp, srx, GFP_KERNEL); |
---|
450 | | - |
---|
451 | | - mutex_unlock(&call->user_mutex); |
---|
452 | | - rxrpc_put_peer(cp.peer); |
---|
453 | | - _leave(" = %d", ret); |
---|
454 | | - return ret; |
---|
455 | | -} |
---|
456 | | -EXPORT_SYMBOL(rxrpc_kernel_retry_call); |
---|
| 398 | +EXPORT_SYMBOL(rxrpc_kernel_get_epoch); |
---|
457 | 399 | |
---|
458 | 400 | /** |
---|
459 | 401 | * rxrpc_kernel_new_call_notification - Get notifications of new calls |
---|
.. | .. |
---|
474 | 416 | rx->discard_new_call = discard_new_call; |
---|
475 | 417 | } |
---|
476 | 418 | EXPORT_SYMBOL(rxrpc_kernel_new_call_notification); |
---|
| 419 | + |
---|
| 420 | +/** |
---|
| 421 | + * rxrpc_kernel_set_max_life - Set maximum lifespan on a call |
---|
| 422 | + * @sock: The socket the call is on |
---|
| 423 | + * @call: The call to configure |
---|
| 424 | + * @hard_timeout: The maximum lifespan of the call in jiffies |
---|
| 425 | + * |
---|
| 426 | + * Set the maximum lifespan of a call. The call will end with ETIME or |
---|
| 427 | + * ETIMEDOUT if it takes longer than this. |
---|
| 428 | + */ |
---|
| 429 | +void rxrpc_kernel_set_max_life(struct socket *sock, struct rxrpc_call *call, |
---|
| 430 | + unsigned long hard_timeout) |
---|
| 431 | +{ |
---|
| 432 | + unsigned long now; |
---|
| 433 | + |
---|
| 434 | + mutex_lock(&call->user_mutex); |
---|
| 435 | + |
---|
| 436 | + now = jiffies; |
---|
| 437 | + hard_timeout += now; |
---|
| 438 | + WRITE_ONCE(call->expect_term_by, hard_timeout); |
---|
| 439 | + rxrpc_reduce_call_timer(call, hard_timeout, now, rxrpc_timer_set_for_hard); |
---|
| 440 | + |
---|
| 441 | + mutex_unlock(&call->user_mutex); |
---|
| 442 | +} |
---|
| 443 | +EXPORT_SYMBOL(rxrpc_kernel_set_max_life); |
---|
477 | 444 | |
---|
478 | 445 | /* |
---|
479 | 446 | * connect an RxRPC socket |
---|
.. | .. |
---|
579 | 546 | |
---|
580 | 547 | rx->local = local; |
---|
581 | 548 | rx->sk.sk_state = RXRPC_CLIENT_BOUND; |
---|
582 | | - /* Fall through */ |
---|
| 549 | + fallthrough; |
---|
583 | 550 | |
---|
584 | 551 | case RXRPC_CLIENT_BOUND: |
---|
585 | 552 | if (!m->msg_name && |
---|
.. | .. |
---|
587 | 554 | m->msg_name = &rx->connect_srx; |
---|
588 | 555 | m->msg_namelen = sizeof(rx->connect_srx); |
---|
589 | 556 | } |
---|
590 | | - /* Fall through */ |
---|
| 557 | + fallthrough; |
---|
591 | 558 | case RXRPC_SERVER_BOUND: |
---|
592 | 559 | case RXRPC_SERVER_LISTENING: |
---|
593 | 560 | ret = rxrpc_do_sendmsg(rx, m, len); |
---|
.. | .. |
---|
605 | 572 | return ret; |
---|
606 | 573 | } |
---|
607 | 574 | |
---|
| 575 | +int rxrpc_sock_set_min_security_level(struct sock *sk, unsigned int val) |
---|
| 576 | +{ |
---|
| 577 | + if (sk->sk_state != RXRPC_UNBOUND) |
---|
| 578 | + return -EISCONN; |
---|
| 579 | + if (val > RXRPC_SECURITY_MAX) |
---|
| 580 | + return -EINVAL; |
---|
| 581 | + lock_sock(sk); |
---|
| 582 | + rxrpc_sk(sk)->min_sec_level = val; |
---|
| 583 | + release_sock(sk); |
---|
| 584 | + return 0; |
---|
| 585 | +} |
---|
| 586 | +EXPORT_SYMBOL(rxrpc_sock_set_min_security_level); |
---|
| 587 | + |
---|
608 | 588 | /* |
---|
609 | 589 | * set RxRPC socket options |
---|
610 | 590 | */ |
---|
611 | 591 | static int rxrpc_setsockopt(struct socket *sock, int level, int optname, |
---|
612 | | - char __user *optval, unsigned int optlen) |
---|
| 592 | + sockptr_t optval, unsigned int optlen) |
---|
613 | 593 | { |
---|
614 | 594 | struct rxrpc_sock *rx = rxrpc_sk(sock->sk); |
---|
615 | 595 | unsigned int min_sec_level; |
---|
.. | .. |
---|
660 | 640 | ret = -EISCONN; |
---|
661 | 641 | if (rx->sk.sk_state != RXRPC_UNBOUND) |
---|
662 | 642 | goto error; |
---|
663 | | - ret = get_user(min_sec_level, |
---|
664 | | - (unsigned int __user *) optval); |
---|
| 643 | + ret = copy_from_sockptr(&min_sec_level, optval, |
---|
| 644 | + sizeof(unsigned int)); |
---|
665 | 645 | if (ret < 0) |
---|
666 | 646 | goto error; |
---|
667 | 647 | ret = -EINVAL; |
---|
.. | .. |
---|
679 | 659 | if (rx->sk.sk_state != RXRPC_SERVER_BOUND2) |
---|
680 | 660 | goto error; |
---|
681 | 661 | ret = -EFAULT; |
---|
682 | | - if (copy_from_user(service_upgrade, optval, |
---|
| 662 | + if (copy_from_sockptr(service_upgrade, optval, |
---|
683 | 663 | sizeof(service_upgrade)) != 0) |
---|
684 | 664 | goto error; |
---|
685 | 665 | ret = -EINVAL; |
---|
.. | .. |
---|
981 | 961 | int ret = -1; |
---|
982 | 962 | unsigned int tmp; |
---|
983 | 963 | |
---|
984 | | - BUILD_BUG_ON(sizeof(struct rxrpc_skb_priv) > FIELD_SIZEOF(struct sk_buff, cb)); |
---|
| 964 | + BUILD_BUG_ON(sizeof(struct rxrpc_skb_priv) > sizeof_field(struct sk_buff, cb)); |
---|
985 | 965 | |
---|
986 | 966 | get_random_bytes(&tmp, sizeof(tmp)); |
---|
987 | 967 | tmp &= 0x3fffffff; |
---|