diff mbox series

Input: uinput - fix Spectre v1 vulnerability

Message ID 20181016111313.GA28307@embeddedor.com (mailing list archive)
State Rejected
Headers show
Series Input: uinput - fix Spectre v1 vulnerability | expand

Commit Message

Gustavo A. R. Silva Oct. 16, 2018, 11:13 a.m. UTC
setup.code 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/input/misc/uinput.c:512 uinput_abs_setup() warn: potential
spectre issue 'dev->absinfo' [w] (local cap)

Fix this by sanitizing setup.code before using it to index dev->absinfo.

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/input/misc/uinput.c | 3 +++
 1 file changed, 3 insertions(+)

Comments

Dmitry Torokhov Oct. 16, 2018, 5:21 p.m. UTC | #1
Hi Gustavo,

On Tue, Oct 16, 2018 at 01:13:13PM +0200, Gustavo A. R. Silva wrote:
> setup.code 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/input/misc/uinput.c:512 uinput_abs_setup() warn: potential
> spectre issue 'dev->absinfo' [w] (local cap)
> 
> Fix this by sanitizing setup.code before using it to index dev->absinfo.

So we are saying that attacker, by repeatedly calling ioctl(...,
UI_ABS_SETUP, ...) will be able to poison branch predictor and discover
another program or kernel secrets? But uinput is a privileged interface
open to root only, as it allows injecting arbitrary keystrokes into the
kernel. And since only root can use uinput, meh?

Thanks.
Gustavo A. R. Silva Oct. 16, 2018, 5:52 p.m. UTC | #2
Hi Dmitry,

On 10/16/18 7:21 PM, Dmitry Torokhov wrote:
> Hi Gustavo,
> 
> On Tue, Oct 16, 2018 at 01:13:13PM +0200, Gustavo A. R. Silva wrote:
>> setup.code 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/input/misc/uinput.c:512 uinput_abs_setup() warn: potential
>> spectre issue 'dev->absinfo' [w] (local cap)
>>
>> Fix this by sanitizing setup.code before using it to index dev->absinfo.
> 
> So we are saying that attacker, by repeatedly calling ioctl(...,
> UI_ABS_SETUP, ...) will be able to poison branch predictor and discover
> another program or kernel secrets? But uinput is a privileged interface
> open to root only, as it allows injecting arbitrary keystrokes into the
> kernel. And since only root can use uinput, meh?
> 

Oh I see... in that case this is a false positive.

Although, I wonder if all these operations are only accessible to root:

static const struct file_operations uinput_fops = {
        .owner          = THIS_MODULE,
        .open           = uinput_open,
        .release        = uinput_release,
        .read           = uinput_read,
        .write          = uinput_write,
        .poll           = uinput_poll,
        .unlocked_ioctl = uinput_ioctl,
#ifdef CONFIG_COMPAT
        .compat_ioctl   = uinput_compat_ioctl,
#endif
        .llseek         = no_llseek,
};

Thanks for the feedback.
--
Gustavo
Dmitry Torokhov Oct. 16, 2018, 6:09 p.m. UTC | #3
On October 16, 2018 10:52:58 AM PDT, "Gustavo A. R. Silva" <gustavo@embeddedor.com> wrote:
>Hi Dmitry,
>
>On 10/16/18 7:21 PM, Dmitry Torokhov wrote:
>> Hi Gustavo,
>> 
>> On Tue, Oct 16, 2018 at 01:13:13PM +0200, Gustavo A. R. Silva wrote:
>>> setup.code 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/input/misc/uinput.c:512 uinput_abs_setup() warn: potential
>>> spectre issue 'dev->absinfo' [w] (local cap)
>>>
>>> Fix this by sanitizing setup.code before using it to index
>dev->absinfo.
>> 
>> So we are saying that attacker, by repeatedly calling ioctl(...,
>> UI_ABS_SETUP, ...) will be able to poison branch predictor and
>discover
>> another program or kernel secrets? But uinput is a privileged
>interface
>> open to root only, as it allows injecting arbitrary keystrokes into
>the
>> kernel. And since only root can use uinput, meh?
>> 
>
>Oh I see... in that case this is a false positive.
>
>Although, I wonder if all these operations are only accessible to root:
>
>static const struct file_operations uinput_fops = {
>        .owner          = THIS_MODULE,
>        .open           = uinput_open,
>        .release        = uinput_release,
>        .read           = uinput_read,
>        .write          = uinput_write,
>        .poll           = uinput_poll,
>        .unlocked_ioctl = uinput_ioctl,
>#ifdef CONFIG_COMPAT
>        .compat_ioctl   = uinput_compat_ioctl,
>#endif
>        .llseek         = no_llseek,
>};

