1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2018 Samsung Electronics Co., Ltd. 4 */ 5 6 #include <linux/jhash.h> 7 #include <linux/slab.h> 8 #include <linux/rwsem.h> 9 #include <linux/mutex.h> 10 #include <linux/wait.h> 11 #include <linux/hashtable.h> 12 #include <net/net_namespace.h> 13 #include <net/genetlink.h> 14 #include <linux/socket.h> 15 #include <linux/workqueue.h> 16 17 #include "vfs_cache.h" 18 #include "transport_ipc.h" 19 #include "server.h" 20 #include "smb_common.h" 21 22 #include "mgmt/user_config.h" 23 #include "mgmt/share_config.h" 24 #include "mgmt/user_session.h" 25 #include "mgmt/tree_connect.h" 26 #include "mgmt/ksmbd_ida.h" 27 #include "connection.h" 28 #include "transport_tcp.h" 29 #include "transport_rdma.h" 30 31 #define IPC_WAIT_TIMEOUT (2 * HZ) 32 33 #define IPC_MSG_HASH_BITS 3 34 static DEFINE_HASHTABLE(ipc_msg_table, IPC_MSG_HASH_BITS); 35 static DECLARE_RWSEM(ipc_msg_table_lock); 36 static DEFINE_MUTEX(startup_lock); 37 38 static DEFINE_IDA(ipc_ida); 39 40 static unsigned int ksmbd_tools_pid; 41 42 static bool ksmbd_ipc_validate_version(struct genl_info *m) 43 { 44 if (m->genlhdr->version != KSMBD_GENL_VERSION) { 45 pr_err("%s. ksmbd: %d, kernel module: %d. %s.\n", 46 "Daemon and kernel module version mismatch", 47 m->genlhdr->version, 48 KSMBD_GENL_VERSION, 49 "User-space ksmbd should terminate"); 50 return false; 51 } 52 return true; 53 } 54 55 struct ksmbd_ipc_msg { 56 unsigned int type; 57 unsigned int sz; 58 unsigned char payload[]; 59 }; 60 61 struct ipc_msg_table_entry { 62 unsigned int handle; 63 unsigned int type; 64 wait_queue_head_t wait; 65 struct hlist_node ipc_table_hlist; 66 67 void *response; 68 }; 69 70 static struct delayed_work ipc_timer_work; 71 72 static int handle_startup_event(struct sk_buff *skb, struct genl_info *info); 73 static int handle_unsupported_event(struct sk_buff *skb, struct genl_info *info); 74 static int handle_generic_event(struct sk_buff *skb, struct genl_info *info); 75 static int ksmbd_ipc_heartbeat_request(void); 76 77 static const struct nla_policy ksmbd_nl_policy[KSMBD_EVENT_MAX + 1] = { 78 [KSMBD_EVENT_UNSPEC] = { 79 .len = 0, 80 }, 81 [KSMBD_EVENT_HEARTBEAT_REQUEST] = { 82 .len = sizeof(struct ksmbd_heartbeat), 83 }, 84 [KSMBD_EVENT_STARTING_UP] = { 85 .len = sizeof(struct ksmbd_startup_request), 86 }, 87 [KSMBD_EVENT_SHUTTING_DOWN] = { 88 .len = sizeof(struct ksmbd_shutdown_request), 89 }, 90 [KSMBD_EVENT_LOGIN_REQUEST] = { 91 .len = sizeof(struct ksmbd_login_request), 92 }, 93 [KSMBD_EVENT_LOGIN_RESPONSE] = { 94 .len = sizeof(struct ksmbd_login_response), 95 }, 96 [KSMBD_EVENT_SHARE_CONFIG_REQUEST] = { 97 .len = sizeof(struct ksmbd_share_config_request), 98 }, 99 [KSMBD_EVENT_SHARE_CONFIG_RESPONSE] = { 100 .len = sizeof(struct ksmbd_share_config_response), 101 }, 102 [KSMBD_EVENT_TREE_CONNECT_REQUEST] = { 103 .len = sizeof(struct ksmbd_tree_connect_request), 104 }, 105 [KSMBD_EVENT_TREE_CONNECT_RESPONSE] = { 106 .len = sizeof(struct ksmbd_tree_connect_response), 107 }, 108 [KSMBD_EVENT_TREE_DISCONNECT_REQUEST] = { 109 .len = sizeof(struct ksmbd_tree_disconnect_request), 110 }, 111 [KSMBD_EVENT_LOGOUT_REQUEST] = { 112 .len = sizeof(struct ksmbd_logout_request), 113 }, 114 [KSMBD_EVENT_RPC_REQUEST] = { 115 }, 116 [KSMBD_EVENT_RPC_RESPONSE] = { 117 }, 118 [KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST] = { 119 }, 120 [KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE] = { 121 }, 122 }; 123 124 static struct genl_ops ksmbd_genl_ops[] = { 125 { 126 .cmd = KSMBD_EVENT_UNSPEC, 127 .doit = handle_unsupported_event, 128 }, 129 { 130 .cmd = KSMBD_EVENT_HEARTBEAT_REQUEST, 131 .doit = handle_unsupported_event, 132 }, 133 { 134 .cmd = KSMBD_EVENT_STARTING_UP, 135 .doit = handle_startup_event, 136 }, 137 { 138 .cmd = KSMBD_EVENT_SHUTTING_DOWN, 139 .doit = handle_unsupported_event, 140 }, 141 { 142 .cmd = KSMBD_EVENT_LOGIN_REQUEST, 143 .doit = handle_unsupported_event, 144 }, 145 { 146 .cmd = KSMBD_EVENT_LOGIN_RESPONSE, 147 .doit = handle_generic_event, 148 }, 149 { 150 .cmd = KSMBD_EVENT_SHARE_CONFIG_REQUEST, 151 .doit = handle_unsupported_event, 152 }, 153 { 154 .cmd = KSMBD_EVENT_SHARE_CONFIG_RESPONSE, 155 .doit = handle_generic_event, 156 }, 157 { 158 .cmd = KSMBD_EVENT_TREE_CONNECT_REQUEST, 159 .doit = handle_unsupported_event, 160 }, 161 { 162 .cmd = KSMBD_EVENT_TREE_CONNECT_RESPONSE, 163 .doit = handle_generic_event, 164 }, 165 { 166 .cmd = KSMBD_EVENT_TREE_DISCONNECT_REQUEST, 167 .doit = handle_unsupported_event, 168 }, 169 { 170 .cmd = KSMBD_EVENT_LOGOUT_REQUEST, 171 .doit = handle_unsupported_event, 172 }, 173 { 174 .cmd = KSMBD_EVENT_RPC_REQUEST, 175 .doit = handle_unsupported_event, 176 }, 177 { 178 .cmd = KSMBD_EVENT_RPC_RESPONSE, 179 .doit = handle_generic_event, 180 }, 181 { 182 .cmd = KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST, 183 .doit = handle_unsupported_event, 184 }, 185 { 186 .cmd = KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE, 187 .doit = handle_generic_event, 188 }, 189 }; 190 191 static struct genl_family ksmbd_genl_family = { 192 .name = KSMBD_GENL_NAME, 193 .version = KSMBD_GENL_VERSION, 194 .hdrsize = 0, 195 .maxattr = KSMBD_EVENT_MAX, 196 .netnsok = true, 197 .module = THIS_MODULE, 198 .ops = ksmbd_genl_ops, 199 .n_ops = ARRAY_SIZE(ksmbd_genl_ops), 200 .resv_start_op = KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE + 1, 201 }; 202 203 static void ksmbd_nl_init_fixup(void) 204 { 205 int i; 206 207 for (i = 0; i < ARRAY_SIZE(ksmbd_genl_ops); i++) 208 ksmbd_genl_ops[i].validate = GENL_DONT_VALIDATE_STRICT | 209 GENL_DONT_VALIDATE_DUMP; 210 211 ksmbd_genl_family.policy = ksmbd_nl_policy; 212 } 213 214 static int rpc_context_flags(struct ksmbd_session *sess) 215 { 216 if (user_guest(sess->user)) 217 return KSMBD_RPC_RESTRICTED_CONTEXT; 218 return 0; 219 } 220 221 static void ipc_update_last_active(void) 222 { 223 if (server_conf.ipc_timeout) 224 server_conf.ipc_last_active = jiffies; 225 } 226 227 static struct ksmbd_ipc_msg *ipc_msg_alloc(size_t sz) 228 { 229 struct ksmbd_ipc_msg *msg; 230 size_t msg_sz = sz + sizeof(struct ksmbd_ipc_msg); 231 232 msg = kvzalloc(msg_sz, GFP_KERNEL); 233 if (msg) 234 msg->sz = sz; 235 return msg; 236 } 237 238 static void ipc_msg_free(struct ksmbd_ipc_msg *msg) 239 { 240 kvfree(msg); 241 } 242 243 static void ipc_msg_handle_free(int handle) 244 { 245 if (handle >= 0) 246 ksmbd_release_id(&ipc_ida, handle); 247 } 248 249 static int handle_response(int type, void *payload, size_t sz) 250 { 251 unsigned int handle = *(unsigned int *)payload; 252 struct ipc_msg_table_entry *entry; 253 int ret = 0; 254 255 ipc_update_last_active(); 256 down_read(&ipc_msg_table_lock); 257 hash_for_each_possible(ipc_msg_table, entry, ipc_table_hlist, handle) { 258 if (handle != entry->handle) 259 continue; 260 261 entry->response = NULL; 262 /* 263 * Response message type value should be equal to 264 * request message type + 1. 265 */ 266 if (entry->type + 1 != type) { 267 pr_err("Waiting for IPC type %d, got %d. Ignore.\n", 268 entry->type + 1, type); 269 } 270 271 entry->response = kvzalloc(sz, GFP_KERNEL); 272 if (!entry->response) { 273 ret = -ENOMEM; 274 break; 275 } 276 277 memcpy(entry->response, payload, sz); 278 wake_up_interruptible(&entry->wait); 279 ret = 0; 280 break; 281 } 282 up_read(&ipc_msg_table_lock); 283 284 return ret; 285 } 286 287 static int ipc_server_config_on_startup(struct ksmbd_startup_request *req) 288 { 289 int ret; 290 291 ksmbd_set_fd_limit(req->file_max); 292 server_conf.flags = req->flags; 293 server_conf.signing = req->signing; 294 server_conf.tcp_port = req->tcp_port; 295 server_conf.ipc_timeout = req->ipc_timeout * HZ; 296 server_conf.deadtime = req->deadtime * SMB_ECHO_INTERVAL; 297 server_conf.share_fake_fscaps = req->share_fake_fscaps; 298 ksmbd_init_domain(req->sub_auth); 299 300 if (req->smb2_max_read) 301 init_smb2_max_read_size(req->smb2_max_read); 302 if (req->smb2_max_write) 303 init_smb2_max_write_size(req->smb2_max_write); 304 if (req->smb2_max_trans) 305 init_smb2_max_trans_size(req->smb2_max_trans); 306 if (req->smb2_max_credits) 307 init_smb2_max_credits(req->smb2_max_credits); 308 if (req->smbd_max_io_size) 309 init_smbd_max_io_size(req->smbd_max_io_size); 310 311 if (req->max_connections) 312 server_conf.max_connections = req->max_connections; 313 314 ret = ksmbd_set_netbios_name(req->netbios_name); 315 ret |= ksmbd_set_server_string(req->server_string); 316 ret |= ksmbd_set_work_group(req->work_group); 317 ret |= ksmbd_tcp_set_interfaces(KSMBD_STARTUP_CONFIG_INTERFACES(req), 318 req->ifc_list_sz); 319 if (ret) { 320 pr_err("Server configuration error: %s %s %s\n", 321 req->netbios_name, req->server_string, 322 req->work_group); 323 return ret; 324 } 325 326 if (req->min_prot[0]) { 327 ret = ksmbd_lookup_protocol_idx(req->min_prot); 328 if (ret >= 0) 329 server_conf.min_protocol = ret; 330 } 331 if (req->max_prot[0]) { 332 ret = ksmbd_lookup_protocol_idx(req->max_prot); 333 if (ret >= 0) 334 server_conf.max_protocol = ret; 335 } 336 337 if (server_conf.ipc_timeout) 338 schedule_delayed_work(&ipc_timer_work, server_conf.ipc_timeout); 339 return 0; 340 } 341 342 static int handle_startup_event(struct sk_buff *skb, struct genl_info *info) 343 { 344 int ret = 0; 345 346 #ifdef CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN 347 if (!netlink_capable(skb, CAP_NET_ADMIN)) 348 return -EPERM; 349 #endif 350 351 if (!ksmbd_ipc_validate_version(info)) 352 return -EINVAL; 353 354 if (!info->attrs[KSMBD_EVENT_STARTING_UP]) 355 return -EINVAL; 356 357 mutex_lock(&startup_lock); 358 if (!ksmbd_server_configurable()) { 359 mutex_unlock(&startup_lock); 360 pr_err("Server reset is in progress, can't start daemon\n"); 361 return -EINVAL; 362 } 363 364 if (ksmbd_tools_pid) { 365 if (ksmbd_ipc_heartbeat_request() == 0) { 366 ret = -EINVAL; 367 goto out; 368 } 369 370 pr_err("Reconnect to a new user space daemon\n"); 371 } else { 372 struct ksmbd_startup_request *req; 373 374 req = nla_data(info->attrs[info->genlhdr->cmd]); 375 ret = ipc_server_config_on_startup(req); 376 if (ret) 377 goto out; 378 server_queue_ctrl_init_work(); 379 } 380 381 ksmbd_tools_pid = info->snd_portid; 382 ipc_update_last_active(); 383 384 out: 385 mutex_unlock(&startup_lock); 386 return ret; 387 } 388 389 static int handle_unsupported_event(struct sk_buff *skb, struct genl_info *info) 390 { 391 pr_err("Unknown IPC event: %d, ignore.\n", info->genlhdr->cmd); 392 return -EINVAL; 393 } 394 395 static int handle_generic_event(struct sk_buff *skb, struct genl_info *info) 396 { 397 void *payload; 398 int sz; 399 int type = info->genlhdr->cmd; 400 401 #ifdef CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN 402 if (!netlink_capable(skb, CAP_NET_ADMIN)) 403 return -EPERM; 404 #endif 405 406 if (type > KSMBD_EVENT_MAX) { 407 WARN_ON(1); 408 return -EINVAL; 409 } 410 411 if (!ksmbd_ipc_validate_version(info)) 412 return -EINVAL; 413 414 if (!info->attrs[type]) 415 return -EINVAL; 416 417 payload = nla_data(info->attrs[info->genlhdr->cmd]); 418 sz = nla_len(info->attrs[info->genlhdr->cmd]); 419 return handle_response(type, payload, sz); 420 } 421 422 static int ipc_msg_send(struct ksmbd_ipc_msg *msg) 423 { 424 struct genlmsghdr *nlh; 425 struct sk_buff *skb; 426 int ret = -EINVAL; 427 428 if (!ksmbd_tools_pid) 429 return ret; 430 431 skb = genlmsg_new(msg->sz, GFP_KERNEL); 432 if (!skb) 433 return -ENOMEM; 434 435 nlh = genlmsg_put(skb, 0, 0, &ksmbd_genl_family, 0, msg->type); 436 if (!nlh) 437 goto out; 438 439 ret = nla_put(skb, msg->type, msg->sz, msg->payload); 440 if (ret) { 441 genlmsg_cancel(skb, nlh); 442 goto out; 443 } 444 445 genlmsg_end(skb, nlh); 446 ret = genlmsg_unicast(&init_net, skb, ksmbd_tools_pid); 447 if (!ret) 448 ipc_update_last_active(); 449 return ret; 450 451 out: 452 nlmsg_free(skb); 453 return ret; 454 } 455 456 static void *ipc_msg_send_request(struct ksmbd_ipc_msg *msg, unsigned int handle) 457 { 458 struct ipc_msg_table_entry entry; 459 int ret; 460 461 if ((int)handle < 0) 462 return NULL; 463 464 entry.type = msg->type; 465 entry.response = NULL; 466 init_waitqueue_head(&entry.wait); 467 468 down_write(&ipc_msg_table_lock); 469 entry.handle = handle; 470 hash_add(ipc_msg_table, &entry.ipc_table_hlist, entry.handle); 471 up_write(&ipc_msg_table_lock); 472 473 ret = ipc_msg_send(msg); 474 if (ret) 475 goto out; 476 477 ret = wait_event_interruptible_timeout(entry.wait, 478 entry.response != NULL, 479 IPC_WAIT_TIMEOUT); 480 out: 481 down_write(&ipc_msg_table_lock); 482 hash_del(&entry.ipc_table_hlist); 483 up_write(&ipc_msg_table_lock); 484 return entry.response; 485 } 486 487 static int ksmbd_ipc_heartbeat_request(void) 488 { 489 struct ksmbd_ipc_msg *msg; 490 int ret; 491 492 msg = ipc_msg_alloc(sizeof(struct ksmbd_heartbeat)); 493 if (!msg) 494 return -EINVAL; 495 496 msg->type = KSMBD_EVENT_HEARTBEAT_REQUEST; 497 ret = ipc_msg_send(msg); 498 ipc_msg_free(msg); 499 return ret; 500 } 501 502 struct ksmbd_login_response *ksmbd_ipc_login_request(const char *account) 503 { 504 struct ksmbd_ipc_msg *msg; 505 struct ksmbd_login_request *req; 506 struct ksmbd_login_response *resp; 507 508 if (strlen(account) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ) 509 return NULL; 510 511 msg = ipc_msg_alloc(sizeof(struct ksmbd_login_request)); 512 if (!msg) 513 return NULL; 514 515 msg->type = KSMBD_EVENT_LOGIN_REQUEST; 516 req = (struct ksmbd_login_request *)msg->payload; 517 req->handle = ksmbd_acquire_id(&ipc_ida); 518 strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ); 519 520 resp = ipc_msg_send_request(msg, req->handle); 521 ipc_msg_handle_free(req->handle); 522 ipc_msg_free(msg); 523 return resp; 524 } 525 526 struct ksmbd_spnego_authen_response * 527 ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len) 528 { 529 struct ksmbd_ipc_msg *msg; 530 struct ksmbd_spnego_authen_request *req; 531 struct ksmbd_spnego_authen_response *resp; 532 533 msg = ipc_msg_alloc(sizeof(struct ksmbd_spnego_authen_request) + 534 blob_len + 1); 535 if (!msg) 536 return NULL; 537 538 msg->type = KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST; 539 req = (struct ksmbd_spnego_authen_request *)msg->payload; 540 req->handle = ksmbd_acquire_id(&ipc_ida); 541 req->spnego_blob_len = blob_len; 542 memcpy(req->spnego_blob, spnego_blob, blob_len); 543 544 resp = ipc_msg_send_request(msg, req->handle); 545 ipc_msg_handle_free(req->handle); 546 ipc_msg_free(msg); 547 return resp; 548 } 549 550 struct ksmbd_tree_connect_response * 551 ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess, 552 struct ksmbd_share_config *share, 553 struct ksmbd_tree_connect *tree_conn, 554 struct sockaddr *peer_addr) 555 { 556 struct ksmbd_ipc_msg *msg; 557 struct ksmbd_tree_connect_request *req; 558 struct ksmbd_tree_connect_response *resp; 559 560 if (strlen(user_name(sess->user)) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ) 561 return NULL; 562 563 if (strlen(share->name) >= KSMBD_REQ_MAX_SHARE_NAME) 564 return NULL; 565 566 msg = ipc_msg_alloc(sizeof(struct ksmbd_tree_connect_request)); 567 if (!msg) 568 return NULL; 569 570 msg->type = KSMBD_EVENT_TREE_CONNECT_REQUEST; 571 req = (struct ksmbd_tree_connect_request *)msg->payload; 572 573 req->handle = ksmbd_acquire_id(&ipc_ida); 574 req->account_flags = sess->user->flags; 575 req->session_id = sess->id; 576 req->connect_id = tree_conn->id; 577 strscpy(req->account, user_name(sess->user), KSMBD_REQ_MAX_ACCOUNT_NAME_SZ); 578 strscpy(req->share, share->name, KSMBD_REQ_MAX_SHARE_NAME); 579 snprintf(req->peer_addr, sizeof(req->peer_addr), "%pIS", peer_addr); 580 581 if (peer_addr->sa_family == AF_INET6) 582 req->flags |= KSMBD_TREE_CONN_FLAG_REQUEST_IPV6; 583 if (test_session_flag(sess, CIFDS_SESSION_FLAG_SMB2)) 584 req->flags |= KSMBD_TREE_CONN_FLAG_REQUEST_SMB2; 585 586 resp = ipc_msg_send_request(msg, req->handle); 587 ipc_msg_handle_free(req->handle); 588 ipc_msg_free(msg); 589 return resp; 590 } 591 592 int ksmbd_ipc_tree_disconnect_request(unsigned long long session_id, 593 unsigned long long connect_id) 594 { 595 struct ksmbd_ipc_msg *msg; 596 struct ksmbd_tree_disconnect_request *req; 597 int ret; 598 599 msg = ipc_msg_alloc(sizeof(struct ksmbd_tree_disconnect_request)); 600 if (!msg) 601 return -ENOMEM; 602 603 msg->type = KSMBD_EVENT_TREE_DISCONNECT_REQUEST; 604 req = (struct ksmbd_tree_disconnect_request *)msg->payload; 605 req->session_id = session_id; 606 req->connect_id = connect_id; 607 608 ret = ipc_msg_send(msg); 609 ipc_msg_free(msg); 610 return ret; 611 } 612 613 int ksmbd_ipc_logout_request(const char *account, int flags) 614 { 615 struct ksmbd_ipc_msg *msg; 616 struct ksmbd_logout_request *req; 617 int ret; 618 619 if (strlen(account) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ) 620 return -EINVAL; 621 622 msg = ipc_msg_alloc(sizeof(struct ksmbd_logout_request)); 623 if (!msg) 624 return -ENOMEM; 625 626 msg->type = KSMBD_EVENT_LOGOUT_REQUEST; 627 req = (struct ksmbd_logout_request *)msg->payload; 628 req->account_flags = flags; 629 strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ); 630 631 ret = ipc_msg_send(msg); 632 ipc_msg_free(msg); 633 return ret; 634 } 635 636 struct ksmbd_share_config_response * 637 ksmbd_ipc_share_config_request(const char *name) 638 { 639 struct ksmbd_ipc_msg *msg; 640 struct ksmbd_share_config_request *req; 641 struct ksmbd_share_config_response *resp; 642 643 if (strlen(name) >= KSMBD_REQ_MAX_SHARE_NAME) 644 return NULL; 645 646 msg = ipc_msg_alloc(sizeof(struct ksmbd_share_config_request)); 647 if (!msg) 648 return NULL; 649 650 msg->type = KSMBD_EVENT_SHARE_CONFIG_REQUEST; 651 req = (struct ksmbd_share_config_request *)msg->payload; 652 req->handle = ksmbd_acquire_id(&ipc_ida); 653 strscpy(req->share_name, name, KSMBD_REQ_MAX_SHARE_NAME); 654 655 resp = ipc_msg_send_request(msg, req->handle); 656 ipc_msg_handle_free(req->handle); 657 ipc_msg_free(msg); 658 return resp; 659 } 660 661 struct ksmbd_rpc_command *ksmbd_rpc_open(struct ksmbd_session *sess, int handle) 662 { 663 struct ksmbd_ipc_msg *msg; 664 struct ksmbd_rpc_command *req; 665 struct ksmbd_rpc_command *resp; 666 667 msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command)); 668 if (!msg) 669 return NULL; 670 671 msg->type = KSMBD_EVENT_RPC_REQUEST; 672 req = (struct ksmbd_rpc_command *)msg->payload; 673 req->handle = handle; 674 req->flags = ksmbd_session_rpc_method(sess, handle); 675 req->flags |= KSMBD_RPC_OPEN_METHOD; 676 req->payload_sz = 0; 677 678 resp = ipc_msg_send_request(msg, req->handle); 679 ipc_msg_free(msg); 680 return resp; 681 } 682 683 struct ksmbd_rpc_command *ksmbd_rpc_close(struct ksmbd_session *sess, int handle) 684 { 685 struct ksmbd_ipc_msg *msg; 686 struct ksmbd_rpc_command *req; 687 struct ksmbd_rpc_command *resp; 688 689 msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command)); 690 if (!msg) 691 return NULL; 692 693 msg->type = KSMBD_EVENT_RPC_REQUEST; 694 req = (struct ksmbd_rpc_command *)msg->payload; 695 req->handle = handle; 696 req->flags = ksmbd_session_rpc_method(sess, handle); 697 req->flags |= KSMBD_RPC_CLOSE_METHOD; 698 req->payload_sz = 0; 699 700 resp = ipc_msg_send_request(msg, req->handle); 701 ipc_msg_free(msg); 702 return resp; 703 } 704 705 struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle, 706 void *payload, size_t payload_sz) 707 { 708 struct ksmbd_ipc_msg *msg; 709 struct ksmbd_rpc_command *req; 710 struct ksmbd_rpc_command *resp; 711 712 msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1); 713 if (!msg) 714 return NULL; 715 716 msg->type = KSMBD_EVENT_RPC_REQUEST; 717 req = (struct ksmbd_rpc_command *)msg->payload; 718 req->handle = handle; 719 req->flags = ksmbd_session_rpc_method(sess, handle); 720 req->flags |= rpc_context_flags(sess); 721 req->flags |= KSMBD_RPC_WRITE_METHOD; 722 req->payload_sz = payload_sz; 723 memcpy(req->payload, payload, payload_sz); 724 725 resp = ipc_msg_send_request(msg, req->handle); 726 ipc_msg_free(msg); 727 return resp; 728 } 729 730 struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle) 731 { 732 struct ksmbd_ipc_msg *msg; 733 struct ksmbd_rpc_command *req; 734 struct ksmbd_rpc_command *resp; 735 736 msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command)); 737 if (!msg) 738 return NULL; 739 740 msg->type = KSMBD_EVENT_RPC_REQUEST; 741 req = (struct ksmbd_rpc_command *)msg->payload; 742 req->handle = handle; 743 req->flags = ksmbd_session_rpc_method(sess, handle); 744 req->flags |= rpc_context_flags(sess); 745 req->flags |= KSMBD_RPC_READ_METHOD; 746 req->payload_sz = 0; 747 748 resp = ipc_msg_send_request(msg, req->handle); 749 ipc_msg_free(msg); 750 return resp; 751 } 752 753 struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle, 754 void *payload, size_t payload_sz) 755 { 756 struct ksmbd_ipc_msg *msg; 757 struct ksmbd_rpc_command *req; 758 struct ksmbd_rpc_command *resp; 759 760 msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1); 761 if (!msg) 762 return NULL; 763 764 msg->type = KSMBD_EVENT_RPC_REQUEST; 765 req = (struct ksmbd_rpc_command *)msg->payload; 766 req->handle = handle; 767 req->flags = ksmbd_session_rpc_method(sess, handle); 768 req->flags |= rpc_context_flags(sess); 769 req->flags |= KSMBD_RPC_IOCTL_METHOD; 770 req->payload_sz = payload_sz; 771 memcpy(req->payload, payload, payload_sz); 772 773 resp = ipc_msg_send_request(msg, req->handle); 774 ipc_msg_free(msg); 775 return resp; 776 } 777 778 struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess, void *payload, 779 size_t payload_sz) 780 { 781 struct ksmbd_ipc_msg *msg; 782 struct ksmbd_rpc_command *req; 783 struct ksmbd_rpc_command *resp; 784 785 msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1); 786 if (!msg) 787 return NULL; 788 789 msg->type = KSMBD_EVENT_RPC_REQUEST; 790 req = (struct ksmbd_rpc_command *)msg->payload; 791 req->handle = ksmbd_acquire_id(&ipc_ida); 792 req->flags = rpc_context_flags(sess); 793 req->flags |= KSMBD_RPC_RAP_METHOD; 794 req->payload_sz = payload_sz; 795 memcpy(req->payload, payload, payload_sz); 796 797 resp = ipc_msg_send_request(msg, req->handle); 798 ipc_msg_handle_free(req->handle); 799 ipc_msg_free(msg); 800 return resp; 801 } 802 803 static int __ipc_heartbeat(void) 804 { 805 unsigned long delta; 806 807 if (!ksmbd_server_running()) 808 return 0; 809 810 if (time_after(jiffies, server_conf.ipc_last_active)) { 811 delta = (jiffies - server_conf.ipc_last_active); 812 } else { 813 ipc_update_last_active(); 814 schedule_delayed_work(&ipc_timer_work, 815 server_conf.ipc_timeout); 816 return 0; 817 } 818 819 if (delta < server_conf.ipc_timeout) { 820 schedule_delayed_work(&ipc_timer_work, 821 server_conf.ipc_timeout - delta); 822 return 0; 823 } 824 825 if (ksmbd_ipc_heartbeat_request() == 0) { 826 schedule_delayed_work(&ipc_timer_work, 827 server_conf.ipc_timeout); 828 return 0; 829 } 830 831 mutex_lock(&startup_lock); 832 WRITE_ONCE(server_conf.state, SERVER_STATE_RESETTING); 833 server_conf.ipc_last_active = 0; 834 ksmbd_tools_pid = 0; 835 pr_err("No IPC daemon response for %lus\n", delta / HZ); 836 mutex_unlock(&startup_lock); 837 return -EINVAL; 838 } 839 840 static void ipc_timer_heartbeat(struct work_struct *w) 841 { 842 if (__ipc_heartbeat()) 843 server_queue_ctrl_reset_work(); 844 } 845 846 int ksmbd_ipc_id_alloc(void) 847 { 848 return ksmbd_acquire_id(&ipc_ida); 849 } 850 851 void ksmbd_rpc_id_free(int handle) 852 { 853 ksmbd_release_id(&ipc_ida, handle); 854 } 855 856 void ksmbd_ipc_release(void) 857 { 858 cancel_delayed_work_sync(&ipc_timer_work); 859 genl_unregister_family(&ksmbd_genl_family); 860 } 861 862 void ksmbd_ipc_soft_reset(void) 863 { 864 mutex_lock(&startup_lock); 865 ksmbd_tools_pid = 0; 866 cancel_delayed_work_sync(&ipc_timer_work); 867 mutex_unlock(&startup_lock); 868 } 869 870 int ksmbd_ipc_init(void) 871 { 872 int ret = 0; 873 874 ksmbd_nl_init_fixup(); 875 INIT_DELAYED_WORK(&ipc_timer_work, ipc_timer_heartbeat); 876 877 ret = genl_register_family(&ksmbd_genl_family); 878 if (ret) { 879 pr_err("Failed to register KSMBD netlink interface %d\n", ret); 880 cancel_delayed_work_sync(&ipc_timer_work); 881 } 882 883 return ret; 884 } 885