• Artem Bityutskiy's avatar
    UBIFS: prepare to fix a horrid bug · 33f1a63a
    Artem Bityutskiy authored
    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: default avatarAl Viro <viro@zeniv.linux.org.uk>
    Tested-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
    Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    33f1a63a
dir.c 32 KB