Whamcloud - gitweb
LU-12275 sec: control client side encryption 33/36433/19
authorSebastien Buisson <sbuisson@ddn.com>
Fri, 11 Oct 2019 08:34:02 +0000 (08:34 +0000)
committerOleg Drokin <green@whamcloud.com>
Wed, 10 Jun 2020 20:51:15 +0000 (20:51 +0000)
Client enables encryption by default. However, this should be
possible only if server side is encryption aware.
Moreover, we want to give the ability to decide which clients can
make use of encryption, by extending the nodemap mechanism with a
new 'forbid_encryption' property, set to 0 by default.

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: I765e5ce555e8277319c03c770cb6e6ac73cfc9e8
Reviewed-on: https://review.whamcloud.com/36433
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: John L. Hammond <jhammond@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
12 files changed:
lustre/include/lustre_nodemap.h
lustre/include/uapi/linux/lustre/lustre_cfg.h
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/mgs/mgs_handler.c
lustre/mgs/mgs_llog.c
lustre/ptlrpc/nodemap_handler.c
lustre/ptlrpc/nodemap_lproc.c
lustre/ptlrpc/nodemap_storage.c
lustre/target/tgt_handler.c
lustre/utils/obd.c

index 9d200bf..199dc79 100644 (file)
@@ -77,7 +77,8 @@ struct lu_nodemap {
                                 nmf_allow_root_access:1,
                                 nmf_map_uid_only:1,
                                 nmf_map_gid_only:1,
-                                nmf_enable_audit:1;
+                                nmf_enable_audit:1,
+                                nmf_forbid_encryption:1;
        /* unique ID set by MGS */
        unsigned int             nm_id;
        /* nodemap ref counter */
@@ -139,6 +140,7 @@ int nodemap_set_mapping_mode(const char *name, enum nodemap_mapping_modes mode);
 int nodemap_set_squash_uid(const char *name, uid_t uid);
 int nodemap_set_squash_gid(const char *name, gid_t gid);
 int nodemap_set_audit_mode(const char *name, bool enable_audit);
+int nodemap_set_forbid_encryption(const char *name, bool forbid_encryption);
 bool nodemap_can_setquota(const struct lu_nodemap *nodemap);
 int nodemap_add_idmap(const char *name, enum nodemap_id_type id_type,
                      const __u32 map[2]);
index 30d5c7d..520f3ef 100644 (file)
@@ -137,6 +137,7 @@ enum lcfg_command_type {
        LCFG_NODEMAP_MAP_MODE     = 0x00ce059, /**< set the mapping mode */
        LCFG_NODEMAP_AUDIT_MODE   = 0x00ce05a, /**< set the audit mode */
        LCFG_NODEMAP_SET_SEPOL    = 0x00ce05b, /**< set SELinux policy */
+       LCFG_NODEMAP_FORBID_ENCRYPT     = 0x00ce05c, /**< forbid encryption */
 };
 
 struct lustre_cfg_bufs {
index 6450380..5e1364d 100644 (file)
@@ -904,7 +904,8 @@ struct ptlrpc_body_v2 {
                                OBD_CONNECT2_LSOM | \
                                OBD_CONNECT2_ASYNC_DISCARD | \
                                OBD_CONNECT2_PCC | \
-                               OBD_CONNECT2_CRUSH)
+                               OBD_CONNECT2_CRUSH | \
+                               OBD_CONNECT2_ENCRYPT)
 
 #define OST_CONNECT_SUPPORTED  (OBD_CONNECT_SRVLOCK | OBD_CONNECT_GRANT | \
                                OBD_CONNECT_REQPORTAL | OBD_CONNECT_VERSION | \
@@ -925,7 +926,8 @@ struct ptlrpc_body_v2 {
                                OBD_CONNECT_GRANT_PARAM | \
                                OBD_CONNECT_SHORTIO | OBD_CONNECT_FLAGS2)
 
-#define OST_CONNECT_SUPPORTED2 (OBD_CONNECT2_LOCKAHEAD | OBD_CONNECT2_INC_XID)
+#define OST_CONNECT_SUPPORTED2 (OBD_CONNECT2_LOCKAHEAD | OBD_CONNECT2_INC_XID |\
+                               OBD_CONNECT2_ENCRYPT)
 
 #define ECHO_CONNECT_SUPPORTED (OBD_CONNECT_FID)
 #define ECHO_CONNECT_SUPPORTED2 0
