summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-08-24 11:39:12 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-08-24 11:39:12 +0900
commitbdebfe7962f9de9a1aacc5408794e07911db7348 (patch)
tree602f4bca49ed470ab635dbc3b4e7fa702108c939
parentb6d2dc2cdf7103142936373eb85f991e6cba6762 (diff)
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
-rw-r--r--src/modules/evas/image_loaders/jp2k/evas_image_load_jp2k.c24
1 files 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,
68 opj_image_t *image; 68 opj_image_t *image;
69 int format; 69 int format;
70 int k; 70 int k;
71 const unsigned char sig_j2k[2] =
72 { 0xff, 0x4f };
73 const unsigned char sig_jp2[10] =
74 { 0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a };
71 75
72 if (length < 2) 76 if (length < 2)
73 { 77 {
@@ -75,10 +79,9 @@ evas_image_load_file_head_jp2k_internal(unsigned int *w, unsigned int *h,
75 return EINA_FALSE; 79 return EINA_FALSE;
76 } 80 }
77 81
78 if (((unsigned char *)map)[0] == 0xFF && ((unsigned char *)map)[1] == 0x4F) 82 if ((length >= 2) && (!memcmp(map, sig_j2k, 2))) format = CODEC_J2K;
79 format = CODEC_J2K; 83 else if ((length >= 10) && (!memcmp(map, sig_jp2, 10))) format = CODEC_JP2;
80 else 84 else return EINA_FALSE;
81 format = CODEC_JP2;
82 85
83 memset(&event_mgr, 0, sizeof(event_mgr)); 86 memset(&event_mgr, 0, sizeof(event_mgr));
84 event_mgr.error_handler = _jp2k_error_cb; 87 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,
153 unsigned int *iter; 156 unsigned int *iter;
154 int format; 157 int format;
155 int idx; 158 int idx;
156 159 const unsigned char sig_j2k[2] =
157 if (((unsigned char *)map)[0] == 0xFF && ((unsigned char *)map)[1] == 0x4F) 160 { 0xff, 0x4f };
158 format = CODEC_J2K; 161 const unsigned char sig_jp2[10] =
159 else 162 { 0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a };
160 format = CODEC_JP2; 163
164 if ((length >= 2) && (!memcmp(map, sig_j2k, 2))) format = CODEC_J2K;
165 else if ((length >= 10) && (!memcmp(map, sig_jp2, 10))) format = CODEC_JP2;
166 else return EINA_FALSE;
161 167
162 opj_set_default_decoder_parameters(&params); 168 opj_set_default_decoder_parameters(&params);
163 info = opj_create_decompress(format); 169 info = opj_create_decompress(format);