From cce22074a77f9545e86742f423245059bd623e6a Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Tue, 2 May 2017 13:22:00 -0700 Subject: [PATCH] iscsi: fix ISID interpretation in login requests The ISID field is a 6-byte field in network (big-endian) byte order. The previous code was casting the uint8_t isid[6] value into uint64_t, which was actually casting the address of the first byte of isid (not the contents of the array), and it was also not correctly converting byte order. Change-Id: Idd114e06d30040cf28931d7da7ffdc8d6c45e82a Signed-off-by: Daniel Verkamp --- lib/iscsi/iscsi.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index 347ce9d4a..5f81c33b2 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -224,6 +224,17 @@ spdk_gen_random(uint8_t *buf, size_t len) #endif /* USE_RANDOM */ } +static uint64_t +spdk_iscsi_get_isid(const uint8_t isid[6]) +{ + return (uint64_t)isid[0] << 40 | + (uint64_t)isid[1] << 32 | + (uint64_t)isid[2] << 24 | + (uint64_t)isid[3] << 16 | + (uint64_t)isid[4] << 8 | + (uint64_t)isid[5]; +} + static int spdk_bin2hex(char *buf, size_t len, const uint8_t *data, size_t data_len) { @@ -1345,7 +1356,7 @@ spdk_iscsi_op_login_check_session(struct spdk_iscsi_conn *conn, rsph = (struct iscsi_bhs_login_rsp *) & (rsp_pdu->bhs); /* check existing session */ SPDK_TRACELOG(SPDK_TRACE_ISCSI, "isid=%"PRIx64", tsih=%u, cid=%u\n", - (uint64_t)rsph->isid, from_be16(&rsph->tsih), cid); + spdk_iscsi_get_isid(rsph->isid), from_be16(&rsph->tsih), cid); if (rsph->tsih != 0) { /* multiple connections */ rc = spdk_append_iscsi_sess(conn, initiator_port_name, @@ -1353,7 +1364,7 @@ spdk_iscsi_op_login_check_session(struct spdk_iscsi_conn *conn, if (rc < 0) { SPDK_ERRLOG("isid=%"PRIx64", tsih=%u, cid=%u:" "spdk_append_iscsi_sess() failed\n", - (uint64_t)rsph->isid, from_be16(&rsph->tsih), + spdk_iscsi_get_isid(rsph->isid), from_be16(&rsph->tsih), cid); /* Can't include in session */ rsph->status_class = ISCSI_CLASS_INITIATOR_ERROR; @@ -1558,7 +1569,7 @@ spdk_iscsi_op_login_initialize_port(struct spdk_iscsi_conn *conn, snprintf(conn->initiator_name, sizeof(conn->initiator_name), "%s", val); snprintf(initiator_port_name, name_length, - "%s,i,0x%12.12" PRIx64, val, (uint64_t)rsph->isid); + "%s,i,0x%12.12" PRIx64, val, spdk_iscsi_get_isid(rsph->isid)); spdk_strlwr(conn->initiator_name); spdk_strlwr(initiator_port_name); SPDK_TRACELOG(SPDK_TRACE_DEBUG, "Initiator name: %s\n", @@ -1603,9 +1614,9 @@ spdk_iscsi_op_login_set_conn_info(struct spdk_iscsi_conn *conn, /* initialize parameters */ conn->StatSN = from_be32(&rsph->stat_sn); spdk_scsi_port_construct(&conn->sess->initiator_port, - (uint64_t)rsph->isid, 0, + spdk_iscsi_get_isid(rsph->isid), 0, initiator_port_name); - conn->sess->isid = (uint64_t)rsph->isid; + conn->sess->isid = spdk_iscsi_get_isid(rsph->isid); conn->sess->target = target; /* Discovery sessions will not have a target. */