linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] xen/pv-scsi: update header and harden frontend
@ 2022-04-20  9:24 Juergen Gross
  2022-04-20  9:25 ` [PATCH 1/4] xen: update vscsiif.h Juergen Gross
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Juergen Gross @ 2022-04-20  9:24 UTC (permalink / raw)
  To: xen-devel, linux-scsi, linux-kernel
  Cc: Juergen Gross, Boris Ostrovsky, Stefano Stabellini,
	James E.J. Bottomley, Martin K. Petersen

Update the Xen PV-scsi interface from the Xen tree and adapt the
related drivers to use the new definitions.

Harden the frontend driver to be no longer vulnerable to a malicious
backend.

Juergen Gross (4):
  xen: update vscsiif.h
  xen/scsiback: use new command result macros
  xen/scsifront: use new command result macros
  xen/scsifront: harden driver against malicious backend

 drivers/scsi/xen-scsifront.c       | 168 ++++++++++++++++++++++-------
 drivers/xen/xen-scsiback.c         |  82 +++++++++++++-
 include/xen/interface/io/vscsiif.h | 133 ++++++++++++++++++++++-
 3 files changed, 340 insertions(+), 43 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/4] xen: update vscsiif.h
  2022-04-20  9:24 [PATCH 0/4] xen/pv-scsi: update header and harden frontend Juergen Gross
@ 2022-04-20  9:25 ` Juergen Gross
  2022-04-20  9:25 ` [PATCH 2/4] xen/scsiback: use new command result macros Juergen Gross
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 12+ messages in thread
From: Juergen Gross @ 2022-04-20  9:25 UTC (permalink / raw)
  To: xen-devel, linux-scsi, linux-kernel
  Cc: Juergen Gross, Boris Ostrovsky, Stefano Stabellini

Update include/xen/interface/io/vscsiif.h to its newest version.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 include/xen/interface/io/vscsiif.h | 133 ++++++++++++++++++++++++++++-
 1 file changed, 129 insertions(+), 4 deletions(-)

diff --git a/include/xen/interface/io/vscsiif.h b/include/xen/interface/io/vscsiif.h
index 1f6047d3de44..7ea4dc9611c4 100644
--- a/include/xen/interface/io/vscsiif.h
+++ b/include/xen/interface/io/vscsiif.h
@@ -43,7 +43,7 @@
  *
  *      A string specifying the backend device: either a 4-tuple "h:c:t:l"
  *      (host, controller, target, lun, all integers), or a WWN (e.g.
- *      "naa.60014054ac780582").
+ *      "naa.60014054ac780582:0").
  *
  * v-dev
  *      Values:         string
@@ -87,6 +87,75 @@
  *      response structures.
  */
 
+/*
+ * Xenstore format in practice
+ * ===========================
+ *
+ * The backend driver uses a single_host:many_devices notation to manage domU
+ * devices. Everything is stored in /local/domain/<backend_domid>/backend/vscsi/.
+ * The xenstore layout looks like this (dom0 is assumed to be the backend_domid):
+ *
+ *     <domid>/<vhost>/feature-host = "0"
+ *     <domid>/<vhost>/frontend = "/local/domain/<domid>/device/vscsi/0"
+ *     <domid>/<vhost>/frontend-id = "<domid>"
+ *     <domid>/<vhost>/online = "1"
+ *     <domid>/<vhost>/state = "4"
+ *     <domid>/<vhost>/vscsi-devs/dev-0/p-dev = "8:0:2:1" or "naa.wwn:lun"
+ *     <domid>/<vhost>/vscsi-devs/dev-0/state = "4"
+ *     <domid>/<vhost>/vscsi-devs/dev-0/v-dev = "0:0:0:0"
+ *     <domid>/<vhost>/vscsi-devs/dev-1/p-dev = "8:0:2:2"
+ *     <domid>/<vhost>/vscsi-devs/dev-1/state = "4"
+ *     <domid>/<vhost>/vscsi-devs/dev-1/v-dev = "0:0:1:0"
+ *
+ * The frontend driver maintains its state in
+ * /local/domain/<domid>/device/vscsi/.
+ *
+ *     <vhost>/backend = "/local/domain/0/backend/vscsi/<domid>/<vhost>"
+ *     <vhost>/backend-id = "0"
+ *     <vhost>/event-channel = "20"
+ *     <vhost>/ring-ref = "43"
+ *     <vhost>/state = "4"
+ *     <vhost>/vscsi-devs/dev-0/state = "4"
+ *     <vhost>/vscsi-devs/dev-1/state = "4"
+ *
+ * In addition to the entries for backend and frontend these flags are stored
+ * for the toolstack:
+ *
+ *     <domid>/<vhost>/vscsi-devs/dev-1/p-devname = "/dev/$device"
+ *     <domid>/<vhost>/libxl_ctrl_index = "0"
+ *
+ *
+ * Backend/frontend protocol
+ * =========================
+ *
+ * To create a vhost along with a device:
+ *     <domid>/<vhost>/feature-host = "0"
+ *     <domid>/<vhost>/frontend = "/local/domain/<domid>/device/vscsi/0"
+ *     <domid>/<vhost>/frontend-id = "<domid>"
+ *     <domid>/<vhost>/online = "1"
+ *     <domid>/<vhost>/state = "1"
+ *     <domid>/<vhost>/vscsi-devs/dev-0/p-dev = "8:0:2:1"
+ *     <domid>/<vhost>/vscsi-devs/dev-0/state = "1"
+ *     <domid>/<vhost>/vscsi-devs/dev-0/v-dev = "0:0:0:0"
+ * Wait for <domid>/<vhost>/state + <domid>/<vhost>/vscsi-devs/dev-0/state become 4
+ *
+ * To add another device to a vhost:
+ *     <domid>/<vhost>/state = "7"
+ *     <domid>/<vhost>/vscsi-devs/dev-1/p-dev = "8:0:2:2"
+ *     <domid>/<vhost>/vscsi-devs/dev-1/state = "1"
+ *     <domid>/<vhost>/vscsi-devs/dev-1/v-dev = "0:0:1:0"
+ * Wait for <domid>/<vhost>/state + <domid>/<vhost>/vscsi-devs/dev-1/state become 4
+ *
+ * To remove a device from a vhost:
+ *     <domid>/<vhost>/state = "7"
+ *     <domid>/<vhost>/vscsi-devs/dev-1/state = "5"
+ * Wait for <domid>/<vhost>/state to become 4
+ * Wait for <domid>/<vhost>/vscsi-devs/dev-1/state become 6
+ * Remove <domid>/<vhost>/vscsi-devs/dev-1/{state,p-dev,v-dev,p-devname}
+ * Remove <domid>/<vhost>/vscsi-devs/dev-1/
+ *
+ */
+
 /* Requests from the frontend to the backend */
 
 /*
@@ -117,7 +186,8 @@
  * (plus the set VSCSIIF_SG_GRANT bit), the number of scsiif_request_segment
  * elements referencing the target data buffers is calculated from the lengths
  * of the seg[] elements (the sum of all valid seg[].length divided by the
- * size of one scsiif_request_segment structure).
+ * size of one scsiif_request_segment structure). The frontend may use a mix of
+ * direct and indirect requests.
  */
 #define VSCSIIF_ACT_SCSI_CDB		1
 
@@ -154,12 +224,14 @@
 
 /*
  * based on Linux kernel 2.6.18, still valid
+ *
  * Changing these values requires support of multiple protocols via the rings
  * as "old clients" will blindly use these values and the resulting structure
  * sizes.
  */
 #define VSCSIIF_MAX_COMMAND_SIZE	16
 #define VSCSIIF_SENSE_BUFFERSIZE	96
+#define VSCSIIF_PAGE_SIZE		4096
 
 struct scsiif_request_segment {
 	grant_ref_t gref;
@@ -167,7 +239,8 @@ struct scsiif_request_segment {
 	uint16_t length;
 };
 
-#define VSCSIIF_SG_PER_PAGE (PAGE_SIZE / sizeof(struct scsiif_request_segment))
+#define VSCSIIF_SG_PER_PAGE	(VSCSIIF_PAGE_SIZE / \
+				 sizeof(struct scsiif_request_segment))
 
 /* Size of one request is 252 bytes */
 struct vscsiif_request {
@@ -207,6 +280,58 @@ struct vscsiif_response {
 	uint32_t reserved[36];
 };
 
+/* SCSI I/O status from vscsiif_response->rslt */
+#define XEN_VSCSIIF_RSLT_STATUS(x)  ((x) & 0x00ff)
+
+/* Host I/O status from vscsiif_response->rslt */
+#define XEN_VSCSIIF_RSLT_HOST(x)    (((x) & 0x00ff0000) >> 16)
+#define XEN_VSCSIIF_RSLT_HOST_OK                   0
+/* Couldn't connect before timeout */
+#define XEN_VSCSIIF_RSLT_HOST_NO_CONNECT           1
+/* Bus busy through timeout */
+#define XEN_VSCSIIF_RSLT_HOST_BUS_BUSY             2
+/* Timed out for other reason */
+#define XEN_VSCSIIF_RSLT_HOST_TIME_OUT             3
+/* Bad target */
+#define XEN_VSCSIIF_RSLT_HOST_BAD_TARGET           4
+/* Abort for some other reason */
+#define XEN_VSCSIIF_RSLT_HOST_ABORT                5
+/* Parity error */
+#define XEN_VSCSIIF_RSLT_HOST_PARITY               6
+/* Internal error */
+#define XEN_VSCSIIF_RSLT_HOST_ERROR                7
+/* Reset by somebody */
+#define XEN_VSCSIIF_RSLT_HOST_RESET                8
+/* Unexpected interrupt */
+#define XEN_VSCSIIF_RSLT_HOST_BAD_INTR             9
+/* Force command past mid-layer */
+#define XEN_VSCSIIF_RSLT_HOST_PASSTHROUGH         10
+/* Retry requested */
+#define XEN_VSCSIIF_RSLT_HOST_SOFT_ERROR          11
+/* Hidden retry requested */
+#define XEN_VSCSIIF_RSLT_HOST_IMM_RETRY           12
+/* Requeue command requested */
+#define XEN_VSCSIIF_RSLT_HOST_REQUEUE             13
+/* Transport error disrupted I/O */
+#define XEN_VSCSIIF_RSLT_HOST_TRANSPORT_DISRUPTED 14
+/* Transport class fastfailed */
+#define XEN_VSCSIIF_RSLT_HOST_TRANSPORT_FAILFAST  15
+/* Permanent target failure */
+#define XEN_VSCSIIF_RSLT_HOST_TARGET_FAILURE      16
+/* Permanent nexus failure on path */
+#define XEN_VSCSIIF_RSLT_HOST_NEXUS_FAILURE       17
+/* Space allocation on device failed */
+#define XEN_VSCSIIF_RSLT_HOST_ALLOC_FAILURE       18
+/* Medium error */
+#define XEN_VSCSIIF_RSLT_HOST_MEDIUM_ERROR        19
+/* Transport marginal errors */
+#define XEN_VSCSIIF_RSLT_HOST_TRANSPORT_MARGINAL  20
+
+/* Result values of reset operations */
+#define XEN_VSCSIIF_RSLT_RESET_SUCCESS  0x2002
+#define XEN_VSCSIIF_RSLT_RESET_FAILED   0x2003
+
 DEFINE_RING_TYPES(vscsiif, struct vscsiif_request, struct vscsiif_response);
 
-#endif /*__XEN__PUBLIC_IO_SCSI_H__*/
+
+#endif  /*__XEN__PUBLIC_IO_SCSI_H__*/
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/4] xen/scsiback: use new command result macros
  2022-04-20  9:24 [PATCH 0/4] xen/pv-scsi: update header and harden frontend Juergen Gross
  2022-04-20  9:25 ` [PATCH 1/4] xen: update vscsiif.h Juergen Gross
