From 5017e33b6d241def57adf4efee29fb947ad8a804 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 9 Oct 2019 19:44:06 +0200 Subject: [PATCH] coverity 226232 - tainted input --- client/emv/emv_pk.c | 50 +++++++++++++++++++++++++++------------------ client/emv/emv_pk.h | 2 +- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/client/emv/emv_pk.c b/client/emv/emv_pk.c index fbd0e39a9..3331e50a5 100644 --- a/client/emv/emv_pk.c +++ b/client/emv/emv_pk.c @@ -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; diff --git a/client/emv/emv_pk.h b/client/emv/emv_pk.h index dfc249710..015a06dd6 100644 --- a/client/emv/emv_pk.h +++ b/client/emv/emv_pk.h @@ -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);