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