From: Andreas Dilger Date: Thu, 13 Sep 2012 02:35:55 +0000 (-0600) Subject: LU-1923 lov: verify stripe is on given device X-Git-Tag: 2.3.51~104 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=0a6c19106efc4ab14e745685215ec72694d98b5c;p=fs%2Flustre-release.git LU-1923 lov: verify stripe is on given device When restarting FIEMAP from a file with many extents, the first supplied fiemap extent contains the offset of the previous last extent found. If this data is invalid, it may cause the LOV code to acccess out-of-bounds array indices. Verify data passed from userspace is within bounds. Signed-off-by: Andreas Dilger Change-Id: I8e70e891b9f23c8f72aa78a4807369584ac2b04f Reviewed-on: http://review.whamcloud.com/3962 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Oleg Drokin Reviewed-by: wangdi --- diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index ea72c2e..c0ee782 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -2250,6 +2250,8 @@ obd_size fiemap_calc_fm_end_offset(struct ll_user_fiemap *fiemap, break; } } + if (stripe_no == -1) + return -EINVAL; /* If we have finished mapping on previous device, shift logical * offset to start of next device */ @@ -2353,7 +2355,7 @@ static int lov_fiemap(struct lov_obd *lov, __u32 keylen, void *key, int count_local; unsigned int get_num_extents = 0; int ost_index = 0, actual_start_stripe, start_stripe; - obd_size fm_start, fm_end, fm_length, fm_end_offset = 0; + obd_size fm_start, fm_end, fm_length, fm_end_offset; obd_size curr_loc; int current_extent = 0, rc = 0, i; int ost_eof = 0; /* EOF for object */ @@ -2389,8 +2391,10 @@ static int lov_fiemap(struct lov_obd *lov, __u32 keylen, void *key, last_stripe = fiemap_calc_last_stripe(lsm, fm_start, fm_end, actual_start_stripe, &stripe_count); - fm_end_offset = fiemap_calc_fm_end_offset(fiemap, lsm, fm_start, fm_end, - &start_stripe); + fm_end_offset = fiemap_calc_fm_end_offset(fiemap, lsm, fm_start, + fm_end, &start_stripe); + if (fm_end_offset == -EINVAL) + return -EINVAL; if (fiemap->fm_extent_count == 0) { get_num_extents = 1;