diff options
Diffstat (limited to 'net/sunrpc/auth_gss/gss_rpc_xdr.c')
| -rw-r--r-- | net/sunrpc/auth_gss/gss_rpc_xdr.c | 23 | 
1 files changed, 16 insertions, 7 deletions
| diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c index 1ec19f6f0c2b..eeeba5adee6d 100644 --- a/net/sunrpc/auth_gss/gss_rpc_xdr.c +++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c @@ -793,20 +793,26 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,  {  	u32 value_follows;  	int err; +	struct page *scratch; + +	scratch = alloc_page(GFP_KERNEL); +	if (!scratch) +		return -ENOMEM; +	xdr_set_scratch_buffer(xdr, page_address(scratch), PAGE_SIZE);  	/* res->status */  	err = gssx_dec_status(xdr, &res->status);  	if (err) -		return err; +		goto out_free;  	/* res->context_handle */  	err = gssx_dec_bool(xdr, &value_follows);  	if (err) -		return err; +		goto out_free;  	if (value_follows) {  		err = gssx_dec_ctx(xdr, res->context_handle);  		if (err) -			return err; +			goto out_free;  	} else {  		res->context_handle = NULL;  	} @@ -814,11 +820,11 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,  	/* res->output_token */  	err = gssx_dec_bool(xdr, &value_follows);  	if (err) -		return err; +		goto out_free;  	if (value_follows) {  		err = gssx_dec_buffer(xdr, res->output_token);  		if (err) -			return err; +			goto out_free;  	} else {  		res->output_token = NULL;  	} @@ -826,14 +832,17 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp,  	/* res->delegated_cred_handle */  	err = gssx_dec_bool(xdr, &value_follows);  	if (err) -		return err; +		goto out_free;  	if (value_follows) {  		/* we do not support upcall servers sending this data. */ -		return -EINVAL; +		err = -EINVAL; +		goto out_free;  	}  	/* res->options */  	err = gssx_dec_option_array(xdr, &res->options); +out_free: +	__free_page(scratch);  	return err;  } |