Skip to content

Commit 05eeee2

Browse files
groeckrafaeljw
authored andcommitted
thermal/core: Protect sysfs accesses to thermal operations with thermal zone mutex
Protect access to thermal operations against thermal zone removal by acquiring the thermal zone device mutex. After acquiring the mutex, check if the thermal zone device is registered and abort the operation if not. With this change, we can call __thermal_zone_device_update() instead of thermal_zone_device_update() from trip_point_temp_store() and from emul_temp_store(). Similar, we can call __thermal_zone_set_trips() instead of thermal_zone_set_trips() from trip_point_hyst_store(). Signed-off-by: Guenter Roeck <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent ea37bec commit 05eeee2

File tree

3 files changed

+69
-16
lines changed

3 files changed

+69
-16
lines changed

drivers/thermal/thermal_core.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,8 @@ static void thermal_zone_device_init(struct thermal_zone_device *tz)
403403
pos->initialized = false;
404404
}
405405

406-
static void __thermal_zone_device_update(struct thermal_zone_device *tz,
407-
enum thermal_notify_event event)
406+
void __thermal_zone_device_update(struct thermal_zone_device *tz,
407+
enum thermal_notify_event event)
408408
{
409409
int count;
410410

drivers/thermal/thermal_core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ int thermal_register_governor(struct thermal_governor *);
109109
void thermal_unregister_governor(struct thermal_governor *);
110110
int thermal_zone_device_set_policy(struct thermal_zone_device *, char *);
111111
int thermal_build_list_of_policies(char *buf);
112+
void __thermal_zone_device_update(struct thermal_zone_device *tz,
113+
enum thermal_notify_event event);
112114

113115
/* Helpers */
114116
void thermal_zone_set_trips(struct thermal_zone_device *tz);

drivers/thermal/thermal_sysfs.c

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,14 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
9292
if (sscanf(attr->attr.name, "trip_point_%d_type", &trip) != 1)
9393
return -EINVAL;
9494

95-
result = tz->ops->get_trip_type(tz, trip, &type);
95+
mutex_lock(&tz->lock);
96+
97+
if (device_is_registered(dev))
98+
result = tz->ops->get_trip_type(tz, trip, &type);
99+
else
100+
result = -ENODEV;
101+
102+
mutex_unlock(&tz->lock);
96103
if (result)
97104
return result;
98105

@@ -128,10 +135,17 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
128135
if (kstrtoint(buf, 10, &temperature))
129136
return -EINVAL;
130137

138+
mutex_lock(&tz->lock);
139+
140+
if (!device_is_registered(dev)) {
141+
ret = -ENODEV;
142+
goto unlock;
143+
}
144+
131145
if (tz->ops->set_trip_temp) {
132146
ret = tz->ops->set_trip_temp(tz, trip, temperature);
133147
if (ret)
134-
return ret;
148+
goto unlock;
135149
}
136150

137151
if (tz->trips)
@@ -140,16 +154,22 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr,
140154
if (tz->ops->get_trip_hyst) {
141155
ret = tz->ops->get_trip_hyst(tz, trip, &hyst);
142156
if (ret)
143-
return ret;
157+
goto unlock;
144158
}
145159

146160
ret = tz->ops->get_trip_type(tz, trip, &type);
147161
if (ret)
148-
return ret;
162+
goto unlock;
149163

150164
thermal_notify_tz_trip_change(tz->id, trip, type, temperature, hyst);
151165

152-
thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
166+
__thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
167+
168+
unlock:
169+
mutex_unlock(&tz->lock);
170+
171+
if (ret)
172+
return ret;
153173

154174
return count;
155175
}
@@ -168,7 +188,14 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
168188
if (sscanf(attr->attr.name, "trip_point_%d_temp", &trip) != 1)
169189
return -EINVAL;
170190

171-
ret = tz->ops->get_trip_temp(tz, trip, &temperature);
191+
mutex_lock(&tz->lock);
192+
193+
if (device_is_registered(dev))
194+
ret = tz->ops->get_trip_temp(tz, trip, &temperature);
195+
else
196+
ret = -ENODEV;
197+
198+
mutex_unlock(&tz->lock);
172199

173200
if (ret)
174201
return ret;
@@ -193,6 +220,13 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
193220
if (kstrtoint(buf, 10, &temperature))
194221
return -EINVAL;
195222

223+
mutex_lock(&tz->lock);
224+
225+
if (!device_is_registered(dev)) {
226+
ret = -ENODEV;
227+
goto unlock;
228+
}
229+
196230
/*
197231
* We are not doing any check on the 'temperature' value
198232
* here. The driver implementing 'set_trip_hyst' has to
@@ -201,7 +235,10 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
201235
ret = tz->ops->set_trip_hyst(tz, trip, temperature);
202236

203237
if (!ret)
204-
thermal_zone_set_trips(tz);
238+
__thermal_zone_set_trips(tz);
239+
240+
unlock:
241+
mutex_unlock(&tz->lock);
205242

206243
return ret ? ret : count;
207244
}
@@ -220,7 +257,14 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
220257
if (sscanf(attr->attr.name, "trip_point_%d_hyst", &trip) != 1)
221258
return -EINVAL;
222259

223-
ret = tz->ops->get_trip_hyst(tz, trip, &temperature);
260+
mutex_lock(&tz->lock);
261+
262+
if (device_is_registered(dev))
263+
ret = tz->ops->get_trip_hyst(tz, trip, &temperature);
264+
else
265+
ret = -ENODEV;
266+
267+
mutex_unlock(&tz->lock);
224268

225269
return ret ? ret : sprintf(buf, "%d\n", temperature);
226270
}
@@ -269,16 +313,23 @@ emul_temp_store(struct device *dev, struct device_attribute *attr,
269313
if (kstrtoint(buf, 10, &temperature))
270314
return -EINVAL;
271315

272-
if (!tz->ops->set_emul_temp) {
273-
mutex_lock(&tz->lock);
316+
mutex_lock(&tz->lock);
317+
318+
if (!device_is_registered(dev)) {
319+
ret = -ENODEV;
320+
goto unlock;
321+
}
322+
323+
if (!tz->ops->set_emul_temp)
274324
tz->emul_temperature = temperature;
275-
mutex_unlock(&tz->lock);
276-
} else {
325+
else
277326
ret = tz->ops->set_emul_temp(tz, temperature);
278-
}
279327

280328
if (!ret)
281-
thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
329+
__thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
330+
331+
unlock:
332+
mutex_unlock(&tz->lock);
282333

283334
return ret ? ret : count;
284335
}

0 commit comments

Comments
 (0)