diff options
author | Theodore Ts'o <tytso@mit.edu> | 2024-04-17 16:52:00 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2024-04-17 16:58:26 -0400 |
commit | b53ce7848c2ed2cf4acf2ba9384e96129bc89d25 (patch) | |
tree | c02f0263a0f1eb1e630ae50955893b319ca30b9b | |
parent | 55bc5ce40648e4df91c019b05fbfcc9c5b803c10 (diff) | |
download | e2fsprogs-b53ce7848c2ed2cf4acf2ba9384e96129bc89d25.tar.gz |
e2fsck: don't try backup superblocks beyond the size of the device
Commit f7ef5f3e356d ("e2fsck: check all sparse_super backups") tries
to limit the number of block groups to search for backup superblocks
based on ctx->num_blocks. Unfortunately, get_backup_sb() gets called
before ctx->num_blocks is set, so we try all block groups up to 2**32
- 1. Not only does this waste time trying to read from blocks that
don't exist, it triggers the UBSAN checker when multiplying a very
large number by the block size.
Fix this by using ext2fs_get_Device_size(), and if that isn't
available, arbitrarily cap things so that we search block groups up to
128.
Fixes: f7ef5f3e356d ("e2fsck: check all sparse_super backups")
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r-- | e2fsck/util.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/e2fsck/util.c b/e2fsck/util.c index 6982966e6..734e45cad 100644 --- a/e2fsck/util.c +++ b/e2fsck/util.c @@ -588,16 +588,26 @@ blk64_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name, for (; blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) { dgrp_t grp, three = 1, five = 5, seven = 7; - dgrp_t limit = (dgrp_t)-1; + dgrp_t limit; blk_t this_bpg = bpg ? bpg : blocksize * 8; - - if (ctx->num_blocks && limit > ctx->num_blocks / this_bpg) - limit = ctx->num_blocks / this_bpg; + blk64_t num_blocks; + + if (ext2fs_get_device_size2(ctx->filesystem_name, + blocksize, + &num_blocks) == 0) { + limit = num_blocks / this_bpg; + } else { + /* If we can't figure out the device size, + * arbitrarily set a limit which is enough for + * 8 block groups or so... + */ + limit = 128; + } io_channel_set_blksize(io, blocksize); while ((grp = ext2fs_list_backups(NULL, &three, - &five, &seven)) < limit) { + &five, &seven)) <= limit) { blk64_t superblock = (blk64_t)grp * this_bpg; if (blocksize == 1024) |