Skip to content

Commit 10172f2

Browse files
Jon Derrickliu-song-6
authored andcommitted
md: Fix types in sb writer
Page->index is a pgoff_t and multiplying could cause overflows on a 32-bit architecture. In the sb writer, this is used to calculate and verify the sector being used, and is multiplied by a sector value. Using sector_t will cast it to a u64 type and is the more appropriate type for the unit. Additionally, the integer size unit is converted to a sector unit in later calculations, and is now corrected to be an unsigned type. Finally, clean up the calculations using variable aliases to improve readabiliy. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jon Derrick <jonathan.derrick@linux.dev> Signed-off-by: Song Liu <song@kernel.org> Link: https://lore.kernel.org/r/20230224183323.638-3-jonathan.derrick@linux.dev
1 parent 328e17d commit 10172f2

1 file changed

Lines changed: 14 additions & 21 deletions

File tree

drivers/md/md-bitmap.c

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -215,56 +215,49 @@ static int __write_sb_page(struct md_rdev *rdev, struct bitmap *bitmap,
215215
struct block_device *bdev;
216216
struct mddev *mddev = bitmap->mddev;
217217
struct bitmap_storage *store = &bitmap->storage;
218-
loff_t offset = mddev->bitmap_info.offset;
219-
int size = PAGE_SIZE;
218+
sector_t offset = mddev->bitmap_info.offset;
219+
sector_t ps, sboff, doff;
220+
unsigned int size = PAGE_SIZE;
220221

221222
bdev = (rdev->meta_bdev) ? rdev->meta_bdev : rdev->bdev;
222223
if (page->index == store->file_pages - 1) {
223-
int last_page_size = store->bytes & (PAGE_SIZE - 1);
224+
unsigned int last_page_size = store->bytes & (PAGE_SIZE - 1);
224225

225226
if (last_page_size == 0)
226227
last_page_size = PAGE_SIZE;
227228
size = roundup(last_page_size,
228229
bdev_logical_block_size(bdev));
229230
}
230231

232+
ps = page->index * PAGE_SIZE / SECTOR_SIZE;
233+
sboff = rdev->sb_start + offset;
234+
doff = rdev->data_offset;
235+
231236
/* Just make sure we aren't corrupting data or metadata */
232237
if (mddev->external) {
233238
/* Bitmap could be anywhere. */
234-
if (rdev->sb_start + offset
235-
+ (page->index * (PAGE_SIZE / SECTOR_SIZE))
236-
> rdev->data_offset &&
237-
rdev->sb_start + offset
238-
< (rdev->data_offset + mddev->dev_sectors
239-
+ (PAGE_SIZE / SECTOR_SIZE)))
239+
if (sboff + ps > doff &&
240+
sboff < (doff + mddev->dev_sectors + PAGE_SIZE / SECTOR_SIZE))
240241
return -EINVAL;
241242
} else if (offset < 0) {
242243
/* DATA BITMAP METADATA */
243-
if (offset
244-
+ (long)(page->index * (PAGE_SIZE / SECTOR_SIZE))
245-
+ size / SECTOR_SIZE > 0)
244+
if (offset + ps + size / SECTOR_SIZE > 0)
246245
/* bitmap runs in to metadata */
247246
return -EINVAL;
248247

249-
if (rdev->data_offset + mddev->dev_sectors
250-
> rdev->sb_start + offset)
248+
if (doff + mddev->dev_sectors > sboff)
251249
/* data runs in to bitmap */
252250
return -EINVAL;
253251
} else if (rdev->sb_start < rdev->data_offset) {
254252
/* METADATA BITMAP DATA */
255-
if (rdev->sb_start + offset
256-
+ page->index * (PAGE_SIZE / SECTOR_SIZE)
257-
+ size / SECTOR_SIZE > rdev->data_offset)
253+
if (sboff + ps + size / SECTOR_SIZE > doff)
258254
/* bitmap runs in to data */
259255
return -EINVAL;
260256
} else {
261257
/* DATA METADATA BITMAP - no problems */
262258
}
263259

264-
md_super_write(mddev, rdev,
265-
rdev->sb_start + offset
266-
+ page->index * (PAGE_SIZE / SECTOR_SIZE),
267-
size, page);
260+
md_super_write(mddev, rdev, sboff + ps, (int) size, page);
268261
return 0;
269262
}
270263

0 commit comments

Comments
 (0)