@@ -96,7 +96,7 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
96
96
struct acpi_prmt_handler_info * handler_info ;
97
97
struct prm_handler_info * th ;
98
98
struct prm_module_info * tm ;
99
- u64 mmio_count = 0 ;
99
+ u64 * mmio_count ;
100
100
u64 cur_handler = 0 ;
101
101
u32 module_info_size = 0 ;
102
102
u64 mmio_range_size = 0 ;
@@ -105,6 +105,8 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
105
105
module_info = (struct acpi_prmt_module_info * ) header ;
106
106
module_info_size = struct_size (tm , handlers , module_info -> handler_info_count );
107
107
tm = kmalloc (module_info_size , GFP_KERNEL );
108
+ if (!tm )
109
+ goto parse_prmt_out1 ;
108
110
109
111
guid_copy (& tm -> guid , (guid_t * ) module_info -> module_guid );
110
112
tm -> major_rev = module_info -> major_rev ;
@@ -117,14 +119,24 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
117
119
* Each module is associated with a list of addr
118
120
* ranges that it can use during the service
119
121
*/
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 );
122
127
tm -> mmio_info = kmalloc (mmio_range_size , GFP_KERNEL );
128
+ if (!tm -> mmio_info )
129
+ goto parse_prmt_out3 ;
130
+
123
131
temp_mmio = memremap (module_info -> mmio_list_pointer , mmio_range_size , MEMREMAP_WB );
132
+ if (!temp_mmio )
133
+ goto parse_prmt_out4 ;
124
134
memmove (tm -> mmio_info , temp_mmio , mmio_range_size );
125
135
} 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
+
128
140
tm -> mmio_info -> mmio_count = 0 ;
129
141
}
130
142
@@ -142,6 +154,15 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end)
142
154
} while (++ cur_handler < tm -> handler_count && (handler_info = get_next_handler (handler_info )));
143
155
144
156
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 ;
145
166
}
146
167
147
168
#define GET_MODULE 0
0 commit comments