kwo pushed a commit to branch master.

http://git.enlightenment.org/legacy/imlib2.git/commit/?id=993911b6e5af7936d6da317aa5e2d9eee2cacfb1

commit 993911b6e5af7936d6da317aa5e2d9eee2cacfb1
Author: Tobias Stoeckmann <[email protected]>
Date:   Sun Feb 19 15:58:14 2017 +0100

    Avoid out of boundary operations while parsing xpm
    
    It is possible to trigger out of boundary read and write accesses while
    parsing XPM files.
    
    1. If the color definition is shorter than the specified cpp, i.e.
       characters per pixel, an out of boundary write can be triggered.
       The write will modify stack memory and could therefore be used to
       corrupt local variables or return addresses.
    2. If the pixel area contains less than the required amount of
       characters per pixel, an out of boundary read can be triggered.
       This affects files with more than one character per pixel.
    3. If an out of memory condition occurs, a null pointer dereference can
       be triggered because the variable line is reallocated if not enough
       memory was available. Dereferencing line with an offset would lead
       to yet another out of boundary write, which will lead to a
       segmentation fault on almost every system out there.
---
 src/modules/loaders/loader_xpm.c | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/src/modules/loaders/loader_xpm.c b/src/modules/loaders/loader_xpm.c
index 5379a2f..412a1bd 100644
--- a/src/modules/loaders/loader_xpm.c
+++ b/src/modules/loaders/loader_xpm.c
@@ -202,7 +202,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, char 
progress_granularity,
                   if ((cpp > 5) || (cpp < 1))
                     {
                        fprintf(stderr,
-                               "IMLIB ERROR: XPM files with characters per 
pixel > 5 or < 1not supported\n");
+                               "IMLIB ERROR: XPM files with characters per 
pixel > 5 or < 1 not supported\n");
                        free(line);
                        fclose(f);
                        xpm_parse_done();
@@ -277,6 +277,14 @@ load(ImlibImage * im, ImlibProgressFunction progress, char 
progress_granularity,
                        col[0] = 0;
                        s[0] = 0;
                        len = strlen(line);
+                       if (len < cpp)
+                         {
+                            free(cmap);
+                            free(line);
+                            fclose(f);
+                            xpm_parse_done();
+                            return 0;
+                         }
                        strncpy(cmap[j].str, line, cpp);
                        cmap[j].str[cpp] = 0;
                        cmap[j].r = -1;
@@ -415,7 +423,8 @@ load(ImlibImage * im, ImlibProgressFunction progress, char 
progress_granularity,
 #define CM2_G()     (unsigned char)cmap[lookup[col[0] - ' '][col[1] - ' ']].g
 #define CM2_B()     (unsigned char)cmap[lookup[col[0] - ' '][col[1] - ' ']].b
                        for (i = 0;
-                            ((i < 65536) && (ptr < end) && (line[i])); i++)
+                            ((i < 65536) && (ptr < end)
+                             && (line[i]) && (line[i + 1])); i++)
                          {
                             col[0] = line[i++];
                             col[1] = line[i];
@@ -438,7 +447,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, char 
progress_granularity,
                        for (i = 0;
                             ((i < 65536) && (ptr < end) && (line[i])); i++)
                          {
-                            for (j = 0; j < cpp; j++, i++)
+                            for (j = 0; ((j < cpp) && (line[i])); j++, i++)
                               {
                                  col[j] = line[i];
                               }
@@ -506,8 +515,19 @@ load(ImlibImage * im, ImlibProgressFunction progress, char 
progress_granularity,
 
         if (i >= lsz)
           {
+             char               *nline;
+
              lsz += 256;
-             line = realloc(line, lsz);
+             nline = realloc(line, lsz);
+             if (nline == NULL)
+               {
+                  free(cmap);
+                  free(line);
+                  fclose(f);
+                  xpm_parse_done();
+                  return 0;
+               }
+             line = nline;
           }
 
         if ((context > 1) && (count >= pixels))

-- 


Reply via email to