From 11f90c515ae4d87e80cb89f55fa34f74f9a2e74d Mon Sep 17 00:00:00 2001 From: yangsheng Date: Tue, 16 Mar 2010 21:58:48 +0800 Subject: [PATCH] b=22187 properly handle null value for setattr -n lustre.lov i=adilger i=johann Running "setfattr -n trusted.lov ." causes a NULL dereference in ll_setxattr() due to no checking if "value" is NULL. This command now resets to the default striping when executed against a directory. --- lustre/llite/dir.c | 41 +++++++++++++++++++++++------------------ lustre/llite/xattr.c | 8 +++----- lustre/mdc/mdc_lib.c | 15 +++++++++++++-- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index ce66441..613848b 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -982,23 +982,27 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, struct lustre_sb_info *lsi = s2lsi(inode->i_sb); struct obd_device *mgc = lsi->lsi_mgc; char *fsname = NULL, *param = NULL; - int lum_size = sizeof(struct lov_user_md_v1); - struct iattr attr = { 0 }; - int rc = 0; + int lum_size = 0, rc = 0; - if (lump->lmm_magic == LOV_USER_MAGIC_V3) - lum_size = sizeof(struct lov_user_md_v3); - /* - * This is coming from userspace, so should be in - * local endian. But the MDS would like it in little - * endian, so we swab it before we send it. - */ - if ((lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V1)) && - (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V3))) { - rc = lustre_swab_lov_user_md(lump); - if (rc) - return rc; + if (lump != NULL) { + if (lump->lmm_magic == LOV_USER_MAGIC_V3) + lum_size = sizeof(struct lov_user_md_v3); + else + lum_size = sizeof(struct lov_user_md_v1); + /* + * This is coming from userspace, so should be in + * local endian. But the MDS would like it in little + * endian, so we swab it before we send it. + */ + if ((lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V1)) && + (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V3))) { + rc = lustre_swab_lov_user_md(lump); + if (rc) + return rc; + } + } else { /* NULL value means remove LOV EA */ + lum_size = sizeof(struct lov_user_md_v1); } ll_prepare_mdc_op_data(&data, inode, NULL, NULL, 0, 0, NULL); @@ -1024,21 +1028,22 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, fsname = ll_get_fsname(inode); /* Set root stripesize */ sprintf(param, "%s-MDT0000.lov.stripesize=%u", fsname, - le32_to_cpu(lump->lmm_stripe_size)); + lump ? le32_to_cpu(lump->lmm_stripe_size) : 0); rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param); if (rc) goto end; /* Set root stripecount */ sprintf(param, "%s-MDT0000.lov.stripecount=%u", fsname, - le16_to_cpu(lump->lmm_stripe_count)); + lump ? le16_to_cpu(lump->lmm_stripe_count) : 0); rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param); if (rc) goto end; /* Set root stripeoffset */ sprintf(param, "%s-MDT0000.lov.stripeoffset=%u", fsname, - le16_to_cpu(lump->lmm_stripe_offset)); + lump ? le16_to_cpu(lump->lmm_stripe_offset) : + (typeof(lump->lmm_stripe_offset))(-1)); rc = ll_send_mgc_param(mgc->u.cli.cl_mgc_mgsexp, param); if (rc) goto end; diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index 8fbc7bf..586e120 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -183,18 +183,16 @@ int ll_setxattr(struct dentry *dentry, const char *name, /* Attributes that are saved via getxattr will always have * the stripe_offset as 0. Instead, the MDS should be * allowed to pick the starting OST index. b=17846 */ - if (lump->lmm_stripe_offset == 0) + if (lump != NULL && lump->lmm_stripe_offset == 0) lump->lmm_stripe_offset = -1; - if (S_ISREG(inode->i_mode)) { + if (lump != NULL && S_ISREG(inode->i_mode)) { struct file f; int flags = FMODE_WRITE; f.f_dentry = dentry; - rc = ll_lov_setstripe_ea_info(inode, &f, flags, - lump, sizeof(*lump)); + ll_lov_setstripe_ea_info(inode, &f, flags, lump, size); /* b10667: rc always be 0 here for now */ - rc = 0; } else if (S_ISDIR(inode->i_mode)) { rc = ll_dir_setstripe(inode, lump, 0); } diff --git a/lustre/mdc/mdc_lib.c b/lustre/mdc/mdc_lib.c index 443227c..68d1206 100644 --- a/lustre/mdc/mdc_lib.c +++ b/lustre/mdc/mdc_lib.c @@ -439,6 +439,7 @@ void mdc_setattr_pack_18(struct ptlrpc_request *req, int offset, struct mdc_op_data *data, struct iattr *iattr, void *ea, int ealen, void *ea2, int ea2len) { + struct lov_user_md *lum = NULL; struct mds_rec_setattr *rec = lustre_msg_buf(req->rq_reqmsg, offset, sizeof(*rec)); ENTRY; @@ -472,7 +473,15 @@ void mdc_setattr_pack_18(struct ptlrpc_request *req, int offset, return; } - memcpy(lustre_msg_buf(req->rq_reqmsg, offset + 1, ealen), ea, ealen); + lum = lustre_msg_buf(req->rq_reqmsg, offset + 1, ealen); + if (ea == NULL) { /* Remove LOV EA */ + lum->lmm_magic = LOV_USER_MAGIC_V1; + lum->lmm_stripe_size = 0; + lum->lmm_stripe_count = 0; + lum->lmm_stripe_offset = (typeof(lum->lmm_stripe_offset))(-1); + } else { + memcpy(lum, ea, ealen); + } if (ea2len == 0) { EXIT; @@ -519,7 +528,9 @@ static void mdc_setattr_pack_20(struct ptlrpc_request *req, int offset, EXIT; return; } - memcpy(lustre_msg_buf(req->rq_reqmsg, offset + 3, ealen), ea, ealen); + if (ea) + memcpy(lustre_msg_buf(req->rq_reqmsg, offset + 3, ealen), + ea, ealen); if (ea2len == 0) { EXIT; -- 1.8.3.1