From: fanyong Date: Mon, 21 Aug 2006 16:10:48 +0000 (+0000) Subject: The arguments "lump" of lov_setstripe and lov_getstripe can be called X-Git-Tag: v1_8_0_110~486^2~1128 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=bde8051db9d8b6377c9a10266c1551ec872b42db;p=fs%2Flustre-release.git The arguments "lump" of lov_setstripe and lov_getstripe can be called from both user level and kernel level. So copy_from_user or copy_to_user maybe failed. In these case, we shoule use memcpy to do that. to --- diff --git a/lustre/lov/lov_pack.c b/lustre/lov/lov_pack.c index c4b0751..8e3b72c 100644 --- a/lustre/lov/lov_pack.c +++ b/lustre/lov/lov_pack.c @@ -37,6 +37,8 @@ #include "lov_internal.h" +#define USER_SPACE_TOP USER_DS.seg + void lov_dump_lmm_v1(int level, struct lov_mds_md_v1 *lmm) { struct lov_ost_data_v1 *lod; @@ -293,9 +295,13 @@ int lov_setstripe(struct obd_export *exp, struct lov_stripe_md **lsmp, int rc; ENTRY; - rc = copy_from_user(&lum, lump, sizeof(lum)); - if (rc) - RETURN(-EFAULT); + if ((unsigned long)lump < USER_SPACE_TOP) { + rc = copy_from_user(&lum, lump, sizeof(lum)); + if (rc) + RETURN(-EFAULT); + } else { + memcpy(&lum, lump, sizeof(lum)); + } if (lum.lmm_magic != LOV_USER_MAGIC) { if (lum.lmm_magic == __swab32(LOV_USER_MAGIC)) { @@ -409,9 +415,13 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm, if (!lsm) RETURN(-ENODATA); - rc = copy_from_user(&lum, lump, sizeof(lum)); - if (rc) - RETURN(-EFAULT); + if ((unsigned long)lump < USER_SPACE_TOP) { + rc = copy_from_user(&lum, lump, sizeof(lum)); + if (rc) + RETURN(-EFAULT); + } else { + memcpy(&lum, lump, sizeof(lum)); + } if (lum.lmm_magic != LOV_USER_MAGIC) RETURN(-EINVAL); @@ -428,12 +438,21 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm, /* User wasn't expecting this many OST entries */ if (lum.lmm_stripe_count == 0) { - if (copy_to_user(lump, lmmk, sizeof(lum))) - rc = -EFAULT; + if ((unsigned long)lump < USER_SPACE_TOP) { + if (copy_to_user(lump, lmmk, sizeof(lum))) + rc = -EFAULT; + } else { + memcpy(lump, lmmk, sizeof(lum)); + } } else if (lum.lmm_stripe_count < lmmk->lmm_stripe_count) { rc = -EOVERFLOW; - } else if (copy_to_user(lump, lmmk, lmm_size)) { - rc = -EFAULT; + } else { + if ((unsigned long)lump < USER_SPACE_TOP) { + if (copy_to_user(lump, lmmk, sizeof(lum))) + rc = -EFAULT; + } else { + memcpy(lump, lmmk, sizeof(lum)); + } } obd_free_diskmd(exp, &lmmk);