Browse code

bb12122: improving bounds checking in a more intuitive way, and adding additional check that I missed earlier.

Micah Snyder authored on 2018/05/25 01:40:42
Showing 1 changed files
... ...
@@ -671,6 +671,7 @@ static inline int parsehwp3_docsummary(cli_ctx *ctx, off_t offset)
671 671
 static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int level, off_t *roffset, int *last)
672 672
 {
673 673
     off_t offset = *roffset;
674
+    off_t new_offset;
674 675
     uint16_t nchars, nlines, content;
675 676
     uint8_t ppfs, ifsc, cfsb;
676 677
     int i, c, l, sp = 0, term = 0, ret = CL_SUCCESS;
... ...
@@ -780,7 +781,12 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
780 780
         offset += HWP3_LINEINFO_SIZE;
781 781
     }
782 782
 #else
783
-    offset += (nlines * HWP3_LINEINFO_SIZE);
783
+    new_offset = offset + (nlines * HWP3_LINEINFO_SIZE);
784
+    if ((new_offset <= offset) || (new_offset >= map->len)) {
785
+        cli_errmsg("HWP3.x: Paragraph[%d, %d]: length value is too high, invalid. %u\n", level, p, nlines);
786
+        return CL_EPARSE;
787
+    }
788
+    offset = new_offset;
784 789
 #endif
785 790
 
786 791
     if (offset >= map->len)
... ...
@@ -835,7 +841,8 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
835 835
     /* scan for end-of-paragraph [0x0d00 on offset parity to current content] */
