Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9507271d authored by Scott Mayhew's avatar Scott Mayhew Committed by J. Bruce Fields
Browse files

svcrpc: fix potential GSSX_ACCEPT_SEC_CONTEXT decoding failures



In an environment where the KDC is running Active Directory, the
exported composite name field returned in the context could be large
enough to span a page boundary.  Attaching a scratch buffer to the
decoding xdr_stream helps deal with those cases.

The case where we saw this was actually due to behavior that's been
fixed in newer gss-proxy versions, but we're fixing it here too.

Signed-off-by: default avatarScott Mayhew <smayhew@redhat.com>
Cc: stable@vger.kernel.org
Reviewed-by: default avatarSimo Sorce <simo@redhat.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 8287f009
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -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;
}