]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
SUNRPC/nfs: Fix return value for nfs4_callback_compound()
authorTrond Myklebust <trondmy@gmail.com>
Tue, 9 Apr 2019 15:46:14 +0000 (11:46 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 Sep 2021 09:47:47 +0000 (11:47 +0200)
commit 83dd59a0b9afc3b1a2642fb5c9b0585b1c08768f upstream.

RPC server procedures are normally expected to return a __be32 encoded
status value of type 'enum rpc_accept_stat', however at least one function
wants to return an authentication status of type 'enum rpc_auth_stat'
in the case where authentication fails.
This patch adds functionality to allow this.

Fixes: a4e187d83d88 ("NFS: Don't drop CB requests with invalid principals")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/nfs/callback_xdr.c
include/linux/sunrpc/svc.h
net/sunrpc/svc.c

index a87a562734077c221884edaf7962086af6e7a643..57558a8d92e9ba4ae3214365d4314b06ebb6499b 100644 (file)
@@ -991,7 +991,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp)
 
 out_invalidcred:
        pr_warn_ratelimited("NFS: NFSv4 callback contains invalid cred\n");
-       return rpc_autherr_badcred;
+       return svc_return_autherr(rqstp, rpc_autherr_badcred);
 }
 
 /*
index fdb6b317d974739afcdf5519d8872790493bc244..c46abf35c9bb6e63b782ef3fe6fe5133c417779c 100644 (file)
@@ -271,6 +271,7 @@ struct svc_rqst {
 #define        RQ_VICTIM       (5)                     /* about to be shut down */
 #define        RQ_BUSY         (6)                     /* request is busy */
 #define        RQ_DATA         (7)                     /* request has data */
+#define RQ_AUTHERR     (8)                     /* Request status is auth error */
        unsigned long           rq_flags;       /* flags field */
        ktime_t                 rq_qtime;       /* enqueue time */
 
@@ -504,6 +505,7 @@ unsigned int           svc_fill_write_vector(struct svc_rqst *rqstp,
 char             *svc_fill_symlink_pathname(struct svc_rqst *rqstp,
                                             struct kvec *first, void *p,
                                             size_t total);
+__be32            svc_return_autherr(struct svc_rqst *rqstp, __be32 auth_err);
 
 #define        RPC_MAX_ADDRBUFLEN      (63U)
 
index 11d393c0477288f7f36ca764e0764da584a38349..6a606af8de81995f1a8461c26612f99b5766434d 100644 (file)
@@ -1146,6 +1146,22 @@ static __printf(2,3) void svc_printk(struct svc_rqst *rqstp, const char *fmt, ..
 
 extern void svc_tcp_prep_reply_hdr(struct svc_rqst *);
 
+__be32
+svc_return_autherr(struct svc_rqst *rqstp, __be32 auth_err)
+{
+       set_bit(RQ_AUTHERR, &rqstp->rq_flags);
+       return auth_err;
+}
+EXPORT_SYMBOL_GPL(svc_return_autherr);
+
+static __be32
+svc_get_autherr(struct svc_rqst *rqstp, __be32 *statp)
+{
+       if (test_and_clear_bit(RQ_AUTHERR, &rqstp->rq_flags))
+               return *statp;
+       return rpc_auth_ok;
+}
+
 /*
  * Common routine for processing the RPC request.
  */
@@ -1296,11 +1312,9 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
                                procp->pc_release(rqstp);
                        goto dropit;
                }
-               if (*statp == rpc_autherr_badcred) {
-                       if (procp->pc_release)
-                               procp->pc_release(rqstp);
-                       goto err_bad_auth;
-               }
+               auth_stat = svc_get_autherr(rqstp, statp);
+               if (auth_stat != rpc_auth_ok)
+                       goto err_release_bad_auth;
                if (*statp == rpc_success && procp->pc_encode &&
                    !procp->pc_encode(rqstp, resv->iov_base + resv->iov_len)) {
                        dprintk("svc: failed to encode reply\n");
@@ -1359,6 +1373,9 @@ err_bad_rpc:
        svc_putnl(resv, 2);
        goto sendit;
 
+err_release_bad_auth:
+       if (procp->pc_release)
+               procp->pc_release(rqstp);
 err_bad_auth:
        dprintk("svc: authentication failed (%d)\n", ntohl(auth_stat));
        serv->sv_stats->rpcbadauth++;