From: Gustavo A. R. Silva Date: Wed, 9 Jan 2019 23:39:06 +0000 (-0600) Subject: ipmi: msghandler: Fix potential Spectre v1 vulnerabilities X-Git-Tag: Ubuntu-4.15.0-49.53~18 X-Git-Url: https://git.proxmox.com/?p=mirror_ubuntu-bionic-kernel.git;a=commitdiff_plain;h=6c03b0aeab58eeb2abafb425fba3beeef1a400f5 ipmi: msghandler: Fix potential Spectre v1 vulnerabilities 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 Signed-off-by: Corey Minyard CVE-2017-5753 (backported from commit a7102c7461794a5bb31af24b08e9e0f50038897a) [juergh: Adjusted context.] Signed-off-by: Juerg Haefliger Acked-by: Stefan Bader Acked-by: Kleber Sacilotto de Souza Signed-off-by: Stefan Bader --- diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 7f51acd74e10..f6c3f2ec49bd 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -49,6 +49,7 @@ #include #include #include +#include #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;