Commit 9e80aeb7c7244c29b2c28049cd2149d3ab10a56a
Committed by
Greg Kroah-Hartman
1 parent
713beaa02f
rpc: fix xdr_truncate_encode to handle buffer ending on page boundary
commit 49a068f82a1d30eb585d7804b05948376be6cf9a upstream. A struct xdr_stream at a page boundary might point to the end of one page or the beginning of the next, but xdr_truncate_encode isn't prepared to handle the former. This can cause corruption of NFSv4 READDIR replies in the case that a readdir entry that would have exceeded the client's dircount/maxcount limit would have ended exactly on a 4k page boundary. You're more likely to hit this case on large directories. Other xdr_truncate_encode callers are probably also affected. Reported-by: Holger Hoffstätte <holger.hoffstaette@googlemail.com> Tested-by: Holger Hoffstätte <holger.hoffstaette@googlemail.com> Fixes: 3e19ce762b53 "rpc: xdr_truncate_encode" Signed-off-by: J. Bruce Fields <bfields@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 1 changed file with 3 additions and 3 deletions Side-by-side Diff
net/sunrpc/xdr.c
... | ... | @@ -606,7 +606,7 @@ |
606 | 606 | struct kvec *head = buf->head; |
607 | 607 | struct kvec *tail = buf->tail; |
608 | 608 | int fraglen; |
609 | - int new, old; | |
609 | + int new; | |
610 | 610 | |
611 | 611 | if (len > buf->len) { |
612 | 612 | WARN_ON_ONCE(1); |
... | ... | @@ -628,8 +628,8 @@ |
628 | 628 | buf->len -= fraglen; |
629 | 629 | |
630 | 630 | new = buf->page_base + buf->page_len; |
631 | - old = new + fraglen; | |
632 | - xdr->page_ptr -= (old >> PAGE_SHIFT) - (new >> PAGE_SHIFT); | |
631 | + | |
632 | + xdr->page_ptr = buf->pages + (new >> PAGE_SHIFT); | |
633 | 633 | |
634 | 634 | if (buf->page_len && buf->len == len) { |
635 | 635 | xdr->p = page_address(*xdr->page_ptr); |