Whamcloud - gitweb
LU-7623 Update obd iocontrol methods with __user attribute
[fs/lustre-release.git] / lustre / mgs / mgs_handler.c
index a77c1cf..f1a643e 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2010, 2014, Intel Corporation.
+ * Copyright (c) 2010, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -94,11 +94,18 @@ static int mgs_exception(struct tgt_session_info *tsi)
        RETURN(0);
 }
 
+static inline bool str_starts_with(const char *str, const char *prefix)
+{
+       return strncmp(str, prefix, strlen(prefix)) == 0;
+}
+
 static int mgs_set_info(struct tgt_session_info *tsi)
 {
        struct mgs_thread_info  *mgi;
        struct mgs_send_param   *msp, *rep_msp;
        struct lustre_cfg       *lcfg;
+       size_t                   param_len;
+       char                    *s;
        int                      rc;
 
        ENTRY;
@@ -111,6 +118,20 @@ static int mgs_set_info(struct tgt_session_info *tsi)
        if (msp == NULL)
                RETURN(err_serious(-EFAULT));
 
+       param_len = strnlen(msp->mgs_param, sizeof(msp->mgs_param));
+       if (param_len == 0 || param_len == sizeof(msp->mgs_param))
+               RETURN(-EINVAL);
+
+       /* We only allow '*.lov.stripe{size,count,offset}=*' from an RPC. */
+       s = strchr(msp->mgs_param, '.');
+       if (s == NULL)
+               RETURN(-EINVAL);
+
+       if (!str_starts_with(s + 1, "lov.stripesize=") &&
+           !str_starts_with(s + 1, "lov.stripecount=") &&
+           !str_starts_with(s + 1, "lov.stripeoffset="))
+               RETURN(-EINVAL);
+
        /* Construct lustre_cfg structure to pass to function mgs_setparam */
        lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
        lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, msp->mgs_param);
@@ -631,7 +652,6 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
                                 struct obd_ioctl_data *data)
 {
        struct lustre_cfg       *lcfg = NULL;
-       struct lu_nodemap       *nodemap;
        lnet_nid_t              nid;
        const char              *nodemap_name = NULL;
        const char              *nidstr = NULL;
@@ -639,8 +659,9 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
        const char              *idtype_str = NULL;
        char                    *param = NULL;
        char                    fs_idstr[16];
+       char                    name_buf[LUSTRE_NODEMAP_NAME_LENGTH + 1];
        int                     rc = 0;
-       __u32                   client_id;
+       unsigned long           client_id;
        __u32                   fs_id;
        __u32                   cmd;
        int                     idtype;
@@ -687,10 +708,10 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
                        GOTO(out_lcfg, rc = -EINVAL);
                nidstr = lustre_cfg_string(lcfg, 1);
                nid = libcfs_str2nid(nidstr);
-               nodemap = nodemap_classify_nid(nid);
-               memset(data->ioc_pbuf1, 0, data->ioc_plen1);
-               if (copy_to_user(data->ioc_pbuf1, nodemap->nm_name,
-                                strlen(nodemap->nm_name)) != 0)
+               nodemap_test_nid(nid, name_buf, sizeof(name_buf));
+               rc = copy_to_user(data->ioc_pbuf1, name_buf,
+                                 MIN(data->ioc_plen1, sizeof(name_buf)));
+               if (rc != 0)
                        GOTO(out_lcfg, rc = -EFAULT);
                break;
        case LCFG_NODEMAP_TEST_ID:
@@ -701,16 +722,16 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
                client_idstr = lustre_cfg_string(lcfg, 3);
 
                nid = libcfs_str2nid(nidstr);
-               nodemap = nodemap_classify_nid(nid);
-               client_id = simple_strtoul(client_idstr, NULL, 10);
-
                if (strcmp(idtype_str, "uid") == 0)
                        idtype = NODEMAP_UID;
                else
                        idtype = NODEMAP_GID;
 
-               fs_id = nodemap_map_id(nodemap, idtype, NODEMAP_CLIENT_TO_FS,
-                                      client_id);
+               rc = kstrtoul(client_idstr, 10, &client_id);
+               if (rc != 0)
+                       GOTO(out_lcfg, rc = -EINVAL);
+
+               fs_id = nodemap_test_id(nid, idtype, client_id);
 
                if (data->ioc_plen1 < sizeof(fs_idstr))
                        GOTO(out_lcfg, rc = -EINVAL);
@@ -842,7 +863,7 @@ out_pool:
 
 /* from mdt_iocontrol */
 static int mgs_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
-                        void *karg, void *uarg)
+                        void *karg, void __user *uarg)
 {
        struct mgs_device *mgs = exp2mgs_dev(exp);
         struct obd_ioctl_data *data = karg;
@@ -935,17 +956,6 @@ out_free:
                rc = mgs_iocontrol_nodemap(&env, mgs, data);
                break;
 
-       case OBD_IOC_DUMP_LOG: {
-               struct llog_ctxt *ctxt;
-
-               ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
-               rc = class_config_dump_llog(&env, ctxt, data->ioc_inlbuf1,
-                                           NULL);
-                llog_ctxt_put(ctxt);
-
-               break;
-        }
-
        case OBD_IOC_CATLOGLIST:
                rc = mgs_list_logs(&env, mgs, data);
                break;
@@ -1072,6 +1082,11 @@ static struct tgt_opc_slice mgs_common_slice[] = {
                .tos_hs        = mgs_llog_handlers
        },
        {
+               .tos_opc_start = SEC_FIRST_OPC,
+               .tos_opc_end   = SEC_LAST_OPC,
+               .tos_hs        = tgt_sec_ctx_handlers
+       },
+       {
                .tos_hs        = NULL
        }
 };
