64 lines
2.0 KiB
Diff
64 lines
2.0 KiB
Diff
|
From 225e5d093b519f9dbe9fcaacd995426f0e5194f6 Mon Sep 17 00:00:00 2001
|
||
|
From: Theodore Ts'o <tytso@mit.edu>
|
||
|
Date: Wed, 28 Jul 2021 13:51:13 -0400
|
||
|
Subject: [PATCH] e2fsck: fix f_baddotdir failure on big-endian systems
|
||
|
|
||
|
Commit 63f44aafb1f2 ("e2fsck: fix ".." more gracefully if possible")
|
||
|
changed the check_dot() function to try to avoid resetting the '..'
|
||
|
entry when the '.' entry is too large.. But if we do that, then on
|
||
|
big-endian systems, we need to try byte swapping the rest of the
|
||
|
directory entries, or else the f_baddotdir test will fail on
|
||
|
big-endian systems.
|
||
|
|
||
|
Also add a check to avoid UBSAN warning when there is not enough space
|
||
|
at the end of the directory block for a directory entry, and so we can
|
||
|
potentially overflow some pointer arithmetic when trying to byte swap
|
||
|
the remainder of the (negative) space in the directory block.
|
||
|
|
||
|
Fixes: 63f44aafb1f2 ("e2fsck: fix ".." more gracefully if possible")
|
||
|
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
|
||
|
---
|
||
|
e2fsck/pass2.c | 18 +++++++++++++-----
|
||
|
1 file changed, 13 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
|
||
|
index f00cb40e..bd974c55 100644
|
||
|
--- a/e2fsck/pass2.c
|
||
|
+++ b/e2fsck/pass2.c
|
||
|
@@ -458,6 +458,12 @@ static int check_dot(e2fsck_t ctx,
|
||
|
ext2fs_dirent_set_name_len(nextdir, 0);
|
||
|
ext2fs_dirent_set_file_type(nextdir,
|
||
|
ftype);
|
||
|
+#ifdef WORDS_BIGENDIAN
|
||
|
+ } else {
|
||
|
+ (void) ext2fs_dirent_swab_in2(ctx->fs,
|
||
|
+ (char *) nextdir,
|
||
|
+ ctx->fs->blocksize - 12, 0);
|
||
|
+#endif
|
||
|
}
|
||
|
status = 1;
|
||
|
}
|
||
|
@@ -1370,12 +1376,14 @@ skip_checksum:
|
||
|
hash_in_dirent);
|
||
|
#ifdef WORDS_BIGENDIAN
|
||
|
if (need_reswab) {
|
||
|
+ unsigned int len;
|
||
|
+
|
||
|
(void) ext2fs_get_rec_len(fs,
|
||
|
- dirent, &rec_len);
|
||
|
- ext2fs_dirent_swab_in2(fs,
|
||
|
- ((char *)dirent) + offset + rec_len,
|
||
|
- max_block_size - offset - rec_len,
|
||
|
- 0);
|
||
|
+ dirent, &len);
|
||
|
+ len += offset;
|
||
|
+ if (max_block_size > len)
|
||
|
+ ext2fs_dirent_swab_in2(fs,
|
||
|
+ ((char *)dirent) + len, max_block_size - len, 0);
|
||
|
}
|
||
|
#endif
|
||
|
dir_modified++;
|
||
|
--
|
||
|
2.31.1
|
||
|
|