Skip to content
  • NeilBrown's avatar
    nfsd: fix memory corruption caused by readdir · b602345d
    NeilBrown authored
    If the result of an NFSv3 readdir{,plus} request results in the
    "offset" on one entry having to be split across 2 pages, and is sized
    so that the next directory entry doesn't fit in the requested size,
    then memory corruption can happen.
    
    When encode_entry() is called after encoding the last entry that fits,
    it notices that ->offset and ->offset1 are set, and so stores the
    offset value in the two pages as required.  It clears ->offset1 but
    *does not* clear ->offset.
    
    Normally this omission doesn't matter as encode_entry_baggage() will
    be called, and will set ->offset to a suitable value (not on a page
    boundary).
    But in the case where cd->buflen < elen and nfserr_toosmall is
    returned, ->offset is not reset.
    
    This means that nfsd3proc_readdirplus will see ->offset with a value 4
    bytes before the end of a page, and ->offset1 set to NULL.
    It will try to write 8bytes to ->offset.
    If we are lucky, the next page will be read-only, and the system will
      BUG: unable to handle kernel paging request at...
    
    If we are unlucky, some innocent page will have the first 4 bytes
    corrupted.
    
    nfsd3proc_readdir() doesn't even check for ->offset1, it just blindly
    writes 8 bytes to the offset wherever it is.
    
    Fix this by clearing ->offset after it is used, and copying the
    ->offset handling code from nfsd3_proc_readdirplus into
    nfsd3_proc_readdir.
    
    (Note that the commit hash in the Fixes tag is from the 'history'
     tree - this bug predates git).
    
    Fixes: 0b1d57cf7654 ("[PATCH] kNFSd: Fix nfs3 dentry encoding")
    Fixes-URL: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=0b1d57cf7654
    
    
    Cc: stable@vger.kernel.org (v2.6.12+)
    Signed-off-by: default avatarNeilBrown <neilb@suse.com>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    b602345d