From: "Panagiotis Issaris" The EFI driver allocates memory and writes into it without checking the success of the allocation. Furthermore, on failure of the firmware_register() it doesn't free the allocated memory and on failure of the subsys_create_file() calls it returns zero instead of the errorcode. Signed-off-by: Panagiotis Issaris Signed-off-by: Andrew Morton --- 25-akpm/drivers/firmware/efivars.c | 44 +++++++++++++++++++++++++++++-------- 1 files changed, 35 insertions(+), 9 deletions(-) diff -puN drivers/firmware/efivars.c~efi-fix-failure-handling drivers/firmware/efivars.c --- 25/drivers/firmware/efivars.c~efi-fix-failure-handling 2005-03-07 20:41:43.000000000 -0800 +++ 25-akpm/drivers/firmware/efivars.c 2005-03-07 20:41:43.000000000 -0800 @@ -665,14 +665,22 @@ efivars_init(void) { efi_status_t status = EFI_NOT_FOUND; efi_guid_t vendor_guid; - efi_char16_t *variable_name = kmalloc(1024, GFP_KERNEL); + efi_char16_t *variable_name; struct subsys_attribute *attr; unsigned long variable_name_size = 1024; - int i, rc = 0, error = 0; + int i, error = 0; if (!efi_enabled) return -ENODEV; + variable_name = kmalloc(variable_name_size, GFP_KERNEL); + if (!variable_name) { + printk(KERN_ERR "efivars: Memory allocation failed.\n"); + return -ENOMEM; + } + + memset(variable_name, 0, variable_name_size); + printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, EFIVARS_DATE); @@ -680,21 +688,27 @@ efivars_init(void) * For now we'll register the efi subsys within this driver */ - rc = firmware_register(&efi_subsys); + error = firmware_register(&efi_subsys); - if (rc) - return rc; + if (error) { + printk(KERN_ERR "efivars: Firmware registration failed with error %d.\n", error); + goto out_free; + } kset_set_kset_s(&vars_subsys, efi_subsys); - subsystem_register(&vars_subsys); + + error = subsystem_register(&vars_subsys); + + if (error) { + printk(KERN_ERR "efivars: Subsystem registration failed with error %d.\n", error); + goto out_firmware_unregister; + } /* * Per EFI spec, the maximum storage allocated for both * the variable name and variable data is 1024 bytes. */ - memset(variable_name, 0, 1024); - do { variable_name_size = 1024; @@ -734,8 +748,20 @@ efivars_init(void) error = subsys_create_file(&efi_subsys, attr); } + if (error) + printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error); + else + goto out_free; + + subsystem_unregister(&vars_subsys); + +out_firmware_unregister: + firmware_unregister(&efi_subsys); + +out_free: kfree(variable_name); - return 0; + + return error; } static void __exit _