CVE-2017-7448: Divide By Zero (CWE-369)
value: The allocate_channel_framebuffer function in uncompressed_components.hh in Dropbox Lepton 1.2.1 allows remote attackers to cause a denial of service (divide-by-zero error and application crash) via a malformed JPEG image.
CWE description: The product divides a value by zero.
CVSS v3 base score: 5.5
Published: 2017-04-05T23:59Z
Repository: https://github.com/dropbox/lepton
Language: C++
Files changed: src/lepton/uncompressed_components.hh, src/vp8/model/model.hh
Commit date: 2017-04-05 00:04:19 -0700
Commit message: check divide by zero, fixing #86

Diff: diff --git a/src/lepton/uncompressed_components.hh b/src/lepton/uncompressed_components.hh
index 6fc6602..e9341c0 100644
--- a/src/lepton/uncompressed_components.hh
+++ b/src/lepton/uncompressed_components.hh
@@ -117,13 +117,19 @@ public:
         for (int cmp = 0; cmp < (int)header_.size() && cmp < cmpc_; cmp++) {
             int bc_allocated = header_[cmp].info_.bc;
             int64_t max_cmp_bc = max_number_of_blocks;
             max_cmp_bc *= header_[cmp].info_.bcv;
             max_cmp_bc *= header_[cmp].info_.bch;
-            max_cmp_bc /= total_req_blocks;
+            if (total_req_blocks) {
+                max_cmp_bc /= total_req_blocks;
+            }
             if (bc_allocated > max_cmp_bc) {
-                bc_allocated = max_cmp_bc - (max_cmp_bc % header_[cmp].info_.bch);
+                int rem = 0;
+                if (header_[cmp].info_.bch) {
+                    rem = (max_cmp_bc % header_[cmp].info_.bch);
+                }
+                bc_allocated = max_cmp_bc - rem;
             }
             if (cmp == desired_cmp) {
                 framebuffer->init(header_[cmp].info_.bch,
                                   header_[cmp].info_.bcv,
                                   bc_allocated,
diff --git a/src/vp8/model/model.hh b/src/vp8/model/model.hh
index 0f5549f..3bc0bd1 100644
--- a/src/vp8/model/model.hh
+++ b/src/vp8/model/model.hh
@@ -252,12 +252,14 @@ public:
             969, 838, 878, 886, 969, 838, 969, 838,
             1020, 854, 871, 870, 1010, 969, 1020, 1020,
             1020, 854, 854, 838, 1020, 838, 1020, 838
         };
         for (int coord = 0; coord < 64; ++coord) {
-            freqmax_[(int)color][coord] = (freqmax[coord] + quantization_table_[(int)color][coord] - 1)
-                / quantization_table_[(int)color][coord];
+            freqmax_[(int)color][coord] = (freqmax[coord] + quantization_table_[(int)color][coord] - 1);
+            if (quantization_table_[(int)color][coord]) {
+                freqmax_[(int)color][coord] /= quantization_table_[(int)color][coord];
+            }
             uint8_t max_len = uint16bit_length(freqmax_[(int)color][coord]);
             bitlen_freqmax_[(int)color][coord] = max_len;
             if (max_len > (int)RESIDUAL_NOISE_FLOOR) {
                 min_noise_threshold_[(int)color][coord] = max_len - RESIDUAL_NOISE_FLOOR;
             }

Vulnerable code:             max_cmp_bc /= total_req_blocks;
                bc_allocated = max_cmp_bc - (max_cmp_bc % header_[cmp].info_.bch);
            freqmax_[(int)color][coord] = (freqmax[coord] + quantization_table_[(int)color][coord] - 1)
                / quantization_table_[(int)color][coord];
Fixed code:             if (total_req_blocks) {
                max_cmp_bc /= total_req_blocks;
            }
                int rem = 0;
                if (header_[cmp].info_.bch) {
                    rem = (max_cmp_bc % header_[cmp].info_.bch);
                }
                bc_allocated = max_cmp_bc - rem;
            freqmax_[(int)color][coord] = (freqmax[coord] + quantization_table_[(int)color][coord] - 1);
            if (quantization_table_[(int)color][coord]) {
                freqmax_[(int)color][coord] /= quantization_table_[(int)color][coord];
            }