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

Commit bfa9d86d authored by Zhipeng Lu's avatar Zhipeng Lu Committed by Sasha Levin
Browse files

SUNRPC: fix some memleaks in gssx_dec_option_array



[ Upstream commit 3cfcfc102a5e57b021b786a755a38935e357797d ]

The creds and oa->data need to be freed in the error-handling paths after
their allocation. So this patch add these deallocations in the
corresponding paths.

Fixes: 1d658336 ("SUNRPC: Add RPC based upcall mechanism for RPCGSS auth")
Signed-off-by: default avatarZhipeng Lu <alexious@zju.edu.cn>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 52018aa1
Loading
Loading
Loading
Loading
+19 −8
Original line number Diff line number Diff line
@@ -250,8 +250,8 @@ static int gssx_dec_option_array(struct xdr_stream *xdr,

	creds = kzalloc(sizeof(struct svc_cred), GFP_KERNEL);
	if (!creds) {
		kfree(oa->data);
		return -ENOMEM;
		err = -ENOMEM;
		goto free_oa;
	}

	oa->data[0].option.data = CREDS_VALUE;
@@ -265,29 +265,40 @@ static int gssx_dec_option_array(struct xdr_stream *xdr,

		/* option buffer */
		p = xdr_inline_decode(xdr, 4);
		if (unlikely(p == NULL))
			return -ENOSPC;
		if (unlikely(p == NULL)) {
			err = -ENOSPC;
			goto free_creds;
		}

		length = be32_to_cpup(p);
		p = xdr_inline_decode(xdr, length);
		if (unlikely(p == NULL))
			return -ENOSPC;
		if (unlikely(p == NULL)) {
			err = -ENOSPC;
			goto free_creds;
		}

		if (length == sizeof(CREDS_VALUE) &&
		    memcmp(p, CREDS_VALUE, sizeof(CREDS_VALUE)) == 0) {
			/* We have creds here. parse them */
			err = gssx_dec_linux_creds(xdr, creds);
			if (err)
				return err;
				goto free_creds;
			oa->data[0].value.len = 1; /* presence */
		} else {
			/* consume uninteresting buffer */
			err = gssx_dec_buffer(xdr, &dummy);
			if (err)
				return err;
				goto free_creds;
		}
	}
	return 0;

free_creds:
	kfree(creds);
free_oa:
	kfree(oa->data);
	oa->data = NULL;
	return err;
}

static int gssx_dec_status(struct xdr_stream *xdr,