Skip to content

Commit 13d2575

Browse files
BK1603jankara
authored andcommitted
reiserfs: check directory items on read from disk
While verifying the leaf item that we read from the disk, reiserfs doesn't check the directory items, this could cause a crash when we read a directory item from the disk that has an invalid deh_location. This patch adds a check to the directory items read from the disk that does a bounds check on deh_location for the directory entries. Any directory entry header with a directory entry offset greater than the item length is considered invalid. Link: https://lore.kernel.org/r/[email protected] Reported-by: [email protected] Signed-off-by: Shreyansh Chouhan <[email protected]> Signed-off-by: Jan Kara <[email protected]>
1 parent 728d392 commit 13d2575

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

fs/reiserfs/stree.c

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,24 @@ void pathrelse(struct treepath *search_path)
387387
search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;
388388
}
389389

390+
static int has_valid_deh_location(struct buffer_head *bh, struct item_head *ih)
391+
{
392+
struct reiserfs_de_head *deh;
393+
int i;
394+
395+
deh = B_I_DEH(bh, ih);
396+
for (i = 0; i < ih_entry_count(ih); i++) {
397+
if (deh_location(&deh[i]) > ih_item_len(ih)) {
398+
reiserfs_warning(NULL, "reiserfs-5094",
399+
"directory entry location seems wrong %h",
400+
&deh[i]);
401+
return 0;
402+
}
403+
}
404+
405+
return 1;
406+
}
407+
390408
static int is_leaf(char *buf, int blocksize, struct buffer_head *bh)
391409
{
392410
struct block_head *blkh;
@@ -454,11 +472,14 @@ static int is_leaf(char *buf, int blocksize, struct buffer_head *bh)
454472
"(second one): %h", ih);
455473
return 0;
456474
}
457-
if (is_direntry_le_ih(ih) && (ih_item_len(ih) < (ih_entry_count(ih) * IH_SIZE))) {
458-
reiserfs_warning(NULL, "reiserfs-5093",
459-
"item entry count seems wrong %h",
460-
ih);
461-
return 0;
475+
if (is_direntry_le_ih(ih)) {
476+
if (ih_item_len(ih) < (ih_entry_count(ih) * IH_SIZE)) {
477+
reiserfs_warning(NULL, "reiserfs-5093",
478+
"item entry count seems wrong %h",
479+
ih);
480+
return 0;
481+
}
482+
return has_valid_deh_location(bh, ih);
462483
}
463484
prev_location = ih_location(ih);
464485
}

0 commit comments

Comments
 (0)