at v6.2 632 lines 14 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org> 4 * Copyright (C) 2018 Samsung Electronics Co., Ltd. 5 */ 6 7#include "glob.h" 8#include "oplock.h" 9#include "misc.h" 10#include <linux/sched/signal.h> 11#include <linux/workqueue.h> 12#include <linux/sysfs.h> 13#include <linux/module.h> 14#include <linux/moduleparam.h> 15 16#include "server.h" 17#include "smb_common.h" 18#include "smbstatus.h" 19#include "connection.h" 20#include "transport_ipc.h" 21#include "mgmt/user_session.h" 22#include "crypto_ctx.h" 23#include "auth.h" 24 25int ksmbd_debug_types; 26 27struct ksmbd_server_config server_conf; 28 29enum SERVER_CTRL_TYPE { 30 SERVER_CTRL_TYPE_INIT, 31 SERVER_CTRL_TYPE_RESET, 32}; 33 34struct server_ctrl_struct { 35 int type; 36 struct work_struct ctrl_work; 37}; 38 39static DEFINE_MUTEX(ctrl_lock); 40 41static int ___server_conf_set(int idx, char *val) 42{ 43 if (idx >= ARRAY_SIZE(server_conf.conf)) 44 return -EINVAL; 45 46 if (!val || val[0] == 0x00) 47 return -EINVAL; 48 49 kfree(server_conf.conf[idx]); 50 server_conf.conf[idx] = kstrdup(val, GFP_KERNEL); 51 if (!server_conf.conf[idx]) 52 return -ENOMEM; 53 return 0; 54} 55 56int ksmbd_set_netbios_name(char *v) 57{ 58 return ___server_conf_set(SERVER_CONF_NETBIOS_NAME, v); 59} 60 61int ksmbd_set_server_string(char *v) 62{ 63 return ___server_conf_set(SERVER_CONF_SERVER_STRING, v); 64} 65 66int ksmbd_set_work_group(char *v) 67{ 68 return ___server_conf_set(SERVER_CONF_WORK_GROUP, v); 69} 70 71char *ksmbd_netbios_name(void) 72{ 73 return server_conf.conf[SERVER_CONF_NETBIOS_NAME]; 74} 75 76char *ksmbd_server_string(void) 77{ 78 return server_conf.conf[SERVER_CONF_SERVER_STRING]; 79} 80 81char *ksmbd_work_group(void) 82{ 83 return server_conf.conf[SERVER_CONF_WORK_GROUP]; 84} 85 86/** 87 * check_conn_state() - check state of server thread connection 88 * @work: smb work containing server thread information 89 * 90 * Return: 0 on valid connection, otherwise 1 to reconnect 91 */ 92static inline int check_conn_state(struct ksmbd_work *work) 93{ 94 struct smb_hdr *rsp_hdr; 95 96 if (ksmbd_conn_exiting(work) || ksmbd_conn_need_reconnect(work)) { 97 rsp_hdr = work->response_buf; 98 rsp_hdr->Status.CifsError = STATUS_CONNECTION_DISCONNECTED; 99 return 1; 100 } 101 return 0; 102} 103 104#define SERVER_HANDLER_CONTINUE 0 105#define SERVER_HANDLER_ABORT 1 106 107static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn, 108 u16 *cmd) 109{ 110 struct smb_version_cmds *cmds; 111 u16 command; 112 int ret; 113 114 if (check_conn_state(work)) 115 return SERVER_HANDLER_CONTINUE; 116 117 if (ksmbd_verify_smb_message(work)) 118 return SERVER_HANDLER_ABORT; 119 120 command = conn->ops->get_cmd_val(work); 121 *cmd = command; 122 123andx_again: 124 if (command >= conn->max_cmds) { 125 conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER); 126 return SERVER_HANDLER_CONTINUE; 127 } 128 129 cmds = &conn->cmds[command]; 130 if (!cmds->proc) { 131 ksmbd_debug(SMB, "*** not implemented yet cmd = %x\n", command); 132 conn->ops->set_rsp_status(work, STATUS_NOT_IMPLEMENTED); 133 return SERVER_HANDLER_CONTINUE; 134 } 135 136 if (work->sess && conn->ops->is_sign_req(work, command)) { 137 ret = conn->ops->check_sign_req(work); 138 if (!ret) { 139 conn->ops->set_rsp_status(work, STATUS_ACCESS_DENIED); 140 return SERVER_HANDLER_CONTINUE; 141 } 142 } 143 144 ret = cmds->proc(work); 145 146 if (ret < 0) 147 ksmbd_debug(CONN, "Failed to process %u [%d]\n", command, ret); 148 /* AndX commands - chained request can return positive values */ 149 else if (ret > 0) { 150 command = ret; 151 *cmd = command; 152 goto andx_again; 153 } 154 155 if (work->send_no_response) 156 return SERVER_HANDLER_ABORT; 157 return SERVER_HANDLER_CONTINUE; 158} 159 160static void __handle_ksmbd_work(struct ksmbd_work *work, 161 struct ksmbd_conn *conn) 162{ 163 u16 command = 0; 164 int rc; 165 166 if (conn->ops->allocate_rsp_buf(work)) 167 return; 168 169 if (conn->ops->is_transform_hdr && 170 conn->ops->is_transform_hdr(work->request_buf)) { 171 rc = conn->ops->decrypt_req(work); 172 if (rc < 0) { 173 conn->ops->set_rsp_status(work, STATUS_DATA_ERROR); 174 goto send; 175 } 176 177 work->encrypted = true; 178 } 179 180 rc = conn->ops->init_rsp_hdr(work); 181 if (rc) { 182 /* either uid or tid is not correct */ 183 conn->ops->set_rsp_status(work, STATUS_INVALID_HANDLE); 184 goto send; 185 } 186 187 if (conn->ops->check_user_session) { 188 rc = conn->ops->check_user_session(work); 189 if (rc < 0) { 190 command = conn->ops->get_cmd_val(work); 191 conn->ops->set_rsp_status(work, 192 STATUS_USER_SESSION_DELETED); 193 goto send; 194 } else if (rc > 0) { 195 rc = conn->ops->get_ksmbd_tcon(work); 196 if (rc < 0) { 197 conn->ops->set_rsp_status(work, 198 STATUS_NETWORK_NAME_DELETED); 199 goto send; 200 } 201 } 202 } 203 204 do { 205 rc = __process_request(work, conn, &command); 206 if (rc == SERVER_HANDLER_ABORT) 207 break; 208 209 /* 210 * Call smb2_set_rsp_credits() function to set number of credits 211 * granted in hdr of smb2 response. 212 */ 213 if (conn->ops->set_rsp_credits) { 214 spin_lock(&conn->credits_lock); 215 rc = conn->ops->set_rsp_credits(work); 216 spin_unlock(&conn->credits_lock); 217 if (rc < 0) { 218 conn->ops->set_rsp_status(work, 219 STATUS_INVALID_PARAMETER); 220 goto send; 221 } 222 } 223 224 if (work->sess && 225 (work->sess->sign || smb3_11_final_sess_setup_resp(work) || 226 conn->ops->is_sign_req(work, command))) 227 conn->ops->set_sign_rsp(work); 228 } while (is_chained_smb2_message(work)); 229 230 if (work->send_no_response) 231 return; 232 233send: 234 smb3_preauth_hash_rsp(work); 235 if (work->sess && work->sess->enc && work->encrypted && 236 conn->ops->encrypt_resp) { 237 rc = conn->ops->encrypt_resp(work); 238 if (rc < 0) 239 conn->ops->set_rsp_status(work, STATUS_DATA_ERROR); 240 } 241 242 ksmbd_conn_write(work); 243} 244 245/** 246 * handle_ksmbd_work() - process pending smb work requests 247 * @wk: smb work containing request command buffer 248 * 249 * called by kworker threads to processing remaining smb work requests 250 */ 251static void handle_ksmbd_work(struct work_struct *wk) 252{ 253 struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work); 254 struct ksmbd_conn *conn = work->conn; 255 256 atomic64_inc(&conn->stats.request_served); 257 258 __handle_ksmbd_work(work, conn); 259 260 ksmbd_conn_try_dequeue_request(work); 261 ksmbd_free_work_struct(work); 262 /* 263 * Checking waitqueue to dropping pending requests on 264 * disconnection. waitqueue_active is safe because it 265 * uses atomic operation for condition. 266 */ 267 if (!atomic_dec_return(&conn->r_count) && waitqueue_active(&conn->r_count_q)) 268 wake_up(&conn->r_count_q); 269} 270 271/** 272 * queue_ksmbd_work() - queue a smb request to worker thread queue 273 * for proccessing smb command and sending response 274 * @conn: connection instance 275 * 276 * read remaining data from socket create and submit work. 277 */ 278static int queue_ksmbd_work(struct ksmbd_conn *conn) 279{ 280 struct ksmbd_work *work; 281 282 work = ksmbd_alloc_work_struct(); 283 if (!work) { 284 pr_err("allocation for work failed\n"); 285 return -ENOMEM; 286 } 287 288 work->conn = conn; 289 work->request_buf = conn->request_buf; 290 conn->request_buf = NULL; 291 292 if (ksmbd_init_smb_server(work)) { 293 ksmbd_free_work_struct(work); 294 return -EINVAL; 295 } 296 297 ksmbd_conn_enqueue_request(work); 298 atomic_inc(&conn->r_count); 299 /* update activity on connection */ 300 conn->last_active = jiffies; 301 INIT_WORK(&work->work, handle_ksmbd_work); 302 ksmbd_queue_work(work); 303 return 0; 304} 305 306static int ksmbd_server_process_request(struct ksmbd_conn *conn) 307{ 308 return queue_ksmbd_work(conn); 309} 310 311static int ksmbd_server_terminate_conn(struct ksmbd_conn *conn) 312{ 313 ksmbd_sessions_deregister(conn); 314 destroy_lease_table(conn); 315 return 0; 316} 317 318static void ksmbd_server_tcp_callbacks_init(void) 319{ 320 struct ksmbd_conn_ops ops; 321 322 ops.process_fn = ksmbd_server_process_request; 323 ops.terminate_fn = ksmbd_server_terminate_conn; 324 325 ksmbd_conn_init_server_callbacks(&ops); 326} 327 328static void server_conf_free(void) 329{ 330 int i; 331 332 for (i = 0; i < ARRAY_SIZE(server_conf.conf); i++) { 333 kfree(server_conf.conf[i]); 334 server_conf.conf[i] = NULL; 335 } 336} 337 338static int server_conf_init(void) 339{ 340 WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP); 341 server_conf.enforced_signing = 0; 342 server_conf.min_protocol = ksmbd_min_protocol(); 343 server_conf.max_protocol = ksmbd_max_protocol(); 344 server_conf.auth_mechs = KSMBD_AUTH_NTLMSSP; 345#ifdef CONFIG_SMB_SERVER_KERBEROS5 346 server_conf.auth_mechs |= KSMBD_AUTH_KRB5 | 347 KSMBD_AUTH_MSKRB5; 348#endif 349 return 0; 350} 351 352static void server_ctrl_handle_init(struct server_ctrl_struct *ctrl) 353{ 354 int ret; 355 356 ret = ksmbd_conn_transport_init(); 357 if (ret) { 358 server_queue_ctrl_reset_work(); 359 return; 360 } 361 362 WRITE_ONCE(server_conf.state, SERVER_STATE_RUNNING); 363} 364 365static void server_ctrl_handle_reset(struct server_ctrl_struct *ctrl) 366{ 367 ksmbd_ipc_soft_reset(); 368 ksmbd_conn_transport_destroy(); 369 server_conf_free(); 370 server_conf_init(); 371 WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP); 372} 373 374static void server_ctrl_handle_work(struct work_struct *work) 375{ 376 struct server_ctrl_struct *ctrl; 377 378 ctrl = container_of(work, struct server_ctrl_struct, ctrl_work); 379 380 mutex_lock(&ctrl_lock); 381 switch (ctrl->type) { 382 case SERVER_CTRL_TYPE_INIT: 383 server_ctrl_handle_init(ctrl); 384 break; 385 case SERVER_CTRL_TYPE_RESET: 386 server_ctrl_handle_reset(ctrl); 387 break; 388 default: 389 pr_err("Unknown server work type: %d\n", ctrl->type); 390 } 391 mutex_unlock(&ctrl_lock); 392 kfree(ctrl); 393 module_put(THIS_MODULE); 394} 395 396static int __queue_ctrl_work(int type) 397{ 398 struct server_ctrl_struct *ctrl; 399 400 ctrl = kmalloc(sizeof(struct server_ctrl_struct), GFP_KERNEL); 401 if (!ctrl) 402 return -ENOMEM; 403 404 __module_get(THIS_MODULE); 405 ctrl->type = type; 406 INIT_WORK(&ctrl->ctrl_work, server_ctrl_handle_work); 407 queue_work(system_long_wq, &ctrl->ctrl_work); 408 return 0; 409} 410 411int server_queue_ctrl_init_work(void) 412{ 413 return __queue_ctrl_work(SERVER_CTRL_TYPE_INIT); 414} 415 416int server_queue_ctrl_reset_work(void) 417{ 418 return __queue_ctrl_work(SERVER_CTRL_TYPE_RESET); 419} 420 421static ssize_t stats_show(struct class *class, struct class_attribute *attr, 422 char *buf) 423{ 424 /* 425 * Inc this each time you change stats output format, 426 * so user space will know what to do. 427 */ 428 static int stats_version = 2; 429 static const char * const state[] = { 430 "startup", 431 "running", 432 "reset", 433 "shutdown" 434 }; 435 return sysfs_emit(buf, "%d %s %d %lu\n", stats_version, 436 state[server_conf.state], server_conf.tcp_port, 437 server_conf.ipc_last_active / HZ); 438} 439 440static ssize_t kill_server_store(struct class *class, 441 struct class_attribute *attr, const char *buf, 442 size_t len) 443{ 444 if (!sysfs_streq(buf, "hard")) 445 return len; 446 447 pr_info("kill command received\n"); 448 mutex_lock(&ctrl_lock); 449 WRITE_ONCE(server_conf.state, SERVER_STATE_RESETTING); 450 __module_get(THIS_MODULE); 451 server_ctrl_handle_reset(NULL); 452 module_put(THIS_MODULE); 453 mutex_unlock(&ctrl_lock); 454 return len; 455} 456 457static const char * const debug_type_strings[] = {"smb", "auth", "vfs", 458 "oplock", "ipc", "conn", 459 "rdma"}; 460 461static ssize_t debug_show(struct class *class, struct class_attribute *attr, 462 char *buf) 463{ 464 ssize_t sz = 0; 465 int i, pos = 0; 466 467 for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) { 468 if ((ksmbd_debug_types >> i) & 1) { 469 pos = sysfs_emit_at(buf, sz, "[%s] ", debug_type_strings[i]); 470 } else { 471 pos = sysfs_emit_at(buf, sz, "%s ", debug_type_strings[i]); 472 } 473 sz += pos; 474 } 475 sz += sysfs_emit_at(buf, sz, "\n"); 476 return sz; 477} 478 479static ssize_t debug_store(struct class *class, struct class_attribute *attr, 480 const char *buf, size_t len) 481{ 482 int i; 483 484 for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) { 485 if (sysfs_streq(buf, "all")) { 486 if (ksmbd_debug_types == KSMBD_DEBUG_ALL) 487 ksmbd_debug_types = 0; 488 else 489 ksmbd_debug_types = KSMBD_DEBUG_ALL; 490 break; 491 } 492 493 if (sysfs_streq(buf, debug_type_strings[i])) { 494 if (ksmbd_debug_types & (1 << i)) 495 ksmbd_debug_types &= ~(1 << i); 496 else 497 ksmbd_debug_types |= (1 << i); 498 break; 499 } 500 } 501 502 return len; 503} 504 505static CLASS_ATTR_RO(stats); 506static CLASS_ATTR_WO(kill_server); 507static CLASS_ATTR_RW(debug); 508 509static struct attribute *ksmbd_control_class_attrs[] = { 510 &class_attr_stats.attr, 511 &class_attr_kill_server.attr, 512 &class_attr_debug.attr, 513 NULL, 514}; 515ATTRIBUTE_GROUPS(ksmbd_control_class); 516 517static struct class ksmbd_control_class = { 518 .name = "ksmbd-control", 519 .owner = THIS_MODULE, 520 .class_groups = ksmbd_control_class_groups, 521}; 522 523static int ksmbd_server_shutdown(void) 524{ 525 WRITE_ONCE(server_conf.state, SERVER_STATE_SHUTTING_DOWN); 526 527 class_unregister(&ksmbd_control_class); 528 ksmbd_workqueue_destroy(); 529 ksmbd_ipc_release(); 530 ksmbd_conn_transport_destroy(); 531 ksmbd_crypto_destroy(); 532 ksmbd_free_global_file_table(); 533 destroy_lease_table(NULL); 534 ksmbd_work_pool_destroy(); 535 ksmbd_exit_file_cache(); 536 server_conf_free(); 537 return 0; 538} 539 540static int __init ksmbd_server_init(void) 541{ 542 int ret; 543 544 ret = class_register(&ksmbd_control_class); 545 if (ret) { 546 pr_err("Unable to register ksmbd-control class\n"); 547 return ret; 548 } 549 550 ksmbd_server_tcp_callbacks_init(); 551 552 ret = server_conf_init(); 553 if (ret) 554 goto err_unregister; 555 556 ret = ksmbd_work_pool_init(); 557 if (ret) 558 goto err_unregister; 559 560 ret = ksmbd_init_file_cache(); 561 if (ret) 562 goto err_destroy_work_pools; 563 564 ret = ksmbd_ipc_init(); 565 if (ret) 566 goto err_exit_file_cache; 567 568 ret = ksmbd_init_global_file_table(); 569 if (ret) 570 goto err_ipc_release; 571 572 ret = ksmbd_inode_hash_init(); 573 if (ret) 574 goto err_destroy_file_table; 575 576 ret = ksmbd_crypto_create(); 577 if (ret) 578 goto err_release_inode_hash; 579 580 ret = ksmbd_workqueue_init(); 581 if (ret) 582 goto err_crypto_destroy; 583 584 pr_warn_once("The ksmbd server is experimental\n"); 585 586 return 0; 587 588err_crypto_destroy: 589 ksmbd_crypto_destroy(); 590err_release_inode_hash: 591 ksmbd_release_inode_hash(); 592err_destroy_file_table: 593 ksmbd_free_global_file_table(); 594err_ipc_release: 595 ksmbd_ipc_release(); 596err_exit_file_cache: 597 ksmbd_exit_file_cache(); 598err_destroy_work_pools: 599 ksmbd_work_pool_destroy(); 600err_unregister: 601 class_unregister(&ksmbd_control_class); 602 603 return ret; 604} 605 606/** 607 * ksmbd_server_exit() - shutdown forker thread and free memory at module exit 608 */ 609static void __exit ksmbd_server_exit(void) 610{ 611 ksmbd_server_shutdown(); 612 ksmbd_release_inode_hash(); 613} 614 615MODULE_AUTHOR("Namjae Jeon <linkinjeon@kernel.org>"); 616MODULE_VERSION(KSMBD_VERSION); 617MODULE_DESCRIPTION("Linux kernel CIFS/SMB SERVER"); 618MODULE_LICENSE("GPL"); 619MODULE_SOFTDEP("pre: ecb"); 620MODULE_SOFTDEP("pre: hmac"); 621MODULE_SOFTDEP("pre: md5"); 622MODULE_SOFTDEP("pre: nls"); 623MODULE_SOFTDEP("pre: aes"); 624MODULE_SOFTDEP("pre: cmac"); 625MODULE_SOFTDEP("pre: sha256"); 626MODULE_SOFTDEP("pre: sha512"); 627MODULE_SOFTDEP("pre: aead2"); 628MODULE_SOFTDEP("pre: ccm"); 629MODULE_SOFTDEP("pre: gcm"); 630MODULE_SOFTDEP("pre: crc32"); 631module_init(ksmbd_server_init) 632module_exit(ksmbd_server_exit)