Message ID | 20200915055837.498-1-zhuguangqing83@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Zhang Rui |
Headers | show |
Series | thermal: Fix slab-out-of-bounds in thermal_cooling_device_stats_update() | expand |
On Tue, 2020-09-15 at 13:58 +0800, zhuguangqing83@gmail.com wrote: > From: zhuguangqing <zhuguangqing@xiaomi.com> > > In function thermal_cooling_device_stats_update(), if the input > parameter > new_state is greater or equal to stats->max_states, then it will > cause > slab-out-of-bounds error when execute the code as follows: > stats->trans_table[stats->state * stats->max_states + new_state]++; > > Two functions call the function > thermal_cooling_device_stats_update(). > 1. cur_state_store() > 2. thermal_cdev_set_cur_state() > Both of the two functions call cdev->ops->set_cur_state(cdev, state) > before thermal_cooling_device_stats_update(), if the return value is > not 0, then thermal_cooling_device_stats_update() will not be called. > So if all cdev->ops->set_cur_state(cdev, state) check validity of the > parameter state, then it's ok. Unfortunately, it's not now. > > We have two methods to avoid the slab-out-of-bounds error in > thermal_cooling_device_stats_update(). > 1. Check the validity of the parameter state in all > cdev->ops->set_cur_state(cdev, state). > 2. Check the validity of the parameter state in > thermal_cooling_device_stats_update(). > > Use method 2 in this patch. Because the modification is simple and > resolve the problem in the scope of "#ifdef > CONFIG_THERMAL_STATISTICS". > > Signed-off-by: zhuguangqing <zhuguangqing@xiaomi.com> Hi, Daniel, this patch is a similar fix as https://patchwork.kernel.org/project/linux-pm/patch/20200408041917.2329-4-rui.zhang@intel.com/ I think we'd better take the original fix from Takashi Iwai. And I will refresh and submit the patches that supports dynamic cooling states later when I have time. thanks, rui > --- > drivers/thermal/thermal_sysfs.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/thermal/thermal_sysfs.c > b/drivers/thermal/thermal_sysfs.c > index 8c231219e15d..9c49f744d79d 100644 > --- a/drivers/thermal/thermal_sysfs.c > +++ b/drivers/thermal/thermal_sysfs.c > @@ -756,7 +756,7 @@ void thermal_cooling_device_stats_update(struct > thermal_cooling_device *cdev, > > spin_lock(&stats->lock); > > - if (stats->state == new_state) > + if (stats->state == new_state || new_state >= stats- > >max_states) > goto unlock; > > update_time_in_state(stats);
diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index 8c231219e15d..9c49f744d79d 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -756,7 +756,7 @@ void thermal_cooling_device_stats_update(struct thermal_cooling_device *cdev, spin_lock(&stats->lock); - if (stats->state == new_state) + if (stats->state == new_state || new_state >= stats->max_states) goto unlock; update_time_in_state(stats);