raster pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=bdebfe7962f9de9a1aacc5408794e07911db7348

commit bdebfe7962f9de9a1aacc5408794e07911db7348
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
Date:   Mon Aug 24 11:39:12 2015 +0900

    efl - jp2k loader - guard against openjpeg bug tha causes an abort
    
    so... if you load a non-jp2k file using openjpeg, you can get an abort
    deep inside the openjpeg library that we can't do anything about. we
    set all error handlers but literally the openjpeg code has ab assert
    there that causes this bug. it shouldn't and newer opengjpeg libs have
    it removed, but 1.5.2 has it and this causes an untrappable crash.
    this is simply bad behavior in openjpeg not allowing it to be used
    safely to loade image files. the relevant backtrace:
    
        w=w@entry=0x7fffffffb548, h=h@entry=0x7fffffffb54c,
        alpha=alpha@entry=0x7fffffffb556 "", map=map@entry=0x7fff29ac2000,
        length=<optimized out>, error=error@entry=0x7fffffffb5bc,
        opts=<optimized out>)
        at modules/evas/image_loaders/jp2k/evas_image_load_jp2k.c:111
    
    the relevant code in openjpeg:
    
    int cio_numbytesleft(opj_cio_t *cio) {
      assert((cio->end - cio->bp) >= 0);
            return cio->end - cio->bp;
    }
    
    so that assert is triggered. and nothing can be done about it which is
    pretty poor.
    
    so an upgrade of openjpeg should fix this as in newer versions have
    dropped the assert line in that function, but until poeople have that from
    their distro, this adds magic number checks for file headers that avoids
    using openjpeg if it's not "apparently" a jp2k file. this does not
    stop a corrupt file or a maliciously designed file still causing this
    problem, but it does just result in an abort() and isnn't seemingly an
    overflow isse that can be exploted, so if you still suffer, find a way to
    upgrade openjpeg to 2.x. until then... this reduces inadvertent damage.
    
    @fix
---
 .../evas/image_loaders/jp2k/evas_image_load_jp2k.c | 24 ++++++++++++++--------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/src/modules/evas/image_loaders/jp2k/evas_image_load_jp2k.c 
b/src/modules/evas/image_loaders/jp2k/evas_image_load_jp2k.c
index ececb6d..b20414b 100644
--- a/src/modules/evas/image_loaders/jp2k/evas_image_load_jp2k.c
+++ b/src/modules/evas/image_loaders/jp2k/evas_image_load_jp2k.c
@@ -68,6 +68,10 @@ evas_image_load_file_head_jp2k_internal(unsigned int *w, 
unsigned int *h,
    opj_image_t *image;
    int format;
    int k;
+   const unsigned char sig_j2k[2] =
+     { 0xff, 0x4f };
+   const unsigned char sig_jp2[10] =
+     { 0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a };
 
    if (length < 2)
      {
@@ -75,10 +79,9 @@ evas_image_load_file_head_jp2k_internal(unsigned int *w, 
unsigned int *h,
         return EINA_FALSE;
      }
 
-   if (((unsigned char *)map)[0] == 0xFF && ((unsigned char *)map)[1] == 0x4F)
-     format = CODEC_J2K;
-   else
-     format = CODEC_JP2;
+   if ((length >= 2) && (!memcmp(map, sig_j2k, 2))) format = CODEC_J2K;
+   else if ((length >= 10) && (!memcmp(map, sig_jp2, 10))) format = CODEC_JP2;
+   else return EINA_FALSE;
 
    memset(&event_mgr, 0, sizeof(event_mgr));
    event_mgr.error_handler = _jp2k_error_cb;
@@ -153,11 +156,14 @@ 
evas_image_load_file_data_jp2k_internal(Evas_Image_Load_Opts *opts EINA_UNUSED,
    unsigned int *iter;
    int format;
    int idx;
-
-   if (((unsigned char *)map)[0] == 0xFF && ((unsigned char *)map)[1] == 0x4F)
-     format = CODEC_J2K;
-   else
-     format = CODEC_JP2;
+   const unsigned char sig_j2k[2] =
+     { 0xff, 0x4f };
+   const unsigned char sig_jp2[10] =
+     { 0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a };
+
+   if ((length >= 2) && (!memcmp(map, sig_j2k, 2))) format = CODEC_J2K;
+   else if ((length >= 10) && (!memcmp(map, sig_jp2, 10))) format = CODEC_JP2;
+   else return EINA_FALSE;
 
    opj_set_default_decoder_parameters(&params);
    info = opj_create_decompress(format);

-- 


Reply via email to