Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP5:GA
opensc
opensc-CVE-2024-45616.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File opensc-CVE-2024-45616.patch of Package opensc
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.22.0/src/libopensc/card-cardos.c =================================================================== --- opensc-0.22.0.orig/src/libopensc/card-cardos.c +++ opensc-0.22.0/src/libopensc/card-cardos.c @@ -94,14 +94,14 @@ static void fixup_transceive_length(cons 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) @@ -114,8 +114,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) || @@ -131,7 +131,7 @@ static int cardos_match_card(sc_card_t * apdu.lc = 0; rv = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, 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.22.0/src/libopensc/card-cac1.c =================================================================== --- opensc-0.22.0.orig/src/libopensc/card-cac1.c +++ opensc-0.22.0/src/libopensc/card-cac1.c @@ -95,12 +95,12 @@ static int cac_cac1_get_certificate(sc_c if (apdu.sw1 != 0x63 || apdu.sw2 < 1) { /* we've either finished reading, or hit an error, break */ r = sc_check_sw(card, apdu.sw1, apdu.sw2); - left -= len; + left -= apdu.resplen; break; } /* Adjust the lengths */ - left -= len; - out_ptr += len; + left -= apdu.resplen; + out_ptr += apdu.resplen; len = MIN(left, apdu.sw2); } if (r < 0) { Index: opensc-0.22.0/src/libopensc/card-oberthur.c =================================================================== --- opensc-0.22.0.orig/src/libopensc/card-oberthur.c +++ opensc-0.22.0/src/libopensc/card-oberthur.c @@ -148,7 +148,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; @@ -165,6 +165,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.22.0/src/libopensc/card-gids.c =================================================================== --- opensc-0.22.0.orig/src/libopensc/card-gids.c +++ opensc-0.22.0/src/libopensc/card-gids.c @@ -231,6 +231,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_log(card->ctx, @@ -244,14 +245,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); LOG_TEST_RET(card->ctx, r, "gids get data failed"); LOG_TEST_RET(card->ctx, 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) { LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND); } Index: opensc-0.22.0/src/libopensc/card-mcrd.c =================================================================== --- opensc-0.22.0.orig/src/libopensc/card-mcrd.c +++ opensc-0.22.0/src/libopensc/card-mcrd.c @@ -634,23 +634,25 @@ do_select(sc_card_t * card, u8 kind, } } - if (p2 == 0x04 && apdu.resp[0] == 0x62) { - *file = sc_file_new(); - if (!*file) - LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - /* 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]); - else - process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]); - return SC_SUCCESS; - } + if (p2 == 0x04 && apdu.resplen > 2 && apdu.resp[0] == 0x62) { + *file = sc_file_new(); + if (!*file) + LOG_FUNC_RETURN(card->ctx, 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]); + else + process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]); + 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) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - if (apdu.resp[1] <= apdu.resplen) + if (apdu.resp[1] > apdu.resplen - 2) process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]); return SC_SUCCESS; } Index: opensc-0.22.0/src/libopensc/asn1.c =================================================================== --- opensc-0.22.0.orig/src/libopensc/asn1.c +++ opensc-0.22.0/src/libopensc/asn1.c @@ -68,7 +68,7 @@ int sc_asn1_read_tag(const u8 ** buf, si *buf = NULL; - if (left == 0 || !p) + if (left == 0 || !p || buflen == 0) return SC_ERROR_INVALID_ASN1_OBJECT; if (*p == 0xff || *p == 0) { /* end of data reached */ @@ -83,6 +83,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.22.0/src/libopensc/card-dnie.c =================================================================== --- opensc-0.22.0.orig/src/libopensc/card-dnie.c +++ opensc-0.22.0/src/libopensc/card-dnie.c @@ -1185,12 +1185,16 @@ static int dnie_compose_and_send_apdu(sc if (file_out) { /* finally process FCI response */ + size_t len = apdu.resp[1]; sc_file_free(*file_out); *file_out = sc_file_new(); if (*file_out == NULL) { LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); } - res = card->ops->process_fci(card, *file_out, 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); } LOG_FUNC_RETURN(ctx, res); } @@ -1949,7 +1953,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.22.0/src/libopensc/muscle.c =================================================================== --- opensc-0.22.0.orig/src/libopensc/muscle.c +++ opensc-0.22.0/src/libopensc/muscle.c @@ -94,33 +94,35 @@ int msc_partial_read_object(sc_card_t *c apdu.resp = data; r = sc_transmit_apdu(card, &apdu); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); - if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) - return dataLength; - if(apdu.sw1 == 0x9C) { - if(apdu.sw2 == 0x07) { + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00 && dataLength <= apdu.resplen) + return dataLength; + if (apdu.sw1 == 0x9C) { + if (apdu.sw2 == 0x07) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_FILE_NOT_FOUND); - } else if(apdu.sw2 == 0x06) { + } else if (apdu.sw2 == 0x06) { SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_ALLOWED); - } else if(apdu.sw2 == 0x0F) { + } else if (apdu.sw2 == 0x0F) { /* GUESSED */ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); } } sc_log(card->ctx, "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 += r) { r = msc_partial_read_object(card, objectId, offset + i, data + i, MIN(dataLength - i, max_read_unit)); LOG_TEST_RET(card->ctx, r, "Error in partial object read"); + if (r==0) + break; } return dataLength; } Index: opensc-0.22.0/src/libopensc/card-entersafe.c =================================================================== --- opensc-0.22.0.orig/src/libopensc/card-entersafe.c +++ opensc-0.22.0/src/libopensc/card-entersafe.c @@ -1453,7 +1453,9 @@ static int entersafe_get_serialnr(sc_car r=entersafe_transmit_apdu(card, &apdu,0,0,0,0); LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); LOG_TEST_RET(card->ctx, 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);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor