aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xdr.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2013-02-06 08:28:55 -0500
committerJ. Bruce Fields <bfields@redhat.com>2013-02-08 15:19:10 -0500
commit4c190e2f913f038c9c91ee63b59cd037260ba353 (patch)
treefbb813220a57f4c8fbc110b933ff3698e67ec75d /net/sunrpc/xdr.c
parentde0b65ca55dc62b6b477f6e02088df2281da7b51 (diff)
sunrpc: trim off trailing checksum before returning decrypted or integrity authenticated buffer
When GSSAPI integrity signatures are in use, or when we're using GSSAPI privacy with the v2 token format, there is a trailing checksum on the xdr_buf that is returned. It's checked during the authentication stage, and afterward nothing cares about it. Ordinarily, it's not a problem since the XDR code generally ignores it, but it will be when we try to compute a checksum over the buffer to help prevent XID collisions in the duplicate reply cache. Fix the code to trim off the checksums after verifying them. Note that in unwrap_integ_data, we must avoid trying to reverify the checksum if the request was deferred since it will no longer be present when it's revisited. Signed-off-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'net/sunrpc/xdr.c')
-rw-r--r--net/sunrpc/xdr.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 56055632f151..75edcfad6e26 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -879,6 +879,47 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf,
879} 879}
880EXPORT_SYMBOL_GPL(xdr_buf_subsegment); 880EXPORT_SYMBOL_GPL(xdr_buf_subsegment);
881 881
882/**
883 * xdr_buf_trim - lop at most "len" bytes off the end of "buf"
884 * @buf: buf to be trimmed
885 * @len: number of bytes to reduce "buf" by
886 *
887 * Trim an xdr_buf by the given number of bytes by fixing up the lengths. Note
888 * that it's possible that we'll trim less than that amount if the xdr_buf is
889 * too small, or if (for instance) it's all in the head and the parser has
890 * already read too far into it.
891 */
892void xdr_buf_trim(struct xdr_buf *buf, unsigned int len)
893{
894 size_t cur;
895 unsigned int trim = len;
896
897 if (buf->tail[0].iov_len) {
898 cur = min_t(size_t, buf->tail[0].iov_len, trim);
899 buf->tail[0].iov_len -= cur;
900 trim -= cur;
901 if (!trim)
902 goto fix_len;
903 }
904
905 if (buf->page_len) {
906 cur = min_t(unsigned int, buf->page_len, trim);
907 buf->page_len -= cur;
908 trim -= cur;
909 if (!trim)
910 goto fix_len;
911 }
912
913 if (buf->head[0].iov_len) {
914 cur = min_t(size_t, buf->head[0].iov_len, trim);
915 buf->head[0].iov_len -= cur;
916 trim -= cur;
917 }
918fix_len:
919 buf->len -= (len - trim);
920}
921EXPORT_SYMBOL_GPL(xdr_buf_trim);
922
882static void __read_bytes_from_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len) 923static void __read_bytes_from_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len)
883{ 924{
884 unsigned int this_len; 925 unsigned int this_len;