• Artem Bityutskiy's avatar
    UBIFS: fix a horrid bug · 605c912b
    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()'.
    
    This means that 'file->private_data' can be freed while 'ubifs_readdir()' uses
    it, and this is a very bad bug: not only 'ubifs_readdir()' can return garbage,
    but this may corrupt memory and lead to all kinds of problems like crashes an
    security holes.
    
    This patch fixes the problem by using the 'file->f_version' field, which
    '->llseek()' always unconditionally sets to zero. We set it to 1 in
    'ubifs_readdir()' and whenever we detect that it became 0, we know there was a
    seek and it is time to clear the state saved in 'file->private_data'.
    
    I tested this patch by writing a user-space program which runds readdir and
    seek in parallell. I could easily crash the kernel without these patches, but
    could not crash it with these patches.
    
    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>
    605c912b
dir.c 32.7 KB