@@ -5764,39 +5764,48 @@ static term nif_atomvm_read_priv(Context *ctx, int argc, term argv[])
57645764 uint32_t size ;
57655765 struct ListHead * item ;
57665766 term result = UNDEFINED_ATOM ;
5767+ bool invalid_pack = false;
57675768 struct ListHead * avmpack_data = synclist_rdlock (& glb -> avmpack_data );
57685769 LIST_FOR_EACH (item , avmpack_data ) {
57695770 struct AVMPackData * avmpack_data = GET_LIST_ENTRY (item , struct AVMPackData , avmpack_head );
57705771 bool prev_in_use = avmpack_data -> in_use ;
57715772 avmpack_data -> in_use = true;
57725773 if (avmpack_find_section_by_name (
57735774 avmpack_data -> data , avmpack_data -> size , complete_path , & bin_data , & size )) {
5774- // Bound the length prefix to the section payload against a corrupt file size.
5775- if (size >= sizeof (uint32_t )) {
5776- uint32_t file_size = READ_32_ALIGNED ((uint32_t * ) bin_data );
5777- if (file_size <= size - sizeof (uint32_t )) {
5778- free (complete_path );
5779- complete_path = NULL ;
5780- if (UNLIKELY (memory_ensure_free_opt (
5781- ctx , TERM_BOXED_REFC_BINARY_SIZE , MEMORY_CAN_SHRINK )
5782- != MEMORY_GC_OK )) {
5783- avmpack_data -> in_use = prev_in_use ;
5784- synclist_unlock (& glb -> avmpack_data );
5785- RAISE_ERROR (OUT_OF_MEMORY_ATOM );
5786- }
5787- result = term_from_const_binary (((uint8_t * ) bin_data ) + sizeof (uint32_t ),
5788- file_size , & ctx -> heap , ctx -> global );
5789- break ;
5790- }
5775+ // The length prefix must fit the section payload, otherwise the pack is corrupt.
5776+ if (UNLIKELY (size < sizeof (uint32_t ))) {
5777+ avmpack_data -> in_use = prev_in_use ;
5778+ invalid_pack = true;
5779+ break ;
57915780 }
5792- avmpack_data -> in_use = prev_in_use ;
5793- } else {
5794- avmpack_data -> in_use = prev_in_use ;
5781+ uint32_t file_size = READ_32_ALIGNED ((uint32_t * ) bin_data );
5782+ if (UNLIKELY (file_size > size - sizeof (uint32_t ))) {
5783+ avmpack_data -> in_use = prev_in_use ;
5784+ invalid_pack = true;
5785+ break ;
5786+ }
5787+ free (complete_path );
5788+ complete_path = NULL ;
5789+ if (UNLIKELY (memory_ensure_free_opt (ctx , TERM_BOXED_REFC_BINARY_SIZE , MEMORY_CAN_SHRINK )
5790+ != MEMORY_GC_OK )) {
5791+ avmpack_data -> in_use = prev_in_use ;
5792+ synclist_unlock (& glb -> avmpack_data );
5793+ RAISE_ERROR (OUT_OF_MEMORY_ATOM );
5794+ }
5795+ result = term_from_const_binary (
5796+ ((uint8_t * ) bin_data ) + sizeof (uint32_t ), file_size , & ctx -> heap , ctx -> global );
5797+ break ;
57955798 }
5799+ avmpack_data -> in_use = prev_in_use ;
57965800 }
57975801 synclist_unlock (& glb -> avmpack_data );
57985802
57995803 free (complete_path );
5804+
5805+ if (UNLIKELY (invalid_pack )) {
5806+ RAISE_ERROR (INVALID_AVM_ATOM );
5807+ }
5808+
58005809 return result ;
58015810}
58025811
0 commit comments