UBIFS: prepare to fix a horrid bug
authorArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Fri, 28 Jun 2013 11:15:14 +0000 (14:15 +0300)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 29 Jun 2013 08:45:37 +0000 (12:45 +0400)
commit33f1a63ae84dfd9ad298cf275b8f1887043ced36
tree4719106331ac4dff7a16d3ab5b7c0b15ef6ec0d1
parent945fb136dfcb5291b4fb2abd4fd1edf790de44ff
UBIFS: prepare to fix a horrid bug

Al Viro pointed me to the fact that '->readdir()' and '->llseek()' have no
mutual exclusion, which means the 'ubifs_dir_llseek()' can be run while we are
in the middle of 'ubifs_readdir()'.

First of all, this means that 'file->private_data' can be freed while
'ubifs_readdir()' uses it.  But this particular patch does not fix the problem.
This patch is only a preparation, and the fix will follow next.

In this patch we make 'ubifs_readdir()' stop using 'file->f_pos' directly,
because 'file->f_pos' can be changed by '->llseek()' at any point. This may
lead 'ubifs_readdir()' to returning inconsistent data: directory entry names
may correspond to incorrect file positions.

So here we introduce a local variable 'pos', read 'file->f_pose' once at very
the beginning, and then stick to 'pos'. The result of this is that when
'ubifs_dir_llseek()' changes 'file->f_pos' while we are in the middle of
'ubifs_readdir()', the latter "wins".

Cc: stable@vger.kernel.org
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Tested-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/ubifs/dir.c