diff mbox series

[v3] cxl/mbox: Use type __u32 for mailbox payload sizes

Message ID 20220414051246.1244575-1-alison.schofield@intel.com
State Accepted
Commit 26f89535a5bb17915a2e1062c3999a2ee797c7b0
Headers show
Series [v3] cxl/mbox: Use type __u32 for mailbox payload sizes | expand

Commit Message

Alison Schofield April 14, 2022, 5:12 a.m. UTC
From: Alison Schofield <alison.schofield@intel.com>

Payload sizes for mailbox commands are expected to be positive values
coming from userspace. The documentation correctly describes these as
always unsigned values. The mailbox and send structures that support
the mailbox commands however, use __s32 types for the payloads.

Replace  __s32 with __u32 in the mailbox and send command structures
and update usages.

Kernel users of the interface already block all negative values and
there is no known ability for userspace to have grown a dependency on
submitting negative values to the kernel. The known user of the IOCTL,
the CXL command line interface (cxl-cli) already enforces positive
size values.

A Smatch warning of a signedness uncovered this issue.

Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Alison Schofield <alison.schofield@intel.com>
---

Changes in v3:
- Toss v2 changes addressing signedness
- Replace __s32 with __u32 in mbox and send command structures (Ben)
- Update commit message and log
  Was 'Restore signedness to a mailbox payload variable'

Changes in v2:
- Pass the payload sizes as signed rather than move the check (Dan)
- Signedness is now discarded on ssize_t to size_t assignment.
- Update commit msg. Was 'Handle variable size output while still
  signed'
- Update commit log.

 drivers/cxl/core/mbox.c      | 28 +++++++++++++++-------------
 include/uapi/linux/cxl_mem.h | 14 +++++++-------
 2 files changed, 22 insertions(+), 20 deletions(-)


base-commit: 7dc1d11d7abae52aada5340fb98885f0ddbb7c37

Comments

