usb: typec: ucsi: Fix command cancellation
authorHeikki Krogerus <heikki.krogerus@linux.intel.com>
Tue, 6 Jun 2023 11:58:02 +0000 (14:58 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Jun 2023 09:52:51 +0000 (11:52 +0200)
The Cancel command was passed to the write callback as the
offset instead of as the actual command which caused NULL
pointer dereference.

Reported-by: Stephan Bolten <stephan.bolten@gmx.net>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217517
Fixes: 094902bc6a3c ("usb: typec: ucsi: Always cancel the command if PPM reports BUSY condition")
Cc: stable@vger.kernel.org
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Message-ID: <20230606115802.79339-1-heikki.krogerus@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/typec/ucsi/ucsi.c

index 2b472ec..b664ecb 100644 (file)
@@ -132,10 +132,8 @@ static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd)
        if (ret)
                return ret;
 
-       if (cci & UCSI_CCI_BUSY) {
-               ucsi->ops->async_write(ucsi, UCSI_CANCEL, NULL, 0);
-               return -EBUSY;
-       }
+       if (cmd != UCSI_CANCEL && cci & UCSI_CCI_BUSY)
+               return ucsi_exec_command(ucsi, UCSI_CANCEL);
 
        if (!(cci & UCSI_CCI_COMMAND_COMPLETE))
                return -EIO;
@@ -149,6 +147,11 @@ static int ucsi_exec_command(struct ucsi *ucsi, u64 cmd)
                return ucsi_read_error(ucsi);
        }
 
+       if (cmd == UCSI_CANCEL && cci & UCSI_CCI_CANCEL_COMPLETE) {
+               ret = ucsi_acknowledge_command(ucsi);
+               return ret ? ret : -EBUSY;
+       }
+
        return UCSI_CCI_LENGTH(cci);
 }