Skip to content

Commit c52ca71

Browse files
aubreylirafaeljw
authored andcommitted
ACPI: PRM: Handle memory allocation and memory remap failure
Handle memory allocation and memory remap failure in acpi_parse_prmt() when system runs out of memory to avoid the potential NULL pointer dereference errors. Signed-off-by: Aubrey Li <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent caa2bd0 commit c52ca71

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

drivers/acpi/prmt.c

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)