@@ -96,7 +96,7 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
9696 struct acpi_prmt_handler_info * handler_info ;
9797 struct prm_handler_info * th ;
9898 struct prm_module_info * tm ;
99- u64 mmio_count = 0 ;
99+ u64 * mmio_count ;
100100 u64 cur_handler = 0 ;
101101 u32 module_info_size = 0 ;
102102 u64 mmio_range_size = 0 ;
@@ -105,6 +105,8 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
105105 module_info = (struct acpi_prmt_module_info * ) header ;
106106 module_info_size = struct_size (tm , handlers , module_info -> handler_info_count );
107107 tm = kmalloc (module_info_size , GFP_KERNEL );
108+ if (!tm )
109+ goto parse_prmt_out1 ;
108110
109111 guid_copy (& tm -> guid , (guid_t * ) module_info -> module_guid );
110112 tm -> major_rev = module_info -> major_rev ;
@@ -117,14 +119,24 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
117119 * Each module is associated with a list of addr
118120 * ranges that it can use during the service
119121 */
120- mmio_count = * (u64 * ) memremap (module_info -> mmio_list_pointer , 8 , MEMREMAP_WB );
121- mmio_range_size = struct_size (tm -> mmio_info , addr_ranges , mmio_count );
122+ mmio_count = (u64 * ) memremap (module_info -> mmio_list_pointer , 8 , MEMREMAP_WB );
123+ if (!mmio_count )
124+ goto parse_prmt_out2 ;
125+
126+ mmio_range_size = struct_size (tm -> mmio_info , addr_ranges , * mmio_count );
122127 tm -> mmio_info = kmalloc (mmio_range_size , GFP_KERNEL );
128+ if (!tm -> mmio_info )
129+ goto parse_prmt_out3 ;
130+
123131 temp_mmio = memremap (module_info -> mmio_list_pointer , mmio_range_size , MEMREMAP_WB );
132+ if (!temp_mmio )
133+ goto parse_prmt_out4 ;
124134 memmove (tm -> mmio_info , temp_mmio , mmio_range_size );
125135 } else {
126- mmio_range_size = struct_size (tm -> mmio_info , addr_ranges , mmio_count );
127- tm -> mmio_info = kmalloc (mmio_range_size , GFP_KERNEL );
136+ tm -> mmio_info = kmalloc (sizeof (* tm -> mmio_info ), GFP_KERNEL );
137+ if (!tm -> mmio_info )
138+ goto parse_prmt_out2 ;
139+
128140 tm -> mmio_info -> mmio_count = 0 ;
129141 }
130142
@@ -142,6 +154,15 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
142154 } while (++ cur_handler < tm -> handler_count && (handler_info = get_next_handler (handler_info )));
143155
144156 return 0 ;
157+
158+ parse_prmt_out4 :
159+ kfree (tm -> mmio_info );
160+ parse_prmt_out3 :
161+ memunmap (mmio_count );
162+ parse_prmt_out2 :
163+ kfree (tm );
164+ parse_prmt_out1 :
165+ return - ENOMEM ;
145166}
146167
147168#define GET_MODULE 0
0 commit comments