Skip to contentSkip to conversation

ipmi: msghandler: Fix potential Spectre v1 vulnerabilities

PATCH In review Gustavo A. R. Silva 2 participants 2 messages Jan 9, 2019 – Jan 16, 2019 1 message not in the archive

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

PATCH 1/1 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/[email protected]/

---
 drivers/char/ipmi/ipmi_msghandler.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)
drivers/char/ipmi/ipmi_msghandler.c +18 -8
index 480d9bd7e1ab..557e98d9364d 100644
@@ -32,6 +32,7 @@
 #include <linux/moduleparam.h>
 #include <linux/workqueue.h>
 #include <linux/uuid.h>
+#include <linux/nospec.h>
 
 #define IPMI_DRIVER_VERSION "39.2"
 
@@ -1375,10 +1376,12 @@ int ipmi_set_my_address(struct ipmi_user *user,
 	if (!user)
 		return -ENODEV;
 
-	if (channel >= IPMI_MAX_CHANNELS)
+	if (channel >= IPMI_MAX_CHANNELS) {
 		rv = -EINVAL;
-	else
+	} else {
+		channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
 		user->intf->addrinfo[channel].address = address;
+	}
 	release_ipmi_user(user, index);
 
 	return rv;
@@ -1395,10 +1398,12 @@ int ipmi_get_my_address(struct ipmi_user *user,
 	if (!user)
 		return -ENODEV;
 
-	if (channel >= IPMI_MAX_CHANNELS)
+	if (channel >= IPMI_MAX_CHANNELS) {
 		rv = -EINVAL;
-	else
+	} else {
+		channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
 		*address = user->intf->addrinfo[channel].address;
+	}
 	release_ipmi_user(user, index);
 
 	return rv;
@@ -1415,10 +1420,12 @@ int ipmi_set_my_LUN(struct ipmi_user *user,
 	if (!user)
 		return -ENODEV;
 
-	if (channel >= IPMI_MAX_CHANNELS)
+	if (channel >= IPMI_MAX_CHANNELS) {
 		rv = -EINVAL;
-	else
+	} else {
+		channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
 		user->intf->addrinfo[channel].lun = LUN & 0x3;
+	}
 	release_ipmi_user(user, index);
 
 	return rv;
@@ -1435,10 +1442,12 @@ int ipmi_get_my_LUN(struct ipmi_user *user,
 	if (!user)
 		return -ENODEV;
 
-	if (channel >= IPMI_MAX_CHANNELS)
+	if (channel >= IPMI_MAX_CHANNELS) {
 		rv = -EINVAL;
-	else
+	} else {
+		channel = array_index_nospec(channel, IPMI_MAX_CHANNELS);
 		*address = user->intf->addrinfo[channel].lun;
+	}
 	release_ipmi_user(user, index);
 
 	return rv;
@@ -2257,6 +2266,7 @@ static int check_addr(struct ipmi_smi  *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;
Signature · 1 line
2.20.1

A message that is not in the archive (sent off-list or not yet received): [email protected]

#2 lore raw
Quoted 8 lines · Sasha Levin

Hi,

[This is an automated email]

This commit has been processed because it contains a -stable tag. The stable tag indicates that it's relevant for the following trees: all

The bot has tested the following trees: v4.20.2, v4.19.15, v4.14.93, v4.9.150, v4.4.170, v3.18.132.

I'll pull these into my tree.

It sounds like you want this in ASAP, I can do that, though this interface is lower priority, I would think, because it's generally root access only.

-corey

Quoted 63 lines

v4.20.2: Build OK!
v4.19.15: Build OK!
v4.14.93: Failed to apply! Possible dependencies:
1c9f98d1bfbd ("ipmi: Make IPMI panic strings always available") 3fd32f9ec84f ("ipmi: Convert IPMI GUID over to Linux guid_t") 511d57dc71a2 ("ipmi: Get the device id through a function") 68e7e50f195f ("ipmi: Don't use BMC product/dev ids in the BMC name") 9ca15af3164f ("ipmi: Fix issues with BMC refcounts")
a2cb600fa22a ("ipmi: Rework BMC registration")
a9137c3dfae9 ("ipmi: Add a reference from BMC devices to their interfaces") aa9c9ab2443e ("ipmi: allow dynamic BMC version information") b2cfd8ab4add ("ipmi: Rework device id and guid handling to catch changing BMCs") c0734bd594d4 ("ipmi: Retry BMC registration on a failure") f33e4df83e00 ("ipmi: Move bmc find routing to below bmc device type")

v4.9.150: Failed to apply! Possible dependencies:
1c9f98d1bfbd ("ipmi: Make IPMI panic strings always available") 3fd32f9ec84f ("ipmi: Convert IPMI GUID over to Linux guid_t") 511d57dc71a2 ("ipmi: Get the device id through a function") 68e7e50f195f ("ipmi: Don't use BMC product/dev ids in the BMC name") 9ca15af3164f ("ipmi: Fix issues with BMC refcounts")
a2cb600fa22a ("ipmi: Rework BMC registration")
a9137c3dfae9 ("ipmi: Add a reference from BMC devices to their interfaces") aa9c9ab2443e ("ipmi: allow dynamic BMC version information") b2cfd8ab4add ("ipmi: Rework device id and guid handling to catch changing BMCs") c0734bd594d4 ("ipmi: Retry BMC registration on a failure") f33e4df83e00 ("ipmi: Move bmc find routing to below bmc device type")

v4.4.170: Failed to apply! Possible dependencies:
1c9f98d1bfbd ("ipmi: Make IPMI panic strings always available") 3fd32f9ec84f ("ipmi: Convert IPMI GUID over to Linux guid_t") 511d57dc71a2 ("ipmi: Get the device id through a function") 68e7e50f195f ("ipmi: Don't use BMC product/dev ids in the BMC name") 9ca15af3164f ("ipmi: Fix issues with BMC refcounts")
a2cb600fa22a ("ipmi: Rework BMC registration")
a9137c3dfae9 ("ipmi: Add a reference from BMC devices to their interfaces") aa9c9ab2443e ("ipmi: allow dynamic BMC version information") b2cfd8ab4add ("ipmi: Rework device id and guid handling to catch changing BMCs") bd85f4b37ddf ("ipmi: fix crash on reading version from proc after unregisted bmc") c0734bd594d4 ("ipmi: Retry BMC registration on a failure") f33e4df83e00 ("ipmi: Move bmc find routing to below bmc device type")

v3.18.132: Failed to apply! Possible dependencies:
16639eb08a69 ("ipmi: clean up the device handling for the bmc device") 1c9f98d1bfbd ("ipmi: Make IPMI panic strings always available") 3fd32f9ec84f ("ipmi: Convert IPMI GUID over to Linux guid_t") 5a0e10ec4a82 ("ipmi: Remove useless sysfs_name parameters") 9ca15af3164f ("ipmi: Fix issues with BMC refcounts")
a2cb600fa22a ("ipmi: Rework BMC registration")
a9137c3dfae9 ("ipmi: Add a reference from BMC devices to their interfaces") aa9c9ab2443e ("ipmi: allow dynamic BMC version information") b2cfd8ab4add ("ipmi: Rework device id and guid handling to catch changing BMCs") bd85f4b37ddf ("ipmi: fix crash on reading version from proc after unregisted bmc") c0734bd594d4 ("ipmi: Retry BMC registration on a failure") f33e4df83e00 ("ipmi: Move bmc find routing to below bmc device type")

How should we proceed with this patch?

--
Thanks,
Sasha