From: Vincent JARDIN Date: Tue, 22 Oct 2019 21:44:44 +0000 (+0200) Subject: Fix RPC calls: ATTRIBUTE buf not null but length 0 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;p=p11-kit Fix RPC calls: ATTRIBUTE buf not null but length 0 Let's add a support for cases when the buffer != NULL but the length is 0. According to Oasis, buffer = NULL and length = 0 means a query of the length so the subsequent calls with a buffer != NULL should fill then buffer when length is long enough. If not, according to Oasis, one should get a CKR_BUFFER_TOO_SMALL. See the previous commit for IN_ULONG_BUFFER(). This patch is follow a similar design pattern. Fix: issue #257 --- diff --git a/p11-kit/rpc-message.c b/p11-kit/rpc-message.c index 3039a3d..1f8fbc2 100644 --- a/p11-kit/rpc-message.c +++ b/p11-kit/rpc-message.c @@ -241,14 +241,20 @@ p11_rpc_message_write_attribute_buffer (p11_rpc_message *msg, /* Write the number of items */ p11_rpc_buffer_add_uint32 (msg->output, num); + /* Is arr not null ? */ + p11_rpc_buffer_add_byte (msg->output, arr ? 0 : 1); + for (i = 0; i < num; ++i) { attr = &(arr[i]); /* The attribute type */ p11_rpc_buffer_add_uint32 (msg->output, attr->type); + /* rpc_server.c:value_is_null, is the value buffer not NULL ? */ + p11_rpc_buffer_add_byte (msg->output, attr->pValue ? 0 : 1); + /* And the attribute buffer length */ - p11_rpc_buffer_add_uint32 (msg->output, attr->pValue ? attr->ulValueLen : 0); + p11_rpc_buffer_add_uint32 (msg->output, attr->ulValueLen); } return !p11_buffer_failed (msg->output); diff --git a/p11-kit/rpc-server.c b/p11-kit/rpc-server.c index 764ad34..297d2e7 100644 --- a/p11-kit/rpc-server.c +++ b/p11-kit/rpc-server.c @@ -237,6 +237,7 @@ proto_read_attribute_buffer (p11_rpc_message *msg, { CK_ATTRIBUTE_PTR attrs; uint32_t n_attrs, i; + uint8_t attrs_is_null; uint32_t value; assert (msg != NULL); @@ -251,6 +252,16 @@ proto_read_attribute_buffer (p11_rpc_message *msg, if (!p11_rpc_buffer_get_uint32 (msg->input, &msg->parsed, &n_attrs)) return PARSE_ERROR; + /* Is attrs pointer null or not ? */ + if (!p11_rpc_buffer_get_byte (msg->input, &msg->parsed, &attrs_is_null)) + return PARSE_ERROR; + + if (attrs_is_null) { + *result = NULL; + *n_result = n_attrs; + return CKR_OK; + } + /* Allocate memory for the attribute structures */ attrs = p11_rpc_message_alloc_extra (msg, n_attrs * sizeof (CK_ATTRIBUTE)); if (attrs == NULL) @@ -258,6 +269,7 @@ proto_read_attribute_buffer (p11_rpc_message *msg, /* Now go through and fill in each one */ for (i = 0; i < n_attrs; ++i) { + uint8_t value_is_null; /* The attribute type */ if (!p11_rpc_buffer_get_uint32 (msg->input, &msg->parsed, &value)) @@ -265,18 +277,22 @@ proto_read_attribute_buffer (p11_rpc_message *msg, attrs[i].type = value; + /* Is the value buffer not NULL ? */ + if (!p11_rpc_buffer_get_byte (msg->input, &msg->parsed, &value_is_null)) + return PARSE_ERROR; + /* The number of bytes to allocate */ if (!p11_rpc_buffer_get_uint32 (msg->input, &msg->parsed, &value)) return PARSE_ERROR; - if (value == 0) { + attrs[i].ulValueLen = value; + + if (value_is_null) { attrs[i].pValue = NULL; - attrs[i].ulValueLen = 0; } else { attrs[i].pValue = p11_rpc_message_alloc_extra (msg, value); if (!attrs[i].pValue) return CKR_DEVICE_MEMORY; - attrs[i].ulValueLen = value; } }