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 <adilger@whamcloud.com>
Change-Id: I8e70e891b9f23c8f72aa78a4807369584ac2b04f
Reviewed-on: http://review.whamcloud.com/3962
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: wangdi <di.wang@whamcloud.com>
+ if (stripe_no == -1)
+ return -EINVAL;
/* If we have finished mapping on previous device, shift logical
* offset to start of next device */
/* If we have finished mapping on previous device, shift logical
* offset to start of next device */
int count_local;
unsigned int get_num_extents = 0;
int ost_index = 0, actual_start_stripe, start_stripe;
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 */
obd_size curr_loc;
int current_extent = 0, rc = 0, i;
int ost_eof = 0; /* EOF for object */
last_stripe = fiemap_calc_last_stripe(lsm, fm_start, fm_end,
actual_start_stripe, &stripe_count);
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;
if (fiemap->fm_extent_count == 0) {
get_num_extents = 1;