index cb0ebf2..0302620 100644 (file)
@@ -434,6 +434,23 @@ int ll_inode_init_security(struct dentry *dentry, struct inode *inode,
 int ll_listsecurity(struct inode *inode, char *secctx_name,
                    size_t secctx_name_size);
 
+static inline bool obd_connect_has_enc(struct obd_connect_data *data)
+{
+#ifdef HAVE_LUSTRE_CRYPTO
+       return data->ocd_connect_flags & OBD_CONNECT_FLAGS2 &&
+               data->ocd_connect_flags2 & OBD_CONNECT2_ENCRYPT;
+#else
+       return false;
+#endif
+}
+
+static inline void obd_connect_set_enc(struct obd_connect_data *data)
+{
+#ifdef HAVE_LUSTRE_CRYPTO
+       data->ocd_connect_flags2 |= OBD_CONNECT2_ENCRYPT;
+#endif
+}
+
 /*
  * Locking to guarantee consistency of non-atomic updates to long long i_size,
  * consistency between file size and KMS.
index 78ff536..13ee0b2 100644 (file)
@@ -320,6 +320,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
                data->ocd_connect_flags &= ~OBD_CONNECT_PINGLESS;
 
        obd_connect_set_secctx(data);
+       if (ll_sbi_has_encrypt(sbi))
+               obd_connect_set_enc(data);
 
 #if defined(CONFIG_SECURITY)
        data->ocd_connect_flags2 |= OBD_CONNECT2_SELINUX_POLICY;
@@ -429,6 +431,14 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
        if (obd_connect_has_secctx(data))
                sbi->ll_flags |= LL_SBI_FILE_SECCTX;
 
+       if (ll_sbi_has_encrypt(sbi) && !obd_connect_has_enc(data)) {
+               if (ll_sbi_has_test_dummy_encryption(sbi))
+                       LCONSOLE_WARN("%s: server %s does not support encryption feature, encryption deactivated.\n",
+                                     sbi->ll_fsname,
+                                     sbi->ll_md_exp->exp_obd->obd_name);
+               ll_sbi_set_encrypt(sbi, false);
+       }
+
        if (data->ocd_ibits_known & MDS_INODELOCK_XATTR) {
                if (!(data->ocd_connect_flags & OBD_CONNECT_MAX_EASIZE)) {
                        LCONSOLE_INFO("%s: disabling xattr cache due to "
@@ -490,6 +500,9 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
        if (sbi->ll_flags & LL_SBI_ALWAYS_PING)
                data->ocd_connect_flags &= ~OBD_CONNECT_PINGLESS;
 
+       if (ll_sbi_has_encrypt(sbi))
+               obd_connect_set_enc(data);
+
        CDEBUG(D_RPCTRACE, "ocd_connect_flags: %#llx ocd_version: %d "
               "ocd_grant: %d\n", data->ocd_connect_flags,
               data->ocd_version, data->ocd_grant);
@@ -513,6 +526,16 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
                GOTO(out_md, err);
        }
 
+       if (ll_sbi_has_encrypt(sbi) &&
+           !obd_connect_has_enc(&sbi->ll_dt_obd->u.lov.lov_ocd)) {
+               if (ll_sbi_has_test_dummy_encryption(sbi))
+                       LCONSOLE_WARN("%s: server %s does not support encryption feature, encryption deactivated.\n",
+                                     sbi->ll_fsname, dt);
+               ll_sbi_set_encrypt(sbi, false);
+       } else if (ll_sbi_has_test_dummy_encryption(sbi)) {
+               LCONSOLE_WARN("Test dummy encryption mode enabled\n");
+       }
+
        sbi->ll_dt_exp->exp_connect_data = *data;
 
        /* Don't change value if it was specified in the config log */
index 5427e12..e314fa9 100644 (file)
@@ -854,6 +854,7 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
        case LCFG_NODEMAP_SQUASH_GID:
        case LCFG_NODEMAP_MAP_MODE:
        case LCFG_NODEMAP_AUDIT_MODE:
+       case LCFG_NODEMAP_FORBID_ENCRYPT:
                if (lcfg->lcfg_bufcount != 4)
                        GOTO(out_lcfg, rc = -EINVAL);
                nodemap_name = lustre_cfg_string(lcfg, 1);
index eb344a1..a8f8325 100644 (file)
@@ -5436,6 +5436,12 @@ int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
                if (rc == 0)
                        rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
                break;
+       case LCFG_NODEMAP_FORBID_ENCRYPT:
+               rc = kstrtobool(param, &bool_switch);
+               if (rc == 0)
+                       rc = nodemap_set_forbid_encryption(nodemap_name,
+                                                          bool_switch);
+               break;
        case LCFG_NODEMAP_MAP_MODE:
                if (strcmp("both", param) == 0)
                        rc = nodemap_set_mapping_mode(nodemap_name,
index a30cd9c..44fc2f2 100644 (file)
@@ -1172,6 +1172,7 @@ struct lu_nodemap *nodemap_create(const char *name,
                nodemap->nmf_map_uid_only = 0;
                nodemap->nmf_map_gid_only = 0;
                nodemap->nmf_enable_audit = 1;
+               nodemap->nmf_forbid_encryption = 0;
 
                nodemap->nm_squash_uid = NODEMAP_NOBODY_UID;
                nodemap->nm_squash_gid = NODEMAP_NOBODY_GID;
@@ -1193,6 +1194,8 @@ struct lu_nodemap *nodemap_create(const char *name,
                                default_nodemap->nmf_map_gid_only;
                nodemap->nmf_enable_audit =
                        default_nodemap->nmf_enable_audit;
+               nodemap->nmf_forbid_encryption =
+                       default_nodemap->nmf_forbid_encryption;
 
                nodemap->nm_squash_uid = default_nodemap->nm_squash_uid;
                nodemap->nm_squash_gid = default_nodemap->nm_squash_gid;
@@ -1434,6 +1437,34 @@ out:
 }
 EXPORT_SYMBOL(nodemap_set_audit_mode);
 
+/**
+ * Set the nmf_forbid_encryption flag to true or false.
+ * \param      name                    nodemap name
+ * \param      forbid_encryption       if true, forbid encryption
+ * \retval     0 on success
+ *
+ */
+int nodemap_set_forbid_encryption(const char *name, bool forbid_encryption)
+{
+       struct lu_nodemap       *nodemap = NULL;
+       int                     rc = 0;
+
+       mutex_lock(&active_config_lock);
+       nodemap = nodemap_lookup(name);
+       mutex_unlock(&active_config_lock);
+       if (IS_ERR(nodemap))
+               GOTO(out, rc = PTR_ERR(nodemap));
+
+       nodemap->nmf_forbid_encryption = forbid_encryption;
+       rc = nodemap_idx_nodemap_update(nodemap);
+
+       nm_member_revoke_locks(nodemap);
+       nodemap_putref(nodemap);
+out:
+       return rc;
+}
+EXPORT_SYMBOL(nodemap_set_forbid_encryption);
+
 
 /**
  * Add a nodemap
index 62a053f..d3ab5fd 100644 (file)
@@ -637,6 +637,33 @@ static int nodemap_audit_mode_seq_show(struct seq_file *m, void *data)
        return 0;
 }
 
+/**
+ * Reads and prints the forbid_encryption flag for the given nodemap.
+ *
+ * \param      m               seq file in proc fs
+ * \param      data            unused
+ * \retval     0               success
+ */
+static int nodemap_forbid_encryption_seq_show(struct seq_file *m, void *data)
+{
+       struct lu_nodemap *nodemap;
+       int rc;
+
+       mutex_lock(&active_config_lock);
+       nodemap = nodemap_lookup(m->private);
+       mutex_unlock(&active_config_lock);
+       if (IS_ERR(nodemap)) {
+               rc = PTR_ERR(nodemap);
+               CERROR("cannot find nodemap '%s': rc = %d\n",
+                      (char *)m->private, rc);
+               return rc;
+       }
+
+       seq_printf(m, "%d\n", (int)nodemap->nmf_forbid_encryption);
+       nodemap_putref(nodemap);
+       return 0;
+}
+
 static struct lprocfs_vars lprocfs_nm_module_vars[] = {
        {
                .name           = "active",
@@ -655,6 +682,7 @@ LPROC_SEQ_FOPS_RO(nodemap_squash_gid);
 LPROC_SEQ_FOPS_RO(nodemap_deny_unknown);
 LPROC_SEQ_FOPS_RO(nodemap_map_mode);
 LPROC_SEQ_FOPS_RO(nodemap_audit_mode);
+LPROC_SEQ_FOPS_RO(nodemap_forbid_encryption);
 
 const struct file_operations nodemap_ranges_fops = {
        .open                   = nodemap_ranges_open,
@@ -703,6 +731,10 @@ static struct lprocfs_vars lprocfs_nodemap_vars[] = {
                .fops           = &nodemap_audit_mode_fops,
        },
        {
+               .name           = "forbid_encryption",
+               .fops           = &nodemap_forbid_encryption_fops,
+       },
+       {
                .name           = "squash_uid",
                .fops           = &nodemap_squash_uid_fops,
        },
@@ -773,6 +805,10 @@ static struct lprocfs_vars lprocfs_default_nodemap_vars[] = {
                .fops           = &nodemap_audit_mode_fops,
        },
        {
+               .name           = "forbid_encryption",
+               .fops           = &nodemap_forbid_encryption_fops,
+       },
+       {
                NULL
        }
 };
index e22ea72..0cbafb7 100644 (file)
@@ -75,6 +75,7 @@ enum nm_flag_shifts {
        NM_FL_MAP_UID_ONLY = 0x8,
        NM_FL_MAP_GID_ONLY = 0x10,
        NM_FL_ENABLE_AUDIT = 0x20,
+       NM_FL_FORBID_ENCRYPT = 0x40,
 };
 
 static void nodemap_cluster_key_init(struct nodemap_key *nk, unsigned int nm_id)
@@ -104,7 +105,9 @@ static void nodemap_cluster_rec_init(union nodemap_rec *nr,
                (nodemap->nmf_map_gid_only ?
                        NM_FL_MAP_GID_ONLY : 0) |
                (nodemap->nmf_enable_audit ?
-                       NM_FL_ENABLE_AUDIT : 0));
+                       NM_FL_ENABLE_AUDIT : 0) |
+               (nodemap->nmf_forbid_encryption ?
+                       NM_FL_FORBID_ENCRYPT : 0));
 }
 
 static void nodemap_idmap_key_init(struct nodemap_key *nk, unsigned int nm_id,
@@ -757,6 +760,8 @@ static int nodemap_process_keyrec(struct nodemap_config *config,
                                        flags & NM_FL_MAP_GID_ONLY;
                nodemap->nmf_enable_audit =
                                        flags & NM_FL_ENABLE_AUDIT;
+               nodemap->nmf_forbid_encryption =
+                                       flags & NM_FL_FORBID_ENCRYPT;
 
                /* The fileset should be saved otherwise it will be empty
                 * every time in case of "NODEMAP_CLUSTER_IDX". */
index be4afa0..f585359 100644 (file)
@@ -1012,6 +1012,27 @@ int tgt_connect(struct tgt_session_info *tsi)
                rc = req_check_sepol(tsi->tsi_pill);
                if (rc)
                        GOTO(out, rc);
+
+               if (reply->ocd_connect_flags & OBD_CONNECT_FLAGS2 &&
+                   reply->ocd_connect_flags2 & OBD_CONNECT2_ENCRYPT &&
+                   tsi->tsi_pill->rc_req->rq_export) {
+                       bool forbid_encrypt = true;
+                       struct lu_nodemap *nm =
+                        nodemap_get_from_exp(tsi->tsi_pill->rc_req->rq_export);
+
+                       if (!nm) {
+                               /* nodemap_get_from_exp returns NULL in case
+                                * nodemap is not active, so we do not forbid
+                                */
+                               forbid_encrypt = false;
+                       } else if (!IS_ERR(nm)) {
+                               forbid_encrypt = nm->nmf_forbid_encryption;
+                               nodemap_putref(nm);
+                       }
+
+                       if (forbid_encrypt)
+                               GOTO(out, rc = -EACCES);
+               }
        }
 
        RETURN(0);
index defa0f3..9b1cc35 100644 (file)
@@ -4423,7 +4423,7 @@ int jt_nodemap_modify(int argc, char **argv)
                fprintf(stderr,
                        "usage: nodemap_modify --name <nodemap_name> --property <property_name> --value <value>\n");
                fprintf(stderr,
-                       "valid properties: admin trusted map_mode squash_uid squash_gid deny_unknown audit_mode\n");
+                       "valid properties: admin trusted map_mode squash_uid squash_gid deny_unknown audit_mode forbid_encryption\n");
                return -1;
        }
 
@@ -4441,6 +4441,8 @@ int jt_nodemap_modify(int argc, char **argv)
                cmd = LCFG_NODEMAP_MAP_MODE;
        } else if (strcmp("audit_mode", param) == 0) {
                cmd = LCFG_NODEMAP_AUDIT_MODE;
+       } else if (strcmp("forbid_encryption", param) == 0) {
+               cmd = LCFG_NODEMAP_FORBID_ENCRYPT;
        } else {
                fprintf(stderr,
                        "error: %s: nodemap_modify invalid subcommand: %s\n",