nfsd4: check backchannel attributes on create_session
Make sure the client gives us an adequate backchannel. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
parent
55c760cfc4
commit
06b332a522
4 changed files with 52 additions and 24 deletions
|
@ -37,6 +37,7 @@
|
||||||
#include "nfsd.h"
|
#include "nfsd.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
#include "netns.h"
|
#include "netns.h"
|
||||||
|
#include "xdr4cb.h"
|
||||||
|
|
||||||
#define NFSDDBG_FACILITY NFSDDBG_PROC
|
#define NFSDDBG_FACILITY NFSDDBG_PROC
|
||||||
|
|
||||||
|
@ -53,30 +54,6 @@ enum {
|
||||||
NFSPROC4_CLNT_CB_SEQUENCE,
|
NFSPROC4_CLNT_CB_SEQUENCE,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NFS4_MAXTAGLEN 20
|
|
||||||
|
|
||||||
#define NFS4_enc_cb_null_sz 0
|
|
||||||
#define NFS4_dec_cb_null_sz 0
|
|
||||||
#define cb_compound_enc_hdr_sz 4
|
|
||||||
#define cb_compound_dec_hdr_sz (3 + (NFS4_MAXTAGLEN >> 2))
|
|
||||||
#define sessionid_sz (NFS4_MAX_SESSIONID_LEN >> 2)
|
|
||||||
#define cb_sequence_enc_sz (sessionid_sz + 4 + \
|
|
||||||
1 /* no referring calls list yet */)
|
|
||||||
#define cb_sequence_dec_sz (op_dec_sz + sessionid_sz + 4)
|
|
||||||
|
|
||||||
#define op_enc_sz 1
|
|
||||||
#define op_dec_sz 2
|
|
||||||
#define enc_nfs4_fh_sz (1 + (NFS4_FHSIZE >> 2))
|
|
||||||
#define enc_stateid_sz (NFS4_STATEID_SIZE >> 2)
|
|
||||||
#define NFS4_enc_cb_recall_sz (cb_compound_enc_hdr_sz + \
|
|
||||||
cb_sequence_enc_sz + \
|
|
||||||
1 + enc_stateid_sz + \
|
|
||||||
enc_nfs4_fh_sz)
|
|
||||||
|
|
||||||
#define NFS4_dec_cb_recall_sz (cb_compound_dec_hdr_sz + \
|
|
||||||
cb_sequence_dec_sz + \
|
|
||||||
op_dec_sz)
|
|
||||||
|
|
||||||
struct nfs4_cb_compound_hdr {
|
struct nfs4_cb_compound_hdr {
|
||||||
/* args */
|
/* args */
|
||||||
u32 ident; /* minorversion 0 only */
|
u32 ident; /* minorversion 0 only */
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <linux/sunrpc/svcauth_gss.h>
|
#include <linux/sunrpc/svcauth_gss.h>
|
||||||
#include <linux/sunrpc/addr.h>
|
#include <linux/sunrpc/addr.h>
|
||||||
#include "xdr4.h"
|
#include "xdr4.h"
|
||||||
|
#include "xdr4cb.h"
|
||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
#include "current_stateid.h"
|
#include "current_stateid.h"
|
||||||
|
|
||||||
|
@ -1794,6 +1795,27 @@ static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs *ca, struct nfs
|
||||||
return nfs_ok;
|
return nfs_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs *ca)
|
||||||
|
{
|
||||||
|
ca->headerpadsz = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These RPC_MAX_HEADER macros are overkill, especially since we
|
||||||
|
* don't even do gss on the backchannel yet. But this is still
|
||||||
|
* less than 1k. Tighten up this estimate in the unlikely event
|
||||||
|
* it turns out to be a problem for some client:
|
||||||
|
*/
|
||||||
|
if (ca->maxreq_sz < NFS4_enc_cb_recall_sz + RPC_MAX_HEADER_WITH_AUTH)
|
||||||
|
return nfserr_toosmall;
|
||||||
|
if (ca->maxresp_sz < NFS4_dec_cb_recall_sz + RPC_MAX_REPHEADER_WITH_AUTH)
|
||||||
|
return nfserr_toosmall;
|
||||||
|
ca->maxresp_cached = 0;
|
||||||
|
if (ca->maxops < 2)
|
||||||
|
return nfserr_toosmall;
|
||||||
|
|
||||||
|
return nfs_ok;
|
||||||
|
}
|
||||||
|
|
||||||
__be32
|
__be32
|
||||||
nfsd4_create_session(struct svc_rqst *rqstp,
|
nfsd4_create_session(struct svc_rqst *rqstp,
|
||||||
struct nfsd4_compound_state *cstate,
|
struct nfsd4_compound_state *cstate,
|
||||||
|
@ -1810,6 +1832,9 @@ nfsd4_create_session(struct svc_rqst *rqstp,
|
||||||
if (cr_ses->flags & ~SESSION4_FLAG_MASK_A)
|
if (cr_ses->flags & ~SESSION4_FLAG_MASK_A)
|
||||||
return nfserr_inval;
|
return nfserr_inval;
|
||||||
status = check_forechannel_attrs(&cr_ses->fore_channel, nn);
|
status = check_forechannel_attrs(&cr_ses->fore_channel, nn);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
status = check_backchannel_attrs(&cr_ses->back_channel);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
status = nfserr_jukebox;
|
status = nfserr_jukebox;
|
||||||
|
|
23
fs/nfsd/xdr4cb.h
Normal file
23
fs/nfsd/xdr4cb.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#define NFS4_MAXTAGLEN 20
|
||||||
|
|
||||||
|
#define NFS4_enc_cb_null_sz 0
|
||||||
|
#define NFS4_dec_cb_null_sz 0
|
||||||
|
#define cb_compound_enc_hdr_sz 4
|
||||||
|
#define cb_compound_dec_hdr_sz (3 + (NFS4_MAXTAGLEN >> 2))
|
||||||
|
#define sessionid_sz (NFS4_MAX_SESSIONID_LEN >> 2)
|
||||||
|
#define cb_sequence_enc_sz (sessionid_sz + 4 + \
|
||||||
|
1 /* no referring calls list yet */)
|
||||||
|
#define cb_sequence_dec_sz (op_dec_sz + sessionid_sz + 4)
|
||||||
|
|
||||||
|
#define op_enc_sz 1
|
||||||
|
#define op_dec_sz 2
|
||||||
|
#define enc_nfs4_fh_sz (1 + (NFS4_FHSIZE >> 2))
|
||||||
|
#define enc_stateid_sz (NFS4_STATEID_SIZE >> 2)
|
||||||
|
#define NFS4_enc_cb_recall_sz (cb_compound_enc_hdr_sz + \
|
||||||
|
cb_sequence_enc_sz + \
|
||||||
|
1 + enc_stateid_sz + \
|
||||||
|
enc_nfs4_fh_sz)
|
||||||
|
|
||||||
|
#define NFS4_dec_cb_recall_sz (cb_compound_dec_hdr_sz + \
|
||||||
|
cb_sequence_dec_sz + \
|
||||||
|
op_dec_sz)
|
|
@ -138,6 +138,9 @@ typedef __be32 rpc_fraghdr;
|
||||||
#define RPC_MAX_HEADER_WITH_AUTH \
|
#define RPC_MAX_HEADER_WITH_AUTH \
|
||||||
(RPC_CALLHDRSIZE + 2*(2+RPC_MAX_AUTH_SIZE/4))
|
(RPC_CALLHDRSIZE + 2*(2+RPC_MAX_AUTH_SIZE/4))
|
||||||
|
|
||||||
|
#define RPC_MAX_REPHEADER_WITH_AUTH \
|
||||||
|
(RPC_REPHDRSIZE + (2 + RPC_MAX_AUTH_SIZE/4))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RFC1833/RFC3530 rpcbind (v3+) well-known netid's.
|
* RFC1833/RFC3530 rpcbind (v3+) well-known netid's.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue