CVE-2017-11464 (published 2017-07-19T21:29Z)

A SIGFPE is raised in the function box_blur_line of rsvg-filter.c in GNOME librsvg 2.40.17 during an attempted parse of a crafted SVG file, because of incorrect protection against division by zero.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 7.8, HIGH (CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-369
cwe_name: Divide By Zero
description: The product divides a value by zero.
extended_description: This weakness typically occurs when an unexpected value is provided to the product, or if an error occurs that is not properly detected. It frequently occurs in calculations involving physical dimensions such as size, length, width, and height.
         

Fix information:
repo_url: https://github.com/GNOME/librsvg
commit_details: repo_url: https://github.com/GNOME/librsvg
author: Federico Mena Quintero
author_date: 2017-06-27 17:12:51-05:00
msg: bgo#783835 - Don't divide by zero in box_blur_line() for gaussian blurs

We were making the decision to use box blurs, instead of a true
Gaussian kernel, based on the size of *both* x and y dimensions.  Do
them individually instead.
repository: repo_url: https://github.com/GNOME/librsvg
repo_name: GNOME/librsvg
description: Read-only mirror of https://gitlab.gnome.org/GNOME/librsvg
repo_language: Rust
owner: GNOME
file_changes: filename: rsvg-filter.c
change_type: ModificationType.MODIFY
diff: @@ -1417,6 +1417,8 @@ box_blur_line (gint box_width, gint even_offset,
                       kernel; it's the pixel to remove from the accumulator. */
     gint  *ac;     /* Accumulator for each channel                           */
 
+    g_assert (box_width > 0);
+
     ac = g_new0 (gint, bpp);
 
     /* The algorithm differs for even and odd-sized kernels.
@@ -1774,7 +1776,6 @@ gaussian_blur_surface (cairo_surface_t *in,
                        gdouble sx,
                        gdouble sy)
 {
-    gboolean use_box_blur;
     gint width, height;
     cairo_format_t in_format, out_format;
     gint in_stride;
@@ -1818,14 +1819,6 @@ gaussian_blur_surface (cairo_surface_t *in,
     if (sy < 0.0)
         sy = 0.0;
 
-    /* For small radiuses, use a true gaussian kernel; otherwise use three box blurs with
-     * clever offsets.
-     */
-    if (sx < 10.0 && sy < 10.0)
-        use_box_blur = FALSE;
-    else
-        use_box_blur = TRUE;
-
     /* Bail out by just copying? */
     if ((sx == 0.0 && sy == 0.0)
         || sx > 1000 || sy > 1000) {
@@ -1845,6 +1838,15 @@ gaussian_blur_surface (cairo_surface_t *in,
         int y;
         guchar *row_buffer = NULL;
         guchar *row1, *row2;
+        gboolean use_box_blur;
+
+        /* For small radiuses, use a true gaussian kernel; otherwise use three box blurs with
+         * clever offsets.
+         */
+        if (sx < 10.0)
+            use_box_blur = FALSE;
+        else
+            use_box_blur = TRUE;
 
         if (use_box_blur) {
             box_width = compute_box_blur_width (sx);
@@ -1900,6 +1902,15 @@ gaussian_blur_surface (cairo_surface_t *in,
         guchar *col_buffer;
         guchar *col1, *col2;
         int x;
+        gboolean use_box_blur;
+
+        /* For small radiuses, use a true gaussian kernel; otherwise use three box blurs with
+         * clever offsets.
+         */
+        if (sy < 10.0)
+            use_box_blur = FALSE;
+        else
+            use_box_blur = TRUE;
 
         /* twice the size so we can have the source pixels and the blurred pixels */
         col_buffer = g_new0 (guchar, height * bpp * 2);

programming_language: C