Skip to content

Commit 6c09127

Browse files
lrumanciktytso
authored andcommitted
ext4: wipe ext4_dir_entry2 upon file deletion
Upon file deletion, zero out all fields in ext4_dir_entry2 besides rec_len. In case sensitive data is stored in filenames, this ensures no potentially sensitive data is left in the directory entry upon deletion. Also, wipe these fields upon moving a directory entry during the conversion to an htree and when splitting htree nodes. The data wiped may still exist in the journal, but there are future commits planned to address this. Signed-off-by: Leah Rumancik <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 5899593 commit 6c09127

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

fs/ext4/namei.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,7 +1854,14 @@ dx_move_dirents(struct inode *dir, char *from, char *to,
18541854
memcpy (to, de, rec_len);
18551855
((struct ext4_dir_entry_2 *) to)->rec_len =
18561856
ext4_rec_len_to_disk(rec_len, blocksize);
1857+
1858+
/* wipe dir_entry excluding the rec_len field */
18571859
de->inode = 0;
1860+
memset(&de->name_len, 0, ext4_rec_len_from_disk(de->rec_len,
1861+
blocksize) -
1862+
offsetof(struct ext4_dir_entry_2,
1863+
name_len));
1864+
18581865
map++;
18591866
to += rec_len;
18601867
}
@@ -2188,6 +2195,7 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
21882195
data2 = bh2->b_data;
21892196

21902197
memcpy(data2, de, len);
2198+
memset(de, 0, len); /* wipe old data */
21912199
de = (struct ext4_dir_entry_2 *) data2;
21922200
top = data2 + len;
21932201
while ((char *)(de2 = ext4_next_entry(de, blocksize)) < top)
@@ -2577,15 +2585,27 @@ int ext4_generic_delete_entry(struct inode *dir,
25772585
entry_buf, buf_size, i))
25782586
return -EFSCORRUPTED;
25792587
if (de == de_del) {
2580-
if (pde)
2588+
if (pde) {
25812589
pde->rec_len = ext4_rec_len_to_disk(
25822590
ext4_rec_len_from_disk(pde->rec_len,
25832591
blocksize) +
25842592
ext4_rec_len_from_disk(de->rec_len,
25852593
blocksize),
25862594
blocksize);
2587-
else
2595+
2596+
/* wipe entire dir_entry */
2597+
memset(de, 0, ext4_rec_len_from_disk(de->rec_len,
2598+
blocksize));
2599+
} else {
2600+
/* wipe dir_entry excluding the rec_len field */
25882601
de->inode = 0;
2602+
memset(&de->name_len, 0,
2603+
ext4_rec_len_from_disk(de->rec_len,
2604+
blocksize) -
2605+
offsetof(struct ext4_dir_entry_2,
2606+
name_len));
2607+
}
2608+
25892609
inode_inc_iversion(dir);
25902610
return 0;
25912611
}

0 commit comments

Comments
 (0)