PCSC: Use clearer file TLV length validation step

This makes it easier for static analyzer to confirm that the length
field bounds are checked. WPA_GET_BE16() is also used instead of
explicit byte-swapping operations in this file. (CID 68129)

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2014-11-23 18:32:04 +02:00
parent fecc09edc3
commit e7306bcb59

View File

@ -281,77 +281,82 @@ static int scard_parse_fsp_templ(unsigned char *buf, size_t buf_len,
wpa_hexdump(MSG_DEBUG, "SCARD: file header FSP template", wpa_hexdump(MSG_DEBUG, "SCARD: file header FSP template",
pos, end - pos); pos, end - pos);
while (pos + 1 < end) { while (end - pos >= 2) {
unsigned char type, len;
type = pos[0];
len = pos[1];
wpa_printf(MSG_MSGDUMP, "SCARD: file header TLV 0x%02x len=%d", wpa_printf(MSG_MSGDUMP, "SCARD: file header TLV 0x%02x len=%d",
pos[0], pos[1]); type, len);
if (pos + 2 + pos[1] > end) pos += 2;
if (len > (unsigned int) (end - pos))
break; break;
switch (pos[0]) { switch (type) {
case USIM_TLV_FILE_DESC: case USIM_TLV_FILE_DESC:
wpa_hexdump(MSG_MSGDUMP, "SCARD: File Descriptor TLV", wpa_hexdump(MSG_MSGDUMP, "SCARD: File Descriptor TLV",
pos + 2, pos[1]); pos, len);
break; break;
case USIM_TLV_FILE_ID: case USIM_TLV_FILE_ID:
wpa_hexdump(MSG_MSGDUMP, "SCARD: File Identifier TLV", wpa_hexdump(MSG_MSGDUMP, "SCARD: File Identifier TLV",
pos + 2, pos[1]); pos, len);
break; break;
case USIM_TLV_DF_NAME: case USIM_TLV_DF_NAME:
wpa_hexdump(MSG_MSGDUMP, "SCARD: DF name (AID) TLV", wpa_hexdump(MSG_MSGDUMP, "SCARD: DF name (AID) TLV",
pos + 2, pos[1]); pos, len);
break; break;
case USIM_TLV_PROPR_INFO: case USIM_TLV_PROPR_INFO:
wpa_hexdump(MSG_MSGDUMP, "SCARD: Proprietary " wpa_hexdump(MSG_MSGDUMP, "SCARD: Proprietary "
"information TLV", pos + 2, pos[1]); "information TLV", pos, len);
break; break;
case USIM_TLV_LIFE_CYCLE_STATUS: case USIM_TLV_LIFE_CYCLE_STATUS:
wpa_hexdump(MSG_MSGDUMP, "SCARD: Life Cycle Status " wpa_hexdump(MSG_MSGDUMP, "SCARD: Life Cycle Status "
"Integer TLV", pos + 2, pos[1]); "Integer TLV", pos, len);
break; break;
case USIM_TLV_FILE_SIZE: case USIM_TLV_FILE_SIZE:
wpa_hexdump(MSG_MSGDUMP, "SCARD: File size TLV", wpa_hexdump(MSG_MSGDUMP, "SCARD: File size TLV",
pos + 2, pos[1]); pos, len);
if ((pos[1] == 1 || pos[1] == 2) && file_len) { if ((len == 1 || len == 2) && file_len) {
if (pos[1] == 1) if (len == 1)
*file_len = (int) pos[2]; *file_len = (int) pos[0];
else else
*file_len = ((int) pos[2] << 8) | *file_len = WPA_GET_BE16(pos);
(int) pos[3];
wpa_printf(MSG_DEBUG, "SCARD: file_size=%d", wpa_printf(MSG_DEBUG, "SCARD: file_size=%d",
*file_len); *file_len);
} }
break; break;
case USIM_TLV_TOTAL_FILE_SIZE: case USIM_TLV_TOTAL_FILE_SIZE:
wpa_hexdump(MSG_MSGDUMP, "SCARD: Total file size TLV", wpa_hexdump(MSG_MSGDUMP, "SCARD: Total file size TLV",
pos + 2, pos[1]); pos, len);
break; break;
case USIM_TLV_PIN_STATUS_TEMPLATE: case USIM_TLV_PIN_STATUS_TEMPLATE:
wpa_hexdump(MSG_MSGDUMP, "SCARD: PIN Status Template " wpa_hexdump(MSG_MSGDUMP, "SCARD: PIN Status Template "
"DO TLV", pos + 2, pos[1]); "DO TLV", pos, len);
if (pos[1] >= 2 && pos[2] == USIM_PS_DO_TAG && if (len >= 2 && pos[0] == USIM_PS_DO_TAG &&
pos[3] >= 1 && ps_do) { pos[1] >= 1 && ps_do) {
wpa_printf(MSG_DEBUG, "SCARD: PS_DO=0x%02x", wpa_printf(MSG_DEBUG, "SCARD: PS_DO=0x%02x",
pos[4]); pos[2]);
*ps_do = (int) pos[4]; *ps_do = (int) pos[2];
} }
break; break;
case USIM_TLV_SHORT_FILE_ID: case USIM_TLV_SHORT_FILE_ID:
wpa_hexdump(MSG_MSGDUMP, "SCARD: Short File " wpa_hexdump(MSG_MSGDUMP, "SCARD: Short File "
"Identifier (SFI) TLV", pos + 2, pos[1]); "Identifier (SFI) TLV", pos, len);
break; break;
case USIM_TLV_SECURITY_ATTR_8B: case USIM_TLV_SECURITY_ATTR_8B:
case USIM_TLV_SECURITY_ATTR_8C: case USIM_TLV_SECURITY_ATTR_8C:
case USIM_TLV_SECURITY_ATTR_AB: case USIM_TLV_SECURITY_ATTR_AB:
wpa_hexdump(MSG_MSGDUMP, "SCARD: Security attribute " wpa_hexdump(MSG_MSGDUMP, "SCARD: Security attribute "
"TLV", pos + 2, pos[1]); "TLV", pos, len);
break; break;
default: default:
wpa_hexdump(MSG_MSGDUMP, "SCARD: Unrecognized TLV", wpa_hexdump(MSG_MSGDUMP, "SCARD: Unrecognized TLV",
pos, 2 + pos[1]); pos, len);
break; break;
} }
pos += 2 + pos[1]; pos += len;
if (pos == end) if (pos == end)
return 0; return 0;
@ -1096,7 +1101,7 @@ int scard_get_imsi(struct scard_data *scard, char *imsi, size_t *len)
} }
if (scard->sim_type == SCARD_GSM_SIM) { if (scard->sim_type == SCARD_GSM_SIM) {
blen = (buf[2] << 8) | buf[3]; blen = WPA_GET_BE16(&buf[2]);
} else { } else {
int file_size; int file_size;
if (scard_parse_fsp_templ(buf, blen, NULL, &file_size)) if (scard_parse_fsp_templ(buf, blen, NULL, &file_size))
@ -1170,7 +1175,7 @@ int scard_get_mnc_len(struct scard_data *scard)
} }
if (scard->sim_type == SCARD_GSM_SIM) { if (scard->sim_type == SCARD_GSM_SIM) {
file_size = (buf[2] << 8) | buf[3]; file_size = WPA_GET_BE16(&buf[2]);
} else { } else {
if (scard_parse_fsp_templ(buf, blen, NULL, &file_size)) if (scard_parse_fsp_templ(buf, blen, NULL, &file_size))
return -3; return -3;