@ 2022-04-20  9:25 ` Juergen Gross
  2022-04-20 16:12   ` Boris Ostrovsky
  2022-04-20  9:25 ` [PATCH 3/4] xen/scsifront: " Juergen Gross
  2022-04-20  9:25 ` [PATCH 4/4] xen/scsifront: harden driver against malicious backend Juergen Gross
  3 siblings, 1 reply; 12+ messages in thread
From: Juergen Gross @ 2022-04-20  9:25 UTC (permalink / raw)
  To: xen-devel, linux-scsi, linux-kernel
  Cc: Juergen Gross, Boris Ostrovsky, Stefano Stabellini

Instead of using the kernel's values for the result of PV scsi
operations use the values of the interface definition.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 drivers/xen/xen-scsiback.c | 82 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 79 insertions(+), 3 deletions(-)

diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index 0c5e565aa8cf..673dd73844ff 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -280,6 +280,82 @@ static void scsiback_free_translation_entry(struct kref *kref)
 	kfree(entry);
 }
 
+static int32_t scsiback_result(int32_t result)
+{
+	int32_t host_status;
+
+	switch (result >> 16) {
+	case DID_OK:
+		host_status = XEN_VSCSIIF_RSLT_HOST_OK;
+		break;
+	case DID_NO_CONNECT:
+		host_status = XEN_VSCSIIF_RSLT_HOST_NO_CONNECT;
+		break;
+	case DID_BUS_BUSY:
+		host_status = XEN_VSCSIIF_RSLT_HOST_BUS_BUSY;
+		break;
+	case DID_TIME_OUT:
+		host_status = XEN_VSCSIIF_RSLT_HOST_TIME_OUT;
+		break;
+	case DID_BAD_TARGET:
+		host_status = XEN_VSCSIIF_RSLT_HOST_BAD_TARGET;
+		break;
+	case DID_ABORT:
+		host_status = XEN_VSCSIIF_RSLT_HOST_ABORT;
+		break;
+	case DID_PARITY:
+		host_status = XEN_VSCSIIF_RSLT_HOST_PARITY;
+		break;
+	case DID_ERROR:
+		host_status = XEN_VSCSIIF_RSLT_HOST_ERROR;
+		break;
+	case DID_RESET:
+		host_status = XEN_VSCSIIF_RSLT_HOST_RESET;
+		break;
+	case DID_BAD_INTR:
+		host_status = XEN_VSCSIIF_RSLT_HOST_BAD_INTR;
+		break;
+	case DID_PASSTHROUGH:
+		host_status = XEN_VSCSIIF_RSLT_HOST_PASSTHROUGH;
+		break;
+	case DID_SOFT_ERROR:
+		host_status = XEN_VSCSIIF_RSLT_HOST_SOFT_ERROR;
+		break;
+	case DID_IMM_RETRY:
+		host_status = XEN_VSCSIIF_RSLT_HOST_IMM_RETRY;
+		break;
+	case DID_REQUEUE:
+		host_status = XEN_VSCSIIF_RSLT_HOST_REQUEUE;
+		break;
+	case DID_TRANSPORT_DISRUPTED:
+		host_status = XEN_VSCSIIF_RSLT_HOST_TRANSPORT_DISRUPTED;
+		break;
+	case DID_TRANSPORT_FAILFAST:
+		host_status = XEN_VSCSIIF_RSLT_HOST_TRANSPORT_FAILFAST;
+		break;
+	case DID_TARGET_FAILURE:
+		host_status = XEN_VSCSIIF_RSLT_HOST_TARGET_FAILURE;
+		break;
+	case DID_NEXUS_FAILURE:
+		host_status = XEN_VSCSIIF_RSLT_HOST_NEXUS_FAILURE;
+		break;
+	case DID_ALLOC_FAILURE:
+		host_status = XEN_VSCSIIF_RSLT_HOST_ALLOC_FAILURE;
+		break;
+	case DID_MEDIUM_ERROR:
+		host_status = XEN_VSCSIIF_RSLT_HOST_MEDIUM_ERROR;
+		break;
+	case DID_TRANSPORT_MARGINAL:
+		host_status = XEN_VSCSIIF_RSLT_HOST_TRANSPORT_MARGINAL;
+		break;
+	default:
+		host_status = XEN_VSCSIIF_RSLT_HOST_ERROR;
+		break;
+	}
+
+	return (host_status << 16) | (result & 0x00ff);
+}
+
 static void scsiback_send_response(struct vscsibk_info *info,
 			char *sense_buffer, int32_t result, uint32_t resid,
 			uint16_t rqid)
