nfsd: fix rare symlink decoding bug
authorJ. Bruce Fields <bfields@redhat.com>
Thu, 19 Jun 2014 20:44:48 +0000 (16:44 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 9 Jul 2014 18:14:02 +0000 (11:14 -0700)
commit9c252e3881a4b8dae3555b826cb6cf915fd00d09
treef1f28640ff7b6180778c85e473a0e76fdbebaa92
parentb32b30d35e5c0859fe88eabfbb0572aaccb9f46f
nfsd: fix rare symlink decoding bug

commit 76f47128f9b33af1e96819746550d789054c9664 upstream.

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: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4xdr.c