diff --git a/apps/codecs.c b/apps/codecs.c index 4d2dd34ce0..9f34d26e14 100644 --- a/apps/codecs.c +++ b/apps/codecs.c @@ -203,8 +203,9 @@ static int codec_load_ram(struct codec_api *api) return CODEC_ERROR; } - if (hdr->api_version > CODEC_API_VERSION - || hdr->api_version < CODEC_MIN_API_VERSION) { + if (hdr->api_version != CODEC_API_VERSION || + c_hdr->api_size > sizeof(struct codec_api)) + { logf("codec api version error"); lc_close(curr_handle); curr_handle = NULL; diff --git a/apps/plugin.c b/apps/plugin.c index cdbe340ddd..1a0aedf3cc 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -864,10 +864,8 @@ int plugin_load(const char* plugin, const void* parameter) } p_hdr = lc_get_header(current_plugin_handle); - hdr = p_hdr ? &p_hdr->lc_hdr : NULL; - if (hdr == NULL || hdr->magic != PLUGIN_MAGIC || hdr->target_id != TARGET_ID @@ -881,13 +879,15 @@ int plugin_load(const char* plugin, const void* parameter) splash(HZ*2, ID2P(LANG_PLUGIN_WRONG_MODEL)); return -1; } - if (hdr->api_version > PLUGIN_API_VERSION - || hdr->api_version < PLUGIN_MIN_API_VERSION) + + if (hdr->api_version != PLUGIN_API_VERSION || + p_hdr->api_size > sizeof(struct plugin_api)) { lc_close(current_plugin_handle); splash(HZ*2, ID2P(LANG_PLUGIN_WRONG_VERSION)); return -1; } + #if (CONFIG_PLATFORM & PLATFORM_NATIVE) /* tlsf crashes observed on arm with 0x4 aligned addresses */ plugin_size = ALIGN_UP(hdr->end_addr - pluginbuf, 0x8); diff --git a/apps/plugin.h b/apps/plugin.h index 286a5e2794..cf6a1bc4e4 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -157,13 +157,12 @@ int plugin_open(const char *plugin, const char *parameter); #define PLUGIN_MAGIC 0x526F634B /* RocK */ -/* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 265 - -/* update this to latest version if a change to the api struct breaks - backwards compatibility (and please take the opportunity to sort in any - new function which are "waiting" at the end of the function table) */ -#define PLUGIN_MIN_API_VERSION 260 +/* + * Increment this whenever a change breaks the plugin ABI, + * when this happens please take the opportunity to sort in + * any new functions "waiting" at the end of the list. + */ +#define PLUGIN_API_VERSION 266 /* 239 Marks the removal of ARCHOS HWCODEC and CHARCELL */ @@ -962,6 +961,7 @@ struct plugin_header { struct lc_header lc_hdr; /* must be the first */ enum plugin_status(*entry_point)(const void*); const struct plugin_api **api; + size_t api_size; }; #ifdef PLUGIN @@ -973,14 +973,15 @@ extern unsigned char plugin_end_addr[]; const struct plugin_header __header \ __attribute__ ((section (".header")))= { \ { PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \ - plugin_start_addr, plugin_end_addr }, plugin__start, &rb }; + plugin_start_addr, plugin_end_addr, }, \ + plugin__start, &rb, sizeof(struct plugin_api) }; #else /* PLATFORM_HOSTED */ #define PLUGIN_HEADER \ const struct plugin_api *rb DATA_ATTR; \ const struct plugin_header __header \ __attribute__((visibility("default"))) = { \ - { PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, NULL, NULL }, \ - plugin__start, &rb }; + { PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, NULL, NULL }, \ + plugin__start, &rb, sizeof(struct plugin_api) }; #endif /* CONFIG_PLATFORM */ #endif /* PLUGIN */ diff --git a/apps/plugins/imageviewer/image_decoder.c b/apps/plugins/imageviewer/image_decoder.c index eab1c01dbc..0c1776daaa 100644 --- a/apps/plugins/imageviewer/image_decoder.c +++ b/apps/plugins/imageviewer/image_decoder.c @@ -155,7 +155,10 @@ const struct image_decoder *load_decoder(struct loader_info *loader_info) goto error_close; } - if (lc_hdr->api_version != IMGDEC_API_VERSION) + if (lc_hdr->api_version != IMGDEC_API_VERSION || + hdr->img_api_size > sizeof(struct imgdec_api) || + hdr->plugin_api_version != PLUGIN_API_VERSION || + hdr->plugin_api_size > sizeof(struct plugin_api)) { rb->splashf(2*HZ, "%s decoder: Incompatible version.", name); goto error_close; diff --git a/apps/plugins/imageviewer/imageviewer.h b/apps/plugins/imageviewer/imageviewer.h index 19b5db15bb..ac15df5960 100644 --- a/apps/plugins/imageviewer/imageviewer.h +++ b/apps/plugins/imageviewer/imageviewer.h @@ -136,14 +136,17 @@ struct image_decoder { int x, int y, int width, int height); }; -#define IMGDEC_API_VERSION (PLUGIN_API_VERSION << 4 | 0) +#define IMGDEC_API_VERSION 1 /* image decoder header */ struct imgdec_header { struct lc_header lc_hdr; /* must be the first */ const struct image_decoder *decoder; const struct plugin_api **api; + unsigned short plugin_api_version; + size_t plugin_api_size; const struct imgdec_api **img_api; + size_t img_api_size; }; #ifdef IMGDEC @@ -157,15 +160,18 @@ extern const struct image_decoder image_decoder; const struct imgdec_header __header \ __attribute__ ((section (".header")))= { \ { PLUGIN_MAGIC, TARGET_ID, IMGDEC_API_VERSION, \ - plugin_start_addr, plugin_end_addr }, &image_decoder, &rb, &iv }; + plugin_start_addr, plugin_end_addr, }, &image_decoder, \ + &rb, PLUGIN_API_VERSION, sizeof(struct plugin_api), \ + &iv, sizeof(struct imgdec_api) }; #else /* PLATFORM_HOSTED */ #define IMGDEC_HEADER \ const struct plugin_api *rb DATA_ATTR; \ const struct imgdec_api *iv DATA_ATTR; \ const struct imgdec_header __header \ __attribute__((visibility("default"))) = { \ - { PLUGIN_MAGIC, TARGET_ID, IMGDEC_API_VERSION, \ - NULL, NULL }, &image_decoder, &rb, &iv }; + { PLUGIN_MAGIC, TARGET_ID, IMGDEC_API_VERSION, NULL, NULL }, \ + &image_decoder, &rb, PLUGIN_API_VERSION, sizeof(struct plugin_api), \ + &iv, sizeof(struct imgdec_api), }; #endif /* CONFIG_PLATFORM */ #endif diff --git a/apps/plugins/lib/overlay.c b/apps/plugins/lib/overlay.c index 0ecc1bf3e7..065273534e 100644 --- a/apps/plugins/lib/overlay.c +++ b/apps/plugins/lib/overlay.c @@ -83,9 +83,8 @@ enum plugin_status run_overlay(const void* parameter, goto error_close; } - - if (hdr->api_version > PLUGIN_API_VERSION - || hdr->api_version < PLUGIN_MIN_API_VERSION) + if (hdr->api_version != PLUGIN_API_VERSION || + p_hdr->api_size > sizeof(struct plugin_api)) { rb->splashf(2*HZ, "%s overlay: Incompatible version.", name); goto error_close; diff --git a/lib/rbcodec/codecs/codecs.h b/lib/rbcodec/codecs/codecs.h index fd19dcb6b5..aa9d2e8a0d 100644 --- a/lib/rbcodec/codecs/codecs.h +++ b/lib/rbcodec/codecs/codecs.h @@ -71,13 +71,12 @@ /* magic for encoder codecs */ #define CODEC_ENC_MAGIC 0x52454E43 /* RENC */ -/* increase this every time the api struct changes */ -#define CODEC_API_VERSION 49 - -/* update this to latest version if a change to the api struct breaks - backwards compatibility (and please take the opportunity to sort in any - new function which are "waiting" at the end of the function table) */ -#define CODEC_MIN_API_VERSION 49 +/* + * Increment this whenever a change breaks the codec ABI, + * when this happens please take the opportunity to sort in + * any new functions "waiting" at the end of the list. + */ +#define CODEC_API_VERSION 50 /* reasons for calling codec main entrypoint */ enum codec_entry_call_reason { @@ -228,6 +227,7 @@ struct codec_header { enum codec_status(*entry_point)(enum codec_entry_call_reason reason); enum codec_status(*run_proc)(void); struct codec_api **api; + size_t api_size; void * rec_extension[]; /* extension for encoders */ }; @@ -241,15 +241,16 @@ extern unsigned char plugin_end_addr[]; const struct codec_header __header \ __attribute__ ((section (".header")))= { \ { CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, \ - plugin_start_addr, plugin_end_addr }, codec_start, \ - codec_run, &ci }; + plugin_start_addr, plugin_end_addr }, \ + codec_start, codec_run, &ci, sizeof(struct codec_api) }; /* encoders */ #define CODEC_ENC_HEADER \ const struct codec_header __header \ __attribute__ ((section (".header")))= { \ { CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, \ - plugin_start_addr, plugin_end_addr }, codec_start, \ - codec_run, &ci, { enc_callback } }; + plugin_start_addr, plugin_end_addr }, \ + codec_start, codec_run, &ci, sizeof(struct codec_api), \ + { enc_callback } }; #else /* def SIMULATOR */ /* decoders */ @@ -257,13 +258,14 @@ extern unsigned char plugin_end_addr[]; const struct codec_header __header \ __attribute__((visibility("default"))) = { \ { CODEC_MAGIC, TARGET_ID, CODEC_API_VERSION, NULL, NULL }, \ - codec_start, codec_run, &ci }; + codec_start, codec_run, &ci, sizeof(struct codec_api) }; /* encoders */ #define CODEC_ENC_HEADER \ const struct codec_header __header \ __attribute__((visibility("default"))) = { \ { CODEC_ENC_MAGIC, TARGET_ID, CODEC_API_VERSION, NULL, NULL }, \ - codec_start, codec_run, &ci, { enc_callback } }; + codec_start, codec_run, &ci, sizeof(struct codec_api), \ + { enc_callback } }; #endif /* SIMULATOR */ #endif /* CODEC */