Message ID | 1573095182-22008-1-git-send-email-shenkai8@huawei.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | cpufreq: add NULL check to the store method of cpufreq | expand |
On 07-11-19, 02:53, Shen Kai wrote: > From: Kai Shen <shenkai8@huawei.com> > > Add NULL check in the store function here to avoid NULL callback invoking. > Though some interfaces of cpufreq are set as read-only, user can still get > write permission using chmod which can lead to a kernel crash. > > The following operations can lead to a kernel crash. > > chmod +w /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq > echo 1 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq > > This bug was found on linux 4.19 > > Signed-off-by: Kai Shen <shenkai8@huawei.com> > Reported-by: Feilong Lin <linfeilong@huawei.com> > Reviewed-by: Feilong Lin <linfeilong@huawei.com> > Acked-by: Viresh Kumar <viresh.kumar@linaro.org> > --- > drivers/cpufreq/cpufreq.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c > index bffc11b..4ccaa96 100644 > --- a/drivers/cpufreq/cpufreq.c > +++ b/drivers/cpufreq/cpufreq.c > @@ -947,6 +947,9 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, > struct freq_attr *fattr = to_attr(attr); > ssize_t ret = -EINVAL; > > + if (!fattr->store) > + return -EPERM; > + And this should be -EIO, I found that after looking at all the instances of struct kobj_type in the kernel :( Also there is another change you need to make. diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index dd1628192310..4bfaafde9083 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -933,6 +933,9 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) struct freq_attr *fattr = to_attr(attr); ssize_t ret; + if (!fattr->show) + return -EIO; + down_read(&policy->rwsem); ret = fattr->show(policy, buf); up_read(&policy->rwsem); as there is a write-only attribute (reset) in cpufreq stats.
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index bffc11b..4ccaa96 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -947,6 +947,9 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, struct freq_attr *fattr = to_attr(attr); ssize_t ret = -EINVAL; + if (!fattr->store) + return -EPERM; + /* * cpus_read_trylock() is used here to work around a circular lock * dependency problem with respect to the cpufreq_register_driver().