]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.9/drivers-thermal-int340x_thermal-fix-sysfs-race-condi.patch
bd533e4ac331c04863720ba819b941b4c5710217
[thirdparty/kernel/stable-queue.git] / queue-4.9 / drivers-thermal-int340x_thermal-fix-sysfs-race-condi.patch
1 From f5d17a89c386b9e711ab3bb535bb343becb75223 Mon Sep 17 00:00:00 2001
2 From: Aaron Hill <aa1ronham@gmail.com>
3 Date: Mon, 24 Dec 2018 14:23:36 -0500
4 Subject: drivers: thermal: int340x_thermal: Fix sysfs race condition
5
6 [ Upstream commit 129699bb8c7572106b5bbb2407c2daee4727ccad ]
7
8 Changes since V1:
9 * Use dev_info instead of printk
10 * Use dev_warn instead of BUG_ON
11
12 Previously, sysfs_create_group was called before all initialization had
13 fully run - specifically, before pci_set_drvdata was called. Since the
14 sysctl group is visible to userspace as soon as sysfs_create_group
15 returns, a small window of time existed during which a process could read
16 from an uninitialized/partially-initialized device.
17
18 This commit moves the creation of the sysctl group to after all
19 initialized is completed. This ensures that it's impossible for
20 userspace to read from a sysctl file before initialization has fully
21 completed.
22
23 To catch any future regressions, I've added a check to ensure
24 that proc_thermal_emum_mode is never PROC_THERMAL_NONE when a process
25 tries to read from a sysctl file. Previously, the aforementioned race
26 condition could result in the 'else' branch
27 running while PROC_THERMAL_NONE was set,
28 leading to a null pointer deference.
29
30 Signed-off-by: Aaron Hill <aa1ronham@gmail.com>
31 Signed-off-by: Zhang Rui <rui.zhang@intel.com>
32 Signed-off-by: Sasha Levin <sashal@kernel.org>
33 ---
34 .../processor_thermal_device.c | 28 ++++++++++---------
35 1 file changed, 15 insertions(+), 13 deletions(-)
36
37 diff --git a/drivers/thermal/int340x_thermal/processor_thermal_device.c b/drivers/thermal/int340x_thermal/processor_thermal_device.c
38 index 06d46e2ff337e..1fdf6fd24cdff 100644
39 --- a/drivers/thermal/int340x_thermal/processor_thermal_device.c
40 +++ b/drivers/thermal/int340x_thermal/processor_thermal_device.c
41 @@ -77,7 +77,12 @@ static ssize_t power_limit_##index##_##suffix##_show(struct device *dev, \
42 struct pci_dev *pci_dev; \
43 struct platform_device *pdev; \
44 struct proc_thermal_device *proc_dev; \
45 -\
46 + \
47 + if (proc_thermal_emum_mode == PROC_THERMAL_NONE) { \
48 + dev_warn(dev, "Attempted to get power limit before device was initialized!\n"); \
49 + return 0; \
50 + } \
51 + \
52 if (proc_thermal_emum_mode == PROC_THERMAL_PLATFORM_DEV) { \
53 pdev = to_platform_device(dev); \
54 proc_dev = platform_get_drvdata(pdev); \
55 @@ -291,11 +296,6 @@ static int proc_thermal_add(struct device *dev,
56 *priv = proc_priv;
57
58 ret = proc_thermal_read_ppcc(proc_priv);
59 - if (!ret) {
60 - ret = sysfs_create_group(&dev->kobj,
61 - &power_limit_attribute_group);
62 -
63 - }
64 if (ret)
65 return ret;
66
67 @@ -309,8 +309,7 @@ static int proc_thermal_add(struct device *dev,
68
69 proc_priv->int340x_zone = int340x_thermal_zone_add(adev, ops);
70 if (IS_ERR(proc_priv->int340x_zone)) {
71 - ret = PTR_ERR(proc_priv->int340x_zone);
72 - goto remove_group;
73 + return PTR_ERR(proc_priv->int340x_zone);
74 } else
75 ret = 0;
76
77 @@ -324,9 +323,6 @@ static int proc_thermal_add(struct device *dev,
78
79 remove_zone:
80 int340x_thermal_zone_remove(proc_priv->int340x_zone);
81 -remove_group:
82 - sysfs_remove_group(&proc_priv->dev->kobj,
83 - &power_limit_attribute_group);
84
85 return ret;
86 }
87 @@ -357,7 +353,10 @@ static int int3401_add(struct platform_device *pdev)
88 platform_set_drvdata(pdev, proc_priv);
89 proc_thermal_emum_mode = PROC_THERMAL_PLATFORM_DEV;
90
91 - return 0;
92 + dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PLATFORM_DEV\n");
93 +
94 + return sysfs_create_group(&pdev->dev.kobj,
95 + &power_limit_attribute_group);
96 }
97
98 static int int3401_remove(struct platform_device *pdev)
99 @@ -434,7 +433,10 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev,
100 dev_err(&pdev->dev, "No auxiliary DTSs enabled\n");
101 }
102
103 - return 0;
104 + dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PCI\n");
105 +
106 + return sysfs_create_group(&pdev->dev.kobj,
107 + &power_limit_attribute_group);
108 }
109
110 static void proc_thermal_pci_remove(struct pci_dev *pdev)
111 --
112 2.19.1
113