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