aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2018-04-01 23:21:03 -0400
committerJulian Veit <claymore1298@gmail.com>2019-09-03 18:56:00 +0200
commita49c70ad76885f6be425ce8efc5ccc3e7dfb0b44 (patch)
tree8437d06a3201835eeef84eb53abb8ca8351a49c5
parentee128423f9fb777a1763ac154983c0274e31b9ff (diff)
ext4: force revalidation of directory pointer after seekdir(2)p9.0
commit e40ff213898502d299351cc2fe1e350cd186f0d3 upstream. A malicious user could force the directory pointer to be in an invalid spot by using seekdir(2). Use the mechanism we already have to notice if the directory has changed since the last time we called ext4_readdir() to force a revalidation of the pointer. Change-Id: Ife34703951046e66f63048ff098a0ffa6f0cc5d0 Reported-by: syzbot+1236ce66f79263e8a862@syzkaller.appspotmail.com Signed-off-by: Theodore Ts'o <tytso@mit.edu> [bwh: Backported to 3.16: open-code inode_peek_iversion()] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--fs/ext4/dir.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 94a5629ee56..6e109dbb314 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -338,13 +338,15 @@ static loff_t ext4_dir_llseek(struct file *file, loff_t offset, int whence)
{
struct inode *inode = file->f_mapping->host;
int dx_dir = is_dx_dir(inode);
- loff_t htree_max = ext4_get_htree_eof(file);
+ loff_t ret, htree_max = ext4_get_htree_eof(file);
if (likely(dx_dir))
- return generic_file_llseek_size(file, offset, whence,
+ ret = generic_file_llseek_size(file, offset, whence,
htree_max, htree_max);
else
- return ext4_llseek(file, offset, whence);
+ ret = ext4_llseek(file, offset, whence);
+ file->f_version = inode->i_version - 1;
+ return ret;
}
/*