Details
-
Bug
-
Resolution: Unresolved
-
Minor
-
None
-
None
-
None
-
3
-
9223372036854775807
Description
In check_dot() it assumes that the "." and ".." entries are fixed at 12-bytes, but with the dirdata feature storing a FID in these directory entries, they will be larger. If there is some unrelated problem in the directory returned by e2fsck_check_dirent_data() then this check will incorrectly cause the "." and ".." entries to be recreated and clobber the FIDs.
static int check_dot(...) { : dir_data_error = e2fsck_check_dirent_data(ctx, dirent, offset, pctx); : if (rec_len > 12) { new_len = rec_len - 12; if (new_len > 12 && dir_data_error) { if (created || fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) { nextdir = (struct ext2_dir_entry *) ((char *) dirent + 12); dirent->rec_len = 12; (void) ext2fs_set_rec_len(ctx->fs, new_len, nextdir); nextdir->inode = 0; ext2fs_dirent_set_name_len(nextdir, 0); ext2fs_dirent_set_file_type(nextdir, EXT2_FT_UNKNOWN);
As a follow-on, the HTree index will no longer immediately follow the ".." entry (fake_root) and be invalidated:
Directory entry for '.' in ... (1032783) is big. Split? no Second entry '3.3.0' (inode=538027 fid=[0x380020941:0x4c38:0x0]) in directory inode 1032783 should be '..' Fix? no
The code in check_dot() needs to be updated to properly check for the length of dirdata entries.
It doesn't look like same bug appears in check_dotdot(). It is checking for (rec_len < 12), which should be OK, since dirdata entries will always be larger. Properly accounting for rec_len in check_dot() should avoid any problems in check_dotdot(). However, there is LU-7399 which suggests an improvement for rebuilding ".." in other situations.