Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI: MRRM: Fix memory leaks and improve error handling

Add proper error handling and resource cleanup to prevent memory leaks
in add_boot_memory_ranges(). The function now checks for NULL return
from kobject_create_and_add(), uses local buffer for range names to
avoid dynamic allocation, and implements a cleanup path that removes
previously created sysfs groups and kobjects on failure.

This prevents resource leaks when kobject creation or sysfs group
creation fails during boot memory range initialization.

Signed-off-by: Kaushlendra Kumar <kaushlendra.kumar@intel.com>
Reviewed-by: Tony Luck <tony.luck@intel.com>
Link: https://patch.msgid.link/20251030023228.3956296-1-kaushlendra.kumar@intel.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Kaushlendra Kumar and committed by
Rafael J. Wysocki
4b93d211 6146a0f1

+37 -14
+37 -14
drivers/acpi/acpi_mrrm.c
··· 152 152 153 153 static __init int add_boot_memory_ranges(void) 154 154 { 155 - struct kobject *pkobj, *kobj; 155 + struct kobject *pkobj, *kobj, **kobjs; 156 156 int ret = -EINVAL; 157 - char *name; 157 + char name[16]; 158 + int i; 158 159 159 160 pkobj = kobject_create_and_add("memory_ranges", acpi_kobj); 161 + if (!pkobj) 162 + return -ENOMEM; 160 163 161 - for (int i = 0; i < mrrm_mem_entry_num; i++) { 162 - name = kasprintf(GFP_KERNEL, "range%d", i); 163 - if (!name) { 164 - ret = -ENOMEM; 165 - break; 166 - } 167 - 168 - kobj = kobject_create_and_add(name, pkobj); 169 - 170 - ret = sysfs_create_groups(kobj, memory_range_groups); 171 - if (ret) 172 - return ret; 164 + kobjs = kcalloc(mrrm_mem_entry_num, sizeof(*kobjs), GFP_KERNEL); 165 + if (!kobjs) { 166 + kobject_put(pkobj); 167 + return -ENOMEM; 173 168 } 174 169 170 + for (i = 0; i < mrrm_mem_entry_num; i++) { 171 + scnprintf(name, sizeof(name), "range%d", i); 172 + kobj = kobject_create_and_add(name, pkobj); 173 + if (!kobj) { 174 + ret = -ENOMEM; 175 + goto cleanup; 176 + } 177 + 178 + ret = sysfs_create_groups(kobj, memory_range_groups); 179 + if (ret) { 180 + kobject_put(kobj); 181 + goto cleanup; 182 + } 183 + kobjs[i] = kobj; 184 + } 185 + 186 + kfree(kobjs); 187 + return 0; 188 + 189 + cleanup: 190 + for (int j = 0; j < i; j++) { 191 + if (kobjs[j]) { 192 + sysfs_remove_groups(kobjs[j], memory_range_groups); 193 + kobject_put(kobjs[j]); 194 + } 195 + } 196 + kfree(kobjs); 197 + kobject_put(pkobj); 175 198 return ret; 176 199 } 177 200