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; 267 struct ipc_msg_table_entry *entry; 268 int ret = 0; 269 270 /* Prevent 4-byte read beyond declared payload size */ 271 if (sz < sizeof(unsigned int)) 272 return -EINVAL; 273 274 handle = *(unsigned int *)payload; 275 276 ipc_update_last_active(); 277 down_read(&ipc_msg_table_lock); 278 hash_for_each_possible(ipc_msg_table, entry, ipc_table_hlist, handle) { 279 if (handle != entry->handle) 280 continue; 281 282 entry->response = NULL; 283 /* 284 * Response message type value should be equal to 285 * request message type + 1. 286 */ 287 if (entry->type + 1 != type) { 288 pr_err("Waiting for IPC type %d, got %d. Ignore.\n", 289 entry->type + 1, type); 290 continue; 291 } 292 293 entry->response = kvzalloc(sz, KSMBD_DEFAULT_GFP); 294 if (!entry->response) { 295 ret = -ENOMEM; 296 break; 297 } 298 299 memcpy(entry->response, payload, sz); 300 entry->msg_sz = sz; 301 wake_up_interruptible(&entry->wait); 302 ret = 0; 303 break; 304 } 305 up_read(&ipc_msg_table_lock); 306 307 return ret; 308 } 309 310 static int ipc_server_config_on_startup(struct ksmbd_startup_request *req) 311 { 312 int ret; 313 314 ksmbd_set_fd_limit(req->file_max); 315 server_conf.flags = req->flags; 316 server_conf.signing = req->signing; 317 server_conf.tcp_port = req->tcp_port; 318 server_conf.ipc_timeout = req->ipc_timeout * HZ; 319 if (check_mul_overflow(req->deadtime, SMB_ECHO_INTERVAL, 320 &server_conf.deadtime)) { 321 ret = -EINVAL; 322 goto out; 323 } 324 server_conf.share_fake_fscaps = req->share_fake_fscaps; 325 ksmbd_init_domain(req->sub_auth); 326 327 if (req->smb2_max_read) 328 init_smb2_max_read_size(req->smb2_max_read); 329 if (req->smb2_max_write) 330 init_smb2_max_write_size(req->smb2_max_write); 331 if (req->smb2_max_trans) 332 init_smb2_max_trans_size(req->smb2_max_trans); 333 if (req->smb2_max_credits) { 334 init_smb2_max_credits(req->smb2_max_credits); 335 server_conf.max_inflight_req = 336 req->smb2_max_credits; 337 } 338 if (req->smbd_max_io_size) 339 init_smbd_max_io_size(req->smbd_max_io_size); 340 341 if (req->max_connections) 342 server_conf.max_connections = req->max_connections; 343 344 if (req->max_ip_connections) 345 server_conf.max_ip_connections = req->max_ip_connections; 346 347 ret = ksmbd_set_netbios_name(req->netbios_name); 348 ret |= ksmbd_set_server_string(req->server_string); 349 ret |= ksmbd_set_work_group(req->work_group); 350 server_conf.bind_interfaces_only = req->bind_interfaces_only; 351 ret |= ksmbd_tcp_set_interfaces(KSMBD_STARTUP_CONFIG_INTERFACES(req), 352 req->ifc_list_sz); 353 out: 354 if (ret) { 355 pr_err("Server configuration error: %s %s %s\n", 356 req->netbios_name, req->server_string, 357 req->work_group); 358 return ret; 359 } 360 361 if (req->min_prot[0]) { 362 ret = ksmbd_lookup_protocol_idx(req->min_prot); 363 if (ret >= 0) 364 server_conf.min_protocol = ret; 365 } 366 if (req->max_prot[0]) { 367 ret = ksmbd_lookup_protocol_idx(req->max_prot); 368 if (ret >= 0) 369 server_conf.max_protocol = ret; 370 } 371 372 if (server_conf.ipc_timeout) 373 schedule_delayed_work(&ipc_timer_work, server_conf.ipc_timeout); 374 return 0; 375 } 376 377 static int handle_startup_event(struct sk_buff *skb, struct genl_info *info) 378 { 379 int ret = 0; 380 381 #ifdef CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN 382 if (!netlink_capable(skb, CAP_NET_ADMIN)) 383 return -EPERM; 384 #endif 385 386 if (!ksmbd_ipc_validate_version(info)) 387 return -EINVAL; 388 389 if (!info->attrs[KSMBD_EVENT_STARTING_UP]) 390 return -EINVAL; 391 392 mutex_lock(&startup_lock); 393 if (!ksmbd_server_configurable()) { 394 mutex_unlock(&startup_lock); 395 pr_err("Server reset is in progress, can't start daemon\n"); 396 return -EINVAL; 397 } 398 399 if (ksmbd_tools_pid) { 400 if (ksmbd_ipc_heartbeat_request() == 0) { 401 ret = -EINVAL; 402 goto out; 403 } 404 405 pr_err("Reconnect to a new user space daemon\n"); 406 } else { 407 struct ksmbd_startup_request *req; 408 409 req = nla_data(info->attrs[info->genlhdr->cmd]); 410 ret = ipc_server_config_on_startup(req); 411 if (ret) 412 goto out; 413 server_queue_ctrl_init_work(); 414 } 415 416 ksmbd_tools_pid = info->snd_portid; 417 ipc_update_last_active(); 418 419 out: 420 mutex_unlock(&startup_lock); 421 return ret; 422 } 423 424 static int handle_unsupported_event(struct sk_buff *skb, struct genl_info *info) 425 { 426 pr_err("Unknown IPC event: %d, ignore.\n", info->genlhdr->cmd); 427 return -EINVAL; 428 } 429 430 static int handle_generic_event(struct sk_buff *skb, struct genl_info *info) 431 { 432 void *payload; 433 int sz; 434 int type = info->genlhdr->cmd; 435 436 #ifdef CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN 437 if (!netlink_capable(skb, CAP_NET_ADMIN)) 438 return -EPERM; 439 #endif 440 441 if (type > KSMBD_EVENT_MAX) { 442 WARN_ON(1); 443 return -EINVAL; 444 } 445 446 if (!ksmbd_ipc_validate_version(info)) 447 return -EINVAL; 448 449 if (!info->attrs[type]) 450 return -EINVAL; 451 452 payload = nla_data(info->attrs[info->genlhdr->cmd]); 453 sz = nla_len(info->attrs[info->genlhdr->cmd]); 454 return handle_response(type, payload, sz); 455 } 456 457 static int ipc_msg_send(struct ksmbd_ipc_msg *msg) 458 { 459 struct genlmsghdr *nlh; 460 struct sk_buff *skb; 461 int ret = -EINVAL; 462 463 if (!ksmbd_tools_pid) 464 return ret; 465 466 skb = genlmsg_new(msg->sz, KSMBD_DEFAULT_GFP); 467 if (!skb) 468 return -ENOMEM; 469 470 nlh = genlmsg_put(skb, 0, 0, &ksmbd_genl_family, 0, msg->type); 471 if (!nlh) 472 goto out; 473 474 ret = nla_put(skb, msg->type, msg->sz, msg->payload); 475 if (ret) { 476 genlmsg_cancel(skb, nlh); 477 goto out; 478 } 479 480 genlmsg_end(skb, nlh); 481 ret = genlmsg_unicast(&init_net, skb, ksmbd_tools_pid); 482 if (!ret) 483 ipc_update_last_active(); 484 return ret; 485 486 out: 487 nlmsg_free(skb); 488 return ret; 489 } 490 491 static int ipc_validate_msg(struct ipc_msg_table_entry *entry) 492 { 493 unsigned int msg_sz = entry->msg_sz; 494 495 switch (entry->type) { 496 case KSMBD_EVENT_RPC_REQUEST: 497 { 498 struct ksmbd_rpc_command *resp = entry->response; 499 500 msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz; 501 break; 502 } 503 case KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST: 504 { 505 struct ksmbd_spnego_authen_response *resp = entry->response; 506 507 msg_sz = sizeof(struct ksmbd_spnego_authen_response) + 508 resp->session_key_len + resp->spnego_blob_len; 509 break; 510 } 511 case KSMBD_EVENT_SHARE_CONFIG_REQUEST: 512 { 513 struct ksmbd_share_config_response *resp = entry->response; 514 515 if (resp->payload_sz) { 516 if (resp->payload_sz < resp->veto_list_sz) 517 return -EINVAL; 518 519 msg_sz = sizeof(struct ksmbd_share_config_response) + 520 resp->payload_sz; 521 } 522 break; 523 } 524 case KSMBD_EVENT_LOGIN_REQUEST_EXT: 525 { 526 struct ksmbd_login_response_ext *resp = entry->response; 527 528 if (resp->ngroups) { 529 msg_sz = sizeof(struct ksmbd_login_response_ext) + 530 resp->ngroups * sizeof(gid_t); 531 } 532 } 533 } 534 535 return entry->msg_sz != msg_sz ? -EINVAL : 0; 536 } 537 538 static void *ipc_msg_send_request(struct ksmbd_ipc_msg *msg, unsigned int handle) 539 { 540 struct ipc_msg_table_entry entry; 541 int ret; 542 543 if ((int)handle < 0) 544 return NULL; 545 546 entry.type = msg->type; 547 entry.response = NULL; 548 init_waitqueue_head(&entry.wait); 549 550 down_write(&ipc_msg_table_lock); 551 entry.handle = handle; 552 hash_add(ipc_msg_table, &entry.ipc_table_hlist, entry.handle); 553 up_write(&ipc_msg_table_lock); 554 555 ret = ipc_msg_send(msg); 556 if (ret) 557 goto out; 558 559 ret = wait_event_interruptible_timeout(entry.wait, 560 entry.response != NULL, 561 IPC_WAIT_TIMEOUT); 562 if (entry.response) { 563 ret = ipc_validate_msg(&entry); 564 if (ret) { 565 kvfree(entry.response); 566 entry.response = NULL; 567 } 568 } 569 out: 570 down_write(&ipc_msg_table_lock); 571 hash_del(&entry.ipc_table_hlist); 572 up_write(&ipc_msg_table_lock); 573 return entry.response; 574 } 575 576 static int ksmbd_ipc_heartbeat_request(void) 577 { 578 struct ksmbd_ipc_msg *msg; 579 int ret; 580 581 msg = ipc_msg_alloc(sizeof(struct ksmbd_heartbeat)); 582 if (!msg) 583 return -EINVAL; 584 585 msg->type = KSMBD_EVENT_HEARTBEAT_REQUEST; 586 ret = ipc_msg_send(msg); 587 ipc_msg_free(msg); 588 return ret; 589 } 590 591 struct ksmbd_login_response *ksmbd_ipc_login_request(const char *account) 592 { 593 struct ksmbd_ipc_msg *msg; 594 struct ksmbd_login_request *req; 595 struct ksmbd_login_response *resp; 596 597 if (strlen(account) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ) 598 return NULL; 599 600 msg = ipc_msg_alloc(sizeof(struct ksmbd_login_request)); 601 if (!msg) 602 return NULL; 603 604 msg->type = KSMBD_EVENT_LOGIN_REQUEST; 605 req = (struct ksmbd_login_request *)msg->payload; 606 req->handle = ksmbd_acquire_id(&ipc_ida); 607 strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ); 608 609 resp = ipc_msg_send_request(msg, req->handle); 610 ipc_msg_handle_free(req->handle); 611 ipc_msg_free(msg); 612 return resp; 613 } 614 615 struct ksmbd_login_response_ext *ksmbd_ipc_login_request_ext(const char *account) 616 { 617 struct ksmbd_ipc_msg *msg; 618 struct ksmbd_login_request *req; 619 struct ksmbd_login_response_ext *resp; 620 621 if (strlen(account) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ) 622 return NULL; 623 624 msg = ipc_msg_alloc(sizeof(struct ksmbd_login_request)); 625 if (!msg) 626 return NULL; 627 628 msg->type = KSMBD_EVENT_LOGIN_REQUEST_EXT; 629 req = (struct ksmbd_login_request *)msg->payload; 630 req->handle = ksmbd_acquire_id(&ipc_ida); 631 strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ); 632 resp = ipc_msg_send_request(msg, req->handle); 633 ipc_msg_handle_free(req->handle); 634 ipc_msg_free(msg); 635 return resp; 636 } 637 638 struct ksmbd_spnego_authen_response * 639 ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len) 640 { 641 struct ksmbd_ipc_msg *msg; 642 struct ksmbd_spnego_authen_request *req; 643 struct ksmbd_spnego_authen_response *resp; 644 645 if (blob_len > KSMBD_IPC_MAX_PAYLOAD) 646 return NULL; 647 648 msg = ipc_msg_alloc(sizeof(struct ksmbd_spnego_authen_request) + 649 blob_len + 1); 650 if (!msg) 651 return NULL; 652 653 msg->type = KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST; 654 req = (struct ksmbd_spnego_authen_request *)msg->payload; 655 req->handle = ksmbd_acquire_id(&ipc_ida); 656 req->spnego_blob_len = blob_len; 657 memcpy(req->spnego_blob, spnego_blob, blob_len); 658 659 resp = ipc_msg_send_request(msg, req->handle); 660 ipc_msg_handle_free(req->handle); 661 ipc_msg_free(msg); 662 return resp; 663 } 664 665 struct ksmbd_tree_connect_response * 666 ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess, 667 struct ksmbd_share_config *share, 668 struct ksmbd_tree_connect *tree_conn, 669 struct sockaddr *peer_addr) 670 { 671 struct ksmbd_ipc_msg *msg; 672 struct ksmbd_tree_connect_request *req; 673 struct ksmbd_tree_connect_response *resp; 674 675 if (strlen(user_name(sess->user)) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ) 676 return NULL; 677 678 if (strlen(share->name) >= KSMBD_REQ_MAX_SHARE_NAME) 679 return NULL; 680 681 msg = ipc_msg_alloc(sizeof(struct ksmbd_tree_connect_request)); 682 if (!msg) 683 return NULL; 684 685 msg->type = KSMBD_EVENT_TREE_CONNECT_REQUEST; 686 req = (struct ksmbd_tree_connect_request *)msg->payload; 687 688 req->handle = ksmbd_acquire_id(&ipc_ida); 689 req->account_flags = sess->user->flags; 690 req->session_id = sess->id; 691 req->connect_id = tree_conn->id; 692 strscpy(req->account, user_name(sess->user), KSMBD_REQ_MAX_ACCOUNT_NAME_SZ); 693 strscpy(req->share, share->name, KSMBD_REQ_MAX_SHARE_NAME); 694 snprintf(req->peer_addr, sizeof(req->peer_addr), "%pIS", peer_addr); 695 696 if (peer_addr->sa_family == AF_INET6) 697 req->flags |= KSMBD_TREE_CONN_FLAG_REQUEST_IPV6; 698 if (test_session_flag(sess, CIFDS_SESSION_FLAG_SMB2)) 699 req->flags |= KSMBD_TREE_CONN_FLAG_REQUEST_SMB2; 700 701 resp = ipc_msg_send_request(msg, req->handle); 702 ipc_msg_handle_free(req->handle); 703 ipc_msg_free(msg); 704 return resp; 705 } 706 707 int ksmbd_ipc_tree_disconnect_request(unsigned long long session_id, 708 unsigned long long connect_id) 709 { 710 struct ksmbd_ipc_msg *msg; 711 struct ksmbd_tree_disconnect_request *req; 712 int ret; 713 714 msg = ipc_msg_alloc(sizeof(struct ksmbd_tree_disconnect_request)); 715 if (!msg) 716 return -ENOMEM; 717 718 msg->type = KSMBD_EVENT_TREE_DISCONNECT_REQUEST; 719 req = (struct ksmbd_tree_disconnect_request *)msg->payload; 720 req->session_id = session_id; 721 req->connect_id = connect_id; 722 723 ret = ipc_msg_send(msg); 724 ipc_msg_free(msg); 725 return ret; 726 } 727 728 int ksmbd_ipc_logout_request(const char *account, int flags) 729 { 730 struct ksmbd_ipc_msg *msg; 731 struct ksmbd_logout_request *req; 732 int ret; 733 734 if (strlen(account) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ) 735 return -EINVAL; 736 737 msg = ipc_msg_alloc(sizeof(struct ksmbd_logout_request)); 738 if (!msg) 739 return -ENOMEM; 740 741 msg->type = KSMBD_EVENT_LOGOUT_REQUEST; 742 req = (struct ksmbd_logout_request *)msg->payload; 743 req->account_flags = flags; 744 strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ); 745 746 ret = ipc_msg_send(msg); 747 ipc_msg_free(msg); 748 return ret; 749 } 750 751 struct ksmbd_share_config_response * 752 ksmbd_ipc_share_config_request(const char *name) 753 { 754 struct ksmbd_ipc_msg *msg; 755 struct ksmbd_share_config_request *req; 756 struct ksmbd_share_config_response *resp; 757 758 if (strlen(name) >= KSMBD_REQ_MAX_SHARE_NAME) 759 return NULL; 760 761 msg = ipc_msg_alloc(sizeof(struct ksmbd_share_config_request)); 762 if (!msg) 763 return NULL; 764 765 msg->type = KSMBD_EVENT_SHARE_CONFIG_REQUEST; 766 req = (struct ksmbd_share_config_request *)msg->payload; 767 req->handle = ksmbd_acquire_id(&ipc_ida); 768 strscpy(req->share_name, name, KSMBD_REQ_MAX_SHARE_NAME); 769 770 resp = ipc_msg_send_request(msg, req->handle); 771 ipc_msg_handle_free(req->handle); 772 ipc_msg_free(msg); 773 return resp; 774 } 775 776 struct ksmbd_rpc_command *ksmbd_rpc_open(struct ksmbd_session *sess, int handle) 777 { 778 struct ksmbd_ipc_msg *msg; 779 struct ksmbd_rpc_command *req; 780 struct ksmbd_rpc_command *resp; 781 782 msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command)); 783 if (!msg) 784 return NULL; 785 786 msg->type = KSMBD_EVENT_RPC_REQUEST; 787 req = (struct ksmbd_rpc_command *)msg->payload; 788 req->handle = handle; 789 req->flags = ksmbd_session_rpc_method(sess, handle); 790 req->flags |= KSMBD_RPC_OPEN_METHOD; 791 req->payload_sz = 0; 792 793 resp = ipc_msg_send_request(msg, req->handle); 794 ipc_msg_free(msg); 795 return resp; 796 } 797 798 struct ksmbd_rpc_command *ksmbd_rpc_close(struct ksmbd_session *sess, int handle) 799 { 800 struct ksmbd_ipc_msg *msg; 801 struct ksmbd_rpc_command *req; 802 struct ksmbd_rpc_command *resp; 803 804 msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command)); 805 if (!msg) 806 return NULL; 807 808 msg->type = KSMBD_EVENT_RPC_REQUEST; 809 req = (struct ksmbd_rpc_command *)msg->payload; 810 req->handle = handle; 811 req->flags = ksmbd_session_rpc_method(sess, handle); 812 req->flags |= KSMBD_RPC_CLOSE_METHOD; 813 req->payload_sz = 0; 814 815 resp = ipc_msg_send_request(msg, req->handle); 816 ipc_msg_free(msg); 817 return resp; 818 } 819 820 struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle, 821 void *payload, size_t payload_sz) 822 { 823 struct ksmbd_ipc_msg *msg; 824 struct ksmbd_rpc_command *req; 825 struct ksmbd_rpc_command *resp; 826 827 if (payload_sz > KSMBD_IPC_MAX_PAYLOAD) 828 return NULL; 829 830 msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1); 831 if (!msg) 832 return NULL; 833 834 lockdep_assert_not_held(&sess->rpc_lock); 835 836 down_read(&sess->rpc_lock); 837 msg->type = KSMBD_EVENT_RPC_REQUEST; 838 req = (struct ksmbd_rpc_command *)msg->payload; 839 req->handle = handle; 840 req->flags = ksmbd_session_rpc_method(sess, handle); 841 req->flags |= rpc_context_flags(sess); 842 req->flags |= KSMBD_RPC_WRITE_METHOD; 843 req->payload_sz = payload_sz; 844 memcpy(req->payload, payload, payload_sz); 845 up_read(&sess->rpc_lock); 846 847 resp = ipc_msg_send_request(msg, req->handle); 848 ipc_msg_free(msg); 849 return resp; 850 } 851 852 struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle) 853 { 854 struct ksmbd_ipc_msg *msg; 855 struct ksmbd_rpc_command *req; 856 struct ksmbd_rpc_command *resp; 857 858 msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command)); 859 if (!msg) 860 return NULL; 861 862 lockdep_assert_not_held(&sess->rpc_lock); 863 864 down_read(&sess->rpc_lock); 865 msg->type = KSMBD_EVENT_RPC_REQUEST; 866 req = (struct ksmbd_rpc_command *)msg->payload; 867 req->handle = handle; 868 req->flags = ksmbd_session_rpc_method(sess, handle); 869 req->flags |= rpc_context_flags(sess); 870 req->flags |= KSMBD_RPC_READ_METHOD; 871 req->payload_sz = 0; 872 up_read(&sess->rpc_lock); 873 874 resp = ipc_msg_send_request(msg, req->handle); 875 ipc_msg_free(msg); 876 return resp; 877 } 878 879 struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle, 880 void *payload, size_t payload_sz) 881 { 882 struct ksmbd_ipc_msg *msg; 883 struct ksmbd_rpc_command *req; 884 struct ksmbd_rpc_command *resp; 885 886 if (payload_sz > KSMBD_IPC_MAX_PAYLOAD) 887 return NULL; 888 889 msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1); 890 if (!msg) 891 return NULL; 892 893 lockdep_assert_not_held(&sess->rpc_lock); 894 895 down_read(&sess->rpc_lock); 896 msg->type = KSMBD_EVENT_RPC_REQUEST; 897 req = (struct ksmbd_rpc_command *)msg->payload; 898 req->handle = handle; 899 req->flags = ksmbd_session_rpc_method(sess, handle); 900 req->flags |= rpc_context_flags(sess); 901 req->flags |= KSMBD_RPC_IOCTL_METHOD; 902 req->payload_sz = payload_sz; 903 memcpy(req->payload, payload, payload_sz); 904 up_read(&sess->rpc_lock); 905 906 resp = ipc_msg_send_request(msg, req->handle); 907 ipc_msg_free(msg); 908 return resp; 909 } 910 911 static int __ipc_heartbeat(void) 912 { 913 unsigned long delta; 914 915 if (!ksmbd_server_running()) 916 return 0; 917 918 if (time_after(jiffies, server_conf.ipc_last_active)) { 919 delta = (jiffies - server_conf.ipc_last_active); 920 } else { 921 ipc_update_last_active(); 922 schedule_delayed_work(&ipc_timer_work, 923 server_conf.ipc_timeout); 924 return 0; 925 } 926 927 if (delta < server_conf.ipc_timeout) { 928 schedule_delayed_work(&ipc_timer_work, 929 server_conf.ipc_timeout - delta); 930 return 0; 931 } 932 933 if (ksmbd_ipc_heartbeat_request() == 0) { 934 schedule_delayed_work(&ipc_timer_work, 935 server_conf.ipc_timeout); 936 return 0; 937 } 938 939 mutex_lock(&startup_lock); 940 WRITE_ONCE(server_conf.state, SERVER_STATE_RESETTING); 941 server_conf.ipc_last_active = 0; 942 ksmbd_tools_pid = 0; 943 pr_err("No IPC daemon response for %lus\n", delta / HZ); 944 mutex_unlock(&startup_lock); 945 return -EINVAL; 946 } 947 948 static void ipc_timer_heartbeat(struct work_struct *w) 949 { 950 if (__ipc_heartbeat()) 951 server_queue_ctrl_reset_work(); 952 } 953 954 int ksmbd_ipc_id_alloc(void) 955 { 956 return ksmbd_acquire_id(&ipc_ida); 957 } 958 959 void ksmbd_rpc_id_free(int handle) 960 { 961 ksmbd_release_id(&ipc_ida, handle); 962 } 963 964 void ksmbd_ipc_release(void) 965 { 966 cancel_delayed_work_sync(&ipc_timer_work); 967 genl_unregister_family(&ksmbd_genl_family); 968 } 969 970 void ksmbd_ipc_soft_reset(void) 971 { 972 mutex_lock(&startup_lock); 973 ksmbd_tools_pid = 0; 974 cancel_delayed_work_sync(&ipc_timer_work); 975 mutex_unlock(&startup_lock); 976 } 977 978 int ksmbd_ipc_init(void) 979 { 980 int ret = 0; 981 982 ksmbd_nl_init_fixup(); 983 INIT_DELAYED_WORK(&ipc_timer_work, ipc_timer_heartbeat); 984 985 ret = genl_register_family(&ksmbd_genl_family); 986 if (ret) { 987 pr_err("Failed to register KSMBD netlink interface %d\n", ret); 988 cancel_delayed_work_sync(&ipc_timer_work); 989 } 990 991 return ret; 992 } 993