coverity 226232 - tainted input

This commit is contained in:
Philippe Teuwen 2019-10-09 19:44:06 +02:00
commit 5017e33b6d
2 changed files with 31 additions and 21 deletions

View file

@ -42,14 +42,14 @@
#define TOHEX(v) ((v) < 10 ? (v) + '0' : (v) - 10 + 'a')
static ssize_t emv_pk_read_bin(char *buf, unsigned char *bin, size_t size, size_t *read) {
static ssize_t emv_pk_read_bin(char *buf, size_t buflen, unsigned char *bin, size_t size, size_t *read) {
if (buf == NULL)
return 0;
size_t left = size;
char *p = buf;
while (*p == ' ')
while ((*p == ' ') && (p < (buf + buflen - 1)))
p++;
while (left > 0) {
@ -57,15 +57,19 @@ static ssize_t emv_pk_read_bin(char *buf, unsigned char *bin, size_t size, size_
c1 = HEX(*p);
if (c1 == -1)
return -(p - buf);
if (p == (buf + buflen - 1))
return -(p - buf);
p++;
c2 = HEX(*p);
if (c2 == -1)
return -(p - buf);
if (p == (buf + buflen - 1))
return -(p - buf);
p++;
*bin = (c1 * 16 + c2);
bin ++;
left --;
if (*p == ':')
if ((*p == ':') && (p < (buf + buflen - 1)))
p++;
else if (read) {
*read = (size - left);
@ -76,7 +80,7 @@ static ssize_t emv_pk_read_bin(char *buf, unsigned char *bin, size_t size, size_
return -(p - buf);
}
while (*p == ' ')
while ((*p == ' ') && (p < (buf + buflen - 1)))
p++;
p--;
@ -84,7 +88,7 @@ static ssize_t emv_pk_read_bin(char *buf, unsigned char *bin, size_t size, size_
return (p - buf);
}
static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) {
static ssize_t emv_pk_read_ymv(char *buf, size_t buflen, unsigned *ymv) {
if (buf == NULL)
return 0;
@ -95,7 +99,7 @@ static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) {
*ymv = 0;
while (*p == ' ')
while ((*p == ' ') && (p < (buf + buflen - 1)))
p++;
for (i = 0; i < 3; i++) {
@ -103,15 +107,19 @@ static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) {
c1 = BCD(*p);
if (c1 == -1)
return -(p - buf);
if (p == (buf + buflen - 1))
return -(p - buf);
p++;
c2 = BCD(*p);
if (c2 == -1)
return -(p - buf);
if (p == (buf + buflen - 1))
return -(p - buf);
p++;
temp[i] = (c1 * 16 + c2);
}
while (*p == ' ')
while ((*p == ' ') && (p < (buf + buflen - 1)))
p++;
p--;
@ -124,13 +132,13 @@ static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) {
return (p - buf);
}
static ssize_t emv_pk_read_string(char *buf, char *str, size_t size) {
static ssize_t emv_pk_read_string(char *buf, size_t buflen, char *str, size_t size) {
if (buf == NULL)
return 0;
char *p = buf;
while (*p == ' ')
while ((*p == ' ') && (p < (buf + buflen - 1)))
p++;
while (size > 1) {
@ -139,6 +147,8 @@ static ssize_t emv_pk_read_string(char *buf, char *str, size_t size) {
else if (*p < 0x20 || *p >= 0x7f)
return -(p - buf);
*str = *p;
if (p == (buf + buflen - 1))
return -(p - buf);
p++;
str ++;
size --;
@ -146,7 +156,7 @@ static ssize_t emv_pk_read_string(char *buf, char *str, size_t size) {
*str = 0;
while (*p == ' ')
while ((*p == ' ') && (p < (buf + buflen - 1)))
p++;
p--;
@ -155,27 +165,27 @@ static ssize_t emv_pk_read_string(char *buf, char *str, size_t size) {
}
struct emv_pk *emv_pk_parse_pk(char *buf) {
struct emv_pk *emv_pk_parse_pk(char *buf, size_t buflen) {
struct emv_pk *r = calloc(1, sizeof(*r));
ssize_t l;
char temp[10];
l = emv_pk_read_bin(buf, r->rid, 5, NULL);
l = emv_pk_read_bin(buf, buflen, r->rid, 5, NULL);
if (l <= 0)
goto out;
buf += l;
l = emv_pk_read_bin(buf, &r->index, 1, NULL);
l = emv_pk_read_bin(buf, buflen, &r->index, 1, NULL);
if (l <= 0)
goto out;
buf += l;
l = emv_pk_read_ymv(buf, &r->expire);
l = emv_pk_read_ymv(buf, buflen, &r->expire);
if (l <= 0)
goto out;
buf += l;
l = emv_pk_read_string(buf, temp, sizeof(temp));
l = emv_pk_read_string(buf, buflen, temp, sizeof(temp));
if (l <= 0)
goto out;
buf += l;
@ -185,18 +195,18 @@ struct emv_pk *emv_pk_parse_pk(char *buf) {
else
goto out;
l = emv_pk_read_bin(buf, r->exp, sizeof(r->exp), &r->elen);
l = emv_pk_read_bin(buf, buflen, r->exp, sizeof(r->exp), &r->elen);
if (l <= 0)
goto out;
buf += l;
r->modulus = malloc(2048 / 8);
l = emv_pk_read_bin(buf, r->modulus, 2048 / 8, &r->mlen);
l = emv_pk_read_bin(buf, buflen, r->modulus, 2048 / 8, &r->mlen);
if (l <= 0)
goto out2;
buf += l;
l = emv_pk_read_string(buf, temp, sizeof(temp));
l = emv_pk_read_string(buf, buflen, temp, sizeof(temp));
if (l <= 0)
goto out2;
buf += l;
@ -206,7 +216,7 @@ struct emv_pk *emv_pk_parse_pk(char *buf) {
else
goto out2;
l = emv_pk_read_bin(buf, r->hash, 20, NULL);
l = emv_pk_read_bin(buf, buflen, r->hash, 20, NULL);
if (l <= 0)
goto out2;
@ -409,7 +419,7 @@ static struct emv_pk *emv_pk_get_ca_pk_from_file(const char *fname,
if (fgets(buf, sizeof(buf), f) == NULL)
break;
struct emv_pk *pk = emv_pk_parse_pk(buf);
struct emv_pk *pk = emv_pk_parse_pk(buf, sizeof(buf));
if (!pk)
continue;

View file

@ -35,7 +35,7 @@ struct emv_pk {
#define EXPIRE(yy, mm, dd) 0x ## yy ## mm ## dd
struct emv_pk *emv_pk_parse_pk(char *buf);
struct emv_pk *emv_pk_parse_pk(char *bufm, size_t buflen);
struct emv_pk *emv_pk_new(size_t modlen, size_t explen);
void emv_pk_free(struct emv_pk *pk);
char *emv_pk_dump_pk(const struct emv_pk *pk);