| From foo@baz Mon Sep 17 12:33:31 CEST 2018 |
| From: Anton Vasilyev <vasilyev@ispras.ru> |
| Date: Tue, 24 Jul 2018 18:10:38 +0300 |
| Subject: firmware: vpd: Fix section enabled flag on vpd_section_destroy |
| |
| From: Anton Vasilyev <vasilyev@ispras.ru> |
| |
| [ Upstream commit 45ca3f76de0507ecf143f770570af2942f263812 ] |
| |
| static struct ro_vpd and rw_vpd are initialized by vpd_sections_init() |
| in vpd_probe() based on header's ro and rw sizes. |
| In vpd_remove() vpd_section_destroy() performs deinitialization based |
| on enabled flag, which is set to true by vpd_sections_init(). |
| This leads to call of vpd_section_destroy() on already destroyed section |
| for probe-release-probe-release sequence if first probe performs |
| ro_vpd initialization and second probe does not initialize it. |
| |
| The patch adds changing enabled flag on vpd_section_destroy and adds |
| cleanup on the error path of vpd_sections_init. |
| |
| Found by Linux Driver Verification project (linuxtesting.org). |
| |
| Signed-off-by: Anton Vasilyev <vasilyev@ispras.ru> |
| Reviewed-by: Guenter Roeck <linux@roeck-us.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/firmware/google/vpd.c | 5 ++++- |
| 1 file changed, 4 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/firmware/google/vpd.c |
| +++ b/drivers/firmware/google/vpd.c |
| @@ -246,6 +246,7 @@ static int vpd_section_destroy(struct vp |
| sysfs_remove_bin_file(vpd_kobj, &sec->bin_attr); |
| kfree(sec->raw_name); |
| memunmap(sec->baseaddr); |
| + sec->enabled = false; |
| } |
| |
| return 0; |
| @@ -279,8 +280,10 @@ static int vpd_sections_init(phys_addr_t |
| ret = vpd_section_init("rw", &rw_vpd, |
| physaddr + sizeof(struct vpd_cbmem) + |
| header.ro_size, header.rw_size); |
| - if (ret) |
| + if (ret) { |
| + vpd_section_destroy(&ro_vpd); |
| return ret; |
| + } |
| } |
| |
| return 0; |