Properly check for overflow in offsets

This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2013-06-10 10:10:06 -04:00
parent 3001c74580
commit b32ff51219
2 changed files with 53 additions and 4 deletions
+14 -4
View File
@@ -2261,7 +2261,7 @@ ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
int parse_bytes(const char *t, off_t *bytes) {
static const struct {
const char *suffix;
off_t factor;
unsigned long long factor;
} table[] = {
{ "B", 1 },
{ "K", 1024ULL },
@@ -2274,7 +2274,7 @@ int parse_bytes(const char *t, off_t *bytes) {
};
const char *p;
off_t r = 0;
unsigned long long r = 0;
assert(t);
assert(bytes);
@@ -2301,7 +2301,17 @@ int parse_bytes(const char *t, off_t *bytes) {
for (i = 0; i < ELEMENTSOF(table); i++)
if (startswith(e, table[i].suffix)) {
r += (off_t) l * table[i].factor;
unsigned long long tmp;
if ((unsigned long long) l > ULLONG_MAX / table[i].factor)
return -ERANGE;
tmp = l * table[i].factor;
if (tmp > ULLONG_MAX - r)
return -ERANGE;
r += tmp;
if ((unsigned long long) (off_t) r != r)
return -ERANGE;
p = e + strlen(table[i].suffix);
break;
}
@@ -2309,7 +2319,7 @@ int parse_bytes(const char *t, off_t *bytes) {
if (i >= ELEMENTSOF(table))
return -EINVAL;
} while (*p != 0);
} while (*p);
*bytes = r;