[PATCH v2] Input: psmouse: check the result of ps2_command() when detecting devices
From: Alexander Potapenko <glider@google.com>
Date: 2021-12-13 15:01:55
Also in:
lkml
Subsystem:
input (keyboard, mouse, joystick, touchscreen) drivers, the rest · Maintainers:
Dmitry Torokhov, Linus Torvalds
Execution of ps2_command() may fail, leaving the device in inconsistent state. If the command was supposed to write into @param buffer, that one may remain uninitialized. Ensure that ps2_command() failure in device detection functions also results in them returning an error. Signed-off-by: Alexander Potapenko <glider@google.com> --- v2: - add checking to PSMOUSE_CMD_SET* functions --- drivers/input/mouse/psmouse-base.c | 73 ++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 18 deletions(-)
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 0b4a3039f312f..9dde7fd818136 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c@@ -546,13 +546,24 @@ static int genius_detect(struct psmouse *psmouse, bool set_properties) { struct ps2dev *ps2dev = &psmouse->ps2dev; u8 param[4]; + int error; param[0] = 3; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); - ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); - ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); - ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); - ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); + error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + if (error) + return error; + error = ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); + if (error) + return error; + error = ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); + if (error) + return error; + error = ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); + if (error) + return error; + error = ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); + if (error) + return error; if (param[0] != 0x00 || param[1] != 0x33 || param[2] != 0x55) return -ENODEV;
@@ -578,14 +589,23 @@ static int intellimouse_detect(struct psmouse *psmouse, bool set_properties) { struct ps2dev *ps2dev = &psmouse->ps2dev; u8 param[2]; + int error; param[0] = 200; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + if (error) + return error; param[0] = 100; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + if (error) + return error; param[0] = 80; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); - ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); + error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + if (error) + return error; + error = ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); + if (error) + return error; if (param[0] != 3) return -ENODEV;
@@ -611,16 +631,25 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties) { struct ps2dev *ps2dev = &psmouse->ps2dev; u8 param[2]; + int error; intellimouse_detect(psmouse, 0); param[0] = 200; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + if (error) + return error; param[0] = 200; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + if (error) + return error; param[0] = 80; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); - ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); + error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + if (error) + return error; + error = ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); + if (error) + return error; if (param[0] != 4) return -ENODEV;
@@ -658,17 +687,25 @@ static int thinking_detect(struct psmouse *psmouse, bool set_properties) struct ps2dev *ps2dev = &psmouse->ps2dev; u8 param[2]; static const u8 seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 }; - int i; + int error, i; param[0] = 10; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + if (error) + return error; param[0] = 0; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + if (error) + return error; for (i = 0; i < ARRAY_SIZE(seq); i++) { param[0] = seq[i]; - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + error = ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); + if (error) + return error; } - ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); + error = ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); + if (error) + return error; if (param[0] != 2) return -ENODEV;
--
2.34.1.173.g76aa8bc2d0-goog