diff options
author | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2015-08-24 11:39:12 +0900 |
---|---|---|
committer | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2015-08-24 11:39:12 +0900 |
commit | bdebfe7962f9de9a1aacc5408794e07911db7348 (patch) | |
tree | 602f4bca49ed470ab635dbc3b4e7fa702108c939 | |
parent | b6d2dc2cdf7103142936373eb85f991e6cba6762 (diff) | |
download | efl-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.c | 24 |
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(¶ms); info = opj_create_decompress(format); |