Whamcloud - gitweb
LU-13791 mdt: parameter to tune capabilities 38/53538/7
authorAndreas Dilger <adilger@whamcloud.com>
Wed, 20 Dec 2023 18:45:50 +0000 (11:45 -0700)
committerOleg Drokin <green@whamcloud.com>
Wed, 3 Jan 2024 03:03:11 +0000 (03:03 +0000)
Add mdt.*.enable_cap_mask to allow specific capabilities to
be enabled and disabled individually.

Fixes: f05edf8e2b ("LU-13791 sec: enable FS capabilities")
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Change-Id: I6fc0130a90693d673d8c2158e7e31c2de951553d
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53538
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Alexander Zarochentsev <alexander.zarochentsev@hpe.com>
Reviewed-by: Andrew Perepechko <andrew.perepechko@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_lib.c
lustre/mdt/mdt_lproc.c
lustre/tests/sanity-sec.sh

index 82feadc..22efed4 100644 (file)
@@ -323,6 +323,7 @@ struct mdt_device {
        gid_t                      mdt_enable_remote_dir_gid;
                                   /* user with this gid can change projid */
        gid_t                      mdt_enable_chprojid_gid;
+       kernel_cap_t               mdt_enable_cap_mask;
 
        /* lock for osfs and md_root */
        spinlock_t                 mdt_lock;
index 47a338e..3bb864f 100644 (file)
@@ -349,6 +349,21 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
        /* process root_squash here. */
        mdt_root_squash(info, &peernid);
 
+       if (ucred->uc_fsuid) {
+               if (!cap_issubset(ucred->uc_cap, mdt->mdt_enable_cap_mask))
+                       CDEBUG(D_SEC, "%s: drop capabilities %llx for NID %s\n",
+                              mdt_obd_name(mdt),
+#ifdef CAP_FOR_EACH_U32
+                              ucred->uc_cap.cap[0] |
+                              ((u64)ucred->uc_cap.cap[1] << 32),
+#else
+                              ucred->uc_cap.val,
+#endif
+                              libcfs_nidstr(&mdt_info_req(info)->rq_peer.nid));
+               ucred->uc_cap = cap_intersect(ucred->uc_cap,
+                                             mdt->mdt_enable_cap_mask);
+       }
+
        ucred->uc_valid = UCRED_NEW;
        ucred_set_jobid(info, ucred);
        ucred_set_nid(info, ucred);
@@ -522,6 +537,18 @@ static int old_init_ucred_common(struct mdt_thread_info *info,
        mdt_root_squash(info,
                        &mdt_info_req(info)->rq_peer.nid);
 
+       if (uc->uc_fsuid) {
+               if (!cap_issubset(uc->uc_cap, mdt->mdt_enable_cap_mask))
+                       CDEBUG(D_SEC, "%s: drop capabilities %llx for NID %s\n",
+                              mdt_obd_name(mdt),
+#ifdef CAP_FOR_EACH_U32
+                              uc->uc_cap.cap[0] | ((u64)uc->uc_cap.cap[1]<<32),
+#else
+                              uc->uc_cap.val,
+#endif
+                              libcfs_nidstr(&mdt_info_req(info)->rq_peer.nid));
+               uc->uc_cap = cap_intersect(uc->uc_cap,mdt->mdt_enable_cap_mask);
+       }
        uc->uc_valid = UCRED_OLD;
        ucred_set_jobid(info, uc);
        ucred_set_nid(info, uc);
index 9b13a3b..c6108eb 100644 (file)
@@ -589,6 +589,55 @@ mdt_nosquash_nids_seq_write(struct file *file, const char __user *buffer,
 }
 LPROC_SEQ_FOPS(mdt_nosquash_nids);
 
+static ssize_t enable_cap_mask_show(struct kobject *kobj,
+                                   struct attribute *attr, char *buf)
+{
+       struct obd_device *obd = container_of(kobj, struct obd_device,
+                                             obd_kset.kobj);
+       struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+       u64 cap;
+
+       BUILD_BUG_ON(_KERNEL_CAP_T_SIZE != sizeof(u64));
+
+#ifdef CAP_FOR_EACH_U32 /* kernels before v6.2-13111-gf122a08b197d */
+       cap = ((u64)mdt->mdt_enable_cap_mask.cap[1] << 32) |
+              mdt->mdt_enable_cap_mask.cap[0];
+#else
+       cap = mdt->mdt_enable_cap_mask.val;
+#endif
+       return scnprintf(buf, PAGE_SIZE, "%#0llx\n", cap);
+}
+
+static ssize_t enable_cap_mask_store(struct kobject *kobj,
+                                    struct attribute *attr,
+                                    const char *buffer, size_t count)
+{
+       struct obd_device *obd = container_of(kobj, struct obd_device,
+                                             obd_kset.kobj);
+       struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+       unsigned long long val;
+       int rc;
+
+       rc = kstrtoull(buffer, 0, &val);
+       if (rc)
+               /* should also accept symbolic names via cfs_str2mask() */
+               return rc;
+
+#ifdef CAP_FOR_EACH_U32
+       mdt->mdt_enable_cap_mask.cap[0] = val &
+               (CAP_FS_MASK_B0 | CAP_TO_MASK(CAP_SYS_RESOURCE) |
+                CAP_TO_MASK(CAP_LINUX_IMMUTABLE));
+       mdt->mdt_enable_cap_mask.cap[1] = (val >> 32) & CAP_FS_MASK_B1;
+#else
+       mdt->mdt_enable_cap_mask.val = val &
+               (CAP_FS_MASK | BIT_ULL(CAP_SYS_RESOURCE) |
+                BIT_ULL(CAP_LINUX_IMMUTABLE));
+#endif
+
+       return count;
+}
+LUSTRE_RW_ATTR(enable_cap_mask);
+
 static ssize_t enable_remote_dir_gid_show(struct kobject *kobj,
                                          struct attribute *attr, char *buf)
 {
@@ -1267,6 +1316,7 @@ static struct attribute *mdt_attrs[] = {
        &lustre_attr_identity_upcall.attr,
        &lustre_attr_identity_flush.attr,
        &lustre_attr_evict_tgt_nids.attr,
+       &lustre_attr_enable_cap_mask.attr,
        &lustre_attr_enable_chprojid_gid.attr,
        &lustre_attr_enable_dir_migration.attr,
        &lustre_attr_enable_dir_restripe.attr,
index 8de6f43..0d19845 100755 (executable)
@@ -4192,6 +4192,14 @@ test_51() {
                skip "Need MDS version at least 2.13.53"
 
        mkdir $DIR/$tdir || error "mkdir $tdir"
+       local mdts=$(comma_list $(mdts_nodes))
+       local cap_param=mdt.*.enable_cap_mask
+
+       old_cap=($(do_nodes $mdts $LCTL get_param -n $cap_param 2>/dev/null))
+       if [[ -n "$old_cap" ]]; then
+               do_nodes $mdts $LCTL set_param $cap_param=0xf
+               stack_trap "do_nodes $mdts $LCTL set_param $cap_param=$old_cap"
+       fi
 
        touch $DIR/$tdir/$tfile || error "touch $tfile"
        cp $(which chown) $DIR/$tdir || error "cp chown"