]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Add tighter checks to avoid reading past end of buffer 24/head
authorBrian Weaver <cmdrclueless@gmail.com>
Tue, 25 Sep 2012 13:51:12 +0000 (09:51 -0400)
committerBrian Weaver <cmdrclueless@gmail.com>
Tue, 25 Sep 2012 13:51:12 +0000 (09:51 -0400)
The string to base 8/10 conversion routines could read past the
counted end of the buffer if the string is correctly formated.
The number of characters is now checked and decremented for every
character that is consumed for processing.

libarchive/archive_read_support_format_tar.c

index 4538331f3d05382a8e129c0e326fe9684a40bf8a..8186d27383a11f852a40a3299e7f0d0dbb5845df 100644 (file)
@@ -2416,23 +2416,27 @@ tar_atol8(const char *p, unsigned char_cnt)
        limit = INT64_MAX / base;
        last_digit_limit = INT64_MAX % base;
 
-       while (*p == ' ' || *p == '\t')
+       while (char_cnt-- > 0 && (*p == ' ' || *p == '\t'))
                p++;
-       if (*p == '-') {
+
+       sign = 1;
+       if (char_cnt > 0 && *p == '-') {
                sign = -1;
                p++;
-       } else
-               sign = 1;
+               char_cnt--;
+       }
 
        l = 0;
-       digit = *p - '0';
-       while (digit >= 0 && digit < base  && char_cnt-- > 0) {
-               if (l>limit || (l == limit && digit > last_digit_limit)) {
-                       l = INT64_MAX; /* Truncate on overflow. */
-                       break;
+       if (char_cnt > 0) {
+               digit = *p - '0';
+               while (digit >= 0 && digit < base  && char_cnt-- > 0) {
+                       if (l>limit || (l == limit && digit > last_digit_limit)) {
+                               l = INT64_MAX; /* Truncate on overflow. */
+                               break;
+                       }
+                       l = (l * base) + digit;
+                       digit = *++p - '0';
                }
-               l = (l * base) + digit;
-               digit = *++p - '0';
        }
        return (sign < 0) ? -l : l;
 }
@@ -2452,23 +2456,27 @@ tar_atol10(const char *p, unsigned char_cnt)
        limit = INT64_MAX / base;
        last_digit_limit = INT64_MAX % base;
 
-       while (*p == ' ' || *p == '\t')
+       while (char_cnt-- > 0 && (*p == ' ' || *p == '\t'))
                p++;
-       if (*p == '-') {
+
+       sign = 1;
+       if (char_cnt > 0 && *p == '-') {
                sign = -1;
                p++;
-       } else
-               sign = 1;
+               char_cnt--;
+       }
 
        l = 0;
-       digit = *p - '0';
-       while (digit >= 0 && digit < base  && char_cnt-- > 0) {
-               if (l > limit || (l == limit && digit > last_digit_limit)) {
-                       l = INT64_MAX; /* Truncate on overflow. */
-                       break;
+       if (char_cnt > 0) {
+               digit = *p - '0';
+               while (digit >= 0 && digit < base  && char_cnt-- > 0) {
+                       if (l > limit || (l == limit && digit > last_digit_limit)) {
+                               l = INT64_MAX; /* Truncate on overflow. */
+                               break;
+                       }
+                       l = (l * base) + digit;
+                       digit = *++p - '0';
                }
-               l = (l * base) + digit;
-               digit = *++p - '0';
        }
        return (sign < 0) ? -l : l;
 }