aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2014-03-06 13:22:18 -0500
committerJ. Bruce Fields <bfields@redhat.com>2014-05-30 17:32:01 -0400
commitdb3f58a95beea6752d90fed03f9f198d282a3913 (patch)
tree438b162295933ef48f2d9fb1b7aa14a053504521
parent30596768b31069a3ae08fc305f394efb8c42b473 (diff)
rpc: define xdr_restrict_buflen
With this xdr_reserve_space can help us enforce various limits. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--include/linux/sunrpc/xdr.h1
-rw-r--r--net/sunrpc/xdr.c29
2 files changed, 30 insertions, 0 deletions
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index b23d69ffd5ec..70c6b92e15a7 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -217,6 +217,7 @@ extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32
217extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); 217extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
218extern void xdr_commit_encode(struct xdr_stream *xdr); 218extern void xdr_commit_encode(struct xdr_stream *xdr);
219extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len); 219extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len);
220extern int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen);
220extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, 221extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
221 unsigned int base, unsigned int len); 222 unsigned int base, unsigned int len);
222extern unsigned int xdr_stream_pos(const struct xdr_stream *xdr); 223extern unsigned int xdr_stream_pos(const struct xdr_stream *xdr);
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 2b546e8ce43d..39928444c7fb 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -649,6 +649,35 @@ void xdr_truncate_encode(struct xdr_stream *xdr, size_t len)
649EXPORT_SYMBOL(xdr_truncate_encode); 649EXPORT_SYMBOL(xdr_truncate_encode);
650 650
651/** 651/**
652 * xdr_restrict_buflen - decrease available buffer space
653 * @xdr: pointer to xdr_stream
654 * @newbuflen: new maximum number of bytes available
655 *
656 * Adjust our idea of how much space is available in the buffer.
657 * If we've already used too much space in the buffer, returns -1.
658 * If the available space is already smaller than newbuflen, returns 0
659 * and does nothing. Otherwise, adjusts xdr->buf->buflen to newbuflen
660 * and ensures xdr->end is set at most offset newbuflen from the start
661 * of the buffer.
662 */
663int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen)
664{
665 struct xdr_buf *buf = xdr->buf;
666 int left_in_this_buf = (void *)xdr->end - (void *)xdr->p;
667 int end_offset = buf->len + left_in_this_buf;
668
669 if (newbuflen < 0 || newbuflen < buf->len)
670 return -1;
671 if (newbuflen > buf->buflen)
672 return 0;
673 if (newbuflen < end_offset)
674 xdr->end = (void *)xdr->end + newbuflen - end_offset;
675 buf->buflen = newbuflen;
676 return 0;
677}
678EXPORT_SYMBOL(xdr_restrict_buflen);
679
680/**
652 * xdr_write_pages - Insert a list of pages into an XDR buffer for sending 681 * xdr_write_pages - Insert a list of pages into an XDR buffer for sending
653 * @xdr: pointer to xdr_stream 682 * @xdr: pointer to xdr_stream
654 * @pages: list of pages 683 * @pages: list of pages