fix(libs): fix memcmp memory access overflow (#3205)
Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
@@ -102,7 +102,9 @@ static lv_res_t decoder_info(struct _lv_img_decoder_t * decoder, const void * sr
|
|||||||
/*If it's a PNG file in a C array...*/
|
/*If it's a PNG file in a C array...*/
|
||||||
else if(src_type == LV_IMG_SRC_VARIABLE) {
|
else if(src_type == LV_IMG_SRC_VARIABLE) {
|
||||||
const lv_img_dsc_t * img_dsc = src;
|
const lv_img_dsc_t * img_dsc = src;
|
||||||
|
const uint32_t data_size = img_dsc->data_size;
|
||||||
const uint8_t magic[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a};
|
const uint8_t magic[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a};
|
||||||
|
if(data_size < sizeof(magic)) return LV_RES_INV;
|
||||||
if(memcmp(magic, img_dsc->data, sizeof(magic))) return LV_RES_INV;
|
if(memcmp(magic, img_dsc->data, sizeof(magic))) return LV_RES_INV;
|
||||||
header->always_zero = 0;
|
header->always_zero = 0;
|
||||||
header->cf = img_dsc->header.cf; /*Save the color format*/
|
header->cf = img_dsc->header.cf; /*Save the color format*/
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ static lv_res_t decoder_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc
|
|||||||
lv_coord_t len, uint8_t * buf);
|
lv_coord_t len, uint8_t * buf);
|
||||||
static void decoder_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc);
|
static void decoder_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc);
|
||||||
static size_t input_func(JDEC * jd, uint8_t * buff, size_t ndata);
|
static size_t input_func(JDEC * jd, uint8_t * buff, size_t ndata);
|
||||||
static int is_jpg(const uint8_t * raw_data);
|
static int is_jpg(const uint8_t * raw_data, size_t len);
|
||||||
static void lv_sjpg_cleanup(SJPEG * sjpeg);
|
static void lv_sjpg_cleanup(SJPEG * sjpeg);
|
||||||
static void lv_sjpg_free(SJPEG * sjpeg);
|
static void lv_sjpg_free(SJPEG * sjpeg);
|
||||||
|
|
||||||
@@ -157,8 +157,9 @@ static lv_res_t decoder_info(lv_img_decoder_t * decoder, const void * src, lv_im
|
|||||||
lv_res_t ret = LV_RES_OK;
|
lv_res_t ret = LV_RES_OK;
|
||||||
|
|
||||||
if(src_type == LV_IMG_SRC_VARIABLE) {
|
if(src_type == LV_IMG_SRC_VARIABLE) {
|
||||||
uint8_t * raw_sjpeg_data = (uint8_t *)((lv_img_dsc_t *)src)->data;
|
const lv_img_dsc_t * img_dsc = src;
|
||||||
const uint32_t raw_sjpeg_data_size = ((lv_img_dsc_t *)src)->data_size;
|
uint8_t * raw_sjpeg_data = (uint8_t *)img_dsc->data;
|
||||||
|
const uint32_t raw_sjpeg_data_size = img_dsc->data_size;
|
||||||
|
|
||||||
if(!strncmp((char *)raw_sjpeg_data, "_SJPG__", strlen("_SJPG__"))) {
|
if(!strncmp((char *)raw_sjpeg_data, "_SJPG__", strlen("_SJPG__"))) {
|
||||||
|
|
||||||
@@ -175,7 +176,7 @@ static lv_res_t decoder_info(lv_img_decoder_t * decoder, const void * src, lv_im
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(is_jpg(raw_sjpeg_data) == true) {
|
else if(is_jpg(raw_sjpeg_data, raw_sjpeg_data_size) == true) {
|
||||||
header->always_zero = 0;
|
header->always_zero = 0;
|
||||||
header->cf = LV_IMG_CF_RAW;
|
header->cf = LV_IMG_CF_RAW;
|
||||||
|
|
||||||
@@ -348,6 +349,7 @@ static lv_res_t decoder_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t *
|
|||||||
if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
|
if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
|
||||||
uint8_t * data;
|
uint8_t * data;
|
||||||
SJPEG * sjpeg = (SJPEG *) dsc->user_data;
|
SJPEG * sjpeg = (SJPEG *) dsc->user_data;
|
||||||
|
const uint32_t raw_sjpeg_data_size = ((lv_img_dsc_t *)dsc->src)->data_size;
|
||||||
if(sjpeg == NULL) {
|
if(sjpeg == NULL) {
|
||||||
sjpeg = lv_mem_alloc(sizeof(SJPEG));
|
sjpeg = lv_mem_alloc(sizeof(SJPEG));
|
||||||
if(!sjpeg) return LV_RES_INV;
|
if(!sjpeg) return LV_RES_INV;
|
||||||
@@ -420,8 +422,7 @@ static lv_res_t decoder_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t *
|
|||||||
dsc->img_data = NULL;
|
dsc->img_data = NULL;
|
||||||
return lv_ret;
|
return lv_ret;
|
||||||
}
|
}
|
||||||
|
else if(is_jpg(sjpeg->sjpeg_data, raw_sjpeg_data_size) == true) {
|
||||||
else if(is_jpg(sjpeg->sjpeg_data) == true) {
|
|
||||||
|
|
||||||
uint8_t * workb_temp = lv_mem_alloc(TJPGD_WORKBUFF_SIZE);
|
uint8_t * workb_temp = lv_mem_alloc(TJPGD_WORKBUFF_SIZE);
|
||||||
if(! workb_temp) {
|
if(! workb_temp) {
|
||||||
@@ -889,9 +890,10 @@ static void decoder_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_jpg(const uint8_t * raw_data)
|
static int is_jpg(const uint8_t * raw_data, size_t len)
|
||||||
{
|
{
|
||||||
const uint8_t jpg_signature[] = {0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46};
|
const uint8_t jpg_signature[] = {0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46};
|
||||||
|
if(len < sizeof(jpg_signature)) return false;
|
||||||
return memcmp(jpg_signature, raw_data, sizeof(jpg_signature)) == 0;
|
return memcmp(jpg_signature, raw_data, sizeof(jpg_signature)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user