From 3e43e8b839b21753604bbe13847b0544e3e2464e Mon Sep 17 00:00:00 2001 From: gxcreator Date: Tue, 17 Feb 2026 01:39:40 +0100 Subject: [PATCH] fix(cred_mgmt): check array bounds when populating credentialId.transports --- src/fido/cbor_cred_mgmt.c | 3 +++ src/fido/cbor_get_assertion.c | 12 ++++++++++++ src/fido/cbor_make_credential.c | 9 +++++++++ src/fido/cbor_make_credential.h | 4 +++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/fido/cbor_cred_mgmt.c b/src/fido/cbor_cred_mgmt.c index 5d53db8..e8f347f 100644 --- a/src/fido/cbor_cred_mgmt.c +++ b/src/fido/cbor_cred_mgmt.c @@ -79,6 +79,9 @@ int cbor_cred_mgmt(const uint8_t *data, size_t len) { if (strcmp(_fd3, "transports") == 0) { CBOR_PARSE_ARRAY_START(_f3, 4) { + if (credentialId.transports_len >= MAX_TRANSPORT_COUNT) { + CBOR_ERROR(CTAP2_ERR_LIMIT_EXCEEDED); + } CBOR_FIELD_GET_TEXT(credentialId.transports[credentialId.transports_len], 4); credentialId.transports_len++; } diff --git a/src/fido/cbor_get_assertion.c b/src/fido/cbor_get_assertion.c index fac8e01..7c4d61a 100644 --- a/src/fido/cbor_get_assertion.c +++ b/src/fido/cbor_get_assertion.c @@ -124,6 +124,9 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { else if (val_u == 0x03) { // excludeList CBOR_PARSE_ARRAY_START(_f1, 2) { + if (allowList_len >= MAX_CREDENTIAL_COUNT_IN_LIST) { + CBOR_ERROR(CTAP2_ERR_LIMIT_EXCEEDED); + } PublicKeyCredentialDescriptor *pc = &allowList[allowList_len]; CBOR_PARSE_MAP_START(_f2, 3) { @@ -133,6 +136,9 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { if (strcmp(_fd3, "transports") == 0) { CBOR_PARSE_ARRAY_START(_f3, 4) { + if (pc->transports_len >= MAX_TRANSPORT_COUNT) { + CBOR_ERROR(CTAP2_ERR_LIMIT_EXCEEDED); + } CBOR_FIELD_GET_TEXT(pc->transports[pc->transports_len], 4); pc->transports_len++; } @@ -481,6 +487,9 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { } numberOfCredentialsx = numberOfCredentials; datax = (uint8_t *) calloc(1, len); + if (datax == NULL) { + CBOR_ERROR(CTAP1_ERR_OTHER); + } memcpy(datax, data, len); lenx = len; flagsx = flags; @@ -608,6 +617,9 @@ int cbor_get_assertion(const uint8_t *data, size_t len, bool next) { size_t aut_data_len = 32 + 1 + 4 + ext_len; aut_data = (uint8_t *) calloc(1, aut_data_len + clientDataHash.len); + if (aut_data == NULL) { + CBOR_ERROR(CTAP1_ERR_OTHER); + } uint8_t *pa = aut_data; memcpy(pa, rp_id_hash, 32); pa += 32; *pa++ = flags; diff --git a/src/fido/cbor_make_credential.c b/src/fido/cbor_make_credential.c index 25a5d41..5dc3797 100644 --- a/src/fido/cbor_make_credential.c +++ b/src/fido/cbor_make_credential.c @@ -92,6 +92,9 @@ int cbor_make_credential(const uint8_t *data, size_t len) { else if (val_u == 0x04) { // pubKeyCredParams CBOR_PARSE_ARRAY_START(_f1, 2) { + if (pubKeyCredParams_len >= MAX_CREDENTIAL_COUNT_IN_LIST) { + CBOR_ERROR(CTAP2_ERR_LIMIT_EXCEEDED); + } PublicKeyCredentialParameters *pk = &pubKeyCredParams[pubKeyCredParams_len]; CBOR_PARSE_MAP_START(_f2, 3) { @@ -107,6 +110,9 @@ int cbor_make_credential(const uint8_t *data, size_t len) { else if (val_u == 0x05) { // excludeList CBOR_PARSE_ARRAY_START(_f1, 2) { + if (excludeList_len >= MAX_CREDENTIAL_COUNT_IN_LIST) { + CBOR_ERROR(CTAP2_ERR_LIMIT_EXCEEDED); + } PublicKeyCredentialDescriptor *pc = &excludeList[excludeList_len]; CBOR_PARSE_MAP_START(_f2, 3) { @@ -116,6 +122,9 @@ int cbor_make_credential(const uint8_t *data, size_t len) { if (strcmp(_fd3, "transports") == 0) { CBOR_PARSE_ARRAY_START(_f3, 4) { + if (pc->transports_len >= MAX_TRANSPORT_COUNT) { + CBOR_ERROR(CTAP2_ERR_LIMIT_EXCEEDED); + } CBOR_FIELD_GET_TEXT(pc->transports[pc->transports_len], 4); pc->transports_len++; } diff --git a/src/fido/cbor_make_credential.h b/src/fido/cbor_make_credential.h index c66fd50..4e362b3 100644 --- a/src/fido/cbor_make_credential.h +++ b/src/fido/cbor_make_credential.h @@ -40,10 +40,12 @@ typedef struct PublicKeyCredentialParameters { int64_t alg; } PublicKeyCredentialParameters; +#define MAX_TRANSPORT_COUNT 8 + typedef struct PublicKeyCredentialDescriptor { CborCharString type; CborByteString id; - CborCharString transports[8]; + CborCharString transports[MAX_TRANSPORT_COUNT]; size_t transports_len; } PublicKeyCredentialDescriptor;