diff options
-rw-r--r-- | fs/nfs/nfs2xdr.c | 6 | ||||
-rw-r--r-- | fs/nfs/nfs3xdr.c | 6 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 5 | ||||
-rw-r--r-- | include/linux/sunrpc/xdr.h | 1 | ||||
-rw-r--r-- | net/sunrpc/xdr.c | 17 |
5 files changed, 21 insertions, 14 deletions
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index e15bc0306d0c..79c74387a2fe 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
@@ -596,7 +596,6 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy) | |||
596 | struct kvec *iov = rcvbuf->head; | 596 | struct kvec *iov = rcvbuf->head; |
597 | size_t hdrlen; | 597 | size_t hdrlen; |
598 | u32 len, recvd; | 598 | u32 len, recvd; |
599 | char *kaddr; | ||
600 | int status; | 599 | int status; |
601 | 600 | ||
602 | if ((status = ntohl(*p++))) | 601 | if ((status = ntohl(*p++))) |
@@ -623,10 +622,7 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy) | |||
623 | return -EIO; | 622 | return -EIO; |
624 | } | 623 | } |
625 | 624 | ||
626 | /* NULL terminate the string we got */ | 625 | xdr_terminate_string(rcvbuf, len); |
627 | kaddr = (char *)kmap_atomic(rcvbuf->pages[0], KM_USER0); | ||
628 | kaddr[len+rcvbuf->page_base] = '\0'; | ||
629 | kunmap_atomic(kaddr, KM_USER0); | ||
630 | return 0; | 626 | return 0; |
631 | } | 627 | } |
632 | 628 | ||
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 89c40f8ec6e6..52b2fda66e63 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
@@ -824,7 +824,6 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) | |||
824 | struct kvec *iov = rcvbuf->head; | 824 | struct kvec *iov = rcvbuf->head; |
825 | size_t hdrlen; | 825 | size_t hdrlen; |
826 | u32 len, recvd; | 826 | u32 len, recvd; |
827 | char *kaddr; | ||
828 | int status; | 827 | int status; |
829 | 828 | ||
830 | status = ntohl(*p++); | 829 | status = ntohl(*p++); |
@@ -857,10 +856,7 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) | |||
857 | return -EIO; | 856 | return -EIO; |
858 | } | 857 | } |
859 | 858 | ||
860 | /* NULL terminate the string we got */ | 859 | xdr_terminate_string(rcvbuf, len); |
861 | kaddr = (char*)kmap_atomic(rcvbuf->pages[0], KM_USER0); | ||
862 | kaddr[len+rcvbuf->page_base] = '\0'; | ||
863 | kunmap_atomic(kaddr, KM_USER0); | ||
864 | return 0; | 860 | return 0; |
865 | } | 861 | } |
866 | 862 | ||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index b0bd7efe8100..86ab69eb149c 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -4299,7 +4299,6 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) | |||
4299 | size_t hdrlen; | 4299 | size_t hdrlen; |
4300 | u32 len, recvd; | 4300 | u32 len, recvd; |
4301 | __be32 *p; | 4301 | __be32 *p; |
4302 | char *kaddr; | ||
4303 | int status; | 4302 | int status; |
4304 | 4303 | ||
4305 | status = decode_op_hdr(xdr, OP_READLINK); | 4304 | status = decode_op_hdr(xdr, OP_READLINK); |
@@ -4330,9 +4329,7 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) | |||
4330 | * and and null-terminate the text (the VFS expects | 4329 | * and and null-terminate the text (the VFS expects |
4331 | * null-termination). | 4330 | * null-termination). |
4332 | */ | 4331 | */ |
4333 | kaddr = (char *)kmap_atomic(rcvbuf->pages[0], KM_USER0); | 4332 | xdr_terminate_string(rcvbuf, len); |
4334 | kaddr[len+rcvbuf->page_base] = '\0'; | ||
4335 | kunmap_atomic(kaddr, KM_USER0); | ||
4336 | return 0; | 4333 | return 0; |
4337 | out_overflow: | 4334 | out_overflow: |
4338 | print_overflow_msg(__func__, xdr); | 4335 | print_overflow_msg(__func__, xdr); |
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 35cf2e8cd7c6..8c1dcbb54d89 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h | |||
@@ -108,6 +108,7 @@ void xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int, | |||
108 | unsigned int); | 108 | unsigned int); |
109 | void xdr_inline_pages(struct xdr_buf *, unsigned int, | 109 | void xdr_inline_pages(struct xdr_buf *, unsigned int, |
110 | struct page **, unsigned int, unsigned int); | 110 | struct page **, unsigned int, unsigned int); |
111 | void xdr_terminate_string(struct xdr_buf *, const u32); | ||
111 | 112 | ||
112 | static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int len) | 113 | static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int len) |
113 | { | 114 | { |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 3bbef7f5f826..e0725d9d8107 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -111,6 +111,23 @@ xdr_decode_string_inplace(__be32 *p, char **sp, | |||
111 | } | 111 | } |
112 | EXPORT_SYMBOL_GPL(xdr_decode_string_inplace); | 112 | EXPORT_SYMBOL_GPL(xdr_decode_string_inplace); |
113 | 113 | ||
114 | /** | ||
115 | * xdr_terminate_string - '\0'-terminate a string residing in an xdr_buf | ||
116 | * @buf: XDR buffer where string resides | ||
117 | * @len: length of string, in bytes | ||
118 | * | ||
119 | */ | ||
120 | void | ||
121 | xdr_terminate_string(struct xdr_buf *buf, const u32 len) | ||
122 | { | ||
123 | char *kaddr; | ||
124 | |||
125 | kaddr = kmap_atomic(buf->pages[0], KM_USER0); | ||
126 | kaddr[buf->page_base + len] = '\0'; | ||
127 | kunmap_atomic(kaddr, KM_USER0); | ||
128 | } | ||
129 | EXPORT_SYMBOL(xdr_terminate_string); | ||
130 | |||
114 | void | 131 | void |
115 | xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, | 132 | xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, |
116 | unsigned int len) | 133 | unsigned int len) |