Dan Williams April 14, 2022, 4:58 p.m. UTC | #1
On Wed, Apr 13, 2022 at 10:11 PM <alison.schofield@intel.com> wrote:
>
> From: Alison Schofield <alison.schofield@intel.com>
>
> Payload sizes for mailbox commands are expected to be positive values
> coming from userspace. The documentation correctly describes these as
> always unsigned values. The mailbox and send structures that support
> the mailbox commands however, use __s32 types for the payloads.
>
> Replace  __s32 with __u32 in the mailbox and send command structures
> and update usages.
>
> Kernel users of the interface already block all negative values and
> there is no known ability for userspace to have grown a dependency on
> submitting negative values to the kernel. The known user of the IOCTL,
> the CXL command line interface (cxl-cli) already enforces positive
> size values.
>
> A Smatch warning of a signedness uncovered this issue.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
> Signed-off-by: Alison Schofield <alison.schofield@intel.com>
> ---
>
> Changes in v3:
> - Toss v2 changes addressing signedness
> - Replace __s32 with __u32 in mbox and send command structures (Ben)
> - Update commit message and log
>   Was 'Restore signedness to a mailbox payload variable'
>
> Changes in v2:
> - Pass the payload sizes as signed rather than move the check (Dan)
> - Signedness is now discarded on ssize_t to size_t assignment.
> - Update commit msg. Was 'Handle variable size output while still
>   signed'
> - Update commit log.
>
>  drivers/cxl/core/mbox.c      | 28 +++++++++++++++-------------
>  include/uapi/linux/cxl_mem.h | 14 +++++++-------
>  2 files changed, 22 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
> index 8a8388599a85..d54a6d175fff 100644
> --- a/drivers/cxl/core/mbox.c
> +++ b/drivers/cxl/core/mbox.c
> @@ -35,6 +35,7 @@ static bool cxl_raw_allow_all;
>         .flags = _flags,                                                       \
>         }
>
> +#define CXL_VARIABLE_PAYLOAD   ~0U
>  /*
>   * This table defines the supported mailbox commands for the driver. This table
>   * is made up of a UAPI structure. Non-negative values as parameters in the
> @@ -44,26 +45,26 @@ static bool cxl_raw_allow_all;
>  static struct cxl_mem_command cxl_mem_commands[CXL_MEM_COMMAND_ID_MAX] = {
>         CXL_CMD(IDENTIFY, 0, 0x43, CXL_CMD_FLAG_FORCE_ENABLE),
>  #ifdef CONFIG_CXL_MEM_RAW_COMMANDS
> -       CXL_CMD(RAW, ~0, ~0, 0),
> +       CXL_CMD(RAW, CXL_VARIABLE_PAYLOAD, CXL_VARIABLE_PAYLOAD, 0),
>  #endif
> -       CXL_CMD(GET_SUPPORTED_LOGS, 0, ~0, CXL_CMD_FLAG_FORCE_ENABLE),
> +       CXL_CMD(GET_SUPPORTED_LOGS, 0, CXL_VARIABLE_PAYLOAD, CXL_CMD_FLAG_FORCE_ENABLE),
>         CXL_CMD(GET_FW_INFO, 0, 0x50, 0),
>         CXL_CMD(GET_PARTITION_INFO, 0, 0x20, 0),
> -       CXL_CMD(GET_LSA, 0x8, ~0, 0),
> +       CXL_CMD(GET_LSA, 0x8, CXL_VARIABLE_PAYLOAD, 0),
>         CXL_CMD(GET_HEALTH_INFO, 0, 0x12, 0),
> -       CXL_CMD(GET_LOG, 0x18, ~0, CXL_CMD_FLAG_FORCE_ENABLE),
> +       CXL_CMD(GET_LOG, 0x18, CXL_VARIABLE_PAYLOAD, CXL_CMD_FLAG_FORCE_ENABLE),
>         CXL_CMD(SET_PARTITION_INFO, 0x0a, 0, 0),
> -       CXL_CMD(SET_LSA, ~0, 0, 0),
> +       CXL_CMD(SET_LSA, CXL_VARIABLE_PAYLOAD, 0, 0),
>         CXL_CMD(GET_ALERT_CONFIG, 0, 0x10, 0),
>         CXL_CMD(SET_ALERT_CONFIG, 0xc, 0, 0),
>         CXL_CMD(GET_SHUTDOWN_STATE, 0, 0x1, 0),
>         CXL_CMD(SET_SHUTDOWN_STATE, 0x1, 0, 0),
> -       CXL_CMD(GET_POISON, 0x10, ~0, 0),
> +       CXL_CMD(GET_POISON, 0x10, CXL_VARIABLE_PAYLOAD, 0),
>         CXL_CMD(INJECT_POISON, 0x8, 0, 0),
>         CXL_CMD(CLEAR_POISON, 0x48, 0, 0),
>         CXL_CMD(GET_SCAN_MEDIA_CAPS, 0x10, 0x4, 0),
>         CXL_CMD(SCAN_MEDIA, 0x11, 0, 0),
> -       CXL_CMD(GET_SCAN_MEDIA, 0, ~0, 0),
> +       CXL_CMD(GET_SCAN_MEDIA, 0, CXL_VARIABLE_PAYLOAD, 0),
>  };
>
>  /*
> @@ -187,9 +188,10 @@ int cxl_mbox_send_cmd(struct cxl_dev_state *cxlds, u16 opcode, void *in,
>          * Variable sized commands can't be validated and so it's up to the
>          * caller to do that if they wish.
>          */
> -       if (cmd->info.size_out >= 0 && mbox_cmd.size_out != out_size)
> -               return -EIO;
> -
> +       if (cmd->info.size_out != CXL_VARIABLE_PAYLOAD) {
> +               if (mbox_cmd.size_out != out_size)

I'd prefer && here, but not enough to ask for the patch to be re-sent.

I'll pull this into the pending branch.
diff mbox series

Patch

diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
index 8a8388599a85..d54a6d175fff 100644
--- a/drivers/cxl/core/mbox.c
+++ b/drivers/cxl/core/mbox.c
@@ -35,6 +35,7 @@  static bool cxl_raw_allow_all;
 	.flags = _flags,                                                       \
 	}
 