@@ -1084,6 +1099,7 @@ static int mgs_init0(const struct lu_env *env, struct mgs_device *mgs,
        struct lustre_mount_info        *lmi;
        struct llog_ctxt                *ctxt;
        struct fs_db                    *fsdb = NULL;
+       struct fs_db                    *fsdb_srpc = NULL;
        int                              rc;
 
        ENTRY;
@@ -1164,6 +1180,9 @@ static int mgs_init0(const struct lu_env *env, struct mgs_device *mgs,
                CERROR("%s: %s fsdb and log setup failed: rc = %d\n",
                       obd->obd_name, PARAMS_FILENAME, rc);
 
+       /* Setup _mgs fsdb, useful for srpc */
+       mgs__mgs_fsdb_setup(env, mgs, fsdb_srpc);
+
        ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,
                           "mgs_ldlm_client", &obd->obd_ldlm_client);
 
@@ -1382,6 +1401,7 @@ static struct lu_device *mgs_device_fini(const struct lu_env *env,
        mgs_params_fsdb_cleanup(env, mgs);
        mgs_cleanup_fsdb_list(mgs);
 
+       ldlm_namespace_free_prior(obd->obd_namespace, NULL, 1);
        obd_exports_barrier(obd);
        obd_zombie_barrier();
 
@@ -1396,7 +1416,7 @@ static struct lu_device *mgs_device_fini(const struct lu_env *env,
 
        mgs_fs_cleanup(env, mgs);
 
-       ldlm_namespace_free(obd->obd_namespace, NULL, 1);
+       ldlm_namespace_free_post(obd->obd_namespace);
        obd->obd_namespace = NULL;
 
        lu_site_purge(env, d->ld_site, ~0);
@@ -1546,13 +1566,14 @@ static int __init mgs_init(void)
                                   LUSTRE_MGS_NAME, &mgs_device_type);
 }
 
-static void /*__exit*/ mgs_exit(void)
+static void __exit mgs_exit(void)
 {
        class_unregister_type(LUSTRE_MGS_NAME);
 }
 
-MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
-MODULE_DESCRIPTION("Lustre  Management Server (MGS)");
+MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
+MODULE_DESCRIPTION("Lustre Management Server (MGS)");
+MODULE_VERSION(LUSTRE_VERSION_STRING);
 MODULE_LICENSE("GPL");
 
 module_init(mgs_init);