callback_xdr.c (42c2c4249cd0192e29eec71e3e94d7bbc383c8de) callback_xdr.c (459de2edb9105a5d091f8215650e12c0812d59f3)
1/*
2 * linux/fs/nfs/callback_xdr.c
3 *
4 * Copyright (C) 2004 Trond Myklebust
5 *
6 * NFSv4 callback encode/decode procedures
7 */
8#include <linux/kernel.h>

--- 152 unchanged lines hidden (view full) ---

161 printk("NFS: NFSv4 CALLBACK %s: client sent tag of length %u\n",
162 __func__, hdr->taglen);
163 return htonl(NFS4ERR_RESOURCE);
164 }
165 p = read_buf(xdr, 12);
166 if (unlikely(p == NULL))
167 return htonl(NFS4ERR_RESOURCE);
168 hdr->minorversion = ntohl(*p++);
1/*
2 * linux/fs/nfs/callback_xdr.c
3 *
4 * Copyright (C) 2004 Trond Myklebust
5 *
6 * NFSv4 callback encode/decode procedures
7 */
8#include <linux/kernel.h>

--- 152 unchanged lines hidden (view full) ---

161 printk("NFS: NFSv4 CALLBACK %s: client sent tag of length %u\n",
162 __func__, hdr->taglen);
163 return htonl(NFS4ERR_RESOURCE);
164 }
165 p = read_buf(xdr, 12);
166 if (unlikely(p == NULL))
167 return htonl(NFS4ERR_RESOURCE);
168 hdr->minorversion = ntohl(*p++);
169 /* Check minor version is zero or one or two. */
170 if (hdr->minorversion <= 2) {
169 /* Check for minor version support */
170 if (hdr->minorversion <= NFS4_MAX_MINOR_VERSION) {
171 hdr->cb_ident = ntohl(*p++); /* ignored by v4.1 and v4.2 */
172 } else {
173 pr_warn_ratelimited("NFS: %s: NFSv4 server callback with "
174 "illegal minor version %u!\n",
175 __func__, hdr->minorversion);
176 return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
177 }
178 hdr->nops = ntohl(*p);

--- 617 unchanged lines hidden (view full) ---

796 break;
797 default:
798 return htonl(NFS4ERR_OP_ILLEGAL);
799 }
800
801 return htonl(NFS_OK);
802}
803
171 hdr->cb_ident = ntohl(*p++); /* ignored by v4.1 and v4.2 */
172 } else {
173 pr_warn_ratelimited("NFS: %s: NFSv4 server callback with "
174 "illegal minor version %u!\n",
175 __func__, hdr->minorversion);
176 return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
177 }
178 hdr->nops = ntohl(*p);

--- 617 unchanged lines hidden (view full) ---

796 break;
797 default:
798 return htonl(NFS4ERR_OP_ILLEGAL);
799 }
800
801 return htonl(NFS_OK);
802}
803
804static __be32 process_op(uint32_t minorversion, int nop,
805 struct svc_rqst *rqstp,
804static __be32 process_op(int nop, struct svc_rqst *rqstp,
806 struct xdr_stream *xdr_in, void *argp,
807 struct xdr_stream *xdr_out, void *resp,
808 struct cb_process_state *cps)
809{
810 struct callback_op *op = &callback_ops[0];
811 unsigned int op_nr;
812 __be32 status;
813 long maxlen;
814 __be32 res;
815
816 dprintk("%s: start\n", __func__);
817 status = decode_op_hdr(xdr_in, &op_nr);
818 if (unlikely(status))
819 return status;
820
821 dprintk("%s: minorversion=%d nop=%d op_nr=%u\n",
805 struct xdr_stream *xdr_in, void *argp,
806 struct xdr_stream *xdr_out, void *resp,
807 struct cb_process_state *cps)
808{
809 struct callback_op *op = &callback_ops[0];
810 unsigned int op_nr;
811 __be32 status;
812 long maxlen;
813 __be32 res;
814
815 dprintk("%s: start\n", __func__);
816 status = decode_op_hdr(xdr_in, &op_nr);
817 if (unlikely(status))
818 return status;
819
820 dprintk("%s: minorversion=%d nop=%d op_nr=%u\n",
822 __func__, minorversion, nop, op_nr);
821 __func__, cps->minorversion, nop, op_nr);
823
822
824 status = minorversion ? preprocess_nfs41_op(nop, op_nr, &op) :
823 status = cps->minorversion ? preprocess_nfs41_op(nop, op_nr, &op) :
825 preprocess_nfs4_op(op_nr, &op);
826 if (status == htonl(NFS4ERR_OP_ILLEGAL))
827 op_nr = OP_CB_ILLEGAL;
828 if (status)
829 goto encode_hdr;
830
831 if (cps->drc_status) {
832 status = cps->drc_status;

--- 47 unchanged lines hidden (view full) ---

880 return rpc_garbage_args;
881
882 if (hdr_arg.minorversion == 0) {
883 cps.clp = nfs4_find_client_ident(SVC_NET(rqstp), hdr_arg.cb_ident);
884 if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp))
885 return rpc_drop_reply;
886 }
887
824 preprocess_nfs4_op(op_nr, &op);
825 if (status == htonl(NFS4ERR_OP_ILLEGAL))
826 op_nr = OP_CB_ILLEGAL;
827 if (status)
828 goto encode_hdr;
829
830 if (cps->drc_status) {
831 status = cps->drc_status;

--- 47 unchanged lines hidden (view full) ---

879 return rpc_garbage_args;
880
881 if (hdr_arg.minorversion == 0) {
882 cps.clp = nfs4_find_client_ident(SVC_NET(rqstp), hdr_arg.cb_ident);
883 if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp))
884 return rpc_drop_reply;
885 }
886
887 cps.minorversion = hdr_arg.minorversion;
888 hdr_res.taglen = hdr_arg.taglen;
889 hdr_res.tag = hdr_arg.tag;
890 if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0)
891 return rpc_system_err;
892
893 while (status == 0 && nops != hdr_arg.nops) {
888 hdr_res.taglen = hdr_arg.taglen;
889 hdr_res.tag = hdr_arg.tag;
890 if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0)
891 return rpc_system_err;
892
893 while (status == 0 && nops != hdr_arg.nops) {
894 status = process_op(hdr_arg.minorversion, nops, rqstp,
895 &xdr_in, argp, &xdr_out, resp, &cps);
894 status = process_op(nops, rqstp, &xdr_in,
895 argp, &xdr_out, resp, &cps);
896 nops++;
897 }
898
899 /* Buffer overflow in decode_ops_hdr or encode_ops_hdr. Return
900 * resource error in cb_compound status without returning op */
901 if (unlikely(status == htonl(NFS4ERR_RESOURCE_HDR))) {
902 status = htonl(NFS4ERR_RESOURCE);
903 nops--;

--- 96 unchanged lines hidden ---
896 nops++;
897 }
898
899 /* Buffer overflow in decode_ops_hdr or encode_ops_hdr. Return
900 * resource error in cb_compound status without returning op */
901 if (unlikely(status == htonl(NFS4ERR_RESOURCE_HDR))) {
902 status = htonl(NFS4ERR_RESOURCE);
903 nops--;

--- 96 unchanged lines hidden ---