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') #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) if (buf == NULL)
return 0; return 0;
size_t left = size; size_t left = size;
char *p = buf; char *p = buf;
while (*p == ' ') while ((*p == ' ') && (p < (buf + buflen - 1)))
p++; p++;
while (left > 0) { 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); c1 = HEX(*p);
if (c1 == -1) if (c1 == -1)
return -(p - buf); return -(p - buf);
if (p == (buf + buflen - 1))
return -(p - buf);
p++; p++;
c2 = HEX(*p); c2 = HEX(*p);
if (c2 == -1) if (c2 == -1)
return -(p - buf); return -(p - buf);
if (p == (buf + buflen - 1))
return -(p - buf);
p++; p++;
*bin = (c1 * 16 + c2); *bin = (c1 * 16 + c2);
bin ++; bin ++;
left --; left --;
if (*p == ':') if ((*p == ':') && (p < (buf + buflen - 1)))
p++; p++;
else if (read) { else if (read) {
*read = (size - left); *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); return -(p - buf);
} }
while (*p == ' ') while ((*p == ' ') && (p < (buf + buflen - 1)))
p++; p++;
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); 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) if (buf == NULL)
return 0; return 0;
@ -95,7 +99,7 @@ static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) {
*ymv = 0; *ymv = 0;
while (*p == ' ') while ((*p == ' ') && (p < (buf + buflen - 1)))
p++; p++;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
@ -103,15 +107,19 @@ static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) {
c1 = BCD(*p); c1 = BCD(*p);
if (c1 == -1) if (c1 == -1)
return -(p - buf); return -(p - buf);
if (p == (buf + buflen - 1))
return -(p - buf);
p++; p++;
c2 = BCD(*p); c2 = BCD(*p);
if (c2 == -1) if (c2 == -1)
return -(p - buf); return -(p - buf);
if (p == (buf + buflen - 1))
return -(p - buf);
p++; p++;
temp[i] = (c1 * 16 + c2); temp[i] = (c1 * 16 + c2);
} }
while (*p == ' ') while ((*p == ' ') && (p < (buf + buflen - 1)))
p++; p++;
p--; p--;
@ -124,13 +132,13 @@ static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) {
return (p - buf); 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) if (buf == NULL)
return 0; return 0;
char *p = buf; char *p = buf;
while (*p == ' ') while ((*p == ' ') && (p < (buf + buflen - 1)))
p++; p++;
while (size > 1) { 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) else if (*p < 0x20 || *p >= 0x7f)
return -(p - buf); return -(p - buf);
*str = *p; *str = *p;
if (p == (buf + buflen - 1))
return -(p - buf);
p++; p++;
str ++; str ++;
size --; size --;
@ -146,7 +156,7 @@ static ssize_t emv_pk_read_string(char *buf, char *str, size_t size) {
*str = 0; *str = 0;
while (*p == ' ') while ((*p == ' ') && (p < (buf + buflen - 1)))
p++; p++;
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)); struct emv_pk *r = calloc(1, sizeof(*r));
ssize_t l; ssize_t l;
char temp[10]; 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) if (l <= 0)
goto out; goto out;
buf += l; 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) if (l <= 0)
goto out; goto out;
buf += l; buf += l;
l = emv_pk_read_ymv(buf, &r->expire); l = emv_pk_read_ymv(buf, buflen, &r->expire);
if (l <= 0) if (l <= 0)
goto out; goto out;
buf += l; buf += l;
l = emv_pk_read_string(buf, temp, sizeof(temp)); l = emv_pk_read_string(buf, buflen, temp, sizeof(temp));
if (l <= 0) if (l <= 0)
goto out; goto out;
buf += l; buf += l;
@ -185,18 +195,18 @@ struct emv_pk *emv_pk_parse_pk(char *buf) {
else else
goto out; 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) if (l <= 0)
goto out; goto out;
buf += l; buf += l;
r->modulus = malloc(2048 / 8); 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) if (l <= 0)
goto out2; goto out2;
buf += l; buf += l;
l = emv_pk_read_string(buf, temp, sizeof(temp)); l = emv_pk_read_string(buf, buflen, temp, sizeof(temp));
if (l <= 0) if (l <= 0)
goto out2; goto out2;
buf += l; buf += l;
@ -206,7 +216,7 @@ struct emv_pk *emv_pk_parse_pk(char *buf) {
else else
goto out2; 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) if (l <= 0)
goto out2; 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) if (fgets(buf, sizeof(buf), f) == NULL)
break; break;
struct emv_pk *pk = emv_pk_parse_pk(buf); struct emv_pk *pk = emv_pk_parse_pk(buf, sizeof(buf));
if (!pk) if (!pk)
continue; continue;

View file

@ -35,7 +35,7 @@ struct emv_pk {
#define EXPIRE(yy, mm, dd) 0x ## yy ## mm ## dd #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); struct emv_pk *emv_pk_new(size_t modlen, size_t explen);
void emv_pk_free(struct emv_pk *pk); void emv_pk_free(struct emv_pk *pk);
char *emv_pk_dump_pk(const struct emv_pk *pk); char *emv_pk_dump_pk(const struct emv_pk *pk);