Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *   Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
0004  *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
0005  */
0006 
0007 #include "glob.h"
0008 #include "oplock.h"
0009 #include "misc.h"
0010 #include <linux/sched/signal.h>
0011 #include <linux/workqueue.h>
0012 #include <linux/sysfs.h>
0013 #include <linux/module.h>
0014 #include <linux/moduleparam.h>
0015 
0016 #include "server.h"
0017 #include "smb_common.h"
0018 #include "smbstatus.h"
0019 #include "connection.h"
0020 #include "transport_ipc.h"
0021 #include "mgmt/user_session.h"
0022 #include "crypto_ctx.h"
0023 #include "auth.h"
0024 
0025 int ksmbd_debug_types;
0026 
0027 struct ksmbd_server_config server_conf;
0028 
0029 enum SERVER_CTRL_TYPE {
0030     SERVER_CTRL_TYPE_INIT,
0031     SERVER_CTRL_TYPE_RESET,
0032 };
0033 
0034 struct server_ctrl_struct {
0035     int         type;
0036     struct work_struct  ctrl_work;
0037 };
0038 
0039 static DEFINE_MUTEX(ctrl_lock);
0040 
0041 static int ___server_conf_set(int idx, char *val)
0042 {
0043     if (idx >= ARRAY_SIZE(server_conf.conf))
0044         return -EINVAL;
0045 
0046     if (!val || val[0] == 0x00)
0047         return -EINVAL;
0048 
0049     kfree(server_conf.conf[idx]);
0050     server_conf.conf[idx] = kstrdup(val, GFP_KERNEL);
0051     if (!server_conf.conf[idx])
0052         return -ENOMEM;
0053     return 0;
0054 }
0055 
0056 int ksmbd_set_netbios_name(char *v)
0057 {
0058     return ___server_conf_set(SERVER_CONF_NETBIOS_NAME, v);
0059 }
0060 
0061 int ksmbd_set_server_string(char *v)
0062 {
0063     return ___server_conf_set(SERVER_CONF_SERVER_STRING, v);
0064 }
0065 
0066 int ksmbd_set_work_group(char *v)
0067 {
0068     return ___server_conf_set(SERVER_CONF_WORK_GROUP, v);
0069 }
0070 
0071 char *ksmbd_netbios_name(void)
0072 {
0073     return server_conf.conf[SERVER_CONF_NETBIOS_NAME];
0074 }
0075 
0076 char *ksmbd_server_string(void)
0077 {
0078     return server_conf.conf[SERVER_CONF_SERVER_STRING];
0079 }
0080 
0081 char *ksmbd_work_group(void)
0082 {
0083     return server_conf.conf[SERVER_CONF_WORK_GROUP];
0084 }
0085 
0086 /**
0087  * check_conn_state() - check state of server thread connection
0088  * @work:     smb work containing server thread information
0089  *
0090  * Return:  0 on valid connection, otherwise 1 to reconnect
0091  */
0092 static inline int check_conn_state(struct ksmbd_work *work)
0093 {
0094     struct smb_hdr *rsp_hdr;
0095 
0096     if (ksmbd_conn_exiting(work) || ksmbd_conn_need_reconnect(work)) {
0097         rsp_hdr = work->response_buf;
0098         rsp_hdr->Status.CifsError = STATUS_CONNECTION_DISCONNECTED;
0099         return 1;
0100     }
0101     return 0;
0102 }
0103 
0104 #define SERVER_HANDLER_CONTINUE     0
0105 #define SERVER_HANDLER_ABORT        1
0106 
0107 static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn,
0108                  u16 *cmd)
0109 {
0110     struct smb_version_cmds *cmds;
0111     u16 command;
0112     int ret;
0113 
0114     if (check_conn_state(work))
0115         return SERVER_HANDLER_CONTINUE;
0116 
0117     if (ksmbd_verify_smb_message(work))
0118         return SERVER_HANDLER_ABORT;
0119 
0120     command = conn->ops->get_cmd_val(work);
0121     *cmd = command;
0122 
0123 andx_again:
0124     if (command >= conn->max_cmds) {
0125         conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER);
0126         return SERVER_HANDLER_CONTINUE;
0127     }
0128 
0129     cmds = &conn->cmds[command];
0130     if (!cmds->proc) {
0131         ksmbd_debug(SMB, "*** not implemented yet cmd = %x\n", command);
0132         conn->ops->set_rsp_status(work, STATUS_NOT_IMPLEMENTED);
0133         return SERVER_HANDLER_CONTINUE;
0134     }
0135 
0136     if (work->sess && conn->ops->is_sign_req(work, command)) {
0137         ret = conn->ops->check_sign_req(work);
0138         if (!ret) {
0139             conn->ops->set_rsp_status(work, STATUS_ACCESS_DENIED);
0140             return SERVER_HANDLER_CONTINUE;
0141         }
0142     }
0143 
0144     ret = cmds->proc(work);
0145 
0146     if (ret < 0)
0147         ksmbd_debug(CONN, "Failed to process %u [%d]\n", command, ret);
0148     /* AndX commands - chained request can return positive values */
0149     else if (ret > 0) {
0150         command = ret;
0151         *cmd = command;
0152         goto andx_again;
0153     }
0154 
0155     if (work->send_no_response)
0156         return SERVER_HANDLER_ABORT;
0157     return SERVER_HANDLER_CONTINUE;
0158 }
0159 
0160 static void __handle_ksmbd_work(struct ksmbd_work *work,
0161                 struct ksmbd_conn *conn)
0162 {
0163     u16 command = 0;
0164     int rc;
0165 
0166     if (conn->ops->allocate_rsp_buf(work))
0167         return;
0168 
0169     if (conn->ops->is_transform_hdr &&
0170         conn->ops->is_transform_hdr(work->request_buf)) {
0171         rc = conn->ops->decrypt_req(work);
0172         if (rc < 0) {
0173             conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
0174             goto send;
0175         }
0176 
0177         work->encrypted = true;
0178     }
0179 
0180     rc = conn->ops->init_rsp_hdr(work);
0181     if (rc) {
0182         /* either uid or tid is not correct */
0183         conn->ops->set_rsp_status(work, STATUS_INVALID_HANDLE);
0184         goto send;
0185     }
0186 
0187     if (conn->ops->check_user_session) {
0188         rc = conn->ops->check_user_session(work);
0189         if (rc < 0) {
0190             command = conn->ops->get_cmd_val(work);
0191             conn->ops->set_rsp_status(work,
0192                     STATUS_USER_SESSION_DELETED);
0193             goto send;
0194         } else if (rc > 0) {
0195             rc = conn->ops->get_ksmbd_tcon(work);
0196             if (rc < 0) {
0197                 conn->ops->set_rsp_status(work,
0198                     STATUS_NETWORK_NAME_DELETED);
0199                 goto send;
0200             }
0201         }
0202     }
0203 
0204     do {
0205         rc = __process_request(work, conn, &command);
0206         if (rc == SERVER_HANDLER_ABORT)
0207             break;
0208 
0209         /*
0210          * Call smb2_set_rsp_credits() function to set number of credits
0211          * granted in hdr of smb2 response.
0212          */
0213         if (conn->ops->set_rsp_credits) {
0214             spin_lock(&conn->credits_lock);
0215             rc = conn->ops->set_rsp_credits(work);
0216             spin_unlock(&conn->credits_lock);
0217             if (rc < 0) {
0218                 conn->ops->set_rsp_status(work,
0219                     STATUS_INVALID_PARAMETER);
0220                 goto send;
0221             }
0222         }
0223 
0224         if (work->sess &&
0225             (work->sess->sign || smb3_11_final_sess_setup_resp(work) ||
0226              conn->ops->is_sign_req(work, command)))
0227             conn->ops->set_sign_rsp(work);
0228     } while (is_chained_smb2_message(work));
0229 
0230     if (work->send_no_response)
0231         return;
0232 
0233 send:
0234     smb3_preauth_hash_rsp(work);
0235     if (work->sess && work->sess->enc && work->encrypted &&
0236         conn->ops->encrypt_resp) {
0237         rc = conn->ops->encrypt_resp(work);
0238         if (rc < 0) {
0239             conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
0240             goto send;
0241         }
0242     }
0243 
0244     ksmbd_conn_write(work);
0245 }
0246 
0247 /**
0248  * handle_ksmbd_work() - process pending smb work requests
0249  * @wk: smb work containing request command buffer
0250  *
0251  * called by kworker threads to processing remaining smb work requests
0252  */
0253 static void handle_ksmbd_work(struct work_struct *wk)
0254 {
0255     struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work);
0256     struct ksmbd_conn *conn = work->conn;
0257 
0258     atomic64_inc(&conn->stats.request_served);
0259 
0260     __handle_ksmbd_work(work, conn);
0261 
0262     ksmbd_conn_try_dequeue_request(work);
0263     ksmbd_free_work_struct(work);
0264     /*
0265      * Checking waitqueue to dropping pending requests on
0266      * disconnection. waitqueue_active is safe because it
0267      * uses atomic operation for condition.
0268      */
0269     if (!atomic_dec_return(&conn->r_count) && waitqueue_active(&conn->r_count_q))
0270         wake_up(&conn->r_count_q);
0271 }
0272 
0273 /**
0274  * queue_ksmbd_work() - queue a smb request to worker thread queue
0275  *      for proccessing smb command and sending response
0276  * @conn:   connection instance
0277  *
0278  * read remaining data from socket create and submit work.
0279  */
0280 static int queue_ksmbd_work(struct ksmbd_conn *conn)
0281 {
0282     struct ksmbd_work *work;
0283 
0284     work = ksmbd_alloc_work_struct();
0285     if (!work) {
0286         pr_err("allocation for work failed\n");
0287         return -ENOMEM;
0288     }
0289 
0290     work->conn = conn;
0291     work->request_buf = conn->request_buf;
0292     conn->request_buf = NULL;
0293 
0294     if (ksmbd_init_smb_server(work)) {
0295         ksmbd_free_work_struct(work);
0296         return -EINVAL;
0297     }
0298 
0299     ksmbd_conn_enqueue_request(work);
0300     atomic_inc(&conn->r_count);
0301     /* update activity on connection */
0302     conn->last_active = jiffies;
0303     INIT_WORK(&work->work, handle_ksmbd_work);
0304     ksmbd_queue_work(work);
0305     return 0;
0306 }
0307 
0308 static int ksmbd_server_process_request(struct ksmbd_conn *conn)
0309 {
0310     return queue_ksmbd_work(conn);
0311 }
0312 
0313 static int ksmbd_server_terminate_conn(struct ksmbd_conn *conn)
0314 {
0315     ksmbd_sessions_deregister(conn);
0316     destroy_lease_table(conn);
0317     return 0;
0318 }
0319 
0320 static void ksmbd_server_tcp_callbacks_init(void)
0321 {
0322     struct ksmbd_conn_ops ops;
0323 
0324     ops.process_fn = ksmbd_server_process_request;
0325     ops.terminate_fn = ksmbd_server_terminate_conn;
0326 
0327     ksmbd_conn_init_server_callbacks(&ops);
0328 }
0329 
0330 static void server_conf_free(void)
0331 {
0332     int i;
0333 
0334     for (i = 0; i < ARRAY_SIZE(server_conf.conf); i++) {
0335         kfree(server_conf.conf[i]);
0336         server_conf.conf[i] = NULL;
0337     }
0338 }
0339 
0340 static int server_conf_init(void)
0341 {
0342     WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP);
0343     server_conf.enforced_signing = 0;
0344     server_conf.min_protocol = ksmbd_min_protocol();
0345     server_conf.max_protocol = ksmbd_max_protocol();
0346     server_conf.auth_mechs = KSMBD_AUTH_NTLMSSP;
0347 #ifdef CONFIG_SMB_SERVER_KERBEROS5
0348     server_conf.auth_mechs |= KSMBD_AUTH_KRB5 |
0349                 KSMBD_AUTH_MSKRB5;
0350 #endif
0351     return 0;
0352 }
0353 
0354 static void server_ctrl_handle_init(struct server_ctrl_struct *ctrl)
0355 {
0356     int ret;
0357 
0358     ret = ksmbd_conn_transport_init();
0359     if (ret) {
0360         server_queue_ctrl_reset_work();
0361         return;
0362     }
0363 
0364     WRITE_ONCE(server_conf.state, SERVER_STATE_RUNNING);
0365 }
0366 
0367 static void server_ctrl_handle_reset(struct server_ctrl_struct *ctrl)
0368 {
0369     ksmbd_ipc_soft_reset();
0370     ksmbd_conn_transport_destroy();
0371     server_conf_free();
0372     server_conf_init();
0373     WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP);
0374 }
0375 
0376 static void server_ctrl_handle_work(struct work_struct *work)
0377 {
0378     struct server_ctrl_struct *ctrl;
0379 
0380     ctrl = container_of(work, struct server_ctrl_struct, ctrl_work);
0381 
0382     mutex_lock(&ctrl_lock);
0383     switch (ctrl->type) {
0384     case SERVER_CTRL_TYPE_INIT:
0385         server_ctrl_handle_init(ctrl);
0386         break;
0387     case SERVER_CTRL_TYPE_RESET:
0388         server_ctrl_handle_reset(ctrl);
0389         break;
0390     default:
0391         pr_err("Unknown server work type: %d\n", ctrl->type);
0392     }
0393     mutex_unlock(&ctrl_lock);
0394     kfree(ctrl);
0395     module_put(THIS_MODULE);
0396 }
0397 
0398 static int __queue_ctrl_work(int type)
0399 {
0400     struct server_ctrl_struct *ctrl;
0401 
0402     ctrl = kmalloc(sizeof(struct server_ctrl_struct), GFP_KERNEL);
0403     if (!ctrl)
0404         return -ENOMEM;
0405 
0406     __module_get(THIS_MODULE);
0407     ctrl->type = type;
0408     INIT_WORK(&ctrl->ctrl_work, server_ctrl_handle_work);
0409     queue_work(system_long_wq, &ctrl->ctrl_work);
0410     return 0;
0411 }
0412 
0413 int server_queue_ctrl_init_work(void)
0414 {
0415     return __queue_ctrl_work(SERVER_CTRL_TYPE_INIT);
0416 }
0417 
0418 int server_queue_ctrl_reset_work(void)
0419 {
0420     return __queue_ctrl_work(SERVER_CTRL_TYPE_RESET);
0421 }
0422 
0423 static ssize_t stats_show(struct class *class, struct class_attribute *attr,
0424               char *buf)
0425 {
0426     /*
0427      * Inc this each time you change stats output format,
0428      * so user space will know what to do.
0429      */
0430     static int stats_version = 2;
0431     static const char * const state[] = {
0432         "startup",
0433         "running",
0434         "reset",
0435         "shutdown"
0436     };
0437 
0438     ssize_t sz = scnprintf(buf, PAGE_SIZE, "%d %s %d %lu\n", stats_version,
0439                    state[server_conf.state], server_conf.tcp_port,
0440                    server_conf.ipc_last_active / HZ);
0441     return sz;
0442 }
0443 
0444 static ssize_t kill_server_store(struct class *class,
0445                  struct class_attribute *attr, const char *buf,
0446                  size_t len)
0447 {
0448     if (!sysfs_streq(buf, "hard"))
0449         return len;
0450 
0451     pr_info("kill command received\n");
0452     mutex_lock(&ctrl_lock);
0453     WRITE_ONCE(server_conf.state, SERVER_STATE_RESETTING);
0454     __module_get(THIS_MODULE);
0455     server_ctrl_handle_reset(NULL);
0456     module_put(THIS_MODULE);
0457     mutex_unlock(&ctrl_lock);
0458     return len;
0459 }
0460 
0461 static const char * const debug_type_strings[] = {"smb", "auth", "vfs",
0462                           "oplock", "ipc", "conn",
0463                           "rdma"};
0464 
0465 static ssize_t debug_show(struct class *class, struct class_attribute *attr,
0466               char *buf)
0467 {
0468     ssize_t sz = 0;
0469     int i, pos = 0;
0470 
0471     for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) {
0472         if ((ksmbd_debug_types >> i) & 1) {
0473             pos = scnprintf(buf + sz,
0474                     PAGE_SIZE - sz,
0475                     "[%s] ",
0476                     debug_type_strings[i]);
0477         } else {
0478             pos = scnprintf(buf + sz,
0479                     PAGE_SIZE - sz,
0480                     "%s ",
0481                     debug_type_strings[i]);
0482         }
0483         sz += pos;
0484     }
0485     sz += scnprintf(buf + sz, PAGE_SIZE - sz, "\n");
0486     return sz;
0487 }
0488 
0489 static ssize_t debug_store(struct class *class, struct class_attribute *attr,
0490                const char *buf, size_t len)
0491 {
0492     int i;
0493 
0494     for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) {
0495         if (sysfs_streq(buf, "all")) {
0496             if (ksmbd_debug_types == KSMBD_DEBUG_ALL)
0497                 ksmbd_debug_types = 0;
0498             else
0499                 ksmbd_debug_types = KSMBD_DEBUG_ALL;
0500             break;
0501         }
0502 
0503         if (sysfs_streq(buf, debug_type_strings[i])) {
0504             if (ksmbd_debug_types & (1 << i))
0505                 ksmbd_debug_types &= ~(1 << i);
0506             else
0507                 ksmbd_debug_types |= (1 << i);
0508             break;
0509         }
0510     }
0511 
0512     return len;
0513 }
0514 
0515 static CLASS_ATTR_RO(stats);
0516 static CLASS_ATTR_WO(kill_server);
0517 static CLASS_ATTR_RW(debug);
0518 
0519 static struct attribute *ksmbd_control_class_attrs[] = {
0520     &class_attr_stats.attr,
0521     &class_attr_kill_server.attr,
0522     &class_attr_debug.attr,
0523     NULL,
0524 };
0525 ATTRIBUTE_GROUPS(ksmbd_control_class);
0526 
0527 static struct class ksmbd_control_class = {
0528     .name       = "ksmbd-control",
0529     .owner      = THIS_MODULE,
0530     .class_groups   = ksmbd_control_class_groups,
0531 };
0532 
0533 static int ksmbd_server_shutdown(void)
0534 {
0535     WRITE_ONCE(server_conf.state, SERVER_STATE_SHUTTING_DOWN);
0536 
0537     class_unregister(&ksmbd_control_class);
0538     ksmbd_workqueue_destroy();
0539     ksmbd_ipc_release();
0540     ksmbd_conn_transport_destroy();
0541     ksmbd_crypto_destroy();
0542     ksmbd_free_global_file_table();
0543     destroy_lease_table(NULL);
0544     ksmbd_work_pool_destroy();
0545     ksmbd_exit_file_cache();
0546     server_conf_free();
0547     return 0;
0548 }
0549 
0550 static int __init ksmbd_server_init(void)
0551 {
0552     int ret;
0553 
0554     ret = class_register(&ksmbd_control_class);
0555     if (ret) {
0556         pr_err("Unable to register ksmbd-control class\n");
0557         return ret;
0558     }
0559 
0560     ksmbd_server_tcp_callbacks_init();
0561 
0562     ret = server_conf_init();
0563     if (ret)
0564         goto err_unregister;
0565 
0566     ret = ksmbd_work_pool_init();
0567     if (ret)
0568         goto err_unregister;
0569 
0570     ret = ksmbd_init_file_cache();
0571     if (ret)
0572         goto err_destroy_work_pools;
0573 
0574     ret = ksmbd_ipc_init();
0575     if (ret)
0576         goto err_exit_file_cache;
0577 
0578     ret = ksmbd_init_global_file_table();
0579     if (ret)
0580         goto err_ipc_release;
0581 
0582     ret = ksmbd_inode_hash_init();
0583     if (ret)
0584         goto err_destroy_file_table;
0585 
0586     ret = ksmbd_crypto_create();
0587     if (ret)
0588         goto err_release_inode_hash;
0589 
0590     ret = ksmbd_workqueue_init();
0591     if (ret)
0592         goto err_crypto_destroy;
0593 
0594     pr_warn_once("The ksmbd server is experimental\n");
0595 
0596     return 0;
0597 
0598 err_crypto_destroy:
0599     ksmbd_crypto_destroy();
0600 err_release_inode_hash:
0601     ksmbd_release_inode_hash();
0602 err_destroy_file_table:
0603     ksmbd_free_global_file_table();
0604 err_ipc_release:
0605     ksmbd_ipc_release();
0606 err_exit_file_cache:
0607     ksmbd_exit_file_cache();
0608 err_destroy_work_pools:
0609     ksmbd_work_pool_destroy();
0610 err_unregister:
0611     class_unregister(&ksmbd_control_class);
0612 
0613     return ret;
0614 }
0615 
0616 /**
0617  * ksmbd_server_exit() - shutdown forker thread and free memory at module exit
0618  */
0619 static void __exit ksmbd_server_exit(void)
0620 {
0621     ksmbd_server_shutdown();
0622     ksmbd_release_inode_hash();
0623 }
0624 
0625 MODULE_AUTHOR("Namjae Jeon <linkinjeon@kernel.org>");
0626 MODULE_VERSION(KSMBD_VERSION);
0627 MODULE_DESCRIPTION("Linux kernel CIFS/SMB SERVER");
0628 MODULE_LICENSE("GPL");
0629 MODULE_SOFTDEP("pre: ecb");
0630 MODULE_SOFTDEP("pre: hmac");
0631 MODULE_SOFTDEP("pre: md5");
0632 MODULE_SOFTDEP("pre: nls");
0633 MODULE_SOFTDEP("pre: aes");
0634 MODULE_SOFTDEP("pre: cmac");
0635 MODULE_SOFTDEP("pre: sha256");
0636 MODULE_SOFTDEP("pre: sha512");
0637 MODULE_SOFTDEP("pre: aead2");
0638 MODULE_SOFTDEP("pre: ccm");
0639 MODULE_SOFTDEP("pre: gcm");
0640 MODULE_SOFTDEP("pre: crc32");
0641 module_init(ksmbd_server_init)
0642 module_exit(ksmbd_server_exit)