cac: Avoid stack overflow on infinite recursion in CCC chaining
Thanks oss-fuzz Fixes: #1920 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19725
This commit is contained in:
parent
e9308a2011
commit
09531d720a
|
@ -106,6 +106,8 @@
|
||||||
#define CAC_ACR_AMP 0x20
|
#define CAC_ACR_AMP 0x20
|
||||||
#define CAC_ACR_SERVICE 0x21
|
#define CAC_ACR_SERVICE 0x21
|
||||||
|
|
||||||
|
#define CAC_MAX_CCC_DEPTH 16
|
||||||
|
|
||||||
/* hardware data structures (returned in the CCC) */
|
/* hardware data structures (returned in the CCC) */
|
||||||
/* part of the card_url */
|
/* part of the card_url */
|
||||||
typedef struct cac_access_profile {
|
typedef struct cac_access_profile {
|
||||||
|
@ -1420,10 +1422,10 @@ static int cac_parse_cuid(sc_card_t *card, cac_private_data_t *priv, cac_cuid_t
|
||||||
priv->cac_id_len = card_id_len;
|
priv->cac_id_len = card_id_len;
|
||||||
return SC_SUCCESS;
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
static int cac_process_CCC(sc_card_t *card, cac_private_data_t *priv);
|
static int cac_process_CCC(sc_card_t *card, cac_private_data_t *priv, int depth);
|
||||||
|
|
||||||
static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, const u8 *tl,
|
static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, const u8 *tl,
|
||||||
size_t tl_len, u8 *val, size_t val_len)
|
size_t tl_len, u8 *val, size_t val_len, int depth)
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
const u8 *tl_end = tl + tl_len;
|
const u8 *tl_end = tl + tl_len;
|
||||||
|
@ -1520,7 +1522,8 @@ static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, const u8 *tl
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = cac_process_CCC(card, priv);
|
/* Increase depth to avoid infinite recursion */
|
||||||
|
r = cac_process_CCC(card, priv, depth + 1);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
|
@ -1533,12 +1536,16 @@ static int cac_parse_CCC(sc_card_t *card, cac_private_data_t *priv, const u8 *tl
|
||||||
return SC_SUCCESS;
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cac_process_CCC(sc_card_t *card, cac_private_data_t *priv)
|
static int cac_process_CCC(sc_card_t *card, cac_private_data_t *priv, int depth)
|
||||||
{
|
{
|
||||||
u8 *tl = NULL, *val = NULL;
|
u8 *tl = NULL, *val = NULL;
|
||||||
size_t tl_len, val_len;
|
size_t tl_len, val_len;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if (depth < 0) {
|
||||||
|
sc_log(card->ctx, "Too much recursive CCC found. Exiting");
|
||||||
|
return SC_ERROR_INVALID_CARD;
|
||||||
|
}
|
||||||
|
|
||||||
r = cac_read_file(card, CAC_FILE_TAG, &tl, &tl_len);
|
r = cac_read_file(card, CAC_FILE_TAG, &tl, &tl_len);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -1548,7 +1555,7 @@ static int cac_process_CCC(sc_card_t *card, cac_private_data_t *priv)
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
r = cac_parse_CCC(card, priv, tl, tl_len, val, val_len);
|
r = cac_parse_CCC(card, priv, tl, tl_len, val, val_len, depth);
|
||||||
done:
|
done:
|
||||||
if (tl)
|
if (tl)
|
||||||
free(tl);
|
free(tl);
|
||||||
|
@ -1775,7 +1782,7 @@ static int cac_find_and_initialize(sc_card_t *card, int initialize)
|
||||||
priv = cac_new_private_data();
|
priv = cac_new_private_data();
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return SC_ERROR_OUT_OF_MEMORY;
|
return SC_ERROR_OUT_OF_MEMORY;
|
||||||
r = cac_process_CCC(card, priv);
|
r = cac_process_CCC(card, priv, CAC_MAX_CCC_DEPTH);
|
||||||
if (r == SC_SUCCESS) {
|
if (r == SC_SUCCESS) {
|
||||||
card->type = SC_CARD_TYPE_CAC_II;
|
card->type = SC_CARD_TYPE_CAC_II;
|
||||||
card->drv_data = priv;
|
card->drv_data = priv;
|
||||||
|
|
Loading…
Reference in New Issue