Commit 6c091273 authored by Leah Rumancik's avatar Leah Rumancik Committed by Theodore Ts'o

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: default avatarLeah Rumancik <leah.rumancik@gmail.com>
Link: https://lore.kernel.org/r/20210422180834.2242353-1-leah.rumancik@gmail.comSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent 5899593f
...@@ -1854,7 +1854,14 @@ dx_move_dirents(struct inode *dir, char *from, char *to, ...@@ -1854,7 +1854,14 @@ dx_move_dirents(struct inode *dir, char *from, char *to,
memcpy (to, de, rec_len); memcpy (to, de, rec_len);
((struct ext4_dir_entry_2 *) to)->rec_len = ((struct ext4_dir_entry_2 *) to)->rec_len =
ext4_rec_len_to_disk(rec_len, blocksize); ext4_rec_len_to_disk(rec_len, blocksize);
/* wipe dir_entry excluding the rec_len field */
de->inode = 0; de->inode = 0;
memset(&de->name_len, 0, ext4_rec_len_from_disk(de->rec_len,
blocksize) -
offsetof(struct ext4_dir_entry_2,
name_len));
map++; map++;
to += rec_len; to += rec_len;
} }
...@@ -2188,6 +2195,7 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname, ...@@ -2188,6 +2195,7 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
data2 = bh2->b_data; data2 = bh2->b_data;
memcpy(data2, de, len); memcpy(data2, de, len);
memset(de, 0, len); /* wipe old data */
de = (struct ext4_dir_entry_2 *) data2; de = (struct ext4_dir_entry_2 *) data2;
top = data2 + len; top = data2 + len;
while ((char *)(de2 = ext4_next_entry(de, blocksize)) < top) while ((char *)(de2 = ext4_next_entry(de, blocksize)) < top)
...@@ -2577,15 +2585,27 @@ int ext4_generic_delete_entry(struct inode *dir, ...@@ -2577,15 +2585,27 @@ int ext4_generic_delete_entry(struct inode *dir,
entry_buf, buf_size, i)) entry_buf, buf_size, i))
return -EFSCORRUPTED; return -EFSCORRUPTED;
if (de == de_del) { if (de == de_del) {
if (pde) if (pde) {
pde->rec_len = ext4_rec_len_to_disk( pde->rec_len = ext4_rec_len_to_disk(
ext4_rec_len_from_disk(pde->rec_len, ext4_rec_len_from_disk(pde->rec_len,
blocksize) + blocksize) +
ext4_rec_len_from_disk(de->rec_len, ext4_rec_len_from_disk(de->rec_len,
blocksize), blocksize),
blocksize); blocksize);
else
/* wipe entire dir_entry */
memset(de, 0, ext4_rec_len_from_disk(de->rec_len,
blocksize));
} else {
/* wipe dir_entry excluding the rec_len field */
de->inode = 0; de->inode = 0;
memset(&de->name_len, 0,
ext4_rec_len_from_disk(de->rec_len,
blocksize) -
offsetof(struct ext4_dir_entry_2,
name_len));
}
inode_inc_iversion(dir); inode_inc_iversion(dir);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment