Skip to contentSkip to conversation

drm/amdgpu/pm: Fix potential Spectre v1

PATCH In review Gustavo A. R. Silva 4 participants 6 messages Jul 23, 2018 – Jul 31, 2018

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 drm/amdgpu/pm: Fix potential Spectre v1

idx can be indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability.

This issue was detected with the help of Smatch:

drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c:408 amdgpu_set_pp_force_state()
warn: potential spectre issue 'data.states'

Fix this by sanitizing idx before using it to index data.states

Notice that given that speculation windows are large, the policy is to kill the speculation on the first load and not worry if it can be completed with a dependent load/store [1].

[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2

---
 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +2 -1
index 15a1192..a446c7c 100644
@@ -31,7 +31,7 @@
 #include <linux/power_supply.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
-
+#include <linux/nospec.h>
 
 static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev);
 
@@ -403,6 +403,7 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,
 			count = -EINVAL;
 			goto fail;
 		}
+		idx = array_index_nospec(idx, ARRAY_SIZE(data.states));
 
 		amdgpu_dpm_get_pp_num_states(adev, &data);
 		state = data.states[idx];
Signature · 1 line
2.7.4
#1 lore raw
Quoted 9 lines · Gustavo A. R. Silva

idx can be indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability.

This issue was detected with the help of Smatch:

drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c:408 amdgpu_set_pp_force_state()
warn: potential spectre issue 'data.states'

Fix this by sanitizing idx before using it to index data.states

Is this actually necessary? We already check that idx is valid a few lines before:

        if (ret || idx >= ARRAY_SIZE(data.states)) {
                        count = -EINVAL;
                        goto fail;
                }

Alex

Quoted 37 lines

Notice that given that speculation windows are large, the policy is to kill the speculation on the first load and not worry if it can be completed with a dependent load/store [1].

[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2

---
 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +2 -2
index 15a1192..a446c7c 100644
@@ -31,7 +31,7 @@
 #include <linux/power_supply.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
-
+#include <linux/nospec.h>
 
 static int amdgpu_debugfs_pm_init(struct amdgpu_device *adev);
 
@@ -403,6 +403,7 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,
                        count = -EINVAL;
                        goto fail;
                }
+               idx = array_index_nospec(idx, ARRAY_SIZE(data.states));
 
                amdgpu_dpm_get_pp_num_states(adev, &data);
                state = data.states[idx];
--

2.7.4

Quoted 4 lines

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

#2 lore raw
Quoted 10 lines · Alex Deucher
Quoted 8 lines · Gustavo A. R. Silva

idx can be indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability.

This issue was detected with the help of Smatch:

drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c:408 amdgpu_set_pp_force_state()
warn: potential spectre issue 'data.states'

Quoted 8 lines
Quoted 1 line

Fix this by sanitizing idx before using it to index data.states

Is this actually necessary? We already check that idx is valid a few lines before:

        if (ret || idx >= ARRAY_SIZE(data.states)) {
                        count = -EINVAL;
                        goto fail;
                }

A Spectre attack would be based on idx ending up too large, but the CPU speculatively executing the following code assuming idx < ARRAY_SIZE(data.states), and extracting information from the incorrectly speculated code via side channels.

I'm not sure if that's actually possible in this case, but better safe than sorry?

Signature · 6 lines
Earthling Michel Dänzer               |               http://www.amd.com
Libre software enthusiast             |             Mesa and X developer
_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
#3 lore raw
Quoted 20 lines · Michel Dänzer
Quoted 10 lines · Alex Deucher
Quoted 8 lines · Gustavo A. R. Silva

idx can be indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability.

This issue was detected with the help of Smatch:

drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c:408 amdgpu_set_pp_force_state()
warn: potential spectre issue 'data.states'

Quoted 8 lines
Quoted 1 line

Fix this by sanitizing idx before using it to index data.states

Is this actually necessary? We already check that idx is valid a few lines before:

        if (ret || idx >= ARRAY_SIZE(data.states)) {
                        count = -EINVAL;
                        goto fail;
                }
Quoted 7 lines

A Spectre attack would be based on idx ending up too large, but the CPU speculatively executing the following code assuming idx < ARRAY_SIZE(data.states), and extracting information from the incorrectly speculated code via side channels.

I'm not sure if that's actually possible in this case, but better safe than sorry?

Yeah, I'm not sure. I guess this can't hurt.

Alex
_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

maintainer
#4 lore raw

Am 30.07.2018 um 22:14 schrieb Alex Deucher:

Quoted 19 lines · Michel Dänzer
Quoted 18 lines · Alex Deucher
Quoted 17 lines
Quoted 9 lines · Gustavo A. R. Silva

idx can be indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability.

This issue was detected with the help of Smatch:

drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c:408 amdgpu_set_pp_force_state()
warn: potential spectre issue 'data.states'

Fix this by sanitizing idx before using it to index data.states

Is this actually necessary? We already check that idx is valid a few lines before:

         if (ret || idx >= ARRAY_SIZE(data.states)) {
                         count = -EINVAL;
                         goto fail;
                 }
Quoted 8 lines
Quoted 7 lines

A Spectre attack would be based on idx ending up too large, but the CPU speculatively executing the following code assuming idx < ARRAY_SIZE(data.states), and extracting information from the incorrectly speculated code via side channels.

I'm not sure if that's actually possible in this case, but better safe than sorry?

Yeah, I'm not sure. I guess this can't hurt.

Well is idx actually controlable by userspace in an IOCTL? I guess the answer is no.

On the other hand the array_index_nospec() macro makes the overhead absolute negligible.

So I agree that we should be better safe than sorry.

Christian.

Quoted 2 lines

Alex

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

#5 lore raw
Quoted 37 lines · Christian König

Am 30.07.2018 um 22:14 schrieb Alex Deucher:

Quoted 30 lines · Michel Dänzer
Quoted 28 lines · Alex Deucher
Quoted 12 lines
Quoted 9 lines · Gustavo A. R. Silva

idx can be indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability.

This issue was detected with the help of Smatch:

drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c:408 amdgpu_set_pp_force_state()
warn: potential spectre issue 'data.states'

Quoted 8 lines
Quoted 1 line

Fix this by sanitizing idx before using it to index data.states

Is this actually necessary? We already check that idx is valid a few lines before:

         if (ret || idx >= ARRAY_SIZE(data.states)) {
                         count = -EINVAL;
                         goto fail;
                 }

A Spectre attack would be based on idx ending up too large, but the CPU speculatively executing the following code assuming idx < ARRAY_SIZE(data.states), and extracting information from the incorrectly speculated code via side channels.

Quoted 4 lines
Quoted 2 lines

I'm not sure if that's actually possible in this case, but better safe than sorry?

Yeah, I'm not sure. I guess this can't hurt.

Quoted 7 lines

Well is idx actually controlable by userspace in an IOCTL? I guess the answer is no.

On the other hand the array_index_nospec() macro makes the overhead absolute negligible.

So I agree that we should be better safe than sorry.

Ok. Applied.

Thanks,

Alex
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel