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