Browse code

bb12122: Adding checks to validate offsets parsed from file.

Micah Snyder authored on 2018/05/22 05:58:51
Showing 1 changed files
... ...
@@ -833,7 +833,9 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
833 833
         hwp3_debug("HWP3.x: Paragraph[%d, %d]: content starts @ offset %llu\n", level, p, (long long unsigned)offset);
834 834
 
835 835
     /* scan for end-of-paragraph [0x0d00 on offset parity to current content] */
836
-    while (!term) {
836
+    while ((!term) &&
837
+           (offset >= 0) &&
838
+           (offset < map->len)) {
837 839
         if (fmap_readn(map, &content, offset, sizeof(content)) != sizeof(content))
838 840
             return CL_EREAD;
839 841
 
... ...
@@ -872,6 +874,11 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
872 872
                         return CL_EREAD;
873 873
 
874 874
                     length = le32_to_host(length);
875
+                    if ((size_t)length >= (size_t)map->len - 8 - (size_t)offset) {
876
+                        cli_errmsg("HWP3.x: Paragraph[%d, %d]: length value is too high, invalid. %u\n", level, p, length);
877
+                        return CL_EPARSE;
878
+                    }
879
+
875 880
                     offset += (8 + length);
876 881
 #if HWP3_DEBUG
877 882
                     cli_errmsg("HWP3.x: Paragraph[%d, %d]: possible invalid usage of reserved special character %u\n", level, p, content);
... ...
@@ -899,6 +906,11 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
899 899
                         return CL_EREAD;
900 900
 
901 901
                     length = le32_to_host(length);
902
+                    if ((size_t)length >= (size_t)map->len - 8 - (size_t)offset) {
903
+                        cli_errmsg("HWP3.x: Paragraph[%d, %d]: length value is too high, invalid. %u\n", level, p, length);
904
+                        return CL_EPARSE;
905
+                    }
906
+
902 907
                     offset += (8 + length);
903 908
                     break;
904 909
                 }
... ...
@@ -1038,6 +1050,10 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
1038 1038
 
1039 1039
                     /* cell information (27 bytes x ncells(offset 80 of table)) */
1040 1040
                     hwp3_debug("HWP3.x: Paragraph[%d, %d]: box cell info array starts @ %llu\n", level, p, (long long unsigned)offset);
1041
+                    if (27 * (size_t)ncells >= (size_t)map->len - (size_t)offset) {
1042
+                        cli_errmsg("HWP3.x: Paragraph[%d, %d]: number of box cells is too high, invalid. %u\n", level, p, ncells);
1043
+                        return CL_EPARSE;
1044
+                    }
1041 1045
                     offset += (27 * ncells);
1042 1046
 
1043 1047
                     /* cell paragraph list */
... ...
@@ -1079,6 +1095,11 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
1079 1079
                     hwp3_debug("HWP3.x: Paragraph[%d, %d]: drawing is %u additional bytes\n", level, p, size);
1080 1080
 
1081 1081
                     size = le32_to_host(size);
1082
+                    if ((size_t)size >= (size_t)map->len - 348 - (size_t)offset) {
1083
+                        cli_errmsg("HWP3.x: Paragraph[%d, %d]: image size value is too high, invalid. %u\n", level, p, size);
1084
+                        return CL_EPARSE;
1085
+                    }
1086
+
1082 1087
                     offset += (348 + size);
1083 1088
 
1084 1089
                     /* caption paragraph list */
... ...
@@ -1428,6 +1449,10 @@ static inline int parsehwp3_paragraph(cli_ctx *ctx, fmap_t *map, int p, int leve
1428 1428
                         return CL_EREAD;
1429 1429
 
1430 1430
                     length = le32_to_host(length);
1431
+                    if ((size_t)length >= (size_t)map->len - 8 - (size_t)offset) {
1432
+                        cli_errmsg("HWP3.x: Paragraph[%d, %d]: length value is too high, invalid. %u\n", level, p, length);
1433
+                        return CL_EPARSE;
1434
+                    }
1431 1435
 
1432 1436
                     offset += (8 + length);
1433 1437
                     break;
... ...
@@ -1779,6 +1804,10 @@ static int hwp3_cb(void *cbdata, int fd, cli_ctx *ctx)
1779 1779
             cli_jsonint(fonts, NULL, nfonts);
1780 1780
 #endif
1781 1781
         hwp3_debug("HWP3.x: Font Entry %d with %u entries @ offset %llu\n", i+1, nfonts, (long long unsigned)offset);
1782
+        if (2 + (size_t)nfonts * 40 >= (size_t)map->len - (size_t)offset) {
1783
+            cli_errmsg("HWP3.x: Font Entry: number of fonts is too high, invalid. %u\n", nfonts);
1784
+            return CL_EPARSE;
1785
+        }
1782 1786
 
1783 1787
         offset += (2 + nfonts * 40);
1784 1788
     }
... ...
@@ -1796,6 +1825,10 @@ static int hwp3_cb(void *cbdata, int fd, cli_ctx *ctx)
1796 1796
         cli_jsonint(ctx->wrkproperty, "StyleCount", nstyles);
1797 1797
 #endif
1798 1798
     hwp3_debug("HWP3.x: %u Styles @ offset %llu\n", nstyles, (long long unsigned)offset);
1799
+    if (2 +  (size_t)nstyles * 238 >= (size_t)map->len -  (size_t)offset) {
1800
+        cli_errmsg("HWP3.x: Font Entry: number of font styles is too high, invalid. %u\n", nstyles);
1801
+        return CL_EPARSE;
1802
+    }
1799 1803
 
1800 1804
     offset += (2 + nstyles * 238);
1801 1805
 
... ...
@@ -1840,6 +1873,7 @@ int cli_scanhwp3(cli_ctx *ctx)
1840 1840
     struct hwp3_docinfo docinfo;
1841 1841
     int ret = CL_SUCCESS;
1842 1842
     off_t offset = 0;
1843
+    fmap_t *map = *ctx->fmap;
1843 1844
 
1844 1845
 #if HAVE_JSON
1845 1846
     /*
... ...
@@ -1870,6 +1904,10 @@ int cli_scanhwp3(cli_ctx *ctx)
1870 1870
 
1871 1871
     if (docinfo.di_infoblksize) {
1872 1872
         /* OPTIONAL TODO: HANDLE OPTIONAL INFORMATION BLOCK #0's FOR PRECLASS */
1873
+        if ((size_t)docinfo.di_infoblksize >= (size_t)map->len - (size_t)offset) {
1874
+            cli_errmsg("HWP3.x: Doc info block size is too high, invalid. %u\n", docinfo.di_infoblksize);
1875
+            return CL_EPARSE;
1876
+        }
1873 1877
         offset += docinfo.di_infoblksize;
1874 1878
     }
1875 1879