* [PATCH 1/2 v2] nfsd41: error out when client sets maxreq_sz or, maxresp_sz too small
@ 2011-07-02 9:01 Mi Jinlong
2011-07-06 16:26 ` J. Bruce Fields
0 siblings, 1 reply; 5+ messages in thread
From: Mi Jinlong @ 2011-07-02 9:01 UTC (permalink / raw)
To: J. Bruce Fields; +Cc: NFS
According to RFC5661, 18.36.3,
"if the client selects a value for ca_maxresponsesize such that
a replier on a channel could never send a response,the server
SHOULD return NFS4ERR_TOOSMALL in the CREATE_SESSION reply."
This patch let server error out when client sets maxreq_sz less than
SEQUENCE request size, and maxresp_sz less than a SEQUENCE reply size.
Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com>
---
fs/nfsd/nfs4xdr.c | 26 +++++++++++++++++++++++++-
1 files changed, 25 insertions(+), 1 deletions(-)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 9901811..bece272 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1135,11 +1135,25 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
{
DECODE_HEAD;
- u32 dummy;
+ struct xdr_buf *xb = &argp->rqstp->rq_arg;
+ u32 dummy, minreqlen = 0, minresplen = 0;
char *machine_name;
int i;
int nr_secflavs;
+ /* RPC header length and tag, minorversion, Opt count*/
+ minreqlen = (char *)argp->p - ((char *)argp->end - xb->len);
+ /* length with a SEQUENCE operation */
+ minreqlen = minreqlen + sizeof(struct nfs4_sessionid)
+ + 4 * sizeof(__be32);
+
+ /* RPC header, status, tag len */
+ minresplen = argp->rqstp->rq_res.head[0].iov_len + 2 * sizeof(__be32)
+ /* tag, opt count, opcode, op status */
+ + ALIGN(argp->taglen, 4) + 3 * sizeof(__be32)
+ /* sessionid, seqid, 3 * slotid, status*/
+ + sizeof(struct nfs4_sessionid) + 5 * sizeof(__be32);
+
READ_BUF(16);
COPYMEM(&sess->clientid, 8);
READ32(sess->seqid);
@@ -1149,7 +1163,17 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
READ_BUF(28);
READ32(dummy); /* headerpadsz is always 0 */
READ32(sess->fore_channel.maxreq_sz);
+ if (sess->fore_channel.maxreq_sz < minreqlen) {
+ status = nfserr_toosmall;
+ goto out;
+ }
+
READ32(sess->fore_channel.maxresp_sz);
+ if (sess->fore_channel.maxresp_sz < minresplen) {
+ status = nfserr_toosmall;
+ goto out;
+ }
+
READ32(sess->fore_channel.maxresp_cached);
READ32(sess->fore_channel.maxops);
READ32(sess->fore_channel.maxreqs);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2 v2] nfsd41: error out when client sets maxreq_sz or, maxresp_sz too small
2011-07-02 9:01 [PATCH 1/2 v2] nfsd41: error out when client sets maxreq_sz or, maxresp_sz too small Mi Jinlong
@ 2011-07-06 16:26 ` J. Bruce Fields
2011-07-09 3:44 ` [PATCH 1/2 v3] " Mi Jinlong
0 siblings, 1 reply; 5+ messages in thread
From: J. Bruce Fields @ 2011-07-06 16:26 UTC (permalink / raw)
To: Mi Jinlong; +Cc: NFS
On Sat, Jul 02, 2011 at 05:01:44PM +0800, Mi Jinlong wrote:
> According to RFC5661, 18.36.3,
>
> "if the client selects a value for ca_maxresponsesize such that
> a replier on a channel could never send a response,the server
> SHOULD return NFS4ERR_TOOSMALL in the CREATE_SESSION reply."
>
> This patch let server error out when client sets maxreq_sz less than
> SEQUENCE request size, and maxresp_sz less than a SEQUENCE reply size.
>
> Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com>
> ---
> fs/nfsd/nfs4xdr.c | 26 +++++++++++++++++++++++++-
> 1 files changed, 25 insertions(+), 1 deletions(-)
>
> diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
> index 9901811..bece272 100644
> --- a/fs/nfsd/nfs4xdr.c
> +++ b/fs/nfsd/nfs4xdr.c
> @@ -1135,11 +1135,25 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
> {
> DECODE_HEAD;
>
> - u32 dummy;
> + struct xdr_buf *xb = &argp->rqstp->rq_arg;
> + u32 dummy, minreqlen = 0, minresplen = 0;
> char *machine_name;
> int i;
> int nr_secflavs;
>
> + /* RPC header length and tag, minorversion, Opt count*/
> + minreqlen = (char *)argp->p - ((char *)argp->end - xb->len);
> + /* length with a SEQUENCE operation */
> + minreqlen = minreqlen + sizeof(struct nfs4_sessionid)
> + + 4 * sizeof(__be32);
> +
> + /* RPC header, status, tag len */
> + minresplen = argp->rqstp->rq_res.head[0].iov_len + 2 * sizeof(__be32)
> + /* tag, opt count, opcode, op status */
> + + ALIGN(argp->taglen, 4) + 3 * sizeof(__be32)
> + /* sessionid, seqid, 3 * slotid, status*/
> + + sizeof(struct nfs4_sessionid) + 5 * sizeof(__be32);
> +
Could you just calculate this as a constant, assuming the smallest
possible credential and verifier? NFSD_MIN_HDR_SEQ_SZ may be what you
need for the reply.
Calculating it dynamically here using the cred and verifier size from
the create_session request might be more accurate--or it might not, as
there's no guarantee the same size cred adn verifier will be used for
later rpc's.
But that's OK, our goal here isn't to get this 100% correct, as that's
not possible, it's just to add a sanity check that may help catch a
crazy client.
> READ_BUF(16);
> COPYMEM(&sess->clientid, 8);
> READ32(sess->seqid);
> @@ -1149,7 +1163,17 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
> READ_BUF(28);
> READ32(dummy); /* headerpadsz is always 0 */
> READ32(sess->fore_channel.maxreq_sz);
> + if (sess->fore_channel.maxreq_sz < minreqlen) {
> + status = nfserr_toosmall;
Have you checked whether that error actually gets back to the client?
I think it gets turned into a bad_xdr error at some point.
We probably want this in nfsd4_create_session instead.
--b.
> + goto out;
> + }
> +
> READ32(sess->fore_channel.maxresp_sz);
> + if (sess->fore_channel.maxresp_sz < minresplen) {
> + status = nfserr_toosmall;
> + goto out;
> + }
> +
> READ32(sess->fore_channel.maxresp_cached);
> READ32(sess->fore_channel.maxops);
> READ32(sess->fore_channel.maxreqs);
> --
> 1.7.5.4
>
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2 v3] nfsd41: error out when client sets maxreq_sz or, maxresp_sz too small
2011-07-06 16:26 ` J. Bruce Fields
@ 2011-07-09 3:44 ` Mi Jinlong
2011-07-12 11:09 ` J. Bruce Fields
0 siblings, 1 reply; 5+ messages in thread
From: Mi Jinlong @ 2011-07-09 3:44 UTC (permalink / raw)
To: J. Bruce Fields; +Cc: NFS
According to RFC5661, 18.36.3,
"if the client selects a value for ca_maxresponsesize such that
a replier on a channel could never send a response,the server
SHOULD return NFS4ERR_TOOSMALL in the CREATE_SESSION reply."
This patch let server error out when client sets maxreq_sz less than
SEQUENCE request size, and maxresp_sz less than a SEQUENCE reply size.
v3:
use constant for min request size and min response size,
add two function for channel attrs checking(back channel checking
not be implement),
move size check from xdr create_session to nfsd4_create_session,
Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com>
---
fs/nfsd/nfs4state.c | 33 +++++++++++++++++++++++++++++++++
1 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index e98f3c2..e30bf37 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1507,6 +1507,34 @@ nfsd4_replay_create_session(struct nfsd4_create_session *cr_ses,
return slot->sl_status;
}
+#define NFSD_MIN_REQ_HDR_SEQ_SZ ((\
+ 2 * 2 + /* credential,verifier: AUTH_NULL, length 0 */ \
+ 1 + /* MIN tag is length with zero, only length */ \
+ 3 + /* version, opcount, opcode */ \
+ XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
+ /* seqid, slotID, slotID, cache */ \
+ 4 ) * sizeof(__be32))
+
+#define NFSD_MIN_RESP_HDR_SEQ_SZ ((\
+ 2 + /* verifier: AUTH_NULL, length 0 */\
+ 1 + /* status */ \
+ 1 + /* MIN tag is length with zero, only length */ \
+ 3 + /* opcount, opcode, opstatus*/ \
+ XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
+ /* seqid, slotID, slotID, slotID, status */ \
+ 5 ) * sizeof(__be32))
+
+static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs fchannel)
+{
+ return fchannel.maxreq_sz < NFSD_MIN_REQ_HDR_SEQ_SZ
+ || fchannel.maxresp_sz < NFSD_MIN_RESP_HDR_SEQ_SZ;
+}
+
+static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs bchannel)
+{
+ return 0;
+}
+
__be32
nfsd4_create_session(struct svc_rqst *rqstp,
struct nfsd4_compound_state *cstate,
@@ -1575,6 +1603,11 @@ nfsd4_create_session(struct svc_rqst *rqstp,
cr_ses->flags &= ~SESSION4_PERSIST;
cr_ses->flags &= ~SESSION4_RDMA;
+ status = nfserr_toosmall;
+ if (check_forechannel_attrs(cr_ses->fore_channel)
+ || check_backchannel_attrs(cr_ses->back_channel))
+ goto out;
+
status = nfserr_jukebox;
new = alloc_init_session(rqstp, conf, cr_ses);
if (!new)
--
1.7.5.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2 v3] nfsd41: error out when client sets maxreq_sz or, maxresp_sz too small
2011-07-09 3:44 ` [PATCH 1/2 v3] " Mi Jinlong
@ 2011-07-12 11:09 ` J. Bruce Fields
2011-07-14 6:50 ` [PATCH 1/2 v4] " Mi Jinlong
0 siblings, 1 reply; 5+ messages in thread
From: J. Bruce Fields @ 2011-07-12 11:09 UTC (permalink / raw)
To: Mi Jinlong; +Cc: NFS
On Sat, Jul 09, 2011 at 11:44:12AM +0800, Mi Jinlong wrote:
> According to RFC5661, 18.36.3,
>
> "if the client selects a value for ca_maxresponsesize such that
> a replier on a channel could never send a response,the server
> SHOULD return NFS4ERR_TOOSMALL in the CREATE_SESSION reply."
>
> This patch let server error out when client sets maxreq_sz less than
> SEQUENCE request size, and maxresp_sz less than a SEQUENCE reply size.
>
> v3:
> use constant for min request size and min response size,
> add two function for channel attrs checking(back channel checking
> not be implement),
> move size check from xdr create_session to nfsd4_create_session,
>
> Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com>
> ---
> fs/nfsd/nfs4state.c | 33 +++++++++++++++++++++++++++++++++
> 1 files changed, 33 insertions(+), 0 deletions(-)
>
> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> index e98f3c2..e30bf37 100644
> --- a/fs/nfsd/nfs4state.c
> +++ b/fs/nfsd/nfs4state.c
> @@ -1507,6 +1507,34 @@ nfsd4_replay_create_session(struct nfsd4_create_session *cr_ses,
> return slot->sl_status;
> }
>
> +#define NFSD_MIN_REQ_HDR_SEQ_SZ ((\
> + 2 * 2 + /* credential,verifier: AUTH_NULL, length 0 */ \
> + 1 + /* MIN tag is length with zero, only length */ \
> + 3 + /* version, opcount, opcode */ \
> + XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
> + /* seqid, slotID, slotID, cache */ \
> + 4 ) * sizeof(__be32))
> +
> +#define NFSD_MIN_RESP_HDR_SEQ_SZ ((\
> + 2 + /* verifier: AUTH_NULL, length 0 */\
> + 1 + /* status */ \
> + 1 + /* MIN tag is length with zero, only length */ \
> + 3 + /* opcount, opcode, opstatus*/ \
> + XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
> + /* seqid, slotID, slotID, slotID, status */ \
> + 5 ) * sizeof(__be32))
> +
> +static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs fchannel)
> +{
> + return fchannel.maxreq_sz < NFSD_MIN_REQ_HDR_SEQ_SZ
> + || fchannel.maxresp_sz < NFSD_MIN_RESP_HDR_SEQ_SZ;
> +}
> +
> +static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs bchannel)
> +{
> + return 0;
> +}
Let's not bother with check_backchannel_attrs() until it actually does
something.
Other than that, this looks fine.--b.
> +
> __be32
> nfsd4_create_session(struct svc_rqst *rqstp,
> struct nfsd4_compound_state *cstate,
> @@ -1575,6 +1603,11 @@ nfsd4_create_session(struct svc_rqst *rqstp,
> cr_ses->flags &= ~SESSION4_PERSIST;
> cr_ses->flags &= ~SESSION4_RDMA;
>
> + status = nfserr_toosmall;
> + if (check_forechannel_attrs(cr_ses->fore_channel)
> + || check_backchannel_attrs(cr_ses->back_channel))
> + goto out;
> +
> status = nfserr_jukebox;
> new = alloc_init_session(rqstp, conf, cr_ses);
> if (!new)
> --
> 1.7.5.4
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2 v4] nfsd41: error out when client sets maxreq_sz or, maxresp_sz too small
2011-07-12 11:09 ` J. Bruce Fields
@ 2011-07-14 6:50 ` Mi Jinlong
0 siblings, 0 replies; 5+ messages in thread
From: Mi Jinlong @ 2011-07-14 6:50 UTC (permalink / raw)
To: J. Bruce Fields; +Cc: NFS
According to RFC5661, 18.36.3,
"if the client selects a value for ca_maxresponsesize such that
a replier on a channel could never send a response,the server
SHOULD return NFS4ERR_TOOSMALL in the CREATE_SESSION reply."
This patch let server error out when client sets maxreq_sz less than
SEQUENCE request size, and maxresp_sz less than a SEQUENCE reply size.
v4:
Bruce said "Let's not bother with check_backchannel_attrs()
until it actually does something.". So delete the function,
only check fore channel attr.
v3:
use constant for min request size and min response size,
add two function for channel attrs checking(back channel checking
not be implement),
move size check from xdr create_session to nfsd4_create_session,
Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com>
---
fs/nfsd/nfs4state.c | 27 +++++++++++++++++++++++++++
1 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index e98f3c2..72899ec 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1507,6 +1507,29 @@ nfsd4_replay_create_session(struct nfsd4_create_session *cr_ses,
return slot->sl_status;
}
+#define NFSD_MIN_REQ_HDR_SEQ_SZ ((\
+ 2 * 2 + /* credential,verifier: AUTH_NULL, length 0 */ \
+ 1 + /* MIN tag is length with zero, only length */ \
+ 3 + /* version, opcount, opcode */ \
+ XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
+ /* seqid, slotID, slotID, cache */ \
+ 4 ) * sizeof(__be32))
+
+#define NFSD_MIN_RESP_HDR_SEQ_SZ ((\
+ 2 + /* verifier: AUTH_NULL, length 0 */\
+ 1 + /* status */ \
+ 1 + /* MIN tag is length with zero, only length */ \
+ 3 + /* opcount, opcode, opstatus*/ \
+ XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
+ /* seqid, slotID, slotID, slotID, status */ \
+ 5 ) * sizeof(__be32))
+
+static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs fchannel)
+{
+ return fchannel.maxreq_sz < NFSD_MIN_REQ_HDR_SEQ_SZ
+ || fchannel.maxresp_sz < NFSD_MIN_RESP_HDR_SEQ_SZ;
+}
+
__be32
nfsd4_create_session(struct svc_rqst *rqstp,
struct nfsd4_compound_state *cstate,
@@ -1575,6 +1598,10 @@ nfsd4_create_session(struct svc_rqst *rqstp,
cr_ses->flags &= ~SESSION4_PERSIST;
cr_ses->flags &= ~SESSION4_RDMA;
+ status = nfserr_toosmall;
+ if (check_forechannel_attrs(cr_ses->fore_channel))
+ goto out;
+
status = nfserr_jukebox;
new = alloc_init_session(rqstp, conf, cr_ses);
if (!new)
--
1.7.5.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-07-14 6:48 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-02 9:01 [PATCH 1/2 v2] nfsd41: error out when client sets maxreq_sz or, maxresp_sz too small Mi Jinlong
2011-07-06 16:26 ` J. Bruce Fields
2011-07-09 3:44 ` [PATCH 1/2 v3] " Mi Jinlong
2011-07-12 11:09 ` J. Bruce Fields
2011-07-14 6:50 ` [PATCH 1/2 v4] " Mi Jinlong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).