mirror of
https://git.yoctoproject.org/poky
synced 2026-09-12 06:49:32 +02:00
p11-kit: Fix CVE-2026-13757
Pick patch according to [2] [1] https://nvd.nist.gov/vuln/detail/cve-2026-13757 [2] https://ubuntu.com/security/CVE-2026-13757 (From OE-Core rev: 1233224dcb13924b1366775a71fdf0ce72e3a589) Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> Signed-off-by: Yoann Congal <yoann.congal@smile.fr> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
abef4d0701
commit
c71dd3cb0d
265
meta/recipes-support/p11-kit/files/CVE-2026-13757.patch
Normal file
265
meta/recipes-support/p11-kit/files/CVE-2026-13757.patch
Normal file
@@ -0,0 +1,265 @@
|
||||
From 0eedd4ddd7c924f9cbb4ac496b3fda699435c3cf Mon Sep 17 00:00:00 2001
|
||||
From: Zoltan Fridrich <zfridric@redhat.com>
|
||||
Date: Thu, 2 Jul 2026 10:54:47 +0200
|
||||
Subject: [PATCH] rpc: add recursion depth limit into RPC attribute parsing
|
||||
(CVE-2026-13757)
|
||||
|
||||
A DoS was possible when client sent request to a server with deeply
|
||||
nested attributes causing stack exhaustion on the server.
|
||||
This patch adds a recursion limit on all server entry points to
|
||||
prevent such attacks.
|
||||
|
||||
Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
|
||||
|
||||
Upstream-Status: Backport [import from ubuntu p11-kit_0.25.3-4ubuntu2.2.debian.tar.xz
|
||||
Upstream commit https://github.com/p11-glue/p11-kit/commit/0eedd4ddd7c924f9cbb4ac496b3fda699435c3cf]
|
||||
CVE: CVE-2026-13757
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
p11-kit/rpc-message.c | 39 +++++++++++++++++++++++++++++++++-----
|
||||
p11-kit/rpc-message.h | 10 +++++++++-
|
||||
p11-kit/test-rpc-message.c | 39 ++++++++++++++++++++++++++++++++++++--
|
||||
p11-kit/test-rpc.c | 27 ++++++++++++++++++++++++++
|
||||
4 files changed, 107 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/p11-kit/rpc-message.c b/p11-kit/rpc-message.c
|
||||
index 09d7f33..d6f0aad 100644
|
||||
--- a/p11-kit/rpc-message.c
|
||||
+++ b/p11-kit/rpc-message.c
|
||||
@@ -903,6 +903,15 @@ map_attribute_to_value_type (CK_ATTRIBUTE_TYPE type)
|
||||
}
|
||||
}
|
||||
|
||||
+static bool
|
||||
+p11_rpc_buffer_get_attribute_array_value_wrapper (p11_buffer *buffer,
|
||||
+ size_t *offset,
|
||||
+ void *value,
|
||||
+ CK_ULONG *value_length)
|
||||
+{
|
||||
+ return p11_rpc_buffer_get_attribute_array_value (buffer, offset, value, value_length, 0);
|
||||
+}
|
||||
+
|
||||
typedef struct {
|
||||
p11_rpc_value_type type;
|
||||
p11_rpc_value_encoder encode;
|
||||
@@ -912,7 +921,7 @@ typedef struct {
|
||||
static p11_rpc_attribute_serializer p11_rpc_attribute_serializers[] = {
|
||||
{ P11_RPC_VALUE_BYTE, p11_rpc_buffer_add_byte_value, p11_rpc_buffer_get_byte_value },
|
||||
{ P11_RPC_VALUE_ULONG, p11_rpc_buffer_add_ulong_value, p11_rpc_buffer_get_ulong_value },
|
||||
- { P11_RPC_VALUE_ATTRIBUTE_ARRAY, p11_rpc_buffer_add_attribute_array_value, p11_rpc_buffer_get_attribute_array_value },
|
||||
+ { P11_RPC_VALUE_ATTRIBUTE_ARRAY, p11_rpc_buffer_add_attribute_array_value, p11_rpc_buffer_get_attribute_array_value_wrapper },
|
||||
{ P11_RPC_VALUE_MECHANISM_TYPE_ARRAY, p11_rpc_buffer_add_mechanism_type_array_value, p11_rpc_buffer_get_mechanism_type_array_value },
|
||||
{ P11_RPC_VALUE_DATE, p11_rpc_buffer_add_date_value, p11_rpc_buffer_get_date_value },
|
||||
{ P11_RPC_VALUE_BYTE_ARRAY, p11_rpc_buffer_add_byte_array_value, p11_rpc_buffer_get_byte_array_value }
|
||||
@@ -1142,7 +1151,8 @@ bool
|
||||
p11_rpc_buffer_get_attribute_array_value (p11_buffer *buffer,
|
||||
size_t *offset,
|
||||
void *value,
|
||||
- CK_ULONG *value_length)
|
||||
+ CK_ULONG *value_length,
|
||||
+ size_t depth)
|
||||
{
|
||||
uint32_t count, i;
|
||||
CK_ATTRIBUTE *attr, temp;
|
||||
@@ -1157,7 +1167,7 @@ p11_rpc_buffer_get_attribute_array_value (p11_buffer *buffer,
|
||||
attr = value;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
- if (!p11_rpc_buffer_get_attribute (buffer, offset, attr))
|
||||
+ if (!p11_rpc_buffer_get_attribute_recursive (buffer, offset, attr, depth))
|
||||
return false;
|
||||
if (value)
|
||||
attr++;
|
||||
@@ -1255,12 +1265,26 @@ bool
|
||||
p11_rpc_buffer_get_attribute (p11_buffer *buffer,
|
||||
size_t *offset,
|
||||
CK_ATTRIBUTE *attr)
|
||||
+{
|
||||
+ return p11_rpc_buffer_get_attribute_recursive (buffer, offset, attr, 0);
|
||||
+}
|
||||
+
|
||||
+bool
|
||||
+p11_rpc_buffer_get_attribute_recursive (p11_buffer *buffer,
|
||||
+ size_t *offset,
|
||||
+ CK_ATTRIBUTE *attr,
|
||||
+ size_t depth)
|
||||
{
|
||||
uint32_t type, length, decode_length;
|
||||
unsigned char validity;
|
||||
p11_rpc_attribute_serializer *serializer;
|
||||
p11_rpc_value_type value_type;
|
||||
|
||||
+ if (depth > P11_RPC_MAX_RECURSION_DEPTH) {
|
||||
+ p11_debug ("recursion depth limit reached");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
/* The attribute type */
|
||||
if (!p11_rpc_buffer_get_uint32 (buffer, offset, &type))
|
||||
return false;
|
||||
@@ -1284,8 +1308,13 @@ p11_rpc_buffer_get_attribute (p11_buffer *buffer,
|
||||
assert (value_type < ELEMS (p11_rpc_attribute_serializers));
|
||||
serializer = &p11_rpc_attribute_serializers[value_type];
|
||||
assert (serializer != NULL);
|
||||
- if (!serializer->decode (buffer, offset, attr->pValue, &attr->ulValueLen))
|
||||
- return false;
|
||||
+ if (value_type == P11_RPC_VALUE_ATTRIBUTE_ARRAY) {
|
||||
+ if (!p11_rpc_buffer_get_attribute_array_value (buffer, offset, attr->pValue, &attr->ulValueLen, depth + 1))
|
||||
+ return false;
|
||||
+ } else {
|
||||
+ if (!serializer->decode (buffer, offset, attr->pValue, &attr->ulValueLen))
|
||||
+ return false;
|
||||
+ }
|
||||
if (!attr->pValue) {
|
||||
decode_length = attr->ulValueLen;
|
||||
attr->ulValueLen = length;
|
||||
diff --git a/p11-kit/rpc-message.h b/p11-kit/rpc-message.h
|
||||
index f171fc4..671a60d 100644
|
||||
--- a/p11-kit/rpc-message.h
|
||||
+++ b/p11-kit/rpc-message.h
|
||||
@@ -44,6 +44,8 @@
|
||||
#include "pkcs11.h"
|
||||
#include "pkcs11x.h"
|
||||
|
||||
+#define P11_RPC_MAX_RECURSION_DEPTH 8
|
||||
+
|
||||
/* The calls, must be in sync with array below */
|
||||
enum {
|
||||
P11_RPC_CALL_ERROR = 0,
|
||||
@@ -441,6 +443,11 @@ bool p11_rpc_buffer_get_attribute (p11_buffer *buffer,
|
||||
size_t *offset,
|
||||
CK_ATTRIBUTE *attr);
|
||||
|
||||
+bool p11_rpc_buffer_get_attribute_recursive (p11_buffer *buffer,
|
||||
+ size_t *offset,
|
||||
+ CK_ATTRIBUTE *attr,
|
||||
+ size_t depth);
|
||||
+
|
||||
void p11_rpc_buffer_add_byte_value (p11_buffer *buffer,
|
||||
const void *value,
|
||||
CK_ULONG value_length);
|
||||
@@ -468,7 +475,8 @@ bool p11_rpc_buffer_get_attribute_array_value
|
||||
(p11_buffer *buffer,
|
||||
size_t *offset,
|
||||
void *value,
|
||||
- CK_ULONG *value_length);
|
||||
+ CK_ULONG *value_length,
|
||||
+ size_t depth);
|
||||
|
||||
void p11_rpc_buffer_add_mechanism_type_array_value
|
||||
(p11_buffer *buffer,
|
||||
diff --git a/p11-kit/test-rpc-message.c b/p11-kit/test-rpc-message.c
|
||||
index 4c11ea5..f00f2f1 100644
|
||||
--- a/p11-kit/test-rpc-message.c
|
||||
+++ b/p11-kit/test-rpc-message.c
|
||||
@@ -594,11 +594,11 @@ test_attribute_array_value (void)
|
||||
assert (!p11_buffer_failed (&buffer));
|
||||
|
||||
offset2 = offset;
|
||||
- ret = p11_rpc_buffer_get_attribute_array_value(&buffer, &offset, NULL, &val_size);
|
||||
+ ret = p11_rpc_buffer_get_attribute_array_value(&buffer, &offset, NULL, &val_size, 0);
|
||||
assert_num_eq (true, ret);
|
||||
|
||||
offset = offset2;
|
||||
- ret = p11_rpc_buffer_get_attribute_array_value(&buffer, &offset, val, &val_size);
|
||||
+ ret = p11_rpc_buffer_get_attribute_array_value(&buffer, &offset, val, &val_size, 0);
|
||||
assert_num_eq (true, ret);
|
||||
assert_num_eq (val[0].type, CKA_MODIFIABLE);
|
||||
assert_num_eq (*(CK_BBOOL *)val[0].pValue, CK_TRUE);
|
||||
@@ -806,6 +806,40 @@ test_message_write (void)
|
||||
p11_buffer_uninit (&buffer);
|
||||
}
|
||||
|
||||
+static void
|
||||
+test_attribute_recursion_limit (void)
|
||||
+{
|
||||
+ bool ret;
|
||||
+ p11_buffer buffer;
|
||||
+ size_t offset = 0;
|
||||
+ CK_BBOOL truev = CK_TRUE;
|
||||
+ CK_ATTRIBUTE attrs_out;
|
||||
+ CK_ATTRIBUTE attrs[P11_RPC_MAX_RECURSION_DEPTH + 2];
|
||||
+ for (size_t i = 0; i <= P11_RPC_MAX_RECURSION_DEPTH; i++) {
|
||||
+ attrs[i].type = CKA_WRAP_TEMPLATE;
|
||||
+ attrs[i].pValue = &attrs[i + 1];
|
||||
+ attrs[i].ulValueLen = sizeof (CK_ATTRIBUTE);
|
||||
+ }
|
||||
+ attrs[P11_RPC_MAX_RECURSION_DEPTH + 1].type = CKA_ENCRYPT;
|
||||
+ attrs[P11_RPC_MAX_RECURSION_DEPTH + 1].pValue = &truev;
|
||||
+ attrs[P11_RPC_MAX_RECURSION_DEPTH + 1].ulValueLen = sizeof (CK_BBOOL);
|
||||
+
|
||||
+ ret = p11_buffer_init (&buffer, 0);
|
||||
+ assert_num_eq (true, ret);
|
||||
+ p11_rpc_buffer_add_attribute_array_value (&buffer, attrs, ELEMS(attrs));
|
||||
+ assert_num_eq (true, !p11_buffer_failed (&buffer));
|
||||
+
|
||||
+ /* Skip the array count */
|
||||
+ ret = p11_rpc_buffer_get_uint32(&buffer, &offset, NULL);
|
||||
+ assert_num_eq (true, ret);
|
||||
+
|
||||
+ /* Hit recursion limit */
|
||||
+ ret = p11_rpc_buffer_get_attribute(&buffer, &offset, &attrs_out);
|
||||
+ assert_num_eq (false, ret);
|
||||
+
|
||||
+ p11_buffer_uninit (&buffer);
|
||||
+}
|
||||
+
|
||||
#include "test-mock.c"
|
||||
|
||||
static CK_MECHANISM_TYPE mechanisms[] = {
|
||||
@@ -848,6 +882,7 @@ main (int argc,
|
||||
p11_test (test_byte_array_value, "/rpc-message/byte-array-value");
|
||||
p11_test (test_mechanism_value, "/rpc-message/mechanism-value");
|
||||
p11_test (test_message_write, "/rpc-message/message-write");
|
||||
+ p11_test (test_attribute_recursion_limit, "/rpc-message/attribute-recursion-limit");
|
||||
|
||||
test_mock_add_tests ("/rpc-message", NULL);
|
||||
|
||||
diff --git a/p11-kit/test-rpc.c b/p11-kit/test-rpc.c
|
||||
index f214509..6059b89 100644
|
||||
--- a/p11-kit/test-rpc.c
|
||||
+++ b/p11-kit/test-rpc.c
|
||||
@@ -700,6 +700,32 @@ test_mechanism_unsupported (void *module)
|
||||
teardown_mock_module (rpc_module);
|
||||
}
|
||||
|
||||
+static void
|
||||
+test_recursion_limit (void *module)
|
||||
+{
|
||||
+ CK_FUNCTION_LIST_PTR rpc_module;
|
||||
+ CK_SESSION_HANDLE session;
|
||||
+ CK_RV rv;
|
||||
+ CK_BBOOL val;
|
||||
+ CK_ATTRIBUTE attrs[P11_RPC_MAX_RECURSION_DEPTH + 2];
|
||||
+ for (size_t i = 0; i <= P11_RPC_MAX_RECURSION_DEPTH; i++) {
|
||||
+ attrs[i].type = CKA_WRAP_TEMPLATE;
|
||||
+ attrs[i].pValue = &attrs[i + 1];
|
||||
+ attrs[i].ulValueLen = sizeof (CK_ATTRIBUTE);
|
||||
+ }
|
||||
+ attrs[P11_RPC_MAX_RECURSION_DEPTH + 1].type = CKA_ENCRYPT;
|
||||
+ attrs[P11_RPC_MAX_RECURSION_DEPTH + 1].pValue = &val;
|
||||
+ attrs[P11_RPC_MAX_RECURSION_DEPTH + 1].ulValueLen = sizeof (CK_BBOOL);
|
||||
+
|
||||
+ rpc_module = setup_test_rpc_module (&test_normal_vtable, module, &session);
|
||||
+
|
||||
+ /* Hit recursion limit */
|
||||
+ rv = (rpc_module->C_GetAttributeValue) (session, MOCK_PUBLIC_KEY_PREFIX, attrs, 1);
|
||||
+ assert_num_eq (rv, CKR_DEVICE_ERROR);
|
||||
+
|
||||
+ teardown_mock_module (rpc_module);
|
||||
+}
|
||||
+
|
||||
#ifdef OS_UNIX
|
||||
|
||||
static void
|
||||
@@ -805,6 +831,7 @@ main (int argc,
|
||||
p11_testx (test_get_slot_list_no_device, &mock_module_v3_no_slots, "/rpc3/get-slot-list-no-device");
|
||||
p11_testx (test_simultaneous_functions, &mock_module_v3_no_slots, "/rpc3/simultaneous-functions");
|
||||
p11_testx (test_mechanism_unsupported, &mock_module_v3, "/rpc3/mechanism-unsupported");
|
||||
+ p11_testx (test_recursion_limit, &mock_module_v3, "/rpc3/recursion-limit");
|
||||
|
||||
#ifdef OS_UNIX
|
||||
p11_testx (test_fork_and_reinitialize, &mock_module_v3_no_slots, "/rpc3/fork-and-reinitialize");
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -12,6 +12,7 @@ DEPENDS:append = "${@' glib-2.0' if d.getVar('GTKDOC_ENABLED') == 'True' else ''
|
||||
|
||||
SRC_URI = "gitsm://github.com/p11-glue/p11-kit;branch=master;protocol=https \
|
||||
file://fix-parallel-build-failures.patch \
|
||||
file://CVE-2026-13757.patch \
|
||||
"
|
||||
SRCREV = "917e02a3211dabbdea4b079cb598581dce84fda1"
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
Reference in New Issue
Block a user