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)
downloadefl-bdebfe7962f9de9a1aacc5408794e07911db7348.tar.gz
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 ececb6d027..b20414b26b 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);