aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2024-04-17 16:52:00 -0400
committerTheodore Ts'o <tytso@mit.edu>2024-04-17 16:58:26 -0400
commitb53ce7848c2ed2cf4acf2ba9384e96129bc89d25 (patch)
treec02f0263a0f1eb1e630ae50955893b319ca30b9b
parent55bc5ce40648e4df91c019b05fbfcc9c5b803c10 (diff)
downloade2fsprogs-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.c20
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)