/dev/uinput must be 0600, or accessible to equally privileged user, or you'll be opening your system to much mischief.


Thanks.
Gustavo A. R. Silva Oct. 16, 2018, 6:12 p.m. UTC | #4
On 10/16/18 8:09 PM, Dmitry Torokhov wrote:

> 
> /dev/uinput 

I've got it. This explains it all. :)

> must be 0600, or accessible to equally privileged user, or you'll be opening your system to much mischief.
> 
Thanks, Dmitry.
--
Gustavo
Alan Cox Oct. 18, 2018, 7:43 p.m. UTC | #5
On Tue, 16 Oct 2018 20:12:43 +0200
"Gustavo A. R. Silva" <gustavo@embeddedor.com> wrote:

> On 10/16/18 8:09 PM, Dmitry Torokhov wrote:
> 
> > 
> > /dev/uinput   
> 
> I've got it. This explains it all. :)
> 
> > must be 0600, or accessible to equally privileged user, or you'll be opening your system to much mischief.

Still a correct change.

CAP_SYS_RAWIO is not the same as being root, especially in a container.

Alan
Dmitry Torokhov Oct. 18, 2018, 8:07 p.m. UTC | #6
On Thu, Oct 18, 2018 at 12:43 PM Alan Cox <gnomes@lxorguk.ukuu.org.uk> wrote:
>
> On Tue, 16 Oct 2018 20:12:43 +0200
> "Gustavo A. R. Silva" <gustavo@embeddedor.com> wrote:
>
> > On 10/16/18 8:09 PM, Dmitry Torokhov wrote:
> >
> > >
> > > /dev/uinput
> >
> > I've got it. This explains it all. :)
> >
> > > must be 0600, or accessible to equally privileged user, or you'll be opening your system to much mischief.
>
> Still a correct change.
>
> CAP_SYS_RAWIO is not the same as being root, especially in a container.

Giving access to uinput in an unprivileged container is nutty as well.

Thanks.
Pavel Machek Oct. 22, 2018, 2:14 p.m. UTC | #7
On Tue 2018-10-16 19:52:58, Gustavo A. R. Silva wrote:
> Hi Dmitry,
> 
> On 10/16/18 7:21 PM, Dmitry Torokhov wrote:
> > Hi Gustavo,
> > 
> > On Tue, Oct 16, 2018 at 01:13:13PM +0200, Gustavo A. R. Silva wrote:
> >> setup.code 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/input/misc/uinput.c:512 uinput_abs_setup() warn: potential
> >> spectre issue 'dev->absinfo' [w] (local cap)
> >>
> >> Fix this by sanitizing setup.code before using it to index dev->absinfo.
> > 
> > So we are saying that attacker, by repeatedly calling ioctl(...,
> > UI_ABS_SETUP, ...) will be able to poison branch predictor and discover
> > another program or kernel secrets? But uinput is a privileged interface
> > open to root only, as it allows injecting arbitrary keystrokes into the
> > kernel. And since only root can use uinput, meh?
> > 
> 
> Oh I see... in that case this is a false positive.

No, please lets fix it.

Some people are trying to make sure kernel is "more priviledged" than
root -- its called secure boot etc.

And "if you givean attacker possibility to generate keystrokes, he can
read kernel memory as well"... is very unexpected.

Unexpected is bad when talking about security.
								Pavel
diff mbox series

Patch

diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 8ec483e..97b0809 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -42,6 +42,8 @@ 
 #include <linux/input/mt.h>
 #include "../input-compat.h"
 
+#include <linux/nospec.h>
+
 #define UINPUT_NAME		"uinput"
 #define UINPUT_BUFFER_SIZE	16
 #define UINPUT_NUM_REQUESTS	16
@@ -497,6 +499,7 @@  static int uinput_abs_setup(struct uinput_device *udev,
 
 	if (setup.code > ABS_MAX)
 		return -ERANGE;
+	setup.code = array_index_nospec(setup.code, ABS_MAX + 1);
 
 	dev = udev->dev;