+#define CXL_VARIABLE_PAYLOAD	~0U
 /*
  * This table defines the supported mailbox commands for the driver. This table
  * is made up of a UAPI structure. Non-negative values as parameters in the
@@ -44,26 +45,26 @@  static bool cxl_raw_allow_all;
 static struct cxl_mem_command cxl_mem_commands[CXL_MEM_COMMAND_ID_MAX] = {
 	CXL_CMD(IDENTIFY, 0, 0x43, CXL_CMD_FLAG_FORCE_ENABLE),
 #ifdef CONFIG_CXL_MEM_RAW_COMMANDS
-	CXL_CMD(RAW, ~0, ~0, 0),
+	CXL_CMD(RAW, CXL_VARIABLE_PAYLOAD, CXL_VARIABLE_PAYLOAD, 0),
 #endif
-	CXL_CMD(GET_SUPPORTED_LOGS, 0, ~0, CXL_CMD_FLAG_FORCE_ENABLE),
+	CXL_CMD(GET_SUPPORTED_LOGS, 0, CXL_VARIABLE_PAYLOAD, CXL_CMD_FLAG_FORCE_ENABLE),
 	CXL_CMD(GET_FW_INFO, 0, 0x50, 0),
 	CXL_CMD(GET_PARTITION_INFO, 0, 0x20, 0),
-	CXL_CMD(GET_LSA, 0x8, ~0, 0),
+	CXL_CMD(GET_LSA, 0x8, CXL_VARIABLE_PAYLOAD, 0),
 	CXL_CMD(GET_HEALTH_INFO, 0, 0x12, 0),
-	CXL_CMD(GET_LOG, 0x18, ~0, CXL_CMD_FLAG_FORCE_ENABLE),
+	CXL_CMD(GET_LOG, 0x18, CXL_VARIABLE_PAYLOAD, CXL_CMD_FLAG_FORCE_ENABLE),
 	CXL_CMD(SET_PARTITION_INFO, 0x0a, 0, 0),
-	CXL_CMD(SET_LSA, ~0, 0, 0),
+	CXL_CMD(SET_LSA, CXL_VARIABLE_PAYLOAD, 0, 0),
 	CXL_CMD(GET_ALERT_CONFIG, 0, 0x10, 0),
 	CXL_CMD(SET_ALERT_CONFIG, 0xc, 0, 0),
 	CXL_CMD(GET_SHUTDOWN_STATE, 0, 0x1, 0),
 	CXL_CMD(SET_SHUTDOWN_STATE, 0x1, 0, 0),
-	CXL_CMD(GET_POISON, 0x10, ~0, 0),
+	CXL_CMD(GET_POISON, 0x10, CXL_VARIABLE_PAYLOAD, 0),
 	CXL_CMD(INJECT_POISON, 0x8, 0, 0),
 	CXL_CMD(CLEAR_POISON, 0x48, 0, 0),
 	CXL_CMD(GET_SCAN_MEDIA_CAPS, 0x10, 0x4, 0),
 	CXL_CMD(SCAN_MEDIA, 0x11, 0, 0),
-	CXL_CMD(GET_SCAN_MEDIA, 0, ~0, 0),
+	CXL_CMD(GET_SCAN_MEDIA, 0, CXL_VARIABLE_PAYLOAD, 0),
 };
 
 /*
@@ -187,9 +188,10 @@  int cxl_mbox_send_cmd(struct cxl_dev_state *cxlds, u16 opcode, void *in,
 	 * Variable sized commands can't be validated and so it's up to the
 	 * caller to do that if they wish.
 	 */
-	if (cmd->info.size_out >= 0 && mbox_cmd.size_out != out_size)
-		return -EIO;
-
+	if (cmd->info.size_out != CXL_VARIABLE_PAYLOAD) {
+		if (mbox_cmd.size_out != out_size)
+			return -EIO;
+	}
 	return 0;
 }
 EXPORT_SYMBOL_NS_GPL(cxl_mbox_send_cmd, CXL);
@@ -275,7 +277,7 @@  static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox,
 	}
 
 	/* Prepare to handle a full payload for variable sized output */
-	if (out_size < 0)
+	if (out_size == CXL_VARIABLE_PAYLOAD)
 		mbox->size_out = cxlds->payload_size;
 	else
 		mbox->size_out = out_size;
@@ -353,11 +355,11 @@  static int cxl_to_mem_cmd(struct cxl_mem_command *mem_cmd,
 		return -EBUSY;
 
 	/* Check the input buffer is the expected size */
-	if (info->size_in >= 0 && info->size_in != send_cmd->in.size)
+	if (info->size_in != send_cmd->in.size)
 		return -ENOMEM;
 
 	/* Check the output buffer is at least large enough */
-	if (info->size_out >= 0 && send_cmd->out.size < info->size_out)
+	if (send_cmd->out.size < info->size_out)
 		return -ENOMEM;
 
 	*mem_cmd = (struct cxl_mem_command) {
diff --git a/include/uapi/linux/cxl_mem.h b/include/uapi/linux/cxl_mem.h
index 8d206f27bb6d..c71021a2a9ed 100644
--- a/include/uapi/linux/cxl_mem.h
+++ b/include/uapi/linux/cxl_mem.h
@@ -68,8 +68,8 @@  static const struct {
  * struct cxl_command_info - Command information returned from a query.
  * @id: ID number for the command.
  * @flags: Flags that specify command behavior.
- * @size_in: Expected input size, or -1 if variable length.
- * @size_out: Expected output size, or -1 if variable length.
+ * @size_in: Expected input size, or ~0 if variable length.
+ * @size_out: Expected output size, or ~0 if variable length.
  *
  * Represents a single command that is supported by both the driver and the
  * hardware. This is returned as part of an array from the query ioctl. The
@@ -78,7 +78,7 @@  static const struct {
  *
  *  - @id = 10
  *  - @flags = 0
- *  - @size_in = -1
+ *  - @size_in = ~0
  *  - @size_out = 0
  *
  * See struct cxl_mem_query_commands.
@@ -89,8 +89,8 @@  struct cxl_command_info {
 	__u32 flags;
 #define CXL_MEM_COMMAND_FLAG_MASK GENMASK(0, 0)
 
-	__s32 size_in;
-	__s32 size_out;
+	__u32 size_in;
+	__u32 size_out;
 };
 
 /**
@@ -169,13 +169,13 @@  struct cxl_send_command {
 	__u32 retval;
 
 	struct {
-		__s32 size;
+		__u32 size;
 		__u32 rsvd;
 		__u64 payload;
 	} in;
 
 	struct {
-		__s32 size;
+		__u32 size;
 		__u32 rsvd;
 		__u64 payload;
 	} out;