@@ -295,7 +371,7 @@ static void scsiback_send_response(struct vscsibk_info *info,
 	ring_res = RING_GET_RESPONSE(&info->ring, info->ring.rsp_prod_pvt);
 	info->ring.rsp_prod_pvt++;
 
-	ring_res->rslt   = result;
+	ring_res->rslt   = scsiback_result(result);
 	ring_res->rqid   = rqid;
 
 	if (sense_buffer != NULL &&
@@ -555,7 +631,7 @@ static void scsiback_device_action(struct vscsibk_pend *pending_req,
 	struct scsiback_nexus *nexus = tpg->tpg_nexus;
 	struct se_cmd *se_cmd = &pending_req->se_cmd;
 	u64 unpacked_lun = pending_req->v2p->lun;
-	int rc, err = FAILED;
+	int rc, err = XEN_VSCSIIF_RSLT_RESET_FAILED;
 
 	init_completion(&pending_req->tmr_done);
 
@@ -569,7 +645,7 @@ static void scsiback_device_action(struct vscsibk_pend *pending_req,
 	wait_for_completion(&pending_req->tmr_done);
 
 	err = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ?
-		SUCCESS : FAILED;
+		XEN_VSCSIIF_RSLT_RESET_SUCCESS : XEN_VSCSIIF_RSLT_RESET_FAILED;
 
 	scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
 	transport_generic_free_cmd(&pending_req->se_cmd, 0);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/4] xen/scsifront: use new command result macros
  2022-04-20  9:24 [PATCH 0/4] xen/pv-scsi: update header and harden frontend Juergen Gross
  2022-04-20  9:25 ` [PATCH 1/4] xen: update vscsiif.h Juergen Gross
  2022-04-20  9:25 ` [PATCH 2/4] xen/scsiback: use new command result macros Juergen Gross
@ 2022-04-20  9:25 ` Juergen Gross
  2022-04-20  9:25 ` [PATCH 4/4] xen/scsifront: harden driver against malicious backend Juergen Gross
  3 siblings, 0 replies; 12+ messages in thread
From: Juergen Gross @ 2022-04-20  9:25 UTC (permalink / raw)
  To: xen-devel, linux-scsi, linux-kernel
  Cc: Juergen Gross, Boris Ostrovsky, Stefano Stabellini,
	James E.J. Bottomley, Martin K. Petersen

Add a translation layer for the command result values.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 drivers/scsi/xen-scsifront.c | 64 +++++++++++++++++++++++++++++++-----
 1 file changed, 56 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c
index 12109e4c73d4..8511bfc62963 100644
--- a/drivers/scsi/xen-scsifront.c
+++ b/drivers/scsi/xen-scsifront.c
@@ -243,6 +243,56 @@ static void scsifront_gnttab_done(struct vscsifrnt_info *info,
 	kfree(shadow->sg);
 }
 
+static unsigned int scsifront_host_byte(int32_t rslt)
+{
+	switch (XEN_VSCSIIF_RSLT_HOST(rslt)) {
+	case XEN_VSCSIIF_RSLT_HOST_OK:
+		return DID_OK;
+	case XEN_VSCSIIF_RSLT_HOST_NO_CONNECT:
+		return DID_NO_CONNECT;
+	case XEN_VSCSIIF_RSLT_HOST_BUS_BUSY:
+		return DID_BUS_BUSY;
+	case XEN_VSCSIIF_RSLT_HOST_TIME_OUT:
+		return DID_TIME_OUT;
+	case XEN_VSCSIIF_RSLT_HOST_BAD_TARGET:
+		return DID_BAD_TARGET;
+	case XEN_VSCSIIF_RSLT_HOST_ABORT:
+		return DID_ABORT;
+	case XEN_VSCSIIF_RSLT_HOST_PARITY:
+		return DID_PARITY;
+	case XEN_VSCSIIF_RSLT_HOST_ERROR:
+		return DID_ERROR;
+	case XEN_VSCSIIF_RSLT_HOST_RESET:
+		return DID_RESET;
+	case XEN_VSCSIIF_RSLT_HOST_BAD_INTR:
+		return DID_BAD_INTR;
+	case XEN_VSCSIIF_RSLT_HOST_PASSTHROUGH:
+		return DID_PASSTHROUGH;
+	case XEN_VSCSIIF_RSLT_HOST_SOFT_ERROR:
+		return DID_SOFT_ERROR;
+	case XEN_VSCSIIF_RSLT_HOST_IMM_RETRY:
+		return DID_IMM_RETRY;
+	case XEN_VSCSIIF_RSLT_HOST_REQUEUE:
+		return DID_REQUEUE;
+	case XEN_VSCSIIF_RSLT_HOST_TRANSPORT_DISRUPTED:
+		return DID_TRANSPORT_DISRUPTED;
+	case XEN_VSCSIIF_RSLT_HOST_TRANSPORT_FAILFAST:
+		return DID_TRANSPORT_FAILFAST;
+	case XEN_VSCSIIF_RSLT_HOST_TARGET_FAILURE:
+		return DID_TARGET_FAILURE;
+	case XEN_VSCSIIF_RSLT_HOST_NEXUS_FAILURE:
+		return DID_NEXUS_FAILURE;
+	case XEN_VSCSIIF_RSLT_HOST_ALLOC_FAILURE:
+		return DID_ALLOC_FAILURE;
+	case XEN_VSCSIIF_RSLT_HOST_MEDIUM_ERROR:
+		return DID_MEDIUM_ERROR;
+	case XEN_VSCSIIF_RSLT_HOST_TRANSPORT_MARGINAL:
+		return DID_TRANSPORT_MARGINAL;
+	default:
+		return DID_ERROR;
+	}
+}
+
 static void scsifront_cdb_cmd_done(struct vscsifrnt_info *info,
 				   struct vscsiif_response *ring_rsp)
 {
@@ -250,7 +300,6 @@ static void scsifront_cdb_cmd_done(struct vscsifrnt_info *info,
 	struct scsi_cmnd *sc;
 	uint32_t id;
 	uint8_t sense_len;
-	int result;
 
 	id = ring_rsp->rqid;
 	shadow = info->shadow[id];
@@ -261,12 +310,8 @@ static void scsifront_cdb_cmd_done(struct vscsifrnt_info *info,
 	scsifront_gnttab_done(info, shadow);
 	scsifront_put_rqid(info, id);
 
-	result = ring_rsp->rslt;
-	if (result >> 24)
-		set_host_byte(sc, DID_ERROR);
-	else
-		set_host_byte(sc, host_byte(result));
-	set_status_byte(sc, result & 0xff);
+	set_host_byte(sc, scsifront_host_byte(ring_rsp->rslt));
+	set_status_byte(sc, XEN_VSCSIIF_RSLT_STATUS(ring_rsp->rslt));
 	scsi_set_resid(sc, ring_rsp->residual_len);
 
 	sense_len = min_t(uint8_t, VSCSIIF_SENSE_BUFFERSIZE,
@@ -290,7 +335,10 @@ static void scsifront_sync_cmd_done(struct vscsifrnt_info *info,
 	shadow->wait_reset = 1;
 	switch (shadow->rslt_reset) {
 	case RSLT_RESET_WAITING:
-		shadow->rslt_reset = ring_rsp->rslt;
+		if (ring_rsp->rslt == XEN_VSCSIIF_RSLT_RESET_SUCCESS)
+			shadow->rslt_reset = SUCCESS;
+		else
+			shadow->rslt_reset = FAILED;
 		break;
 	case RSLT_RESET_ERR:
 		kick = _scsifront_put_rqid(info, id);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/4] xen/scsifront: harden driver against malicious backend
  2022-04-20  9:24 [PATCH 0/4] xen/pv-scsi: update header and harden frontend Juergen Gross
                   ` (2 preceding siblings ...)
  2022-04-20  9:25 ` [PATCH 3/4] xen/scsifront: " Juergen Gross
@ 2022-04-20  9:25 ` Juergen Gross
  2022-04-20 16:13   ` Boris Ostrovsky
  3 siblings, 1 reply; 12+ messages in thread
From: Juergen Gross @ 2022-04-20  9:25 UTC (permalink / raw)
  To: xen-devel, linux-scsi, linux-kernel
  Cc: Juergen Gross, Boris Ostrovsky, Stefano Stabellini,
	James E.J. Bottomley, Martin K. Petersen

Instead of relying on a well behaved PV scsi backend verify all meta
data received from the backend and avoid multiple reads of the same
data from the shared ring page.

In case any illegal data from the backend is detected switch the
PV device to a new "error" state and deactivate it for further use.

Use the "lateeoi" variant for the event channel in order to avoid
event storms blocking the guest.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 drivers/scsi/xen-scsifront.c | 104 +++++++++++++++++++++++++----------
 1 file changed, 76 insertions(+), 28 deletions(-)

diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c
index 8511bfc62963..761c9c463ecd 100644
--- a/drivers/scsi/xen-scsifront.c
+++ b/drivers/scsi/xen-scsifront.c
@@ -83,6 +83,8 @@ struct vscsifrnt_shadow {
 	uint16_t rqid;
 	uint16_t ref_rqid;
 
+	bool inflight;
+
 	unsigned int nr_grants;		/* number of grants in gref[] */
 	struct scsiif_request_segment *sg;	/* scatter/gather elements */
 	struct scsiif_request_segment seg[VSCSIIF_SG_TABLESIZE];
@@ -104,7 +106,11 @@ struct vscsifrnt_info {
 	struct xenbus_device *dev;
 
 	struct Scsi_Host *host;
-	int host_active;
+	enum {
+		STATE_INACTIVE,
+		STATE_ACTIVE,
+		STATE_ERROR
+	}  host_active;
 
 	unsigned int evtchn;
 	unsigned int irq;
@@ -217,6 +223,8 @@ static int scsifront_do_request(struct vscsifrnt_info *info,
 	for (i = 0; i < (shadow->nr_segments & ~VSCSIIF_SG_GRANT); i++)
 		ring_req->seg[i] = shadow->seg[i];
 
+	shadow->inflight = true;
+
 	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(ring, notify);
 	if (notify)
 		notify_remote_via_irq(info->irq);
@@ -224,6 +232,13 @@ static int scsifront_do_request(struct vscsifrnt_info *info,
 	return 0;
 }
 
+static void scsifront_set_error(struct vscsifrnt_info *info, const char *msg)
+{
+	shost_printk(KERN_ERR, info->host, KBUILD_MODNAME "%s\n"
+		     "Disabling device for further use\n", msg);
+	info->host_active = STATE_ERROR;
+}
+
 static void scsifront_gnttab_done(struct vscsifrnt_info *info,
 				  struct vscsifrnt_shadow *shadow)
 {
@@ -234,9 +249,8 @@ static void scsifront_gnttab_done(struct vscsifrnt_info *info,
 
 	for (i = 0; i < shadow->nr_grants; i++) {
 		if (unlikely(!gnttab_try_end_foreign_access(shadow->gref[i]))) {
-			shost_printk(KERN_ALERT, info->host, KBUILD_MODNAME
-				     "grant still in use by backend\n");
-			BUG();
+			scsifront_set_error(info, "grant still in use by backend");
+			return;
 		}
 	}
 
@@ -308,6 +322,8 @@ static void scsifront_cdb_cmd_done(struct vscsifrnt_info *info,
 	BUG_ON(sc == NULL);
 
 	scsifront_gnttab_done(info, shadow);
+	if (info->host_active == STATE_ERROR)
+		return;
 	scsifront_put_rqid(info, id);
 
 	set_host_byte(sc, scsifront_host_byte(ring_rsp->rslt));
@@ -348,9 +364,7 @@ static void scsifront_sync_cmd_done(struct vscsifrnt_info *info,
 			scsifront_wake_up(info);
 		return;
 	default:
-		shost_printk(KERN_ERR, info->host, KBUILD_MODNAME
-			     "bad reset state %d, possibly leaking %u\n",
-			     shadow->rslt_reset, id);
+		scsifront_set_error(info, "bad reset state");
 		break;
 	}
 	spin_unlock_irqrestore(&info->shadow_lock, flags);
@@ -361,28 +375,41 @@ static void scsifront_sync_cmd_done(struct vscsifrnt_info *info,
 static void scsifront_do_response(struct vscsifrnt_info *info,
 				  struct vscsiif_response *ring_rsp)
 {
-	if (WARN(ring_rsp->rqid >= VSCSIIF_MAX_REQS ||
-		 test_bit(ring_rsp->rqid, info->shadow_free_bitmap),
-		 "illegal rqid %u returned by backend!\n", ring_rsp->rqid))
+	struct vscsifrnt_shadow *shadow;
+
+	if (ring_rsp->rqid >= VSCSIIF_MAX_REQS ||
+	    !info->shadow[ring_rsp->rqid]->inflight) {
+		scsifront_set_error(info, "illegal rqid returned by backend!");
 		return;
+	}
+	shadow = info->shadow[ring_rsp->rqid];
+	shadow->inflight = false;
 
-	if (info->shadow[ring_rsp->rqid]->act == VSCSIIF_ACT_SCSI_CDB)
+	if (shadow->act == VSCSIIF_ACT_SCSI_CDB)
 		scsifront_cdb_cmd_done(info, ring_rsp);
 	else
 		scsifront_sync_cmd_done(info, ring_rsp);
 }
 
-static int scsifront_ring_drain(struct vscsifrnt_info *info)
+static int scsifront_ring_drain(struct vscsifrnt_info *info,
+				unsigned int *eoiflag)
 {
-	struct vscsiif_response *ring_rsp;
+	struct vscsiif_response ring_rsp;
 	RING_IDX i, rp;
 	int more_to_do = 0;
 
-	rp = info->ring.sring->rsp_prod;
-	rmb();	/* ordering required respective to dom0 */
+	rp = READ_ONCE(info->ring.sring->rsp_prod);
+	virt_rmb();	/* ordering required respective to backend */
+	if (RING_RESPONSE_PROD_OVERFLOW(&info->ring, rp)) {
+		scsifront_set_error(info, "illegal number of responses");
+		return 0;
+	}
 	for (i = info->ring.rsp_cons; i != rp; i++) {
-		ring_rsp = RING_GET_RESPONSE(&info->ring, i);
-		scsifront_do_response(info, ring_rsp);
+		RING_COPY_RESPONSE(&info->ring, i, &ring_rsp);
+		scsifront_do_response(info, &ring_rsp);
+		if (info->host_active == STATE_ERROR)
+			return 0;
+		*eoiflag = 0;
 	}
 
 	info->ring.rsp_cons = i;
@@ -395,14 +422,15 @@ static int scsifront_ring_drain(struct vscsifrnt_info *info)
 	return more_to_do;
 }
 
-static int scsifront_cmd_done(struct vscsifrnt_info *info)
+static int scsifront_cmd_done(struct vscsifrnt_info *info,
+			      unsigned int *eoiflag)
 {
 	int more_to_do;
 	unsigned long flags;
 
 	spin_lock_irqsave(info->host->host_lock, flags);
 
-	more_to_do = scsifront_ring_drain(info);
+	more_to_do = scsifront_ring_drain(info, eoiflag);
 
 	info->wait_ring_available = 0;
 
@@ -416,20 +444,28 @@ static int scsifront_cmd_done(struct vscsifrnt_info *info)
 static irqreturn_t scsifront_irq_fn(int irq, void *dev_id)
 {
 	struct vscsifrnt_info *info = dev_id;
+	unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS;
+
+	if (info->host_active == STATE_ERROR) {
+		xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS);
+		return IRQ_HANDLED;
+	}
 
-	while (scsifront_cmd_done(info))
+	while (scsifront_cmd_done(info, &eoiflag))
 		/* Yield point for this unbounded loop. */
 		cond_resched();
 
+	xen_irq_lateeoi(irq, eoiflag);
+
 	return IRQ_HANDLED;
 }
 
 static void scsifront_finish_all(struct vscsifrnt_info *info)
 {
-	unsigned i;
+	unsigned int i, dummy;
 	struct vscsiif_response resp;
 
-	scsifront_ring_drain(info);
+	scsifront_ring_drain(info, &dummy);
 
 	for (i = 0; i < VSCSIIF_MAX_REQS; i++) {
 		if (test_bit(i, info->shadow_free_bitmap))
@@ -586,6 +622,9 @@ static int scsifront_queuecommand(struct Scsi_Host *shost,
 	unsigned long flags;
 	int err;
 
+	if (info->host_active == STATE_ERROR)
+		return SCSI_MLQUEUE_HOST_BUSY;
+
 	sc->result = 0;
 
 	shadow->sc  = sc;
@@ -638,6 +677,9 @@ static int scsifront_action_handler(struct scsi_cmnd *sc, uint8_t act)
 	struct vscsifrnt_shadow *shadow, *s = scsi_cmd_priv(sc);
 	int err = 0;
 
+	if (info->host_active == STATE_ERROR)
+		return FAILED;
+
 	shadow = kzalloc(sizeof(*shadow), GFP_NOIO);
 	if (!shadow)
 		return FAILED;
@@ -709,6 +751,9 @@ static int scsifront_sdev_configure(struct scsi_device *sdev)
 	struct vscsifrnt_info *info = shost_priv(sdev->host);
 	int err;
 
+	if (info->host_active == STATE_ERROR)
+		return -EIO;
+
 	if (info && current == info->curr) {
 		err = xenbus_printf(XBT_NIL, info->dev->nodename,
 			      info->dev_state_path, "%d", XenbusStateConnected);
@@ -784,7 +829,7 @@ static int scsifront_alloc_ring(struct vscsifrnt_info *info)
 		goto free_gnttab;
 	}
 
-	err = bind_evtchn_to_irq(info->evtchn);
+	err = bind_evtchn_to_irq_lateeoi(info->evtchn);
 	if (err <= 0) {
 		xenbus_dev_fatal(dev, err, "bind_evtchn_to_irq");
 		goto free_gnttab;
@@ -914,7 +959,7 @@ static int scsifront_probe(struct xenbus_device *dev,
 		goto free_sring;
 	}
 	info->host = host;
-	info->host_active = 1;
+	info->host_active = STATE_ACTIVE;
 
 	xenbus_switch_state(dev, XenbusStateInitialised);
 
@@ -982,10 +1027,10 @@ static int scsifront_remove(struct xenbus_device *dev)
 	pr_debug("%s: %s removed\n", __func__, dev->nodename);
 
 	mutex_lock(&scsifront_mutex);
-	if (info->host_active) {
+	if (info->host_active != STATE_INACTIVE) {
 		/* Scsi_host not yet removed */
 		scsi_remove_host(info->host);
-		info->host_active = 0;
+		info->host_active = STATE_INACTIVE;
 	}
 	mutex_unlock(&scsifront_mutex);
 
@@ -1009,9 +1054,9 @@ static void scsifront_disconnect(struct vscsifrnt_info *info)
 	 */
 
 	mutex_lock(&scsifront_mutex);
-	if (info->host_active) {
+	if (info->host_active != STATE_INACTIVE) {
 		scsi_remove_host(host);
-		info->host_active = 0;
+		info->host_active = STATE_INACTIVE;
 	}
 	mutex_unlock(&scsifront_mutex);
 
@@ -1029,6 +1074,9 @@ static void scsifront_do_lun_hotplug(struct vscsifrnt_info *info, int op)
 	unsigned int hst, chn, tgt, lun;
 	struct scsi_device *sdev;
 
+	if (info->host_active == STATE_ERROR)
+		return;
+
 	dir = xenbus_directory(XBT_NIL, dev->otherend, "vscsi-devs", &dir_n);
 	if (IS_ERR(dir))
 		return;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] xen/scsiback: use new command result macros
  2022-04-20  9:25 ` [PATCH 2/4] xen/scsiback: use new command result macros Juergen Gross
@ 2022-04-20 16:12   ` Boris Ostrovsky
  2022-04-21  8:40     ` Juergen Gross
  0 siblings, 1 reply; 12+ messages in thread
From: Boris Ostrovsky @ 2022-04-20 16:12 UTC (permalink / raw)
  To: Juergen Gross, xen-devel, linux-scsi, linux-kernel; +Cc: Stefano Stabellini


On 4/20/22 5:25 AM, Juergen Gross wrote:
> @@ -569,7 +645,7 @@ static void scsiback_device_action(struct vscsibk_pend *pending_req,
>   	wait_for_completion(&pending_req->tmr_done);
>   
>   	err = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ?
> -		SUCCESS : FAILED;
> +		XEN_VSCSIIF_RSLT_RESET_SUCCESS : XEN_VSCSIIF_RSLT_RESET_FAILED;
>   
>   	scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
>   	transport_generic_free_cmd(&pending_req->se_cmd, 0);


You also want to initialize err to XEN_VSCSIIF_RSLT_RESET_FAILED.


And also looking at invocations of scsiback_do_resp_with_sense() I think those may need to be adjusted as well.




-boris


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/4] xen/scsifront: harden driver against malicious backend
  2022-04-20  9:25 ` [PATCH 4/4] xen/scsifront: harden driver against malicious backend Juergen Gross
@ 2022-04-20 16:13   ` Boris Ostrovsky
  2022-04-21 10:13     ` Juergen Gross
  0 siblings, 1 reply; 12+ messages in thread
From: Boris Ostrovsky @ 2022-04-20 16:13 UTC (permalink / raw)
  To: Juergen Gross, xen-devel, linux-scsi, linux-kernel
  Cc: Stefano Stabellini, James E.J. Bottomley, Martin K. Petersen

Just a couple of nits.


On 4/20/22 5:25 AM, Juergen Gross wrote:
>   
> -static int scsifront_ring_drain(struct vscsifrnt_info *info)
> +static int scsifront_ring_drain(struct vscsifrnt_info *info,
> +				unsigned int *eoiflag)
>   {
> -	struct vscsiif_response *ring_rsp;
> +	struct vscsiif_response ring_rsp;
>   	RING_IDX i, rp;
>   	int more_to_do = 0;
>   
> -	rp = info->ring.sring->rsp_prod;
> -	rmb();	/* ordering required respective to dom0 */
> +	rp = READ_ONCE(info->ring.sring->rsp_prod);
> +	virt_rmb();	/* ordering required respective to backend */
> +	if (RING_RESPONSE_PROD_OVERFLOW(&info->ring, rp)) {
> +		scsifront_set_error(info, "illegal number of responses");


In net and block drivers we report number of such responses. (But not in usb)


> +		return 0;
> +	}
>   	for (i = info->ring.rsp_cons; i != rp; i++) {
> -		ring_rsp = RING_GET_RESPONSE(&info->ring, i);
> -		scsifront_do_response(info, ring_rsp);
> +		RING_COPY_RESPONSE(&info->ring, i, &ring_rsp);
> +		scsifront_do_response(info, &ring_rsp);
> +		if (info->host_active == STATE_ERROR)
> +			return 0;
> +		*eoiflag = 0;


*eoiflags &= ~XEN_EOI_FLAG_SPURIOUS; ?


We also use eoi_flags name in other instances in this file.


-boris

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] xen/scsiback: use new command result macros
  2022-04-20 16:12   ` Boris Ostrovsky
@ 2022-04-21  8:40     ` Juergen Gross
  2022-04-21 20:56       ` Boris Ostrovsky
  0 siblings, 1 reply; 12+ messages in thread
From: Juergen Gross @ 2022-04-21  8:40 UTC (permalink / raw)
  To: Boris Ostrovsky, xen-devel, linux-scsi, linux-kernel; +Cc: Stefano Stabellini


[-- Attachment #1.1.1: Type: text/plain, Size: 969 bytes --]

On 20.04.22 18:12, Boris Ostrovsky wrote:
> 
> On 4/20/22 5:25 AM, Juergen Gross wrote:
>> @@ -569,7 +645,7 @@ static void scsiback_device_action(struct vscsibk_pend 
>> *pending_req,
>>       wait_for_completion(&pending_req->tmr_done);
>>       err = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ?
>> -        SUCCESS : FAILED;
>> +        XEN_VSCSIIF_RSLT_RESET_SUCCESS : XEN_VSCSIIF_RSLT_RESET_FAILED;
>>       scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
>>       transport_generic_free_cmd(&pending_req->se_cmd, 0);
> 
> 
> You also want to initialize err to XEN_VSCSIIF_RSLT_RESET_FAILED.

I did that.

> And also looking at invocations of scsiback_do_resp_with_sense() I think those 
> may need to be adjusted as well.

No, the invocations are fine, but scsiback_result() needs to pass through
the lowest 16 bits instead of only the lowest 8 bits of the result value.


Juergen


[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/4] xen/scsifront: harden driver against malicious backend
  2022-04-20 16:13   ` Boris Ostrovsky
@ 2022-04-21 10:13     ` Juergen Gross
  2022-04-21 15:29       ` Juergen Gross
  0 siblings, 1 reply; 12+ messages in thread
From: Juergen Gross @ 2022-04-21 10:13 UTC (permalink / raw)
  To: Boris Ostrovsky, xen-devel, linux-scsi, linux-kernel
  Cc: Stefano Stabellini, James E.J. Bottomley, Martin K. Petersen


[-- Attachment #1.1.1: Type: text/plain, Size: 1675 bytes --]

On 20.04.22 18:13, Boris Ostrovsky wrote:
> Just a couple of nits.
> 
> 
> On 4/20/22 5:25 AM, Juergen Gross wrote:
>> -static int scsifront_ring_drain(struct vscsifrnt_info *info)
>> +static int scsifront_ring_drain(struct vscsifrnt_info *info,
>> +                unsigned int *eoiflag)
>>   {
>> -    struct vscsiif_response *ring_rsp;
>> +    struct vscsiif_response ring_rsp;
>>       RING_IDX i, rp;
>>       int more_to_do = 0;
>> -    rp = info->ring.sring->rsp_prod;
>> -    rmb();    /* ordering required respective to dom0 */
>> +    rp = READ_ONCE(info->ring.sring->rsp_prod);
>> +    virt_rmb();    /* ordering required respective to backend */
>> +    if (RING_RESPONSE_PROD_OVERFLOW(&info->ring, rp)) {
>> +        scsifront_set_error(info, "illegal number of responses");
> 
> 
> In net and block drivers we report number of such responses. (But not in usb)
I'm not sure the specific value is of any interest.

>> +        return 0;
>> +    }
>>       for (i = info->ring.rsp_cons; i != rp; i++) {
>> -        ring_rsp = RING_GET_RESPONSE(&info->ring, i);
>> -        scsifront_do_response(info, ring_rsp);
>> +        RING_COPY_RESPONSE(&info->ring, i, &ring_rsp);
>> +        scsifront_do_response(info, &ring_rsp);
>> +        if (info->host_active == STATE_ERROR)
>> +            return 0;
>> +        *eoiflag = 0;
> 
> 
> *eoiflags &= ~XEN_EOI_FLAG_SPURIOUS; ?

Yes, probably better.

> We also use eoi_flags name in other instances in this file.

I'll unify the name.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/4] xen/scsifront: harden driver against malicious backend
  2022-04-21 10:13     ` Juergen Gross
@ 2022-04-21 15:29       ` Juergen Gross
  0 siblings, 0 replies; 12+ messages in thread
From: Juergen Gross @ 2022-04-21 15:29 UTC (permalink / raw)
  To: Boris Ostrovsky, xen-devel, linux-scsi, linux-kernel
  Cc: Stefano Stabellini, James E.J. Bottomley, Martin K. Petersen


[-- Attachment #1.1.1: Type: text/plain, Size: 1830 bytes --]

On 21.04.22 12:13, Juergen Gross wrote:
> On 20.04.22 18:13, Boris Ostrovsky wrote:
>> Just a couple of nits.
>>
>>
>> On 4/20/22 5:25 AM, Juergen Gross wrote:
>>> -static int scsifront_ring_drain(struct vscsifrnt_info *info)
>>> +static int scsifront_ring_drain(struct vscsifrnt_info *info,
>>> +                unsigned int *eoiflag)
>>>   {
>>> -    struct vscsiif_response *ring_rsp;
>>> +    struct vscsiif_response ring_rsp;
>>>       RING_IDX i, rp;
>>>       int more_to_do = 0;
>>> -    rp = info->ring.sring->rsp_prod;
>>> -    rmb();    /* ordering required respective to dom0 */
>>> +    rp = READ_ONCE(info->ring.sring->rsp_prod);
>>> +    virt_rmb();    /* ordering required respective to backend */
>>> +    if (RING_RESPONSE_PROD_OVERFLOW(&info->ring, rp)) {
>>> +        scsifront_set_error(info, "illegal number of responses");
>>
>>
>> In net and block drivers we report number of such responses. (But not in usb)
> I'm not sure the specific value is of any interest.
> 
>>> +        return 0;
>>> +    }
>>>       for (i = info->ring.rsp_cons; i != rp; i++) {
>>> -        ring_rsp = RING_GET_RESPONSE(&info->ring, i);
>>> -        scsifront_do_response(info, ring_rsp);
>>> +        RING_COPY_RESPONSE(&info->ring, i, &ring_rsp);
>>> +        scsifront_do_response(info, &ring_rsp);
>>> +        if (info->host_active == STATE_ERROR)
>>> +            return 0;
>>> +        *eoiflag = 0;
>>
>>
>> *eoiflags &= ~XEN_EOI_FLAG_SPURIOUS; ?
> 
> Yes, probably better.
> 
>> We also use eoi_flags name in other instances in this file.
> 
> I'll unify the name.

Oh, eoi_flags is used in the backend driver. So nothing to unify.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] xen/scsiback: use new command result macros
  2022-04-21  8:40     ` Juergen Gross
@ 2022-04-21 20:56       ` Boris Ostrovsky
  2022-04-28  7:06         ` Juergen Gross
  0 siblings, 1 reply; 12+ messages in thread
From: Boris Ostrovsky @ 2022-04-21 20:56 UTC (permalink / raw)
  To: Juergen Gross, xen-devel, linux-scsi, linux-kernel; +Cc: Stefano Stabellini


On 4/21/22 4:40 AM, Juergen Gross wrote:
> On 20.04.22 18:12, Boris Ostrovsky wrote:
>>
>> On 4/20/22 5:25 AM, Juergen Gross wrote:
>>> @@ -569,7 +645,7 @@ static void scsiback_device_action(struct vscsibk_pend *pending_req,
>>>       wait_for_completion(&pending_req->tmr_done);
>>>       err = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ?
>>> -        SUCCESS : FAILED;
>>> +        XEN_VSCSIIF_RSLT_RESET_SUCCESS : XEN_VSCSIIF_RSLT_RESET_FAILED;
>>>       scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
>>>       transport_generic_free_cmd(&pending_req->se_cmd, 0);
>>
>>
>> You also want to initialize err to XEN_VSCSIIF_RSLT_RESET_FAILED.
>
> I did that.


Yes you did. I don't know what I was was looking at.


>
>> And also looking at invocations of scsiback_do_resp_with_sense() I think those may need to be adjusted as well.
>
> No, the invocations are fine, but scsiback_result() needs to pass through
> the lowest 16 bits instead of only the lowest 8 bits of the result value.
>

What I was thinking was that this could use the reverse of XEN_VSCSIIF_RSLT_HOST(), i.e. something like

#define RSLT_HOST_TO_XEN_VSCSIIF(x)   ((x)<<16)

to be explicit about namespaces.


BTW, should scsiback_result() use XEN_VSCSIIF_RSLT_HOST() at the top?


-boris


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] xen/scsiback: use new command result macros
  2022-04-21 20:56       ` Boris Ostrovsky
@ 2022-04-28  7:06         ` Juergen Gross
  0 siblings, 0 replies; 12+ messages in thread
From: Juergen Gross @ 2022-04-28  7:06 UTC (permalink / raw)
  To: Boris Ostrovsky, xen-devel, linux-scsi, linux-kernel; +Cc: Stefano Stabellini


[-- Attachment #1.1.1: Type: text/plain, Size: 779 bytes --]

On 21.04.22 22:56, Boris Ostrovsky wrote:
> 
> On 4/21/22 4:40 AM, Juergen Gross wrote:
>> On 20.04.22 18:12, Boris Ostrovsky wrote:
>>> And also looking at invocations of scsiback_do_resp_with_sense() I think 
>>> those may need to be adjusted as well.
>>
>> No, the invocations are fine, but scsiback_result() needs to pass through
>> the lowest 16 bits instead of only the lowest 8 bits of the result value.
>>
> 
> What I was thinking was that this could use the reverse of 
> XEN_VSCSIIF_RSLT_HOST(), i.e. something like
> 
> #define RSLT_HOST_TO_XEN_VSCSIIF(x)   ((x)<<16)
> 
> to be explicit about namespaces.

I don't think this is needed.

> BTW, should scsiback_result() use XEN_VSCSIIF_RSLT_HOST() at the top?

Yes, I'll do that.


Juergen

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3149 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2022-04-28  7:06 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-20  9:24 [PATCH 0/4] xen/pv-scsi: update header and harden frontend Juergen Gross
2022-04-20  9:25 ` [PATCH 1/4] xen: update vscsiif.h Juergen Gross
2022-04-20  9:25 ` [PATCH 2/4] xen/scsiback: use new command result macros Juergen Gross
2022-04-20 16:12   ` Boris Ostrovsky
2022-04-21  8:40     ` Juergen Gross
2022-04-21 20:56       ` Boris Ostrovsky
2022-04-28  7:06         ` Juergen Gross
2022-04-20  9:25 ` [PATCH 3/4] xen/scsifront: " Juergen Gross
2022-04-20  9:25 ` [PATCH 4/4] xen/scsifront: harden driver against malicious backend Juergen Gross
2022-04-20 16:13   ` Boris Ostrovsky
2022-04-21 10:13     ` Juergen Gross
2022-04-21 15:29       ` Juergen Gross

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).