Skip to content

Commit

Permalink
iscsit: proper endianess conversions
Browse files Browse the repository at this point in the history
Make sure all on the wire types are use as big endian and big endian only so
that sparse can verify all the conversions are done right.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
  • Loading branch information
Christoph Hellwig authored and Nicholas Bellinger committed Oct 3, 2012
1 parent 66c7db6 commit 50e5c87
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 138 deletions.
121 changes: 55 additions & 66 deletions drivers/target/iscsi/iscsi_target.c
Original file line number Diff line number Diff line change
Expand Up @@ -785,9 +785,6 @@ static int iscsit_handle_scsi_cmd(

hdr = (struct iscsi_scsi_req *) buf;
payload_length = ntoh24(hdr->dlength);
hdr->data_length = be32_to_cpu(hdr->data_length);
hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);

/* FIXME; Add checks for AdditionalHeaderSegment */

Expand Down Expand Up @@ -851,7 +848,7 @@ static int iscsit_handle_scsi_cmd(
buf, conn);
}

if ((hdr->data_length == payload_length) &&
if ((be32_to_cpu(hdr->data_length )== payload_length) &&
(!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) {
pr_err("Expected Data Transfer Length and Length of"
" Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL"
Expand All @@ -860,7 +857,7 @@ static int iscsit_handle_scsi_cmd(
buf, conn);
}

if (payload_length > hdr->data_length) {
if (payload_length > be32_to_cpu(hdr->data_length)) {
pr_err("DataSegmentLength: %u is greater than"
" EDTL: %u, protocol error.\n", payload_length,
hdr->data_length);
Expand Down Expand Up @@ -931,8 +928,8 @@ static int iscsit_handle_scsi_cmd(
spin_unlock_bh(&conn->sess->ttt_lock);
} else if (hdr->flags & ISCSI_FLAG_CMD_WRITE)
cmd->targ_xfer_tag = 0xFFFFFFFF;
cmd->cmd_sn = hdr->cmdsn;
cmd->exp_stat_sn = hdr->exp_statsn;
cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
cmd->first_burst_len = payload_length;

if (cmd->data_direction == DMA_FROM_DEVICE) {
Expand All @@ -951,8 +948,9 @@ static int iscsit_handle_scsi_cmd(
* Initialize struct se_cmd descriptor from target_core_mod infrastructure
*/
transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops,
conn->sess->se_sess, hdr->data_length, cmd->data_direction,
sam_task_attr, cmd->sense_buffer + 2);
conn->sess->se_sess, be32_to_cpu(hdr->data_length),
cmd->data_direction, sam_task_attr,
cmd->sense_buffer + 2);

pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x,"
" ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
Expand Down Expand Up @@ -1027,7 +1025,7 @@ static int iscsit_handle_scsi_cmd(
1, 0, buf, cmd);
}

iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));

/*
* If no Immediate Data is attached, it's OK to return now.
Expand Down Expand Up @@ -1193,10 +1191,6 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)

hdr = (struct iscsi_data *) buf;
payload_length = ntoh24(hdr->dlength);
hdr->ttt = be32_to_cpu(hdr->ttt);
hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
hdr->datasn = be32_to_cpu(hdr->datasn);
hdr->offset = be32_to_cpu(hdr->offset);

if (!payload_length) {
pr_err("DataOUT payload is ZERO, protocol error.\n");
Expand Down Expand Up @@ -1248,7 +1242,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
se_cmd = &cmd->se_cmd;
iscsit_mod_dataout_timer(cmd);

if ((hdr->offset + payload_length) > cmd->se_cmd.data_length) {
if ((be32_to_cpu(hdr->offset) + payload_length) > cmd->se_cmd.data_length) {
pr_err("DataOut Offset: %u, Length %u greater than"
" iSCSI Command EDTL %u, protocol error.\n",
hdr->offset, payload_length, cmd->se_cmd.data_length);
Expand Down Expand Up @@ -1331,7 +1325,8 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
rx_size += payload_length;
iov = &cmd->iov_data[0];

iov_ret = iscsit_map_iovec(cmd, iov, hdr->offset, payload_length);
iov_ret = iscsit_map_iovec(cmd, iov, be32_to_cpu(hdr->offset),
payload_length);
if (iov_ret < 0)
return -1;

Expand Down Expand Up @@ -1362,7 +1357,8 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
u32 data_crc;

data_crc = iscsit_do_crypto_hash_sg(&conn->conn_rx_hash, cmd,
hdr->offset, payload_length, padding,
be32_to_cpu(hdr->offset),
payload_length, padding,
cmd->pad_bytes);

if (checksum != data_crc) {
Expand Down Expand Up @@ -1423,9 +1419,6 @@ static int iscsit_handle_nop_out(

hdr = (struct iscsi_nopout *) buf;
payload_length = ntoh24(hdr->dlength);
hdr->ttt = be32_to_cpu(hdr->ttt);
hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);

if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
pr_err("NOPOUT ITT is reserved, but Immediate Bit is"
Expand Down Expand Up @@ -1455,7 +1448,7 @@ static int iscsit_handle_nop_out(
* Either way, make sure we allocate an struct iscsi_cmd, as both
* can contain ping data.
*/
if (hdr->ttt == 0xFFFFFFFF) {
if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
if (!cmd)
return iscsit_add_reject(
Expand All @@ -1468,12 +1461,12 @@ static int iscsit_handle_nop_out(
1 : 0);
conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
cmd->targ_xfer_tag = 0xFFFFFFFF;
cmd->cmd_sn = hdr->cmdsn;
cmd->exp_stat_sn = hdr->exp_statsn;
cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
cmd->data_direction = DMA_NONE;
}

if (payload_length && (hdr->ttt == 0xFFFFFFFF)) {
if (payload_length && hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
rx_size = payload_length;
ping_data = kzalloc(payload_length + 1, GFP_KERNEL);
if (!ping_data) {
Expand Down Expand Up @@ -1566,7 +1559,7 @@ static int iscsit_handle_nop_out(
list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
spin_unlock_bh(&conn->cmd_lock);

iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));

if (hdr->opcode & ISCSI_OP_IMMEDIATE) {
iscsit_add_cmd_to_response_queue(cmd, conn,
Expand All @@ -1587,11 +1580,11 @@ static int iscsit_handle_nop_out(
return 0;
}

if (hdr->ttt != 0xFFFFFFFF) {
if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) {
/*
* This was a response to a unsolicited NOPIN ping.
*/
cmd = iscsit_find_cmd_from_ttt(conn, hdr->ttt);
cmd = iscsit_find_cmd_from_ttt(conn, be32_to_cpu(hdr->ttt));
if (!cmd)
return -1;

Expand Down Expand Up @@ -1636,10 +1629,6 @@ static int iscsit_handle_task_mgt_cmd(
u8 function;

hdr = (struct iscsi_tm *) buf;
hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
hdr->refcmdsn = be32_to_cpu(hdr->refcmdsn);
hdr->exp_datasn = be32_to_cpu(hdr->exp_datasn);
hdr->flags &= ~ISCSI_FLAG_CMD_FINAL;
function = hdr->flags;

Expand All @@ -1664,8 +1653,8 @@ static int iscsit_handle_task_mgt_cmd(
buf, conn);
}
if ((function != ISCSI_TM_FUNC_ABORT_TASK) &&
(hdr->refcmdsn != ISCSI_RESERVED_TAG))
hdr->refcmdsn = ISCSI_RESERVED_TAG;
be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG)
hdr->refcmdsn = cpu_to_be32(ISCSI_RESERVED_TAG);

cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
if (!cmd)
Expand Down Expand Up @@ -1742,8 +1731,8 @@ static int iscsit_handle_task_mgt_cmd(
cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
cmd->init_task_tag = hdr->itt;
cmd->targ_xfer_tag = 0xFFFFFFFF;
cmd->cmd_sn = hdr->cmdsn;
cmd->exp_stat_sn = hdr->exp_statsn;
cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
se_tmr = cmd->se_cmd.se_tmr_req;
tmr_req = cmd->tmr_req;
/*
Expand Down Expand Up @@ -1827,7 +1816,7 @@ static int iscsit_handle_task_mgt_cmd(
ISCSI_REASON_PROTOCOL_ERROR,
1, 0, buf, cmd);
}
iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));

if (out_of_order_cmdsn || !(hdr->opcode & ISCSI_OP_IMMEDIATE))
return 0;
Expand Down Expand Up @@ -1864,9 +1853,6 @@ static int iscsit_handle_text_cmd(

hdr = (struct iscsi_text *) buf;
payload_length = ntoh24(hdr->dlength);
hdr->ttt = be32_to_cpu(hdr->ttt);
hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);

if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
pr_err("Unable to accept text parameter length: %u"
Expand Down Expand Up @@ -1983,15 +1969,15 @@ static int iscsit_handle_text_cmd(
cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
cmd->targ_xfer_tag = 0xFFFFFFFF;
cmd->cmd_sn = hdr->cmdsn;
cmd->exp_stat_sn = hdr->exp_statsn;
cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
cmd->data_direction = DMA_NONE;

spin_lock_bh(&conn->cmd_lock);
list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
spin_unlock_bh(&conn->cmd_lock);

iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));

if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
Expand Down Expand Up @@ -2125,9 +2111,6 @@ static int iscsit_handle_logout_cmd(

hdr = (struct iscsi_logout *) buf;
reason_code = (hdr->flags & 0x7f);
hdr->cid = be16_to_cpu(hdr->cid);
hdr->cmdsn = be32_to_cpu(hdr->cmdsn);
hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);

if (tiqn) {
spin_lock(&tiqn->logout_stats.lock);
Expand Down Expand Up @@ -2159,9 +2142,9 @@ static int iscsit_handle_logout_cmd(
cmd->immediate_cmd = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
cmd->targ_xfer_tag = 0xFFFFFFFF;
cmd->cmd_sn = hdr->cmdsn;
cmd->exp_stat_sn = hdr->exp_statsn;
cmd->logout_cid = hdr->cid;
cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
cmd->logout_cid = be16_to_cpu(hdr->cid);
cmd->logout_reason = reason_code;
cmd->data_direction = DMA_NONE;

Expand All @@ -2171,15 +2154,15 @@ static int iscsit_handle_logout_cmd(
*/
if ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_SESSION) ||
((reason_code == ISCSI_LOGOUT_REASON_CLOSE_CONNECTION) &&
(hdr->cid == conn->cid)))
be16_to_cpu(hdr->cid) == conn->cid))
logout_remove = 1;

spin_lock_bh(&conn->cmd_lock);
list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
spin_unlock_bh(&conn->cmd_lock);

if (reason_code != ISCSI_LOGOUT_REASON_RECOVERY)
iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));

/*
* Immediate commands are executed, well, immediately.
Expand Down Expand Up @@ -2212,10 +2195,6 @@ static int iscsit_handle_snack(

hdr = (struct iscsi_snack *) buf;
hdr->flags &= ~ISCSI_FLAG_CMD_FINAL;
hdr->ttt = be32_to_cpu(hdr->ttt);
hdr->exp_statsn = be32_to_cpu(hdr->exp_statsn);
hdr->begrun = be32_to_cpu(hdr->begrun);
hdr->runlength = be32_to_cpu(hdr->runlength);

pr_debug("Got ISCSI_INIT_SNACK, ITT: 0x%08x, ExpStatSN:"
" 0x%08x, Type: 0x%02x, BegRun: 0x%08x, RunLength: 0x%08x,"
Expand All @@ -2235,13 +2214,18 @@ static int iscsit_handle_snack(
switch (hdr->flags & ISCSI_FLAG_SNACK_TYPE_MASK) {
case 0:
return iscsit_handle_recovery_datain_or_r2t(conn, buf,
hdr->itt, hdr->ttt, hdr->begrun, hdr->runlength);
hdr->itt,
be32_to_cpu(hdr->ttt),
be32_to_cpu(hdr->begrun),
be32_to_cpu(hdr->runlength));
case ISCSI_FLAG_SNACK_TYPE_STATUS:
return iscsit_handle_status_snack(conn, hdr->itt, hdr->ttt,
hdr->begrun, hdr->runlength);
return iscsit_handle_status_snack(conn, hdr->itt,
be32_to_cpu(hdr->ttt),
be32_to_cpu(hdr->begrun), be32_to_cpu(hdr->runlength));
case ISCSI_FLAG_SNACK_TYPE_DATA_ACK:
return iscsit_handle_data_ack(conn, hdr->ttt, hdr->begrun,
hdr->runlength);
return iscsit_handle_data_ack(conn, be32_to_cpu(hdr->ttt),
be32_to_cpu(hdr->begrun),
be32_to_cpu(hdr->runlength));
case ISCSI_FLAG_SNACK_TYPE_RDATA:
/* FIXME: Support R-Data SNACK */
pr_err("R-Data SNACK Not Supported.\n");
Expand Down Expand Up @@ -2529,11 +2513,16 @@ static int iscsit_send_data_in(
put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);

hdr->itt = cmd->init_task_tag;
hdr->ttt = (hdr->flags & ISCSI_FLAG_DATA_ACK) ?
cpu_to_be32(cmd->targ_xfer_tag) :
0xFFFFFFFF;
hdr->statsn = (set_statsn) ? cpu_to_be32(cmd->stat_sn) :
0xFFFFFFFF;

if (hdr->flags & ISCSI_FLAG_DATA_ACK)
hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
else
hdr->ttt = cpu_to_be32(0xFFFFFFFF);
if (set_statsn)
hdr->statsn = cpu_to_be32(cmd->stat_sn);
else
hdr->statsn = cpu_to_be32(0xFFFFFFFF);

hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
hdr->datasn = cpu_to_be32(datain.data_sn);
Expand Down Expand Up @@ -3088,7 +3077,7 @@ static int iscsit_send_status(
cmd->se_cmd.scsi_sense_length += sizeof (__be16);

padding = -(cmd->se_cmd.scsi_sense_length) & 3;
hton24(hdr->dlength, cmd->se_cmd.scsi_sense_length);
hton24(hdr->dlength, (u32)cmd->se_cmd.scsi_sense_length);
iov[iov_count].iov_base = cmd->sense_buffer;
iov[iov_count++].iov_len =
(cmd->se_cmd.scsi_sense_length + padding);
Expand Down Expand Up @@ -3418,7 +3407,7 @@ static int iscsit_send_reject(
hdr->opcode = ISCSI_OP_REJECT;
hdr->flags |= ISCSI_FLAG_CMD_FINAL;
hton24(hdr->dlength, ISCSI_HDR_LEN);
hdr->ffffffff = 0xffffffff;
hdr->ffffffff = cpu_to_be32(0xffffffff);
cmd->stat_sn = conn->stat_sn++;
hdr->statsn = cpu_to_be32(cmd->stat_sn);
hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
Expand Down
1 change: 0 additions & 1 deletion drivers/target/iscsi/iscsi_target_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,6 @@ struct iscsi_cmd {

struct iscsi_tmr_req {
bool task_reassign:1;
u32 ref_cmd_sn;
u32 exp_data_sn;
struct iscsi_cmd *ref_cmd;
struct iscsi_conn_recovery *conn_recovery;
Expand Down
Loading

0 comments on commit 50e5c87

Please sign in to comment.