478 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (C) 2016 Namjae Jeon <namjae.jeon@protocolfreedom.org>4 * Copyright (C) 2018 Samsung Electronics Co., Ltd.5 */6 7#include <linux/mutex.h>8#include <linux/freezer.h>9#include <linux/module.h>10 11#include "server.h"12#include "smb_common.h"13#include "mgmt/ksmbd_ida.h"14#include "connection.h"15#include "transport_tcp.h"16#include "transport_rdma.h"17 18static DEFINE_MUTEX(init_lock);19 20static struct ksmbd_conn_ops default_conn_ops;21 22LIST_HEAD(conn_list);23DECLARE_RWSEM(conn_list_lock);24 25/**26 * ksmbd_conn_free() - free resources of the connection instance27 *28 * @conn: connection instance to be cleaned up29 *30 * During the thread termination, the corresponding conn instance31 * resources(sock/memory) are released and finally the conn object is freed.32 */33void ksmbd_conn_free(struct ksmbd_conn *conn)34{35 down_write(&conn_list_lock);36 list_del(&conn->conns_list);37 up_write(&conn_list_lock);38 39 xa_destroy(&conn->sessions);40 kvfree(conn->request_buf);41 kfree(conn->preauth_info);42 if (atomic_dec_and_test(&conn->refcnt))43 kfree(conn);44}45 46/**47 * ksmbd_conn_alloc() - initialize a new connection instance48 *49 * Return: ksmbd_conn struct on success, otherwise NULL50 */51struct ksmbd_conn *ksmbd_conn_alloc(void)52{53 struct ksmbd_conn *conn;54 55 conn = kzalloc(sizeof(struct ksmbd_conn), GFP_KERNEL);56 if (!conn)57 return NULL;58 59 conn->need_neg = true;60 ksmbd_conn_set_new(conn);61 conn->local_nls = load_nls("utf8");62 if (!conn->local_nls)63 conn->local_nls = load_nls_default();64 if (IS_ENABLED(CONFIG_UNICODE))65 conn->um = utf8_load(UNICODE_AGE(12, 1, 0));66 else67 conn->um = ERR_PTR(-EOPNOTSUPP);68 if (IS_ERR(conn->um))69 conn->um = NULL;70 atomic_set(&conn->req_running, 0);71 atomic_set(&conn->r_count, 0);72 atomic_set(&conn->refcnt, 1);73 atomic_set(&conn->mux_smb_requests, 0);74 conn->total_credits = 1;75 conn->outstanding_credits = 0;76 77 init_waitqueue_head(&conn->req_running_q);78 init_waitqueue_head(&conn->r_count_q);79 INIT_LIST_HEAD(&conn->conns_list);80 INIT_LIST_HEAD(&conn->requests);81 INIT_LIST_HEAD(&conn->async_requests);82 spin_lock_init(&conn->request_lock);83 spin_lock_init(&conn->credits_lock);84 ida_init(&conn->async_ida);85 xa_init(&conn->sessions);86 87 spin_lock_init(&conn->llist_lock);88 INIT_LIST_HEAD(&conn->lock_list);89 90 init_rwsem(&conn->session_lock);91 92 down_write(&conn_list_lock);93 list_add(&conn->conns_list, &conn_list);94 up_write(&conn_list_lock);95 return conn;96}97 98bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c)99{100 struct ksmbd_conn *t;101 bool ret = false;102 103 down_read(&conn_list_lock);104 list_for_each_entry(t, &conn_list, conns_list) {105 if (memcmp(t->ClientGUID, c->ClientGUID, SMB2_CLIENT_GUID_SIZE))106 continue;107 108 ret = true;109 break;110 }111 up_read(&conn_list_lock);112 return ret;113}114 115void ksmbd_conn_enqueue_request(struct ksmbd_work *work)116{117 struct ksmbd_conn *conn = work->conn;118 struct list_head *requests_queue = NULL;119 120 if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE)121 requests_queue = &conn->requests;122 123 if (requests_queue) {124 atomic_inc(&conn->req_running);125 spin_lock(&conn->request_lock);126 list_add_tail(&work->request_entry, requests_queue);127 spin_unlock(&conn->request_lock);128 }129}130 131void ksmbd_conn_try_dequeue_request(struct ksmbd_work *work)132{133 struct ksmbd_conn *conn = work->conn;134 135 if (list_empty(&work->request_entry) &&136 list_empty(&work->async_request_entry))137 return;138 139 atomic_dec(&conn->req_running);140 spin_lock(&conn->request_lock);141 list_del_init(&work->request_entry);142 spin_unlock(&conn->request_lock);143 if (work->asynchronous)144 release_async_work(work);145 146 wake_up_all(&conn->req_running_q);147}148 149void ksmbd_conn_lock(struct ksmbd_conn *conn)150{151 mutex_lock(&conn->srv_mutex);152}153 154void ksmbd_conn_unlock(struct ksmbd_conn *conn)155{156 mutex_unlock(&conn->srv_mutex);157}158 159void ksmbd_all_conn_set_status(u64 sess_id, u32 status)160{161 struct ksmbd_conn *conn;162 163 down_read(&conn_list_lock);164 list_for_each_entry(conn, &conn_list, conns_list) {165 if (conn->binding || xa_load(&conn->sessions, sess_id))166 WRITE_ONCE(conn->status, status);167 }168 up_read(&conn_list_lock);169}170 171void ksmbd_conn_wait_idle(struct ksmbd_conn *conn)172{173 wait_event(conn->req_running_q, atomic_read(&conn->req_running) < 2);174}175 176int ksmbd_conn_wait_idle_sess_id(struct ksmbd_conn *curr_conn, u64 sess_id)177{178 struct ksmbd_conn *conn;179 int rc, retry_count = 0, max_timeout = 120;180 int rcount = 1;181 182retry_idle:183 if (retry_count >= max_timeout)184 return -EIO;185 186 down_read(&conn_list_lock);187 list_for_each_entry(conn, &conn_list, conns_list) {188 if (conn->binding || xa_load(&conn->sessions, sess_id)) {189 if (conn == curr_conn)190 rcount = 2;191 if (atomic_read(&conn->req_running) >= rcount) {192 rc = wait_event_timeout(conn->req_running_q,193 atomic_read(&conn->req_running) < rcount,194 HZ);195 if (!rc) {196 up_read(&conn_list_lock);197 retry_count++;198 goto retry_idle;199 }200 }201 }202 }203 up_read(&conn_list_lock);204 205 return 0;206}207 208int ksmbd_conn_write(struct ksmbd_work *work)209{210 struct ksmbd_conn *conn = work->conn;211 int sent;212 213 if (!work->response_buf) {214 pr_err("NULL response header\n");215 return -EINVAL;216 }217 218 if (work->send_no_response)219 return 0;220 221 if (!work->iov_idx)222 return -EINVAL;223 224 ksmbd_conn_lock(conn);225 sent = conn->transport->ops->writev(conn->transport, work->iov,226 work->iov_cnt,227 get_rfc1002_len(work->iov[0].iov_base) + 4,228 work->need_invalidate_rkey,229 work->remote_key);230 ksmbd_conn_unlock(conn);231 232 if (sent < 0) {233 pr_err("Failed to send message: %d\n", sent);234 return sent;235 }236 237 return 0;238}239 240int ksmbd_conn_rdma_read(struct ksmbd_conn *conn,241 void *buf, unsigned int buflen,242 struct smb2_buffer_desc_v1 *desc,243 unsigned int desc_len)244{245 int ret = -EINVAL;246 247 if (conn->transport->ops->rdma_read)248 ret = conn->transport->ops->rdma_read(conn->transport,249 buf, buflen,250 desc, desc_len);251 return ret;252}253 254int ksmbd_conn_rdma_write(struct ksmbd_conn *conn,255 void *buf, unsigned int buflen,256 struct smb2_buffer_desc_v1 *desc,257 unsigned int desc_len)258{259 int ret = -EINVAL;260 261 if (conn->transport->ops->rdma_write)262 ret = conn->transport->ops->rdma_write(conn->transport,263 buf, buflen,264 desc, desc_len);265 return ret;266}267 268bool ksmbd_conn_alive(struct ksmbd_conn *conn)269{270 if (!ksmbd_server_running())271 return false;272 273 if (ksmbd_conn_exiting(conn))274 return false;275 276 if (kthread_should_stop())277 return false;278 279 if (atomic_read(&conn->stats.open_files_count) > 0)280 return true;281 282 /*283 * Stop current session if the time that get last request from client284 * is bigger than deadtime user configured and opening file count is285 * zero.286 */287 if (server_conf.deadtime > 0 &&288 time_after(jiffies, conn->last_active + server_conf.deadtime)) {289 ksmbd_debug(CONN, "No response from client in %lu minutes\n",290 server_conf.deadtime / SMB_ECHO_INTERVAL);291 return false;292 }293 return true;294}295 296#define SMB1_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb_hdr))297#define SMB2_MIN_SUPPORTED_HEADER_SIZE (sizeof(struct smb2_hdr) + 4)298 299/**300 * ksmbd_conn_handler_loop() - session thread to listen on new smb requests301 * @p: connection instance302 *303 * One thread each per connection304 *305 * Return: 0 on success306 */307int ksmbd_conn_handler_loop(void *p)308{309 struct ksmbd_conn *conn = (struct ksmbd_conn *)p;310 struct ksmbd_transport *t = conn->transport;311 unsigned int pdu_size, max_allowed_pdu_size;312 char hdr_buf[4] = {0,};313 int size;314 315 mutex_init(&conn->srv_mutex);316 __module_get(THIS_MODULE);317 318 if (t->ops->prepare && t->ops->prepare(t))319 goto out;320 321 conn->last_active = jiffies;322 set_freezable();323 while (ksmbd_conn_alive(conn)) {324 if (try_to_freeze())325 continue;326 327 kvfree(conn->request_buf);328 conn->request_buf = NULL;329 330 size = t->ops->read(t, hdr_buf, sizeof(hdr_buf), -1);331 if (size != sizeof(hdr_buf))332 break;333 334 pdu_size = get_rfc1002_len(hdr_buf);335 ksmbd_debug(CONN, "RFC1002 header %u bytes\n", pdu_size);336 337 if (ksmbd_conn_good(conn))338 max_allowed_pdu_size =339 SMB3_MAX_MSGSIZE + conn->vals->max_write_size;340 else341 max_allowed_pdu_size = SMB3_MAX_MSGSIZE;342 343 if (pdu_size > max_allowed_pdu_size) {344 pr_err_ratelimited("PDU length(%u) exceeded maximum allowed pdu size(%u) on connection(%d)\n",345 pdu_size, max_allowed_pdu_size,346 READ_ONCE(conn->status));347 break;348 }349 350 /*351 * Check maximum pdu size(0x00FFFFFF).352 */353 if (pdu_size > MAX_STREAM_PROT_LEN)354 break;355 356 if (pdu_size < SMB1_MIN_SUPPORTED_HEADER_SIZE)357 break;358 359 /* 4 for rfc1002 length field */360 /* 1 for implied bcc[0] */361 size = pdu_size + 4 + 1;362 conn->request_buf = kvmalloc(size, GFP_KERNEL);363 if (!conn->request_buf)364 break;365 366 memcpy(conn->request_buf, hdr_buf, sizeof(hdr_buf));367 368 /*369 * We already read 4 bytes to find out PDU size, now370 * read in PDU371 */372 size = t->ops->read(t, conn->request_buf + 4, pdu_size, 2);373 if (size < 0) {374 pr_err("sock_read failed: %d\n", size);375 break;376 }377 378 if (size != pdu_size) {379 pr_err("PDU error. Read: %d, Expected: %d\n",380 size, pdu_size);381 continue;382 }383 384 if (!ksmbd_smb_request(conn))385 break;386 387 if (((struct smb2_hdr *)smb2_get_msg(conn->request_buf))->ProtocolId ==388 SMB2_PROTO_NUMBER) {389 if (pdu_size < SMB2_MIN_SUPPORTED_HEADER_SIZE)390 break;391 }392 393 if (!default_conn_ops.process_fn) {394 pr_err("No connection request callback\n");395 break;396 }397 398 if (default_conn_ops.process_fn(conn)) {399 pr_err("Cannot handle request\n");400 break;401 }402 }403 404out:405 ksmbd_conn_set_releasing(conn);406 /* Wait till all reference dropped to the Server object*/407 wait_event(conn->r_count_q, atomic_read(&conn->r_count) == 0);408 409 if (IS_ENABLED(CONFIG_UNICODE))410 utf8_unload(conn->um);411 unload_nls(conn->local_nls);412 if (default_conn_ops.terminate_fn)413 default_conn_ops.terminate_fn(conn);414 t->ops->disconnect(t);415 module_put(THIS_MODULE);416 return 0;417}418 419void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops)420{421 default_conn_ops.process_fn = ops->process_fn;422 default_conn_ops.terminate_fn = ops->terminate_fn;423}424 425int ksmbd_conn_transport_init(void)426{427 int ret;428 429 mutex_lock(&init_lock);430 ret = ksmbd_tcp_init();431 if (ret) {432 pr_err("Failed to init TCP subsystem: %d\n", ret);433 goto out;434 }435 436 ret = ksmbd_rdma_init();437 if (ret) {438 pr_err("Failed to init RDMA subsystem: %d\n", ret);439 goto out;440 }441out:442 mutex_unlock(&init_lock);443 return ret;444}445 446static void stop_sessions(void)447{448 struct ksmbd_conn *conn;449 struct ksmbd_transport *t;450 451again:452 down_read(&conn_list_lock);453 list_for_each_entry(conn, &conn_list, conns_list) {454 t = conn->transport;455 ksmbd_conn_set_exiting(conn);456 if (t->ops->shutdown) {457 up_read(&conn_list_lock);458 t->ops->shutdown(t);459 down_read(&conn_list_lock);460 }461 }462 up_read(&conn_list_lock);463 464 if (!list_empty(&conn_list)) {465 schedule_timeout_interruptible(HZ / 10); /* 100ms */466 goto again;467 }468}469 470void ksmbd_conn_transport_destroy(void)471{472 mutex_lock(&init_lock);473 ksmbd_tcp_destroy();474 ksmbd_rdma_destroy();475 stop_sessions();476 mutex_unlock(&init_lock);477}478