• J. Bruce Fields's avatar
    nfsd: fix rare symlink decoding bug · 47f9b6ad
    J. Bruce Fields authored
    An NFS operation that creates a new symlink includes the symlink data,
    which is xdr-encoded as a length followed by the data plus 0 to 3 bytes
    of zero-padding as required to reach a 4-byte boundary.
    
    The vfs, on the other hand, wants null-terminated data.
    
    The simple way to handle this would be by copying the data into a newly
    allocated buffer with space for the final null.
    
    The current nfsd_symlink code tries to be more clever by skipping that
    step in the (likely) case where the byte following the string is already
    0.
    
    But that assumes that the byte following the string is ours to look at.
    In fact, it might be the first byte of a page that we can't read, or of
    some object that another task might modify.
    
    Worse, the NFSv4 code tries to fix the problem by actually writing to
    that byte.
    
    In the NFSv2/v3 cases this actually appears to be safe:
    
    	- nfs3svc_decode_symlinkargs explicitly null-terminates the data
    	  (after first checking its length and copying it to a new
    	  page).
    	- NFSv2 limits symlinks to 1k.  The buffer holding the rpc
    	  request is always at least a page, and the link data (and
    	  previous fields) have maximum lengths that prevent the request
    	  from reaching the end of a page.
    
    In the NFSv4 case the CREATE op is potentially just one part of a long
    compound so can end up on the end of a page if you're unlucky.
    
    The minimal fix here is to copy and null-terminate in the NFSv4 case.
    The nfsd_symlink() interface here seems too fragile, though.  It should
    really either do the copy itself every time or just require a
    null-terminated string.
    Reported-by: default avatarJeff Layton <jlayton@primarydata.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    
    nfsd: fix rare symlink decoding bug
    
    An NFS operation that creates a new symlink includes the symlink data,
    which is xdr-encoded as a length followed by the data plus 0 to 3 bytes
    of zero-padding as required to reach a 4-byte boundary.
    
    The vfs, on the other hand, wants null-terminated data.
    
    The simple way to handle this would be by copying the data into a newly
    allocated buffer with space for the final null.
    
    The current nfsd_symlink code tries to be more clever by skipping that
    step in the (likely) case where the byte following the string is already
    0.
    
    But that assumes that the byte following the string is ours to look at.
    In fact, it might be the first byte of a page that we can't read, or of
    some object that another task might modify.
    
    Worse, the NFSv4 code tries to fix the problem by actually writing to
    that byte.
    
    In the NFSv2/v3 cases this actually appears to be safe:
    
    	- nfs3svc_decode_symlinkargs explicitly null-terminates the data
    	  (after first checking its length and copying it to a new
    	  page).
    	- NFSv2 limits symlinks to 1k.  The buffer holding the rpc
    	  request is always at least a page, and the link data (and
    	  previous fields) have maximum lengths that prevent the request
    	  from reaching the end of a page.
    
    In the NFSv4 case the CREATE op is potentially just one part of a long
    compound so can end up on the end of a page if you're unlucky.
    
    The minimal fix here is to copy and null-terminate in the NFSv4 case.
    The nfsd_symlink() interface here seems too fragile, though.  It should
    really either do the copy itself every time or just require a
    null-terminated string.
    Reported-by: default avatarJeff Layton <jlayton@primarydata.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    
    nfsd: properly handle embedded newlines in fault_injection input
    
    Currently rpc_pton() fails to handle the case where you echo an address
    into the file, as it barfs on the newline. Ensure that we NULL out the
    first occurrence of any newline.
    Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    
    nfsd: fix return of nfs4_acl_write_who
    
    AFAICT, the only way to hit this error is to pass this function a bogus
    "who" value. In that case, we probably don't want to return -1 as that
    could get sent back to the client. Turn this into nfserr_serverfault,
    which is a more appropriate error for a server bug like this.
    Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    
    nfsd: add appropriate __force directives to filehandle generation code
    
    The filehandle structs all use host-endian values, but will sometimes
    stuff big-endian values into those fields. This is OK since these
    values are opaque to the client, but it confuses sparse. Add __force to
    make it clear that we are doing this intentionally.
    Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    
    nfsd: nfsd_splice_read and nfsd_readv should return __be32
    
    The callers expect a __be32 return and the functions they call return
    __be32, so having these return int is just wrong. Also, nfsd_finish_read
    can be made static.
    Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    
    nfsd: clean up sparse endianness warnings in nfscache.c
    
    We currently hash the XID to determine a hash bucket to use for the
    reply cache entry, which is fed into hash_32 without byte-swapping it.
    Add __force to make sparse happy, and add some comments to explain
    why.
    Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    
    nfsd: add __force to opaque verifier field casts
    
    sparse complains that we're stuffing non-byte-swapped values into
    __be32's here. Since they're supposed to be opaque, it doesn't matter
    much. Just add __force to make sparse happy.
    Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    
    NFSD: Using exp_get for export getting
    
    Don't using cache_get besides export.h, using exp_get for export.
    Signed-off-by: default avatarKinglong Mee <kinglongmee@gmail.com>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    
    NFSD: Using path_get when assigning path for export
    Signed-off-by: default avatarKinglong Mee <kinglongmee@gmail.com>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    
    SUNRPC/NFSD: Change to type of bool for rq_usedeferral and rq_splice_ok
    
    rq_usedeferral and rq_splice_ok are used as 0 and 1, just defined to bool.
    Signed-off-by: default avatarKinglong Mee <kinglongmee@gmail.com>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    
    NFSD: Using min/max/min_t/max_t for calculate
    Signed-off-by: default avatarKinglong Mee <kinglongmee@gmail.com>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    
    (cherry picked from commit b829e919
    76f47128)
    Signed-off-by: default avatarSasha Levin <sasha.levin@oracle.com>
    47f9b6ad
nfs4proc.c 52.1 KB