File 0009-rpc-Handle-special-cases-for-buffer-and-length.patch of Package p11-kit.31290

From e192374d08d5fbbfabad3fbe8913e775fbb8629e Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Fri, 8 Apr 2022 14:39:35 +0200
Subject: [PATCH 09/11] rpc: Handle special cases for buffer and length

When the buffer is not NULL, but the length is zero then treat this as an
empty message. Serialize this in a special way so that the server can
restore the same situation.

Example: Terminate an operation via C_XxxFinal, but there is no more
data for the final part. A call to C_XxxFinal with buffer=NULL and length=0
would be treated as a size query, and would not terminate the operation.
So the way to terminate the operation without more data is to specify
buffer!=NULL but length=0.

When sending a byte array, and the buffer is NULL, and the length is
zero, don't treat this is invalid, but as empty message.

Example: C_XxxUpdate with an empty message.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
 p11-kit/rpc-client.c  | 2 +-
 p11-kit/rpc-message.c | 2 +-
 p11-kit/rpc-server.c  | 6 ++++++
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/p11-kit/rpc-client.c b/p11-kit/rpc-client.c
index 550ebd2..a6816ea 100644
--- a/p11-kit/rpc-client.c
+++ b/p11-kit/rpc-client.c
@@ -570,7 +570,7 @@ proto_read_sesssion_info (p11_rpc_message *msg,
 #define IN_BYTE_BUFFER(arr, len) \
 	if (len == NULL) \
 		{ _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \
-	if (!p11_rpc_message_write_byte_buffer (&_msg, arr ? *len : 0)) \
+	if (!p11_rpc_message_write_byte_buffer (&_msg, arr ? (*len > 0 ? *len : (uint32_t)-1) : 0)) \
 		{ _ret = CKR_HOST_MEMORY; goto _cleanup; }
 
 #define IN_BYTE_ARRAY(arr, len) \
diff --git a/p11-kit/rpc-message.c b/p11-kit/rpc-message.c
index c3f1dbb..960b218 100644
--- a/p11-kit/rpc-message.c
+++ b/p11-kit/rpc-message.c
@@ -372,7 +372,7 @@ p11_rpc_message_write_byte_array (p11_rpc_message *msg,
 	assert (!msg->signature || p11_rpc_message_verify_part (msg, "ay"));
 
 	/* No array, no data, just length */
-	if (!arr) {
+	if (!arr && num != 0) {
 		p11_rpc_buffer_add_byte (msg->output, 0);
 		p11_rpc_buffer_add_uint32 (msg->output, num);
 	} else {
diff --git a/p11-kit/rpc-server.c b/p11-kit/rpc-server.c
index dfdb76d..fb71ed9 100644
--- a/p11-kit/rpc-server.c
+++ b/p11-kit/rpc-server.c
@@ -84,6 +84,12 @@ proto_read_byte_buffer (p11_rpc_message *msg,
 	*n_buffer = length;
 	*buffer = NULL;
 
+	/* length = -1 indicates length = 0, but buffer not NULL */
+	if (length == (uint32_t)-1) {
+		*n_buffer = 0;
+		length = 1; /*allocate 1 dummy byte */
+	}
+
 	/* If set to zero, then they just want the length */
 	if (length == 0)
 		return CKR_OK;
-- 
2.38.1

openSUSE Build Service is sponsored by