improve strtol checking in got-fetch-pack
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
diff --git a/libexec/got-fetch-pack/got-fetch-pack.c b/libexec/got-fetch-pack/got-fetch-pack.c
index e593a8e..8ce243b 100644
--- a/libexec/got-fetch-pack/got-fetch-pack.c
+++ b/libexec/got-fetch-pack/got-fetch-pack.c
@@ -96,25 +96,36 @@ static const struct got_error *
readpkt(int *outlen, int fd, char *buf, int nbuf)
{
const struct got_error *err = NULL;
- char len[5];
+ char lenstr[5];
+ long len;
char *e;
int n;
ssize_t r;
*outlen = 0;
- err = readn(&r, fd, len, 4);
+ err = readn(&r, fd, lenstr, 4);
if (err)
return err;
+ if (r != 4)
+ return got_error(GOT_ERR_IO);
- len[4] = 0;
- n = strtol(len, &e, 16);
+ lenstr[4] = '\0';
+ errno = 0;
+ len = strtol(lenstr, &e, 16);
+ if (lenstr[0] == '\0' || *e != '\0')
+ return got_error(GOT_ERR_BAD_PACKET);
+ if (errno == ERANGE && (len == LONG_MAX || len == LONG_MIN))
+ return got_error(GOT_ERR_BAD_PACKET);
+ if (len > INT_MAX || len < INT_MIN)
+ return got_error(GOT_ERR_BAD_PACKET);
+ n = len;
if (n == 0) {
if (chattygit)
fprintf(stderr, "readpkt: 0000\n");
return NULL;
}
- if (e != len + 4 || n <= 4)
+ if (n <= 4)
return got_error(GOT_ERR_BAD_PACKET);
n -= 4;
if (n >= nbuf)
@@ -127,7 +138,7 @@ readpkt(int *outlen, int fd, char *buf, int nbuf)
return got_error(GOT_ERR_BAD_PACKET);
buf[n] = 0;
if (chattygit)
- fprintf(stderr, "readpkt: %s:\t%.*s\n", len, nbuf, buf);
+ fprintf(stderr, "readpkt: %s:\t%.*s\n", lenstr, nbuf, buf);
*outlen = n;
return NULL;