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