]> granicus.if.org Git - p11-kit/commitdiff
Fix C_GetSlotList() when length is 0
authorVincent JARDIN <vjardin@free.fr>
Mon, 21 Oct 2019 21:20:37 +0000 (23:20 +0200)
committerDaiki Ueno <ueno@gnu.org>
Sun, 27 Oct 2019 06:28:53 +0000 (07:28 +0100)
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 buffer when length is long enough.
If not, according to Oasis, one should get a CKR_BUFFER_TOO_SMALL.

This current fix is for IN_ULONG_BUFFER(), same
should be applied for IN_BYTE_BUFFER() and for IN_ATTRIBUTE_BUFFER().

Include a test_no_slots()

Fix: issue #257

Suggested-by: Daiki Ueno <dueno@redhat.com>
p11-kit/rpc-client.c
p11-kit/rpc-message.c
p11-kit/rpc-message.h
p11-kit/rpc-server.c
p11-kit/test-server.c

index e202e37f0b5fe9d0de343c17b15482625cb47a08..7d7c2818a5eeeb22f73e49c325a32ed25a4580ac 100644 (file)
@@ -582,7 +582,7 @@ proto_read_sesssion_info (p11_rpc_message *msg,
 #define IN_ULONG_BUFFER(arr, len) \
        if (len == NULL) \
                { _ret = CKR_ARGUMENTS_BAD; goto _cleanup; } \
-       if (!p11_rpc_message_write_ulong_buffer (&_msg, arr ? *len : 0)) \
+       if (!p11_rpc_message_write_ulong_buffer (&_msg, arr, len)) \
                { _ret = CKR_HOST_MEMORY; goto _cleanup; }
 
 #define IN_ULONG_ARRAY(arr, len) \
index 672d1c7b8770e97f1a60fc7972469f986aa4ce0c..95bf6cee540ff1a7e25dbd735ec0b1b1910a8106 100644 (file)
@@ -372,14 +372,16 @@ p11_rpc_message_write_byte_array (p11_rpc_message *msg,
 
 bool
 p11_rpc_message_write_ulong_buffer (p11_rpc_message *msg,
-                                    CK_ULONG count)
+                                    CK_ULONG_PTR array,
+                                    CK_ULONG_PTR n_array)
 {
        assert (msg != NULL);
        assert (msg->output != NULL);
 
        /* Make sure this is in the right order */
        assert (!msg->signature || p11_rpc_message_verify_part (msg, "fu"));
-       p11_rpc_buffer_add_uint32 (msg->output, count);
+       p11_rpc_buffer_add_byte (msg->output, array ? 0 : 1);
+       p11_rpc_buffer_add_uint32 (msg->output, *n_array);
        return !p11_buffer_failed (msg->output);
 }
 
index 989bbc0cda665cd5fe2ada04e101c74331694f99..9e1fe0fed00e81e49ecfd893938a50c396f71cdc 100644 (file)
@@ -286,7 +286,8 @@ bool             p11_rpc_message_write_byte_array        (p11_rpc_message *msg,
                                                           CK_ULONG num);
 
 bool             p11_rpc_message_write_ulong_buffer      (p11_rpc_message *msg,
-                                                          CK_ULONG count);
+                                                          CK_ULONG_PTR array,
+                                                          CK_ULONG_PTR n_array);
 
 bool             p11_rpc_message_write_ulong_array       (p11_rpc_message *msg,
                                                           CK_ULONG_PTR arr,
index 846ee94e53bb82c278ee3db5a24f9eac5fa40af6..37c2c54b2bd0b92a52dbbb96db036dd2692bd50f 100644 (file)
@@ -166,6 +166,7 @@ proto_read_ulong_buffer (p11_rpc_message *msg,
                          CK_ULONG *n_buffer)
 {
        uint32_t length;
+       uint8_t buffer_is_null;
 
        assert (msg != NULL);
        assert (buffer != NULL);
@@ -175,6 +176,8 @@ proto_read_ulong_buffer (p11_rpc_message *msg,
        /* Check that we're supposed to be reading this at this point */
        assert (!msg->signature || p11_rpc_message_verify_part (msg, "fu"));
 
+       if (!p11_rpc_buffer_get_byte (msg->input, &msg->parsed, &buffer_is_null))
+               return PARSE_ERROR;
        /* The number of ulongs there's room for on the other end */
        if (!p11_rpc_buffer_get_uint32 (msg->input, &msg->parsed, &length))
                return PARSE_ERROR;
@@ -182,8 +185,8 @@ proto_read_ulong_buffer (p11_rpc_message *msg,
        *n_buffer = length;
        *buffer = NULL;
 
-       /* If set to zero, then they just want the length */
-       if (length == 0)
+       /* If buffer is NULL, the caller just wants the length */
+       if (buffer_is_null)
                return CKR_OK;
 
        *buffer = p11_rpc_message_alloc_extra (msg, length * sizeof (CK_ULONG));
index a1fbcb7b7cfc042ad9d8aa490bb1a166d2c0f720..a820f1591c7e4e68a44789789403559f3ba2bb7c 100644 (file)
@@ -264,6 +264,36 @@ test_open_session_write_protected (void *unused)
        p11_kit_module_release (module);
 }
 
+static void
+test_no_slots (void *unused)
+{
+       CK_FUNCTION_LIST_PTR module;
+       CK_SLOT_ID slots[32];
+       CK_ULONG count;
+       CK_RV rv;
+
+       module = p11_kit_module_load (P11_MODULE_PATH "/p11-kit-client" SHLEXT, 0);
+       assert (module != NULL);
+
+       rv = p11_kit_module_initialize (module);
+       assert (rv == CKR_OK);
+
+       count = 0;
+       rv = module->C_GetSlotList (CK_TRUE, NULL, &count);
+       assert (rv == CKR_OK);
+       assert_num_eq (0, count);
+
+       count = 0;
+       rv = module->C_GetSlotList (CK_TRUE, slots, &count);
+       assert (rv == CKR_OK);
+       assert_num_eq (0, count);
+
+       rv = p11_kit_module_finalize (module);
+       assert (rv == CKR_OK);
+
+       p11_kit_module_release (module);
+}
+
 int
 main (int argc,
       char *argv[])
@@ -283,6 +313,11 @@ main (int argc,
                "pkcs11:?write-protected=yes",
                1
        };
+       struct fixture with_no_slots = {
+               P11_MODULE_PATH "/mock-eight" SHLEXT,
+               "pkcs11:",
+               0
+       };
 
        p11_library_init ();
        mock_module_init ();
@@ -296,6 +331,7 @@ main (int argc,
        p11_testx (test_initialize, (void *)&without_provider, "/server/all/initialize");
        p11_testx (test_initialize_no_address, (void *)&without_provider, "/server/all/initialize-no-address");
        p11_testx (test_open_session, (void *)&without_provider, "/server/all/open-session");
+       p11_testx (test_no_slots, (void *)&with_no_slots, "/server/no-slots");
 
        return p11_test_run (argc, argv);
 }