File opensc-CVE-2024-45616.patch of Package opensc.35664
commit 1d3b410e06d33cfc4c70e8a25386e456cfbd7bd1
Author: Veronika HanulĂková <vhanulik@redhat.com>
Date: Thu Jul 11 15:27:19 2024 +0200
cardos: Fix uninitialized values
Thanks Matteo Marini for report
https://github.com/OpenSC/OpenSC/security/advisories/GHSA-p3mx-7472-h3j8
fuzz_card/2
Index: opensc-0.19.0/src/libopensc/card-cardos.c
===================================================================
--- opensc-0.19.0.orig/src/libopensc/card-cardos.c
+++ opensc-0.19.0/src/libopensc/card-cardos.c
@@ -69,14 +69,14 @@ static unsigned int algorithm_ids_in_tok
static int cardos_match_card(sc_card_t *card)
{
- unsigned char atr[SC_MAX_ATR_SIZE];
+ unsigned char atr[SC_MAX_ATR_SIZE] = {0};
int i;
i = _sc_match_atr(card, cardos_atrs, &card->type);
if (i < 0)
return 0;
- memcpy(atr, card->atr.value, sizeof(atr));
+ memcpy(atr, card->atr.value, card->atr.len);
/* Do not change card type for CIE! */
if (card->type == SC_CARD_TYPE_CARDOS_CIE_V1)
@@ -87,8 +87,8 @@ static int cardos_match_card(sc_card_t *
return 1;
if (card->type == SC_CARD_TYPE_CARDOS_M4_2) {
int rv;
- sc_apdu_t apdu;
- u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
+ sc_apdu_t apdu = {0};
+ u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
/* first check some additional ATR bytes */
if ((atr[4] != 0xff && atr[4] != 0x02) ||
(atr[6] != 0x10 && atr[6] != 0x0a) ||
@@ -104,7 +104,7 @@ static int cardos_match_card(sc_card_t *
apdu.lc = 0;
rv = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "APDU transmit failed");
- if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00)
+ if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00 || apdu.resplen < 2)
return 0;
if (apdu.resp[0] != atr[10] ||
apdu.resp[1] != atr[11])
Index: opensc-0.19.0/src/libopensc/card-oberthur.c
===================================================================
--- opensc-0.19.0.orig/src/libopensc/card-oberthur.c
+++ opensc-0.19.0/src/libopensc/card-oberthur.c
@@ -156,7 +156,7 @@ auth_select_aid(struct sc_card *card)
{
struct sc_apdu apdu;
unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE];
- struct auth_private_data *data = (struct auth_private_data *) card->drv_data;
+ struct auth_private_data *data = (struct auth_private_data *)card->drv_data;
int rv, ii;
struct sc_path tmp_path;
@@ -173,6 +173,9 @@ auth_select_aid(struct sc_card *card)
rv = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
+ if (apdu.resplen < 20) {
+ LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Serial number has incorrect length");
+ }
card->serialnr.len = 4;
memcpy(card->serialnr.value, apdu.resp+15, 4);
Index: opensc-0.19.0/src/libopensc/card-gids.c
===================================================================
--- opensc-0.19.0.orig/src/libopensc/card-gids.c
+++ opensc-0.19.0/src/libopensc/card-gids.c
@@ -212,6 +212,7 @@ static int gids_get_DO(sc_card_t* card,
size_t datasize = 0;
const u8* p;
u8 buffer[MAX_GIDS_FILE_SIZE];
+ size_t buffer_len = sizeof(buffer);
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
@@ -225,14 +226,15 @@ static int gids_get_DO(sc_card_t* card,
apdu.data = data;
apdu.datalen = 04;
apdu.resp = buffer;
- apdu.resplen = sizeof(buffer);
+ apdu.resplen = buffer_len;
apdu.le = 256;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "gids get data failed");
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2), "invalid return");
+ buffer_len = apdu.resplen;
- p = sc_asn1_find_tag(card->ctx, buffer, sizeof(buffer), dataObjectIdentifier, &datasize);
+ p = sc_asn1_find_tag(card->ctx, buffer, buffer_len, dataObjectIdentifier, &datasize);
if (!p) {
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_NOT_FOUND);
}
Index: opensc-0.19.0/src/libopensc/card-mcrd.c
===================================================================
--- opensc-0.19.0.orig/src/libopensc/card-mcrd.c
+++ opensc-0.19.0/src/libopensc/card-mcrd.c
@@ -821,6 +821,8 @@ do_select(sc_card_t * card, u8 kind,
*file = sc_file_new();
if (!*file)
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
+ if (apdu.resp[1] > apdu.resplen - 2)
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
/* EstEID v3.0 cards are buggy and sometimes return a double 0x62 tag */
if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30 && apdu.resp[2] == 0x62)
process_fcp(card, *file, apdu.resp + 4, apdu.resp[3]);
@@ -829,12 +831,12 @@ do_select(sc_card_t * card, u8 kind,
return SC_SUCCESS;
}
- if (p2 != 0x0C && apdu.resp[0] == 0x6F) {
+ if (p2 != 0x0C && apdu.resplen > 2 && apdu.resp[0] == 0x6F) {
*file = sc_file_new();
if (!*file)
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
- if (apdu.resp[1] <= apdu.resplen)
- process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]);
+ if (apdu.resp[1] > apdu.resplen - 2)
+ process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]);
return SC_SUCCESS;
}
return SC_SUCCESS;
Index: opensc-0.19.0/src/libopensc/asn1.c
===================================================================
--- opensc-0.19.0.orig/src/libopensc/asn1.c
+++ opensc-0.19.0/src/libopensc/asn1.c
@@ -67,7 +67,7 @@ int sc_asn1_read_tag(const u8 ** buf, si
*buf = NULL;
- if (left == 0)
+ if (left == 0 || !p || buflen == 0)
return SC_ERROR_INVALID_ASN1_OBJECT;
if (*p == 0xff || *p == 0) {
/* end of data reached */
@@ -82,6 +82,8 @@ int sc_asn1_read_tag(const u8 ** buf, si
*/
cla = (*p & SC_ASN1_TAG_CLASS) | (*p & SC_ASN1_TAG_CONSTRUCTED);
tag = *p & SC_ASN1_TAG_PRIMITIVE;
+ if (left < 1)
+ return SC_ERROR_INVALID_ASN1_OBJECT;
p++;
left--;
if (tag == SC_ASN1_TAG_PRIMITIVE) {
Index: opensc-0.19.0/src/libopensc/card-dnie.c
===================================================================
--- opensc-0.19.0.orig/src/libopensc/card-dnie.c
+++ opensc-0.19.0/src/libopensc/card-dnie.c
@@ -1198,11 +1198,15 @@ static int dnie_compose_and_send_apdu(sc
}
/* finally process FCI response */
+ size_t len = apdu.resp[1];
file = sc_file_new();
if (file == NULL) {
LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
}
- res = card->ops->process_fci(card, file, apdu.resp + 2, apdu.resp[1]);
+ if (apdu.resplen - 2 < len || len < 1) {
+ LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
+ }
+ res = card->ops->process_fci(card, *file_out, apdu.resp + 2, len);
sc_file_free(*file_out);
*file_out = file;
LOG_FUNC_RETURN(ctx, res);
@@ -1967,7 +1971,7 @@ static int dnie_process_fci(struct sc_ca
int *op = df_acl;
int n = 0;
sc_context_t *ctx = NULL;
- if ((card == NULL) || (card->ctx == NULL) || (file == NULL))
+ if ((card == NULL) || (card->ctx == NULL) || (file == NULL) || buflen == 0)
return SC_ERROR_INVALID_ARGUMENTS;
ctx = card->ctx;
LOG_FUNC_CALLED(ctx);
Index: opensc-0.19.0/src/libopensc/muscle.c
===================================================================
--- opensc-0.19.0.orig/src/libopensc/muscle.c
+++ opensc-0.19.0/src/libopensc/muscle.c
@@ -94,7 +94,7 @@ int msc_partial_read_object(sc_card_t *c
apdu.resp = data;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
- if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
+ if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00 && dataLength <= apdu.resplen)
return dataLength;
if(apdu.sw1 == 0x9C) {
if(apdu.sw2 == 0x07) {
@@ -108,19 +108,20 @@ int msc_partial_read_object(sc_card_t *c
}
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
"got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2);
- return dataLength;
-
+ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_UNKNOWN_DATA_RECEIVED);
}
int msc_read_object(sc_card_t *card, msc_id objectId, int offset, u8 *data, size_t dataLength)
{
- int r;
+ int r = 0;
size_t i;
size_t max_read_unit = MSC_MAX_READ;
- for(i = 0; i < dataLength; i += max_read_unit) {
+ for(i = 0; i < dataLength; i += 0) {
r = msc_partial_read_object(card, objectId, offset + i, data + i, MIN(dataLength - i, max_read_unit));
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Error in partial object read");
+ if (r == 0)
+ break;
}
return dataLength;
}
Index: opensc-0.19.0/src/libopensc/card-entersafe.c
===================================================================
--- opensc-0.19.0.orig/src/libopensc/card-entersafe.c
+++ opensc-0.19.0/src/libopensc/card-entersafe.c
@@ -1455,6 +1455,10 @@ static int entersafe_get_serialnr(sc_car
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card,apdu.sw1,apdu.sw2),"EnterSafe get SN failed");
+ if (apdu.resplen != 8)
+ LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Invalid length of SN");
+
+
card->serialnr.len=serial->len=8;
memcpy(card->serialnr.value,rbuf,8);
memcpy(serial->value,rbuf,8);