diff mbox series

drm/amdgpu/pm: Fix potential Spectre v1

Message ID 20180723163232.GA17358@embeddedor.com (mailing list archive)
State New, archived
Headers show
Series drm/amdgpu/pm: Fix potential Spectre v1 | expand

Commit Message

Gustavo A. R. Silva July 23, 2018, 4:32 p.m. UTC
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

Cc: stable@vger.kernel.org
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Alex Deucher July 24, 2018, 8:53 p.m. UTC | #1
On Mon, Jul 23, 2018 at 12:32 PM, Gustavo A. R. Silva
<gustavo@embeddedor.com> wrote:
> 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


>
> 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
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> index 15a1192..a446c7c 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
> @@ -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
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Michel Dänzer July 30, 2018, 9:55 a.m. UTC | #2
On 2018-07-24 10:53 PM, Alex Deucher wrote:
> On Mon, Jul 23, 2018 at 12:32 PM, Gustavo A. R. Silva
> <gustavo@embeddedor.com> wrote:
>> 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;
>                 }

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?
Alex Deucher July 30, 2018, 8:14 p.m. UTC | #3
On Mon, Jul 30, 2018 at 5:55 AM, Michel Dänzer <michel@daenzer.net> wrote:
> On 2018-07-24 10:53 PM, Alex Deucher wrote:
>> On Mon, Jul 23, 2018 at 12:32 PM, Gustavo A. R. Silva
>> <gustavo@embeddedor.com> wrote:
>>> 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;
>>                 }
>
> 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
Christian König July 31, 2018, 6:46 a.m. UTC | #4
Am 30.07.2018 um 22:14 schrieb Alex Deucher:
> On Mon, Jul 30, 2018 at 5:55 AM, Michel Dänzer <michel@daenzer.net> wrote:
>> On 2018-07-24 10:53 PM, Alex Deucher wrote:
>>> On Mon, Jul 23, 2018 at 12:32 PM, Gustavo A. R. Silva
>>> <gustavo@embeddedor.com> wrote:
>>>> 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;
>>>                  }
>> 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.

>
> Alex
Alex Deucher July 31, 2018, 9:29 p.m. UTC | #5
On Tue, Jul 31, 2018 at 2:46 AM, Christian König
<christian.koenig@amd.com> wrote:
> Am 30.07.2018 um 22:14 schrieb Alex Deucher:
>>
>> On Mon, Jul 30, 2018 at 5:55 AM, Michel Dänzer <michel@daenzer.net> wrote:
>>>
>>> On 2018-07-24 10:53 PM, Alex Deucher wrote:
>>>>
>>>> On Mon, Jul 23, 2018 at 12:32 PM, Gustavo A. R. Silva
>>>> <gustavo@embeddedor.com> wrote:
>>>>>
>>>>> 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;
>>>>                  }
>>>
>>> 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.

Ok.  Applied.

Thanks,

Alex
diff mbox series

Patch

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 15a1192..a446c7c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -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];