]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
SUNRPC: Remove xdr_buf_trim()
authorChuck Lever <chuck.lever@oracle.com>
Mon, 11 Feb 2019 16:25:09 +0000 (11:25 -0500)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Thu, 14 Feb 2019 14:39:34 +0000 (09:39 -0500)
The key action of xdr_buf_trim() is that it shortens buf->len, the
length of the xdr_buf's content. The other actions -- shortening the
head, pages, and tail components -- are actually not necessary. In
particular, changing the size of those components can corrupt the
RPC message contained in the buffer. This is an accident waiting to
happen rather than a current bug, as far as we know.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Acked-by: Bruce Fields <bfields@redhat.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
include/linux/sunrpc/xdr.h
net/sunrpc/auth_gss/gss_krb5_wrap.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/xdr.c

index 65af6a204b75ebf86af4a464509cf96827a1365a..9ee3970ba59c31385e3b20a277d560a48bee3fc1 100644 (file)
@@ -179,7 +179,6 @@ xdr_adjust_iovec(struct kvec *iov, __be32 *p)
 extern void xdr_shift_buf(struct xdr_buf *, size_t);
 extern void xdr_buf_from_iov(struct kvec *, struct xdr_buf *);
 extern int xdr_buf_subsegment(struct xdr_buf *, struct xdr_buf *, unsigned int, unsigned int);
-extern void xdr_buf_trim(struct xdr_buf *, unsigned int);
 extern int xdr_buf_read_netobj(struct xdr_buf *, struct xdr_netobj *, unsigned int);
 extern int read_bytes_from_xdr_buf(struct xdr_buf *, unsigned int, void *, unsigned int);
 extern int write_bytes_to_xdr_buf(struct xdr_buf *, unsigned int, void *, unsigned int);
index 5cdde6cb703a423ff48682f86e5275e331bbe242..14a0aff0cd84c644ac9e1bf5e8444630aaec7b55 100644 (file)
@@ -570,14 +570,16 @@ gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
         */
        movelen = min_t(unsigned int, buf->head[0].iov_len, buf->len);
        movelen -= offset + GSS_KRB5_TOK_HDR_LEN + headskip;
-       BUG_ON(offset + GSS_KRB5_TOK_HDR_LEN + headskip + movelen >
-                                                       buf->head[0].iov_len);
+       if (offset + GSS_KRB5_TOK_HDR_LEN + headskip + movelen >
+           buf->head[0].iov_len)
+               return GSS_S_FAILURE;
        memmove(ptr, ptr + GSS_KRB5_TOK_HDR_LEN + headskip, movelen);
        buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip;
        buf->len -= GSS_KRB5_TOK_HDR_LEN + headskip;
 
        /* Trim off the trailing "extra count" and checksum blob */
-       xdr_buf_trim(buf, ec + GSS_KRB5_TOK_HDR_LEN + tailskip);
+       buf->len -= ec + GSS_KRB5_TOK_HDR_LEN + tailskip;
+
        return GSS_S_COMPLETE;
 }
 
index 152790ed309c6f2cb10df426afbf3f9f603025c1..f1aabab4a4c2a8922522f9d741f574854f1d3216 100644 (file)
@@ -896,7 +896,7 @@ unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct g
        if (svc_getnl(&buf->head[0]) != seq)
                goto out;
        /* trim off the mic and padding at the end before returning */
-       xdr_buf_trim(buf, round_up_to_quad(mic.len) + 4);
+       buf->len -= 4 + round_up_to_quad(mic.len);
        stat = 0;
 out:
        kfree(mic.data);
index 5f0aa53fa4ae4d8b91bde4d430b51eb1c8472272..4bce619780625cbbff44aa342087828adf093e84 100644 (file)
@@ -1139,47 +1139,6 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf,
 }
 EXPORT_SYMBOL_GPL(xdr_buf_subsegment);
 
-/**
- * xdr_buf_trim - lop at most "len" bytes off the end of "buf"
- * @buf: buf to be trimmed
- * @len: number of bytes to reduce "buf" by
- *
- * Trim an xdr_buf by the given number of bytes by fixing up the lengths. Note
- * that it's possible that we'll trim less than that amount if the xdr_buf is
- * too small, or if (for instance) it's all in the head and the parser has
- * already read too far into it.
- */
-void xdr_buf_trim(struct xdr_buf *buf, unsigned int len)
-{
-       size_t cur;
-       unsigned int trim = len;
-
-       if (buf->tail[0].iov_len) {
-               cur = min_t(size_t, buf->tail[0].iov_len, trim);
-               buf->tail[0].iov_len -= cur;
-               trim -= cur;
-               if (!trim)
-                       goto fix_len;
-       }
-
-       if (buf->page_len) {
-               cur = min_t(unsigned int, buf->page_len, trim);
-               buf->page_len -= cur;
-               trim -= cur;
-               if (!trim)
-                       goto fix_len;
-       }
-
-       if (buf->head[0].iov_len) {
-               cur = min_t(size_t, buf->head[0].iov_len, trim);
-               buf->head[0].iov_len -= cur;
-               trim -= cur;
-       }
-fix_len:
-       buf->len -= (len - trim);
-}
-EXPORT_SYMBOL_GPL(xdr_buf_trim);
-
 static void __read_bytes_from_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len)
 {
        unsigned int this_len;