Whamcloud - gitweb
LU-12212 mdt: fix SECCTX reply buffer handling
[fs/lustre-release.git] / lustre / mdt / mdt_lib.c
index baaebdc..a7d5130 100644 (file)
@@ -178,6 +178,7 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
        __u32 perm = 0;
        int setuid;
        int setgid;
+       bool is_nm_gid_squashed = false;
        int rc = 0;
 
        ENTRY;
@@ -220,6 +221,10 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
                ucred->uc_suppgids[0] = -1;
                ucred->uc_suppgids[1] = -1;
        }
+
+       if (nodemap && ucred->uc_o_gid == nodemap->nm_squash_gid)
+               is_nm_gid_squashed = true;
+
        nodemap_putref(nodemap);
 
        if (type == BODY_INIT) {
@@ -288,7 +293,8 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
        }
 
        if (perm & CFS_SETGRP_PERM) {
-               if (pud->pud_ngroups) {
+               /* only set groups if GID is not squashed */
+               if (pud->pud_ngroups && !is_nm_gid_squashed) {
                        /* setgroups for local client */
                        ucred->uc_ginfo = groups_alloc(pud->pud_ngroups);
                        if (!ucred->uc_ginfo) {
@@ -301,6 +307,8 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
                                                pud->pud_groups);
                        lustre_groups_sort(ucred->uc_ginfo);
                } else {
+                       ucred->uc_suppgids[0] = -1;
+                       ucred->uc_suppgids[1] = -1;
                        ucred->uc_ginfo = NULL;
                }
        } else {
@@ -673,11 +681,25 @@ void mdt_dump_lmm(int level, const struct lov_mds_md *lmm, __u64 valid)
 void mdt_dump_lmv(unsigned int level, const union lmv_mds_md *lmv)
 {
        const struct lmv_mds_md_v1 *lmm1;
+       const struct lmv_foreign_md *lfm;
        int                        i;
 
        if (likely(!cfs_cdebug_show(level, DEBUG_SUBSYSTEM)))
                return;
 
+       /* foreign LMV case */
+       lfm = &lmv->lmv_foreign_md;
+       if (le32_to_cpu(lfm->lfm_magic) == LMV_MAGIC_FOREIGN) {
+               CDEBUG_LIMIT(level,
+                            "foreign magic 0x%08X, length %u, type %u, flags %u, value '%.*s'\n",
+                            le32_to_cpu(lfm->lfm_magic),
+                            le32_to_cpu(lfm->lfm_length),
+                            le32_to_cpu(lfm->lfm_type),
+                            le32_to_cpu(lfm->lfm_flags),
+                            le32_to_cpu(lfm->lfm_length), lfm->lfm_value);
+               return;
+       }
+
        lmm1 = &lmv->lmv_md_v1;
        CDEBUG(level,
               "magic 0x%08X, master %#X stripe_count %#x hash_type %#x\n",
@@ -768,6 +790,12 @@ int mdt_fix_reply(struct mdt_thread_info *info)
                req_capsule_shrink(pill, &RMF_LOGCOOKIES, acl_size, RCL_SERVER);
        }
 
+       /* Shrink optional SECCTX buffer if it is not used */
+       if (req_capsule_has_field(pill, &RMF_FILE_SECCTX, RCL_SERVER) &&
+           req_capsule_get_size(pill, &RMF_FILE_SECCTX, RCL_SERVER) != 0 &&
+           !(body->mbo_valid & OBD_MD_SECCTX))
+               req_capsule_shrink(pill, &RMF_FILE_SECCTX, 0, RCL_SERVER);
+
        /*
         * Some more field should be shrinked if needed.
         * This should be done by those who added fields to reply message.
@@ -987,7 +1015,7 @@ static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr,
                MDS_ATTR_FROM_OPEN | MDS_ATTR_LSIZE | MDS_ATTR_LBLOCKS |
                MDS_ATTR_OVERRIDE);
        if (in != 0)
-               CERROR("Unknown attr bits: %#llx\n", in);
+               CDEBUG(D_INFO, "Unknown attr bits: %#llx\n", in);
        return out;
 }
 
@@ -1154,6 +1182,7 @@ static int mdt_setattr_unpack(struct mdt_thread_info *info)
                 rr->rr_eadata = req_capsule_client_get(pill, &RMF_EADATA);
                 rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
                                                         RCL_CLIENT);
+
                if (rr->rr_eadatalen > 0) {
                        const struct lmv_user_md        *lum;
 
@@ -1220,8 +1249,8 @@ static int mdt_create_unpack(struct mdt_thread_info *info)
        struct mdt_rec_create *rec;
        struct lu_attr *attr = &info->mti_attr.ma_attr;
        struct mdt_reint_record *rr = &info->mti_rr;
-       struct req_capsule *pill = info->mti_pill;
-       struct md_op_spec *sp = &info->mti_spec;
+       struct req_capsule      *pill = info->mti_pill;
+       struct md_op_spec       *sp = &info->mti_spec;
        int rc;
 
        ENTRY;
@@ -1286,6 +1315,10 @@ static int mdt_create_unpack(struct mdt_thread_info *info)
        if (rc < 0)
                RETURN(rc);
 
+       rc = req_check_sepol(pill);
+       if (rc)
+               RETURN(rc);
+
        rc = mdt_dlmreq_unpack(info);
        RETURN(rc);
 }
@@ -1325,6 +1358,10 @@ static int mdt_link_unpack(struct mdt_thread_info *info)
        if (rc < 0)
                RETURN(rc);
 
+       rc = req_check_sepol(pill);
+       if (rc)
+               RETURN(rc);
+
        rc = mdt_dlmreq_unpack(info);
 
        RETURN(rc);
@@ -1336,7 +1373,7 @@ static int mdt_unlink_unpack(struct mdt_thread_info *info)
        struct mdt_rec_unlink *rec;
        struct lu_attr *attr = &info->mti_attr.ma_attr;
        struct mdt_reint_record *rr = &info->mti_rr;
-       struct req_capsule *pill = info->mti_pill;
+       struct req_capsule      *pill = info->mti_pill;
        int rc;
 
        ENTRY;
@@ -1368,6 +1405,10 @@ static int mdt_unlink_unpack(struct mdt_thread_info *info)
 
        info->mti_spec.no_create = !!req_is_replay(mdt_info_req(info));
 
+       rc = req_check_sepol(pill);
+       if (rc)
+               RETURN(rc);
+
        rc = mdt_dlmreq_unpack(info);
        RETURN(rc);
 }
@@ -1422,6 +1463,10 @@ static int mdt_rename_unpack(struct mdt_thread_info *info)
 
        spec->no_create = !!req_is_replay(mdt_info_req(info));
 
+       rc = req_check_sepol(pill);
+       if (rc)
+               RETURN(rc);
+
        rc = mdt_dlmreq_unpack(info);
 
        RETURN(rc);
@@ -1479,6 +1524,7 @@ static int mdt_migrate_unpack(struct mdt_thread_info *info)
                        rr->rr_eadatalen = req_capsule_get_size(pill,
                                                                &RMF_EADATA,
                                                                RCL_CLIENT);
+
                        if (rr->rr_eadatalen > 0) {
                                rr->rr_eadata = req_capsule_client_get(pill,
                                                                &RMF_EADATA);
@@ -1567,6 +1613,7 @@ static int mdt_open_unpack(struct mdt_thread_info *info)
         if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
                 rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
                                                         RCL_CLIENT);
+
                 if (rr->rr_eadatalen > 0) {
                         rr->rr_eadata = req_capsule_client_get(pill,
                                                                &RMF_EADATA);
@@ -1589,6 +1636,12 @@ static int mdt_open_unpack(struct mdt_thread_info *info)
        rc = mdt_file_secctx_unpack(pill, &sp->sp_cr_file_secctx_name,
                                    &sp->sp_cr_file_secctx,
                                    &sp->sp_cr_file_secctx_size);
+       if (rc < 0)
+               RETURN(rc);
+
+       rc = req_check_sepol(pill);
+       if (rc)
+               RETURN(rc);
 
        RETURN(rc);
 }
@@ -1632,6 +1685,10 @@ static int mdt_setxattr_unpack(struct mdt_thread_info *info)
         if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
                 rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
                                                         RCL_CLIENT);
+
+               if (rr->rr_eadatalen > info->mti_mdt->mdt_max_ea_size)
+                       RETURN(-E2BIG);
+
                 if (rr->rr_eadatalen > 0) {
                         rr->rr_eadata = req_capsule_client_get(pill,
                                                                &RMF_EADATA);
@@ -1645,6 +1702,10 @@ static int mdt_setxattr_unpack(struct mdt_thread_info *info)
                 RETURN(-EFAULT);
         }
 
+       rc = req_check_sepol(pill);
+       if (rc)
+               RETURN(rc);
+
        if (mdt_dlmreq_unpack(info) < 0)
                RETURN(-EPROTO);
 
@@ -1670,6 +1731,7 @@ static int mdt_resync_unpack(struct mdt_thread_info *info)
        uc->uc_cap   = rec->rs_cap;
 
        rr->rr_fid1   = &rec->rs_fid;
+       rr->rr_mirror_id = rec->rs_mirror_id;
 
        /* cookie doesn't need to be swapped but it has been swapped
         * in lustre_swab_mdt_rec_reint() as rr_mtime, so here it needs
@@ -1711,3 +1773,45 @@ int mdt_reint_unpack(struct mdt_thread_info *info, __u32 op)
         }
         RETURN(rc);
 }
+
+void mdt_pack_secctx_in_reply(struct mdt_thread_info *info,
+                             struct mdt_object *child)
+{
+       char *secctx_name;
+       struct lu_buf *buffer;
+       struct mdt_body *repbody;
+       struct req_capsule *pill = info->mti_pill;
+       int rc;
+
+       if (req_capsule_has_field(pill, &RMF_FILE_SECCTX, RCL_SERVER) &&
+           req_capsule_get_size(pill, &RMF_FILE_SECCTX, RCL_SERVER) != 0) {
+               secctx_name =
+                       req_capsule_client_get(pill, &RMF_FILE_SECCTX_NAME);
+               buffer = &info->mti_buf;
+
+               /* fill reply buffer with security context now */
+               buffer->lb_len = req_capsule_get_size(pill, &RMF_FILE_SECCTX,
+                                                     RCL_SERVER);
+               buffer->lb_buf = req_capsule_server_get(info->mti_pill,
+                                                       &RMF_FILE_SECCTX);
+               rc = mo_xattr_get(info->mti_env, mdt_object_child(child),
+                                 buffer, secctx_name);
+               if (rc >= 0) {
+                       CDEBUG(D_SEC,
+                              "found security context of size %d for "DFID"\n",
+                              rc, PFID(mdt_object_fid(child)));
+
+                       repbody = req_capsule_server_get(pill, &RMF_MDT_BODY);
+                       repbody->mbo_valid |= OBD_MD_SECCTX;
+                       if (rc < buffer->lb_len)
+                               req_capsule_shrink(pill, &RMF_FILE_SECCTX, rc,
+                                                  RCL_SERVER);
+               } else {
+                       CDEBUG(D_SEC,
+                            "security context not found for "DFID": rc = %d\n",
+                            PFID(mdt_object_fid(child)), rc);
+                       req_capsule_shrink(pill, &RMF_FILE_SECCTX, 0,
+                                          RCL_SERVER);
+               }
+       }
+}