sunrpc: trim off trailing checksum before returning decrypted or integrity authentica...
[firefly-linux-kernel-4.4.55.git] / net / sunrpc / auth_gss / svcauth_gss.c
index 73e95738660042e7a9d4e7cb252143ec74078265..a5b41e2ac25a2c20da3bbf6556a1db201ac6dd1b 100644 (file)
@@ -817,13 +817,17 @@ read_u32_from_xdr_buf(struct xdr_buf *buf, int base, u32 *obj)
  *     The server uses base of head iovec as read pointer, while the
  *     client uses separate pointer. */
 static int
-unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
+unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
 {
        int stat = -EINVAL;
        u32 integ_len, maj_stat;
        struct xdr_netobj mic;
        struct xdr_buf integ_buf;
 
+       /* Did we already verify the signature on the original pass through? */
+       if (rqstp->rq_deferred)
+               return 0;
+
        integ_len = svc_getnl(&buf->head[0]);
        if (integ_len & 3)
                return stat;
@@ -846,6 +850,8 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
                goto out;
        if (svc_getnl(&buf->head[0]) != seq)
                goto out;
+       /* trim off the mic at the end before returning */
+       xdr_buf_trim(buf, mic.len + 4);
        stat = 0;
 out:
        kfree(mic.data);
@@ -1190,7 +1196,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
                        /* placeholders for length and seq. number: */
                        svc_putnl(resv, 0);
                        svc_putnl(resv, 0);
-                       if (unwrap_integ_data(&rqstp->rq_arg,
+                       if (unwrap_integ_data(rqstp, &rqstp->rq_arg,
                                        gc->gc_seq, rsci->mechctx))
                                goto garbage_args;
                        break;