| .. | .. |
|---|
| 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; |
|---|