]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
ipmi: msghandler: Fix potential Spectre v1 vulnerabilities
authorGustavo A. R. Silva <gustavo@embeddedor.com>
Wed, 9 Jan 2019 23:39:06 +0000 (17:39 -0600)
committerStefan Bader <stefan.bader@canonical.com>
Wed, 24 Apr 2019 08:09:12 +0000 (10:09 +0200)
channel and addr->channel are indirectly controlled by user-space,
hence leading to a potential exploitation of the Spectre variant 1
vulnerability.

These issues were detected with the help of Smatch:

drivers/char/ipmi/ipmi_msghandler.c:1381 ipmi_set_my_address() warn: potential spectre issue 'user->intf->addrinfo' [w] (local cap)
drivers/char/ipmi/ipmi_msghandler.c:1401 ipmi_get_my_address() warn: potential spectre issue 'user->intf->addrinfo' [r] (local cap)
drivers/char/ipmi/ipmi_msghandler.c:1421 ipmi_set_my_LUN() warn: potential spectre issue 'user->intf->addrinfo' [w] (local cap)
drivers/char/ipmi/ipmi_msghandler.c:1441 ipmi_get_my_LUN() warn: potential spectre issue 'user->intf->addrinfo' [r] (local cap)
drivers/char/ipmi/ipmi_msghandler.c:2260 check_addr() warn: potential spectre issue 'intf->addrinfo' [r] (local cap)

Fix this by sanitizing channel and addr->channel before using them to
index user->intf->addrinfo and intf->addrinfo, correspondingly.

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://lore.kernel.org/lkml/20180423164740.GY17484@dhcp22.suse.cz/

Cc: stable@vger.kernel.org
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
CVE-2017-5753

(backported from commit a7102c7461794a5bb31af24b08e9e0f50038897a)
[juergh: Adjusted context.]
Signed-off-by: Juerg Haefliger <juergh@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
drivers/char/ipmi/ipmi_msghandler.c

index 7f51acd74e105e06cbd899457760a58707afe83a..f6c3f2ec49bd9afb24d018a2f5253bd7a4106b55 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/moduleparam.h>
 #include <linux/workqueue.h>
 #include <linux/uuid.h>
+#include <linux/nospec.h>
 
 #define PFX "IPMI message handler: "
 
@@ -1262,6 +1263,7 @@ int ipmi_set_my_address(ipmi_user_t   user,
 {
        if (channel >= IPMI_MAX_CHANNELS)
                return -EINVAL;
+       channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
        user->intf->addrinfo[channel].address = address;
        return 0;
 }
@@ -1273,6 +1275,7 @@ int ipmi_get_my_address(ipmi_user_t   user,
 {
        if (channel >= IPMI_MAX_CHANNELS)
                return -EINVAL;
+       channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
        *address = user->intf->addrinfo[channel].address;
        return 0;
 }
@@ -1284,6 +1287,7 @@ int ipmi_set_my_LUN(ipmi_user_t   user,
 {
        if (channel >= IPMI_MAX_CHANNELS)
                return -EINVAL;
+       channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
        user->intf->addrinfo[channel].lun = LUN & 0x3;
        return 0;
 }
@@ -1295,6 +1299,7 @@ int ipmi_get_my_LUN(ipmi_user_t   user,
 {
        if (channel >= IPMI_MAX_CHANNELS)
                return -EINVAL;
+       channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
        *address = user->intf->addrinfo[channel].lun;
        return 0;
 }
@@ -2061,6 +2066,7 @@ static int check_addr(ipmi_smi_t       intf,
 {
        if (addr->channel >= IPMI_MAX_CHANNELS)
                return -EINVAL;
+       addr->channel = array_index_nospec(addr->channel, IPMI_MAX_CHANNELS);
        *lun = intf->addrinfo[addr->channel].lun;
        *saddr = intf->addrinfo[addr->channel].address;
        return 0;