836 836
     while ((!term) &&
837 837
            (offset >= 0) &&
838
-           (offset < map->len)) {
838
+           (offset < map->len))
839
+    {
839 840
         if (fmap_readn(map, &content, offset, sizeof(content)) != sizeof(content))
840 841
             return CL_EREAD;
841 842
 
... ...
@@ -874,12 +881,13 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
874 874
                         return CL_EREAD;
875 875
 
876 876
                     length = le32_to_host(length);
877
-                    if ((size_t)length >= (size_t)map->len - 8 - (size_t)offset) {
877
+                    new_offset = offset + (8 + length);
878
+                    if ((new_offset <= offset) || (new_offset >= map->len)) {
878 879
                         cli_errmsg("HWP3.x: Paragraph[%d, %d]: length value is too high, invalid. %u\n", level, p, length);
879 880
                         return CL_EPARSE;
880 881
                     }
882
+                    offset = new_offset;
881 883
 
882
-                    offset += (8 + length);
883 884
 #if HWP3_DEBUG
884 885
                     cli_errmsg("HWP3.x: Paragraph[%d, %d]: possible invalid usage of reserved special character %u\n", level, p, content);
885 886
                     return CL_EFORMAT;
... ...
@@ -906,12 +914,12 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
906 906
                         return CL_EREAD;
907 907
 
908 908
                     length = le32_to_host(length);
909
-                    if ((size_t)length >= (size_t)map->len - 8 - (size_t)offset) {
909
+                    new_offset = offset + (8 + length);
910
+                    if ((new_offset <= offset) || (new_offset >= map->len)) {
910 911
                         cli_errmsg("HWP3.x: Paragraph[%d, %d]: length value is too high, invalid. %u\n", level, p, length);
911 912
                         return CL_EPARSE;
912 913
                     }
913
-
914
-                    offset += (8 + length);
914
+                    offset = new_offset;
915 915
                     break;
916 916
                 }
917 917
             case 6: /* bookmark */
... ...
@@ -1050,11 +1058,13 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
1050 1050
 
1051 1051
                     /* cell information (27 bytes x ncells(offset 80 of table)) */
1052 1052
                     hwp3_debug("HWP3.x: Paragraph[%d, %d]: box cell info array starts @ %llu\n", level, p, (long long unsigned)offset);
1053
-                    if (27 * (size_t)ncells >= (size_t)map->len - (size_t)offset) {
1053
+
1054
+                    new_offset = offset + (27 * ncells);
1055
+                    if ((new_offset <= offset) || (new_offset >= map->len)) {
1054 1056
                         cli_errmsg("HWP3.x: Paragraph[%d, %d]: number of box cells is too high, invalid. %u\n", level, p, ncells);
1055 1057
                         return CL_EPARSE;
1056 1058
                     }
1057
-                    offset += (27 * ncells);
1059
+                    offset = new_offset;
1058 1060
 
1059 1061
                     /* cell paragraph list */
1060 1062
                     hwp3_debug("HWP3.x: Paragraph[%d, %d]: box cell paragraph list starts @ %llu\n", level, p, (long long unsigned)offset);
... ...
@@ -1095,12 +1105,12 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
1095 1095
                     hwp3_debug("HWP3.x: Paragraph[%d, %d]: drawing is %u additional bytes\n", level, p, size);
1096 1096
 
1097 1097
                     size = le32_to_host(size);
1098
-                    if ((size_t)size >= (size_t)map->len - 348 - (size_t)offset) {
1098
+                    new_offset = offset + (348 + size);
1099
+                    if ((new_offset <= offset) || (new_offset >= map->len)) {
1099 1100
                         cli_errmsg("HWP3.x: Paragraph[%d, %d]: image size value is too high, invalid. %u\n", level, p, size);
1100 1101
                         return CL_EPARSE;
1101 1102
                     }
1102
-
1103
-                    offset += (348 + size);
1103
+                    offset = new_offset;
1104 1104
 
1105 1105
                     /* caption paragraph list */
1106 1106
                     hwp3_debug("HWP3.x: Paragraph[%d, %d]: drawing caption paragraph list starts @ %llu\n", level, p, (long long unsigned)offset);
... ...
@@ -1449,12 +1459,12 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
1449 1449
                         return CL_EREAD;
1450 1450
 
1451 1451
                     length = le32_to_host(length);
1452
-                    if ((size_t)length >= (size_t)map->len - 8 - (size_t)offset) {
1452
+                    new_offset = offset + (8 + length);
1453
+                    if ((new_offset <= offset) || (new_offset >= map->len)) {
1453 1454
                         cli_errmsg("HWP3.x: Paragraph[%d, %d]: length value is too high, invalid. %u\n", level, p, length);
1454 1455
                         return CL_EPARSE;
1455 1456
                     }
1456
-
1457
-                    offset += (8 + length);
1457
+                    offset = new_offset;
1458 1458
                     break;
1459 1459
                 }
1460 1460
             case 30: /* bundle of blanks (ON SALE for 2.99!) */
... ...
@@ -1750,7 +1760,7 @@ static inline int parsehwp3_infoblk_1(cli_ctx *ctx, fmap_t *dmap, off_t *offset,
1750 1750
 static int hwp3_cb(void *cbdata, int fd, cli_ctx *ctx)
1751 1751
 {
1752 1752
     fmap_t *map, *dmap;
1753
-    off_t offset, start;
1753
+    off_t offset, start, new_offset;
1754 1754
     int i, t = 0, p = 0, last = 0, ret = CL_SUCCESS;
1755 1755
     uint16_t nstyles;
1756 1756
 #if HAVE_JSON
... ...
@@ -1803,13 +1813,12 @@ static int hwp3_cb(void *cbdata, int fd, cli_ctx *ctx)
1803 1803
         if (ctx->options & CL_SCAN_FILE_PROPERTIES)
1804 1804
             cli_jsonint(fonts, NULL, nfonts);
1805 1805
 #endif
1806
-        hwp3_debug("HWP3.x: Font Entry %d with %u entries @ offset %llu\n", i+1, nfonts, (long long unsigned)offset);
1807
-        if (2 + (size_t)nfonts * 40 >= (size_t)map->len - (size_t)offset) {
1806
+        new_offset = offset + (2 + nfonts * 40);
1807
+        if ((new_offset <= offset) || (new_offset >= map->len)) {
1808 1808
             cli_errmsg("HWP3.x: Font Entry: number of fonts is too high, invalid. %u\n", nfonts);
1809 1809
             return CL_EPARSE;
1810 1810
         }
1811
-
1812
-        offset += (2 + nfonts * 40);
1811
+        offset = new_offset;
1813 1812
     }
1814 1813
 
1815 1814
     /* Styles - 2 + (n x 238) bytes where n is the first 2 bytes of the section */
... ...
@@ -1825,11 +1834,11 @@ static int hwp3_cb(void *cbdata, int fd, cli_ctx *ctx)
1825 1825
         cli_jsonint(ctx->wrkproperty, "StyleCount", nstyles);
1826 1826
 #endif
1827 1827
     hwp3_debug("HWP3.x: %u Styles @ offset %llu\n", nstyles, (long long unsigned)offset);
1828
-    if (2 +  (size_t)nstyles * 238 >= (size_t)map->len -  (size_t)offset) {
1828
+    new_offset = offset + (2 + nstyles * 238);
1829
+    if ((new_offset <= offset) || (new_offset >= map->len)) {
1829 1830
         cli_errmsg("HWP3.x: Font Entry: number of font styles is too high, invalid. %u\n", nstyles);
1830 1831
         return CL_EPARSE;
1831 1832
     }
1832
-
1833 1833
     offset += (2 + nstyles * 238);
1834 1834
 
1835 1835
     last = 0;
... ...
@@ -1872,7 +1881,7 @@ int cli_scanhwp3(cli_ctx *ctx)
1872 1872
 {
1873 1873
     struct hwp3_docinfo docinfo;
1874 1874
     int ret = CL_SUCCESS;
1875
-    off_t offset = 0;
1875
+    off_t offset = 0, new_offset = 0;
1876 1876
     fmap_t *map = *ctx->fmap;
1877 1877
 
1878 1878
 #if HAVE_JSON
... ...
@@ -1904,11 +1913,12 @@ int cli_scanhwp3(cli_ctx *ctx)
1904 1904
 
1905 1905
     if (docinfo.di_infoblksize) {
1906 1906
         /* OPTIONAL TODO: HANDLE OPTIONAL INFORMATION BLOCK #0's FOR PRECLASS */
1907
-        if ((size_t)docinfo.di_infoblksize >= (size_t)map->len - (size_t)offset) {
1907
+        new_offset = offset + docinfo.di_infoblksize;
1908
+        if ((new_offset <= offset) || (new_offset >= map->len)) {
1908 1909
             cli_errmsg("HWP3.x: Doc info block size is too high, invalid. %u\n", docinfo.di_infoblksize);
1909 1910
             return CL_EPARSE;
1910 1911
         }
1911
-        offset += docinfo.di_infoblksize;
1912
+        offset = new_offset;
1912 1913
     }
1913 1914
 
1914 1915
     if (docinfo.di_compressed)