diff options
| author | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2018-12-30 18:49:36 -0500 |
|---|---|---|
| committer | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2018-12-30 18:49:36 -0500 |
| commit | bba3d2daa8a9bc888902275401f15ef48fcdd378 (patch) | |
| tree | 82fc0c9b852be399200d374ed3eb0f91ce9811fe /drivers/rtc | |
| parent | e01b5781958de08942af341ce26768d5e0fbcdf5 (diff) | |
rtc: nvmem: fix possible use after free
In cas of probe failure, devres may free the memory allocated for
rtc->nvram before devm_rtc_release_device() is called. This leads to
rtc_nvram_unregister using it after being freed which may lead to a crash.
This has been shown to happen after commit 461e557b9727 ("rtc: nvmem: use
devm_nvmem_register()")
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Diffstat (limited to 'drivers/rtc')
| -rw-r--r-- | drivers/rtc/nvmem.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/rtc/nvmem.c b/drivers/rtc/nvmem.c index ebdfe8e3a1a0..dce518d5e50e 100644 --- a/drivers/rtc/nvmem.c +++ b/drivers/rtc/nvmem.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| 13 | #include <linux/nvmem-consumer.h> | 13 | #include <linux/nvmem-consumer.h> |
| 14 | #include <linux/rtc.h> | 14 | #include <linux/rtc.h> |
| 15 | #include <linux/slab.h> | ||
| 15 | #include <linux/sysfs.h> | 16 | #include <linux/sysfs.h> |
| 16 | 17 | ||
| 17 | /* | 18 | /* |
| @@ -45,9 +46,7 @@ static int rtc_nvram_register(struct rtc_device *rtc, | |||
| 45 | { | 46 | { |
| 46 | int err; | 47 | int err; |
| 47 | 48 | ||
| 48 | rtc->nvram = devm_kzalloc(rtc->dev.parent, | 49 | rtc->nvram = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL); |
| 49 | sizeof(struct bin_attribute), | ||
| 50 | GFP_KERNEL); | ||
| 51 | if (!rtc->nvram) | 50 | if (!rtc->nvram) |
| 52 | return -ENOMEM; | 51 | return -ENOMEM; |
| 53 | 52 | ||
| @@ -64,7 +63,7 @@ static int rtc_nvram_register(struct rtc_device *rtc, | |||
| 64 | err = sysfs_create_bin_file(&rtc->dev.parent->kobj, | 63 | err = sysfs_create_bin_file(&rtc->dev.parent->kobj, |
| 65 | rtc->nvram); | 64 | rtc->nvram); |
| 66 | if (err) { | 65 | if (err) { |
| 67 | devm_kfree(rtc->dev.parent, rtc->nvram); | 66 | kfree(rtc->nvram); |
| 68 | rtc->nvram = NULL; | 67 | rtc->nvram = NULL; |
| 69 | } | 68 | } |
| 70 | 69 | ||
| @@ -74,6 +73,8 @@ static int rtc_nvram_register(struct rtc_device *rtc, | |||
| 74 | static void rtc_nvram_unregister(struct rtc_device *rtc) | 73 | static void rtc_nvram_unregister(struct rtc_device *rtc) |
| 75 | { | 74 | { |
| 76 | sysfs_remove_bin_file(&rtc->dev.parent->kobj, rtc->nvram); | 75 | sysfs_remove_bin_file(&rtc->dev.parent->kobj, rtc->nvram); |
| 76 | kfree(rtc->nvram); | ||
| 77 | rtc->nvram = NULL; | ||
| 77 | } | 78 | } |
| 78 | 79 | ||
| 79 | /* | 80 | /* |
