Commit ebdc4fc5 authored by Bobi Jam's avatar Bobi Jam Committed by Greg Kroah-Hartman

staging/lustre/llite: prevent buffer overflow in fiemap

lov_fiemap() does not take consider its @vallen parameter, which is
the max buffer size the caller can hold for the fiemap extents.

This patch fixes this and limits the max mapped fiemap extent count
to fit in the preallocted buffer.

This patch also fixes a memory out of bound write issue when the
fiemap call is only for detecting the number of existing extent.
Signed-off-by: default avatarBobi Jam <bobijam.xu@intel.com>
Reviewed-on: http://review.whamcloud.com/9834
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4619Reviewed-by: default avatarFan Yong <fan.yong@intel.com>
Reviewed-by: default avatarPatrick Farrell <paf@cray.com>
Signed-off-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a1e7e2d4
......@@ -1721,12 +1721,12 @@ int ll_release_openhandle(struct dentry *dentry, struct lookup_intent *it)
* Make the FIEMAP get_info call and returns the result.
*/
static int ll_do_fiemap(struct inode *inode, struct ll_user_fiemap *fiemap,
int num_bytes)
size_t num_bytes)
{
struct obd_export *exp = ll_i2dtexp(inode);
struct lov_stripe_md *lsm = NULL;
struct ll_fiemap_info_key fm_key = { .name = KEY_FIEMAP, };
int vallen = num_bytes;
__u32 vallen = num_bytes;
int rc;
/* Checks for fiemap flags */
......@@ -3080,15 +3080,18 @@ static int ll_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
fiemap->fm_extent_count = fieinfo->fi_extents_max;
fiemap->fm_start = start;
fiemap->fm_length = len;
memcpy(&fiemap->fm_extents[0], fieinfo->fi_extents_start,
sizeof(struct ll_fiemap_extent));
if (extent_count > 0)
memcpy(&fiemap->fm_extents[0], fieinfo->fi_extents_start,
sizeof(struct ll_fiemap_extent));
rc = ll_do_fiemap(inode, fiemap, num_bytes);
fieinfo->fi_flags = fiemap->fm_flags;
fieinfo->fi_extents_mapped = fiemap->fm_mapped_extents;
memcpy(fieinfo->fi_extents_start, &fiemap->fm_extents[0],
fiemap->fm_mapped_extents * sizeof(struct ll_fiemap_extent));
if (extent_count > 0)
memcpy(fieinfo->fi_extents_start, &fiemap->fm_extents[0],
fiemap->fm_mapped_extents *
sizeof(struct ll_fiemap_extent));
OBD_FREE_LARGE(fiemap, num_bytes);
return rc;
......
......@@ -2248,11 +2248,12 @@ static int lov_fiemap(struct lov_obd *lov, __u32 keylen, void *key,
if (fm_end_offset == -EINVAL)
GOTO(out, rc = -EINVAL);
if (fiemap_count_to_size(fiemap->fm_extent_count) > *vallen)
fiemap->fm_extent_count = fiemap_size_to_count(*vallen);
if (fiemap->fm_extent_count == 0) {
get_num_extents = 1;
count_local = 0;
}
/* Check each stripe */
for (cur_stripe = start_stripe, i = 0; i < stripe_count;
i++, cur_stripe = (cur_stripe + 1) % lsm->lsm_stripe_count) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment