From 5228e3e672fcc6394e2144cacc49ce29fc690b18 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 2 Aug 2013 12:53:27 +0200 Subject: [PATCH] Rebase to 1.9.0 - Cherry-pick selected patches from upstream --- .gitignore | 2 +- ...est.patch => 0000-install-iscsi-test.patch | 6 +- 0001-distribute-pkgconfig-file.patch | 42 - ...nect-if-reconnect-is-already-defered.patch | 34 + ...-of-iscsi_context-in-iscsi_reconnect.patch | 29 + ...Q-codes-related-to-thin-provisioning.patch | 75 ++ 0003-fix-crash-in-iscsi-tools.patch | 53 - ...2-64-bit-accessors-for-reading-from-.patch | 385 ++++++ ...alling-functions-scsi_get-set_uint16.patch | 1034 ----------------- 0005-fix-bug-in-md5-code.patch | 25 + ....patch => 0006-use-libgcrypt-for-MD5.patch | 50 +- 0007-URL-encoded-Targetnames.patch | 228 ++++ ...function-to-read-a-byte-from-the-dat.patch | 537 +++++++++ ...evel-do-not-use-unsafe-pointer-casts.patch | 113 ++ 0010-Add-a-cast-to-ssize_t.patch | 25 + 0011-Use-PRIu64-for-format-string.patch | 26 + 0012-bump-soname.patch | 15 + 0013-disable-ld_iscsi.patch | 13 + 0014-fix-another-aliasing-problem.patch | 18 + 0015-fix-arm-aliasing-problem.patch | 212 ++++ 0016-avoid-casting-struct-sockaddr.patch | 76 ++ ...e-scsi_get-set_uint16-32-64-in-tests.patch | 209 ++++ libiscsi.spec | 49 +- sources | 2 +- 24 files changed, 2089 insertions(+), 1169 deletions(-) rename 0004-install-iscsi-test.patch => 0000-install-iscsi-test.patch (64%) delete mode 100644 0001-distribute-pkgconfig-file.patch create mode 100644 0001-do-not-reconnect-if-reconnect-is-already-defered.patch create mode 100644 0002-fix-leak-of-iscsi_context-in-iscsi_reconnect.patch create mode 100644 0003-Add-ASCQ-codes-related-to-thin-provisioning.patch delete mode 100644 0003-fix-crash-in-iscsi-tools.patch create mode 100644 0004-Create-safe-16-32-64-bit-accessors-for-reading-from-.patch delete mode 100644 0005-Use-the-un-marshalling-functions-scsi_get-set_uint16.patch create mode 100644 0005-fix-bug-in-md5-code.patch rename 0002-use-libgcrypt-for-MD5.patch => 0006-use-libgcrypt-for-MD5.patch (78%) create mode 100644 0007-URL-encoded-Targetnames.patch create mode 100644 0008-SCSI-add-a-safe-function-to-read-a-byte-from-the-dat.patch create mode 100644 0009-scsi-lowlevel-do-not-use-unsafe-pointer-casts.patch create mode 100644 0010-Add-a-cast-to-ssize_t.patch create mode 100644 0011-Use-PRIu64-for-format-string.patch create mode 100644 0012-bump-soname.patch create mode 100644 0013-disable-ld_iscsi.patch create mode 100644 0014-fix-another-aliasing-problem.patch create mode 100644 0015-fix-arm-aliasing-problem.patch create mode 100644 0016-avoid-casting-struct-sockaddr.patch create mode 100644 0017-use-scsi_get-set_uint16-32-64-in-tests.patch diff --git a/.gitignore b/.gitignore index d442d8f..4e7fe70 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -/libiscsi-1.7.0.tar.gz +/libiscsi-1.9.0.tar.gz diff --git a/0004-install-iscsi-test.patch b/0000-install-iscsi-test.patch similarity index 64% rename from 0004-install-iscsi-test.patch rename to 0000-install-iscsi-test.patch index e74dd3b..a2c3e4a 100644 --- a/0004-install-iscsi-test.patch +++ b/0000-install-iscsi-test.patch @@ -8,6 +8,6 @@ index b750cdb..8bde4ac 100644 -noinst_PROGRAMS += bin/iscsi-test +bin_PROGRAMS += bin/iscsi-test - dist_noinst_HEADERS += test-tool/iscsi-test.h - bin_iscsi_test_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/test-tool - bin_iscsi_test_LDFLAGS = -ldl + dist_noinst_HEADERS += test-tool/iscsi-support.h \ + test-tool/iscsi-test.h \ + test-tool/iscsi-test-cu.h diff --git a/0001-distribute-pkgconfig-file.patch b/0001-distribute-pkgconfig-file.patch deleted file mode 100644 index b30f6ef..0000000 --- a/0001-distribute-pkgconfig-file.patch +++ /dev/null @@ -1,42 +0,0 @@ -diff --git a/Makefile.am b/Makefile.am -index b750cdb..869b4d0 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -11,6 +11,9 @@ EXTRA_DIST = autogen.sh COPYING LICENCE-GPL-2.txt LICENCE-LGPL-2.1.txt \ - - # Simplify conditions below by declaring variables as empty - -+pkgconfigdir = $(libdir)/pkgconfig -+pkgconfig_DATA = libiscsi.pc -+ - bin_PROGRAMS = - noinst_PROGRAMS = - EXTRA_PROGRAMS = -diff --git a/configure.ac b/configure.ac -index bb95018..d3e393d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -81,5 +81,5 @@ else - fi - AM_CONDITIONAL(PROGRAMS, [test "$ac_cv_have_popt" = yes]) - --AC_CONFIG_FILES(Makefile) -+AC_CONFIG_FILES(Makefile libiscsi.pc) - AC_OUTPUT -diff --git a/libiscsi.pc.in b/libiscsi.pc.in -index e69de29..730a258 100644 ---- a/libiscsi.pc.in -+++ b/libiscsi.pc.in -@@ -0,0 +1,12 @@ -+prefix=@prefix@ -+exec_prefix=${prefix} -+libdir=@libdir@ -+includedir=@includedir@ -+ -+Name: libiscsi -+Description: iSCSI initiator library -+Version: @VERSION@ -+ -+Libs: -L${libdir} -liscsi -+Libs.private: -+Cflags: -I${includedir} diff --git a/0001-do-not-reconnect-if-reconnect-is-already-defered.patch b/0001-do-not-reconnect-if-reconnect-is-already-defered.patch new file mode 100644 index 0000000..66832a8 --- /dev/null +++ b/0001-do-not-reconnect-if-reconnect-is-already-defered.patch @@ -0,0 +1,34 @@ +From 327b51ed5b2bdf0a4fc0b50a9cdd8c1f4993e49a Mon Sep 17 00:00:00 2001 +From: Peter Lieven +Date: Mon, 11 Mar 2013 08:44:11 +0100 +Subject: [PATCH] do not reconnect if reconnect is already defered + +If the amount of reconnects is limited with iscsi_set_reconnect_max_retries() +it might happen that iscsi_reconnect is called while there is already a deferred +reconnect. + +Signed-off-by: Peter Lieven +--- + lib/connect.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/lib/connect.c b/lib/connect.c +index 86a60f8..d3fa9d1 100644 +--- a/lib/connect.c ++++ b/lib/connect.c +@@ -219,6 +219,12 @@ int iscsi_reconnect(struct iscsi_context *old_iscsi) + { + struct iscsi_context *iscsi = old_iscsi; + ++ /* if there is already a deferred reconnect do not try again */ ++ if (iscsi->reconnect_deferred) { ++ ISCSI_LOG(iscsi, 2, "reconnect initiated, but reconnect is already deferred"); ++ return -1; ++ } ++ + ISCSI_LOG(iscsi, 2, "reconnect initiated"); + + /* This is mainly for tests, where we do not want to automatically +-- +1.8.1.4 + diff --git a/0002-fix-leak-of-iscsi_context-in-iscsi_reconnect.patch b/0002-fix-leak-of-iscsi_context-in-iscsi_reconnect.patch new file mode 100644 index 0000000..973af48 --- /dev/null +++ b/0002-fix-leak-of-iscsi_context-in-iscsi_reconnect.patch @@ -0,0 +1,29 @@ +From 5a94d5d73a18369e6f7b7c54674dc20b9c7d0a8e Mon Sep 17 00:00:00 2001 +From: Peter Lieven +Date: Mon, 11 Mar 2013 08:51:18 +0100 +Subject: [PATCH] fix leak of iscsi_context in iscsi_reconnect + +in case the maximum number of reconnects is limited with +iscsi_set_reconnect_max_retries() the an iscsi_context +is leaked if the limit is exhausted. + +Signed-off-by: Peter Lieven +--- + lib/connect.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lib/connect.c b/lib/connect.c +index d3fa9d1..7429496 100644 +--- a/lib/connect.c ++++ b/lib/connect.c +@@ -277,6 +277,7 @@ try_again: + if (iscsi_full_connect_sync(iscsi, iscsi->portal, iscsi->lun) != 0) { + if (iscsi->reconnect_max_retries != -1 && retry >= iscsi->reconnect_max_retries) { + iscsi_defer_reconnect(old_iscsi); ++ iscsi_destroy_context(iscsi); + return -1; + } + int backoff=retry; +-- +1.8.1.4 + diff --git a/0003-Add-ASCQ-codes-related-to-thin-provisioning.patch b/0003-Add-ASCQ-codes-related-to-thin-provisioning.patch new file mode 100644 index 0000000..55415ac --- /dev/null +++ b/0003-Add-ASCQ-codes-related-to-thin-provisioning.patch @@ -0,0 +1,75 @@ +From 80ef1807ef0c11ec5940d5763b12f3c0d4b6d32e Mon Sep 17 00:00:00 2001 +From: Peter Lieven +Date: Mon, 11 Mar 2013 12:13:42 +0100 +Subject: [PATCH] Add ASCQ codes related to thin-provisioning + +Signed-off-by: Peter Lieven +--- + include/scsi-lowlevel.h | 31 +++++++++++++++++-------------- + lib/scsi-lowlevel.c | 6 ++++++ + 2 files changed, 23 insertions(+), 14 deletions(-) + +diff --git a/include/scsi-lowlevel.h b/include/scsi-lowlevel.h +index cd1abd4..07d39be 100644 +--- a/include/scsi-lowlevel.h ++++ b/include/scsi-lowlevel.h +@@ -144,20 +144,23 @@ enum scsi_sense_key { + EXTERN const char *scsi_sense_key_str(int key); + + /* ascq */ +-#define SCSI_SENSE_ASCQ_MISCOMPARE_DURING_VERIFY 0x1d00 +-#define SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE 0x2000 +-#define SCSI_SENSE_ASCQ_LBA_OUT_OF_RANGE 0x2100 +-#define SCSI_SENSE_ASCQ_INVALID_FIELD_IN_CDB 0x2400 +-#define SCSI_SENSE_ASCQ_LOGICAL_UNIT_NOT_SUPPORTED 0x2500 +-#define SCSI_SENSE_ASCQ_WRITE_PROTECTED 0x2700 +-#define SCSI_SENSE_ASCQ_BUS_RESET 0x2900 +-#define SCSI_SENSE_ASCQ_CAPACITY_DATA_HAS_CHANGED 0x2a09 +-#define SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT 0x3a00 +-#define SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED 0x3a01 +-#define SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN 0x3a02 +-#define SCSI_SENSE_ASCQ_INTERNAL_TARGET_FAILURE 0x4400 +-#define SCSI_SENSE_ASCQ_MEDIUM_LOAD_OR_EJECT_FAILED 0x5300 +-#define SCSI_SENSE_ASCQ_MEDIUM_REMOVAL_PREVENTED 0x5302 ++#define SCSI_SENSE_ASCQ_MISCOMPARE_DURING_VERIFY 0x1d00 ++#define SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE 0x2000 ++#define SCSI_SENSE_ASCQ_LBA_OUT_OF_RANGE 0x2100 ++#define SCSI_SENSE_ASCQ_INVALID_FIELD_IN_CDB 0x2400 ++#define SCSI_SENSE_ASCQ_LOGICAL_UNIT_NOT_SUPPORTED 0x2500 ++#define SCSI_SENSE_ASCQ_WRITE_PROTECTED 0x2700 ++#define SCSI_SENSE_ASCQ_BUS_RESET 0x2900 ++#define SCSI_SENSE_ASCQ_MODE_PARAMETERS_CHANGED 0x2a01 ++#define SCSI_SENSE_ASCQ_CAPACITY_DATA_HAS_CHANGED 0x2a09 ++#define SCSI_SENSE_ASCQ_THIN_PROVISION_SOFT_THRES_REACHED 0x3807 ++#define SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT 0x3a00 ++#define SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED 0x3a01 ++#define SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN 0x3a02 ++#define SCSI_SENSE_ASCQ_INQUIRY_DATA_HAS_CHANGED 0x3f03 ++#define SCSI_SENSE_ASCQ_INTERNAL_TARGET_FAILURE 0x4400 ++#define SCSI_SENSE_ASCQ_MEDIUM_LOAD_OR_EJECT_FAILED 0x5300 ++#define SCSI_SENSE_ASCQ_MEDIUM_REMOVAL_PREVENTED 0x5302 + + EXTERN const char *scsi_sense_ascq_str(int ascq); + +diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c +index b6af650..b49e873 100644 +--- a/lib/scsi-lowlevel.c ++++ b/lib/scsi-lowlevel.c +@@ -149,8 +149,14 @@ scsi_sense_ascq_str(int ascq) + "MEDIUM_NOT_PRESENT-TRAY_OPEN"}, + {SCSI_SENSE_ASCQ_BUS_RESET, + "BUS_RESET"}, ++ {SCSI_SENSE_ASCQ_MODE_PARAMETERS_CHANGED, ++ "MODE PARAMETERS CHANGED"}, + {SCSI_SENSE_ASCQ_CAPACITY_DATA_HAS_CHANGED, + "CAPACITY_DATA_HAS_CHANGED"}, ++ {SCSI_SENSE_ASCQ_THIN_PROVISION_SOFT_THRES_REACHED, ++ "THIN PROVISIONING SOFT THRESHOLD REACHED"}, ++ {SCSI_SENSE_ASCQ_INQUIRY_DATA_HAS_CHANGED, ++ "INQUIRY DATA HAS CHANGED"}, + {SCSI_SENSE_ASCQ_INTERNAL_TARGET_FAILURE, + "INTERNAL_TARGET_FAILURE"}, + {SCSI_SENSE_ASCQ_MISCOMPARE_DURING_VERIFY, +-- +1.8.1.4 + diff --git a/0003-fix-crash-in-iscsi-tools.patch b/0003-fix-crash-in-iscsi-tools.patch deleted file mode 100644 index 37ae089..0000000 --- a/0003-fix-crash-in-iscsi-tools.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 38ef7b1e200f8f6315335c5b6aba3405bf9ee404 Mon Sep 17 00:00:00 2001 -From: Paolo Bonzini -Date: Fri, 3 May 2013 13:26:37 +0200 -Subject: [PATCH] fix crash in iscsi-tools - ---- - src/iscsi-inq.c | 2 -- - src/iscsi-ls.c | 2 -- - src/iscsi-readcapacity16.c | 2 -- - 3 files changed, 6 deletions(-) - -diff --git a/src/iscsi-inq.c b/src/iscsi-inq.c -index 031e4e3..fa15a53 100644 ---- a/src/iscsi-inq.c -+++ b/src/iscsi-inq.c -@@ -276,8 +276,6 @@ int main(int argc, const char *argv[]) - } - iscsi_url = iscsi_parse_full_url(iscsi, url); - -- if (url) free(url); -- - if (iscsi_url == NULL) { - fprintf(stderr, "Failed to parse URL: %s\n", - iscsi_get_error(iscsi)); -diff --git a/src/iscsi-ls.c b/src/iscsi-ls.c -index b8c4b7c..6feec11 100644 ---- a/src/iscsi-ls.c -+++ b/src/iscsi-ls.c -@@ -373,8 +373,6 @@ int main(int argc, const char *argv[]) - - iscsi_url = iscsi_parse_portal_url(iscsi, url); - -- if (url) free(url); -- - if (iscsi_url == NULL) { - fprintf(stderr, "Failed to parse URL: %s\n", - iscsi_get_error(iscsi)); -diff --git a/src/iscsi-readcapacity16.c b/src/iscsi-readcapacity16.c -index bbbc38f..39a70b9 100644 ---- a/src/iscsi-readcapacity16.c -+++ b/src/iscsi-readcapacity16.c -@@ -118,8 +118,6 @@ int main(int argc, const char *argv[]) - } - iscsi_url = iscsi_parse_full_url(iscsi, url); - -- if (url) free(url); -- - if (iscsi_url == NULL) { - fprintf(stderr, "Failed to parse URL: %s\n", - iscsi_get_error(iscsi)); --- -1.8.2 - diff --git a/0004-Create-safe-16-32-64-bit-accessors-for-reading-from-.patch b/0004-Create-safe-16-32-64-bit-accessors-for-reading-from-.patch new file mode 100644 index 0000000..4b563d1 --- /dev/null +++ b/0004-Create-safe-16-32-64-bit-accessors-for-reading-from-.patch @@ -0,0 +1,385 @@ +From d280ce8ad742426bebe610ebfd8559b46876f4ee Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Mon, 22 Apr 2013 22:11:53 -0700 +Subject: [PATCH] Create safe 16/32/64 bit accessors for reading from the + datain buffer and use it throughout the scsi lowlevel file. + +We probably want a safe accessor for byte access to at some stage. +--- + lib/scsi-lowlevel.c | 154 +++++++++++++++++++++++++++++++++------------------- + 1 file changed, 98 insertions(+), 56 deletions(-) + +diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c +index c517d57..77c0bb6 100644 +--- a/lib/scsi-lowlevel.c ++++ b/lib/scsi-lowlevel.c +@@ -232,6 +232,48 @@ scsi_get_uint16(const unsigned char *c) + return ntohs(*(uint16_t *)c); + } + ++static inline uint64_t ++task_get_uint64(struct scsi_task *task, int offset) ++{ ++ if (offset <= task->datain.size - 8) { ++ const unsigned char *c = &task->datain.data[offset]; ++ uint64_t val; ++ ++ val = ntohl(*(uint32_t *)c); ++ val <<= 32; ++ c += 4; ++ val |= ntohl(*(uint32_t *)c); ++ ++ return val; ++ } else { ++ return 0; ++ } ++} ++ ++static inline uint32_t ++task_get_uint32(struct scsi_task *task, int offset) ++{ ++ if (offset <= task->datain.size - 4) { ++ const unsigned char *c = &task->datain.data[offset]; ++ ++ return ntohl(*(uint32_t *)c); ++ } else { ++ return 0; ++ } ++} ++ ++static inline uint16_t ++task_get_uint16(struct scsi_task *task, int offset) ++{ ++ if (offset <= task->datain.size - 2) { ++ const unsigned char *c = &task->datain.data[offset]; ++ ++ return ntohs(*(uint16_t *)c); ++ } else { ++ return 0; ++ } ++} ++ + inline void + scsi_set_uint64(unsigned char *c, uint64_t v) + { +@@ -319,7 +361,7 @@ scsi_reportluns_datain_getfullsize(struct scsi_task *task) + { + uint32_t list_size; + +- list_size = scsi_get_uint32(&task->datain.data[0]) + 8; ++ list_size = task_get_uint32(task, 0) + 8; + + return list_size; + } +@@ -338,7 +380,7 @@ scsi_reportluns_datain_unmarshall(struct scsi_task *task) + return NULL; + } + +- list_size = scsi_get_uint32(&task->datain.data[0]) + 8; ++ list_size = task_get_uint32(task, 0) + 8; + if (list_size < task->datain.size) { + return NULL; + } +@@ -352,7 +394,7 @@ scsi_reportluns_datain_unmarshall(struct scsi_task *task) + + list->num = num_luns; + for (i = 0; i < num_luns; i++) { +- list->luns[i] = scsi_get_uint16(&task->datain.data[i*8+8]); ++ list->luns[i] = task_get_uint16(task, i * 8 + 8); + } + + return list; +@@ -442,7 +484,7 @@ scsi_readtoc_datain_getfullsize(struct scsi_task *task) + { + uint16_t toc_data_len; + +- toc_data_len = scsi_get_uint16(&task->datain.data[0]) + 2; ++ toc_data_len = task_get_uint16(task, 0) + 2; + + return toc_data_len; + } +@@ -465,7 +507,7 @@ scsi_readtoc_desc_unmarshall(struct scsi_task *task, struct scsi_readtoc_list *l + list->desc[i].desc.toc.track + = task->datain.data[4+8*i+2]; + list->desc[i].desc.toc.lba +- = scsi_get_uint32(&task->datain.data[4+8*i+4]); ++ = task_get_uint32(task, 4 + 8 * i + 4); + break; + case SCSI_READ_SESSION_INFO: + list->desc[i].desc.ses.adr +@@ -475,7 +517,7 @@ scsi_readtoc_desc_unmarshall(struct scsi_task *task, struct scsi_readtoc_list *l + list->desc[i].desc.ses.first_in_last + = task->datain.data[4+8*i+2]; + list->desc[i].desc.ses.lba +- = scsi_get_uint32(&task->datain.data[4+8*i+4]); ++ = task_get_uint32(task, 4 + 8 * i + 4); + break; + case SCSI_READ_FULL_TOC: + list->desc[i].desc.full.session +@@ -610,22 +652,22 @@ scsi_serviceactionin_datain_unmarshall(struct scsi_task *task) + if (rc16 == NULL) { + return NULL; + } +- rc16->returned_lba = scsi_get_uint32(&task->datain.data[0]); +- rc16->returned_lba = (rc16->returned_lba << 32) | scsi_get_uint32(&task->datain.data[4]); +- rc16->block_length = scsi_get_uint32(&task->datain.data[8]); ++ rc16->returned_lba = task_get_uint32(task, 0); ++ rc16->returned_lba = (rc16->returned_lba << 32) | task_get_uint32(task, 4); ++ rc16->block_length = task_get_uint32(task, 8); + rc16->p_type = (task->datain.data[12] >> 1) & 0x07; + rc16->prot_en = task->datain.data[12] & 0x01; + rc16->p_i_exp = (task->datain.data[13] >> 4) & 0x0f; + rc16->lbppbe = task->datain.data[13] & 0x0f; + rc16->lbpme = !!(task->datain.data[14] & 0x80); + rc16->lbprz = !!(task->datain.data[14] & 0x40); +- rc16->lalba = scsi_get_uint16(&task->datain.data[14]) & 0x3fff; ++ rc16->lalba = task_get_uint16(task, 14) & 0x3fff; + return rc16; + } + case SCSI_GET_LBA_STATUS: { + struct scsi_get_lba_status *gls = scsi_malloc(task, + sizeof(*gls)); +- int32_t len = scsi_get_uint32(&task->datain.data[0]); ++ int32_t len = task_get_uint32(task, 0); + int i; + + if (gls == NULL) { +@@ -646,11 +688,11 @@ scsi_serviceactionin_datain_unmarshall(struct scsi_task *task) + } + + for (i = 0; i < (int)gls->num_descriptors; i++) { +- gls->descriptors[i].lba = scsi_get_uint32(&task->datain.data[8 + i * sizeof(struct scsi_lba_status_descriptor) + 0]); ++ gls->descriptors[i].lba = task_get_uint32(task, 8 + i * sizeof(struct scsi_lba_status_descriptor) + 0); + gls->descriptors[i].lba <<= 32; +- gls->descriptors[i].lba |= scsi_get_uint32(&task->datain.data[8 + i * sizeof(struct scsi_lba_status_descriptor) + 4]); ++ gls->descriptors[i].lba |= task_get_uint32(task, 8 + i * sizeof(struct scsi_lba_status_descriptor) + 4); + +- gls->descriptors[i].num_blocks = scsi_get_uint32(&task->datain.data[8 + i * sizeof(struct scsi_lba_status_descriptor) + 8]); ++ gls->descriptors[i].num_blocks = task_get_uint32(task, 8 + i * sizeof(struct scsi_lba_status_descriptor) + 8); + + gls->descriptors[i].provisioning = task->datain.data[8 + i * sizeof(struct scsi_lba_status_descriptor) + 12] & 0x0f; + } +@@ -676,7 +718,7 @@ scsi_persistentreservein_datain_getfullsize(struct scsi_task *task) + { + switch (scsi_persistentreservein_sa(task)) { + case SCSI_PERSISTENT_RESERVE_READ_KEYS: +- return scsi_get_uint32(&task->datain.data[4]) + 8; ++ return task_get_uint32(task, 4) + 8; + case SCSI_PERSISTENT_RESERVE_READ_RESERVATION: + return 8; + case SCSI_PERSISTENT_RESERVE_REPORT_CAPABILITIES: +@@ -696,24 +738,24 @@ scsi_persistentreservein_datain_unmarshall(struct scsi_task *task) + + switch (scsi_persistentreservein_sa(task)) { + case SCSI_PERSISTENT_RESERVE_READ_KEYS: +- i = scsi_get_uint32(&task->datain.data[4]); ++ i = task_get_uint32(task, 4); + + rk = scsi_malloc(task, offsetof(struct scsi_persistent_reserve_in_read_keys, keys) + i); + if (rk == NULL) { + return NULL; + } +- rk->prgeneration = scsi_get_uint32(&task->datain.data[0]); +- rk->additional_length = scsi_get_uint32(&task->datain.data[4]); ++ rk->prgeneration = task_get_uint32(task, 0); ++ rk->additional_length = task_get_uint32(task, 4); + + rk->num_keys = rk->additional_length / 8; + for (i = 0; i < (int)rk->num_keys; i++) { +- rk->keys[i] = scsi_get_uint64(&task->datain.data[8 + i * 8]); ++ rk->keys[i] = task_get_uint64(task, 8 + i * 8); + } + return rk; + case SCSI_PERSISTENT_RESERVE_READ_RESERVATION: { + size_t alloc_sz; + +- i = scsi_get_uint32(&task->datain.data[4]); ++ i = task_get_uint32(task, 4); + alloc_sz = offsetof( + struct scsi_persistent_reserve_in_read_reservation, + reserved) + i; +@@ -723,12 +765,12 @@ scsi_persistentreservein_datain_unmarshall(struct scsi_task *task) + return NULL; + } + memset(rr, 0, alloc_sz); +- rr->prgeneration = scsi_get_uint32(&task->datain.data[0]); ++ rr->prgeneration = task_get_uint32(task, 0); + + if (i > 0) { + rr->reserved = 1; + rr->reservation_key = +- scsi_get_uint64(&task->datain.data[8]); ++ task_get_uint64(task, 8); + rr->pr_type = task->datain.data[21] & 0xff; + } + +@@ -739,14 +781,14 @@ scsi_persistentreservein_datain_unmarshall(struct scsi_task *task) + if (rc == NULL) { + return NULL; + } +- rc->length = scsi_get_uint16(&task->datain.data[0]); ++ rc->length = task_get_uint16(task, 0); + rc->crh = !!(task->datain.data[2] & 0x10); + rc->sip_c = !!(task->datain.data[2] & 0x08); + rc->atp_c = !!(task->datain.data[2] & 0x04); + rc->ptpl_c = !!(task->datain.data[2] & 0x01); + rc->tmv = !!(task->datain.data[3] & 0x80); + rc->allow_commands = task->datain.data[3] >> 4; +- rc->persistent_reservation_type_mask = scsi_get_uint16(&task->datain.data[4]); ++ rc->persistent_reservation_type_mask = task_get_uint16(task, 4); + + return rc; + default: +@@ -776,7 +818,7 @@ scsi_maintenancein_datain_getfullsize(struct scsi_task *task) + + switch (scsi_maintenancein_sa(task)) { + case SCSI_REPORT_SUPPORTED_OP_CODES: +- return scsi_get_uint32(&task->datain.data[0]) + 4; ++ return task_get_uint32(task, 0) + 4; + default: + return -1; + } +@@ -799,7 +841,7 @@ scsi_maintenancein_datain_unmarshall(struct scsi_task *task) + return NULL; + } + +- len = scsi_get_uint32(&task->datain.data[0]); ++ len = task_get_uint32(task, 0); + rsoc = scsi_malloc(task, sizeof(struct scsi_report_supported_op_codes) + len); + if (rsoc == NULL) { + return NULL; +@@ -900,8 +942,8 @@ scsi_readcapacity10_datain_unmarshall(struct scsi_task *task) + return NULL; + } + +- rc10->lba = scsi_get_uint32(&task->datain.data[0]); +- rc10->block_size = scsi_get_uint32(&task->datain.data[4]); ++ rc10->lba = task_get_uint32(task, 0); ++ rc10->block_size = task_get_uint32(task, 4); + + return rc10; + } +@@ -972,7 +1014,7 @@ scsi_inquiry_datain_getfullsize(struct scsi_task *task) + case SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION: + case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS: + case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING: +- return scsi_get_uint16(&task->datain.data[2]) + 4; ++ return task_get_uint16(task, 2) + 4; + default: + return -1; + } +@@ -1079,7 +1120,7 @@ scsi_inquiry_unmarshall_device_identification(struct scsi_task *task) + { + struct scsi_inquiry_device_identification *inq = scsi_malloc(task, + sizeof(*inq)); +- int remaining = scsi_get_uint16(&task->datain.data[2]); ++ int remaining = task_get_uint16(task, 2); + unsigned char *dptr; + + if (inq == NULL) { +@@ -1148,17 +1189,18 @@ scsi_inquiry_unmarshall_block_limits(struct scsi_task *task) + + inq->wsnz = task->datain.data[4] & 0x01; + inq->max_cmp = task->datain.data[5]; +- inq->opt_gran = scsi_get_uint16(&task->datain.data[6]); +- inq->max_xfer_len = scsi_get_uint32(&task->datain.data[8]); +- inq->opt_xfer_len = scsi_get_uint32(&task->datain.data[12]); +- inq->max_prefetch = scsi_get_uint32(&task->datain.data[16]); +- inq->max_unmap = scsi_get_uint32(&task->datain.data[20]); +- inq->max_unmap_bdc = scsi_get_uint32(&task->datain.data[24]); +- inq->opt_unmap_gran = scsi_get_uint32(&task->datain.data[28]); ++ inq->opt_gran = task_get_uint16(task, 6); ++ inq->max_xfer_len = task_get_uint32(task, 8); ++ inq->opt_xfer_len = task_get_uint32(task, 12); ++ inq->max_prefetch = task_get_uint32(task, 16); ++ inq->max_unmap = task_get_uint32(task, 20); ++ inq->max_unmap_bdc = task_get_uint32(task, 24); ++ inq->opt_unmap_gran = task_get_uint32(task, 28); + inq->ugavalid = !!(task->datain.data[32]&0x80); +- inq->unmap_gran_align = scsi_get_uint32(&task->datain.data[32]) & 0x7fffffff; +- inq->max_ws_len = scsi_get_uint32(&task->datain.data[36]); +- inq->max_ws_len = (inq->max_ws_len << 32) | scsi_get_uint32(&task->datain.data[40]); ++ inq->unmap_gran_align = task_get_uint32(task, 32) & 0x7fffffff; ++ inq->max_ws_len = task_get_uint32(task, 36); ++ inq->max_ws_len = (inq->max_ws_len << 32) ++ | task_get_uint32(task, 40); + + return inq; + } +@@ -1175,7 +1217,7 @@ scsi_inquiry_unmarshall_block_device_characteristics(struct scsi_task *task) + inq->device_type = task->datain.data[0]&0x1f; + inq->pagecode = task->datain.data[1]; + +- inq->medium_rotation_rate = scsi_get_uint16(&task->datain.data[4]); ++ inq->medium_rotation_rate = task_get_uint16(task, 4); + return inq; + } + +@@ -2040,10 +2082,10 @@ scsi_parse_mode_caching(struct scsi_task *task, int pos, struct scsi_mode_page * + mp->caching.demand_read_retention_priority = (task->datain.data[pos+1] >> 4) & 0x0f; + mp->caching.write_retention_priority = task->datain.data[pos+1] & 0x0f; + +- mp->caching.disable_prefetch_transfer_length = scsi_get_uint16(&task->datain.data[pos+2]); +- mp->caching.minimum_prefetch = scsi_get_uint16(&task->datain.data[pos+4]); +- mp->caching.maximum_prefetch = scsi_get_uint16(&task->datain.data[pos+6]); +- mp->caching.maximum_prefetch_ceiling = scsi_get_uint16(&task->datain.data[pos+8]); ++ mp->caching.disable_prefetch_transfer_length = task_get_uint16(task, pos + 2); ++ mp->caching.minimum_prefetch = task_get_uint16(task, pos + 4); ++ mp->caching.maximum_prefetch = task_get_uint16(task, pos + 6); ++ mp->caching.maximum_prefetch_ceiling = task_get_uint16(task, pos + 8); + + mp->caching.fsw = task->datain.data[pos+10] & 0x80; + mp->caching.lbcss = task->datain.data[pos+10] & 0x40; +@@ -2051,7 +2093,7 @@ scsi_parse_mode_caching(struct scsi_task *task, int pos, struct scsi_mode_page * + mp->caching.nv_dis = task->datain.data[pos+10] & 0x01; + + mp->caching.number_of_cache_segments = task->datain.data[pos+11]; +- mp->caching.cache_segment_size = scsi_get_uint16(&task->datain.data[pos+12]); ++ mp->caching.cache_segment_size = task_get_uint16(task, pos + 12); + } + + static void +@@ -2059,15 +2101,15 @@ scsi_parse_mode_disconnect_reconnect(struct scsi_task *task, int pos, struct scs + { + mp->disconnect_reconnect.buffer_full_ratio = task->datain.data[pos]; + mp->disconnect_reconnect.buffer_empty_ratio = task->datain.data[pos+1]; +- mp->disconnect_reconnect.bus_inactivity_limit = scsi_get_uint16(&task->datain.data[pos+2]); +- mp->disconnect_reconnect.disconnect_time_limit = scsi_get_uint16(&task->datain.data[pos+4]); +- mp->disconnect_reconnect.connect_time_limit = scsi_get_uint16(&task->datain.data[pos+6]); +- mp->disconnect_reconnect.maximum_burst_size = scsi_get_uint16(&task->datain.data[pos+8]); ++ mp->disconnect_reconnect.bus_inactivity_limit = task_get_uint16(task, pos + 2); ++ mp->disconnect_reconnect.disconnect_time_limit = task_get_uint16(task, pos + 4); ++ mp->disconnect_reconnect.connect_time_limit = task_get_uint16(task, pos + 6); ++ mp->disconnect_reconnect.maximum_burst_size = task_get_uint16(task, pos + 8); + mp->disconnect_reconnect.emdp = task->datain.data[pos+10] & 0x80; + mp->disconnect_reconnect.fair_arbitration = (task->datain.data[pos+10]>>4) & 0x0f; + mp->disconnect_reconnect.dimm = task->datain.data[pos+10] & 0x08; + mp->disconnect_reconnect.dtdc = task->datain.data[pos+10] & 0x07; +- mp->disconnect_reconnect.first_burst_size = scsi_get_uint16(&task->datain.data[pos+12]); ++ mp->disconnect_reconnect.first_burst_size = task_get_uint16(task, pos + 12); + } + + static void +@@ -2081,8 +2123,8 @@ scsi_parse_mode_informational_exceptions_control(struct scsi_task *task, int pos + mp->iec.ebackerr = task->datain.data[pos] & 0x02; + mp->iec.logerr = task->datain.data[pos] & 0x01; + mp->iec.mrie = task->datain.data[pos+1] & 0x0f; +- mp->iec.interval_timer = scsi_get_uint32(&task->datain.data[pos+2]); +- mp->iec.report_count = scsi_get_uint32(&task->datain.data[pos+6]); ++ mp->iec.interval_timer = task_get_uint32(task, pos + 2); ++ mp->iec.report_count = task_get_uint32(task, pos + 6); + } + + +@@ -2129,7 +2171,7 @@ scsi_modesense_datain_unmarshall(struct scsi_task *task) + + if (mp->spf) { + mp->subpage_code = task->datain.data[pos++]; +- mp->len = scsi_get_uint16(&task->datain.data[pos]); ++ mp->len = task_get_uint16(task, pos); + pos += 2; + } else { + mp->subpage_code = 0; +-- +1.8.1.4 + diff --git a/0005-Use-the-un-marshalling-functions-scsi_get-set_uint16.patch b/0005-Use-the-un-marshalling-functions-scsi_get-set_uint16.patch deleted file mode 100644 index 274e159..0000000 --- a/0005-Use-the-un-marshalling-functions-scsi_get-set_uint16.patch +++ /dev/null @@ -1,1034 +0,0 @@ -diff --git a/include/scsi-lowlevel.h b/include/scsi-lowlevel.h -index 9d25b47..cfb1b03 100644 ---- a/include/scsi-lowlevel.h -+++ b/include/scsi-lowlevel.h -@@ -833,6 +846,11 @@ EXTERN struct scsi_task *scsi_cdb_report_supported_opcodes(int report_timeouts, - - void *scsi_malloc(struct scsi_task *task, size_t size); - -+inline uint32_t scsi_get_uint32(const unsigned char *c); -+inline uint16_t scsi_get_uint16(const unsigned char *c); -+inline void scsi_set_uint32(unsigned char *c, uint32_t val); -+inline void scsi_set_uint16(unsigned char *c, uint16_t val); -+ - #ifdef __cplusplus - } - #endif -diff --git a/lib/login.c b/lib/login.c -index 5da4d21..8d0c86e 100644 ---- a/lib/login.c -+++ b/lib/login.c -@@ -30,6 +30,7 @@ - #include - #include "iscsi.h" - #include "iscsi-private.h" -+#include "scsi-lowlevel.h" - #include "md5.h" - #ifdef HAVE_LIBGCRYPT - #include -@@ -974,11 +975,11 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, - char *ptr = (char *)in->data; - int size = in->data_pos; - -- status = ntohs(*(uint16_t *)&in->hdr[36]); -+ status = scsi_get_uint16(&in->hdr[36]); - -- iscsi->statsn = ntohs(*(uint16_t *)&in->hdr[24]); -+ iscsi->statsn = scsi_get_uint16(&in->hdr[24]); - -- maxcmdsn = ntohl(*(uint32_t *)&in->hdr[32]); -+ maxcmdsn = scsi_get_uint32(&in->hdr[32]); - if (maxcmdsn > iscsi->maxcmdsn) { - iscsi->maxcmdsn = maxcmdsn; - } -@@ -1163,7 +1164,7 @@ struct iscsi_in_pdu *in) - { - uint32_t maxcmdsn; - -- maxcmdsn = ntohl(*(uint32_t *)&in->hdr[32]); -+ maxcmdsn = scsi_get_uint32(&in->hdr[32]); - if (maxcmdsn > iscsi->maxcmdsn) { - iscsi->maxcmdsn = maxcmdsn; - } -diff --git a/lib/pdu.c b/lib/pdu.c -index f9cbf80..454d780 100644 ---- a/lib/pdu.c -+++ b/lib/pdu.c -@@ -166,8 +166,8 @@ iscsi_pdu_add_data(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, - } - - /* update data segment length */ -- *(uint32_t *)&pdu->outdata.data[4] = htonl(pdu->outdata.size -- - ISCSI_HEADER_SIZE); -+ scsi_set_uint32(&pdu->outdata.data[4], pdu->outdata.size -+ - ISCSI_HEADER_SIZE); - - return 0; - } -@@ -177,8 +177,8 @@ iscsi_get_pdu_data_size(const unsigned char *hdr) - { - int size; - -- size = (ntohl(*(uint32_t *)&hdr[4])&0x00ffffff); -- size = (size+3)&0xfffffffc; -+ size = scsi_get_uint32(&hdr[4]) & 0x00ffffff; -+ size = (size+3) & 0xfffffffc; - - return size; - } -@@ -236,9 +236,9 @@ int iscsi_process_target_nop_in(struct iscsi_context *iscsi, - uint32_t ttt; - uint32_t statsn; - -- ttt = ntohl(*(uint32_t *)&in->hdr[20]); -+ ttt = scsi_get_uint32(&in->hdr[20]); - -- statsn = ntohl(*(uint32_t *)&in->hdr[24]); -+ statsn = scsi_get_uint32(&in->hdr[24]); - if (statsn > iscsi->statsn) { - iscsi->statsn = statsn; - } -@@ -268,7 +268,7 @@ int iscsi_process_reject(struct iscsi_context *iscsi, - return -1; - } - -- itt = ntohl(*(uint32_t *)&in->data[16]); -+ itt = scsi_get_uint32(&in->data[16]); - - for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) { - if (pdu->itt == itt) { -@@ -302,7 +302,7 @@ iscsi_process_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in) - - opcode = in->hdr[0] & 0x3f; - ahslen = in->hdr[4]; -- itt = ntohl(*(uint32_t *)&in->hdr[16]); -+ itt = scsi_get_uint32(&in->hdr[16]); - - if (ahslen != 0) { - iscsi_set_error(iscsi, "cant handle expanded headers yet"); -@@ -449,13 +449,13 @@ iscsi_process_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in) - void - iscsi_pdu_set_itt(struct iscsi_pdu *pdu, uint32_t itt) - { -- *(uint32_t *)&pdu->outdata.data[16] = htonl(itt); -+ scsi_set_uint32(&pdu->outdata.data[16], itt); - } - - void - iscsi_pdu_set_ritt(struct iscsi_pdu *pdu, uint32_t ritt) - { -- *(uint32_t *)&pdu->outdata.data[20] = htonl(ritt); -+ scsi_set_uint32(&pdu->outdata.data[20], ritt); - } - - void -@@ -473,43 +473,43 @@ iscsi_pdu_set_immediate(struct iscsi_pdu *pdu) - void - iscsi_pdu_set_ttt(struct iscsi_pdu *pdu, uint32_t ttt) - { -- *(uint32_t *)&pdu->outdata.data[20] = htonl(ttt); -+ scsi_set_uint32(&pdu->outdata.data[20], ttt); - } - - void - iscsi_pdu_set_cmdsn(struct iscsi_pdu *pdu, uint32_t cmdsn) - { -- *(uint32_t *)&pdu->outdata.data[24] = htonl(cmdsn); -+ scsi_set_uint32(&pdu->outdata.data[24], cmdsn); - } - - void - iscsi_pdu_set_rcmdsn(struct iscsi_pdu *pdu, uint32_t rcmdsn) - { -- *(uint32_t *)&pdu->outdata.data[32] = htonl(rcmdsn); -+ scsi_set_uint32(&pdu->outdata.data[32], rcmdsn); - } - - void - iscsi_pdu_set_datasn(struct iscsi_pdu *pdu, uint32_t datasn) - { -- *(uint32_t *)&pdu->outdata.data[36] = htonl(datasn); -+ scsi_set_uint32(&pdu->outdata.data[36], datasn); - } - - void - iscsi_pdu_set_expstatsn(struct iscsi_pdu *pdu, uint32_t expstatsnsn) - { -- *(uint32_t *)&pdu->outdata.data[28] = htonl(expstatsnsn); -+ scsi_set_uint32(&pdu->outdata.data[28], expstatsnsn); - } - - void - iscsi_pdu_set_bufferoffset(struct iscsi_pdu *pdu, uint32_t bufferoffset) - { -- *(uint32_t *)&pdu->outdata.data[40] = htonl(bufferoffset); -+ scsi_set_uint32(&pdu->outdata.data[40], bufferoffset); - } - - void - iscsi_pdu_set_cdb(struct iscsi_pdu *pdu, struct scsi_task *task) - { -- memset(&pdu->outdata.data[32], 0, 16); -+ memset(&pdu->outdata.data[32], 0, 16); - memcpy(&pdu->outdata.data[32], task->cdb, task->cdb_size); - } - -@@ -523,5 +523,5 @@ iscsi_pdu_set_lun(struct iscsi_pdu *pdu, uint32_t lun) - void - iscsi_pdu_set_expxferlen(struct iscsi_pdu *pdu, uint32_t expxferlen) - { -- *(uint32_t *)&pdu->outdata.data[20] = htonl(expxferlen); -+ scsi_set_uint32(&pdu->outdata.data[20], expxferlen); - } -diff --git a/lib/scsi-command.c b/lib/scsi-command.c -index f6d8d0f..7f1e1c0 100644 ---- a/lib/scsi-command.c -+++ b/lib/scsi-command.c -@@ -328,12 +328,12 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, - struct iscsi_scsi_cbdata *scsi_cbdata = pdu->scsi_cbdata; - struct scsi_task *task = scsi_cbdata->task; - -- statsn = ntohl(*(uint32_t *)&in->hdr[24]); -+ statsn = scsi_get_uint32(&in->hdr[24]); - if (statsn > iscsi->statsn) { - iscsi->statsn = statsn; - } - -- maxcmdsn = ntohl(*(uint32_t *)&in->hdr[32]); -+ maxcmdsn = scsi_get_uint32(&in->hdr[32]); - if (maxcmdsn > iscsi->maxcmdsn) { - iscsi->maxcmdsn = maxcmdsn; - } -@@ -368,7 +368,7 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, - * These flags should only be set if the S flag is also set - */ - if (flags & (ISCSI_PDU_DATA_RESIDUAL_OVERFLOW|ISCSI_PDU_DATA_RESIDUAL_UNDERFLOW)) { -- task->residual = ntohl(*((uint32_t *)&in->hdr[44])); -+ task->residual = scsi_get_uint32(&in->hdr[44]); - if (flags & ISCSI_PDU_DATA_RESIDUAL_UNDERFLOW) { - task->residual_status = SCSI_RESIDUAL_UNDERFLOW; - } else { -@@ -392,10 +392,20 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, - memcpy(task->datain.data, in->data, task->datain.size); - - task->sense.error_type = task->datain.data[2] & 0x7f; -- task->sense.key = task->datain.data[4] & 0x0f; -- task->sense.ascq = ntohs(*(uint16_t *) -- &(task->datain.data[14])); -- -+ switch (task->sense.error_type) { -+ case 0x70: -+ case 0x71: -+ task->sense.key = task->datain.data[4] & 0x0f; -+ task->sense.ascq = scsi_get_uint16( -+ &(task->datain.data[14])); -+ break; -+ case 0x72: -+ case 0x73: -+ task->sense.key = task->datain.data[3] & 0x0f; -+ task->sense.ascq = scsi_get_uint16( -+ &(task->datain.data[4])); -+ break; -+ } - iscsi_set_error(iscsi, "SENSE KEY:%s(%d) ASCQ:%s(0x%04x)", - scsi_sense_key_str(task->sense.key), - task->sense.key, -@@ -429,12 +439,12 @@ iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, - struct scsi_task *task = scsi_cbdata->task; - int dsl; - -- statsn = ntohl(*(uint32_t *)&in->hdr[24]); -+ statsn = scsi_get_uint32(&in->hdr[24]); - if (statsn > iscsi->statsn) { - iscsi->statsn = statsn; - } - -- maxcmdsn = ntohl(*(uint32_t *)&in->hdr[32]); -+ maxcmdsn = scsi_get_uint32(&in->hdr[32]); - if (maxcmdsn > iscsi->maxcmdsn) { - iscsi->maxcmdsn = maxcmdsn; - } -@@ -447,7 +457,7 @@ iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, - pdu->private_data); - return -1; - } -- dsl = ntohl(*(uint32_t *)&in->hdr[4])&0x00ffffff; -+ dsl = scsi_get_uint32(&in->hdr[4]) & 0x00ffffff; - - /* Dont add to reassembly buffer if we already have a user buffer */ - if (scsi_task_get_data_in_buffer(task, 0, NULL) == NULL) { -@@ -479,7 +489,7 @@ iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, - * These flags should only be set if the S flag is also set - */ - if (flags & (ISCSI_PDU_DATA_RESIDUAL_OVERFLOW|ISCSI_PDU_DATA_RESIDUAL_UNDERFLOW)) { -- task->residual = ntohl(*((uint32_t *)&in->hdr[44])); -+ task->residual = scsi_get_uint32(&in->hdr[44]); - if (flags & ISCSI_PDU_DATA_RESIDUAL_UNDERFLOW) { - task->residual_status = SCSI_RESIDUAL_UNDERFLOW; - } else { -@@ -509,11 +519,11 @@ iscsi_process_r2t(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, - { - uint32_t ttt, offset, len, maxcmdsn; - -- ttt = ntohl(*(uint32_t *)&in->hdr[20]); -- offset = ntohl(*(uint32_t *)&in->hdr[40]); -- len = ntohl(*(uint32_t *)&in->hdr[44]); -+ ttt = scsi_get_uint32(&in->hdr[20]); -+ offset = scsi_get_uint32(&in->hdr[40]); -+ len = scsi_get_uint32(&in->hdr[44]); - -- maxcmdsn = ntohl(*(uint32_t *)&in->hdr[32]); -+ maxcmdsn = scsi_get_uint32(&in->hdr[32]); - if (maxcmdsn > iscsi->maxcmdsn) { - iscsi->maxcmdsn = maxcmdsn; - } -@@ -1431,12 +1441,12 @@ iscsi_unmap_task(struct iscsi_context *iscsi, int lun, int anchor, int group, - scsi_free_scsi_task(task); - return NULL; - } -- *((uint16_t *)&data[0]) = htons(xferlen - 2); -- *((uint16_t *)&data[2]) = htons(xferlen - 8); -+ scsi_set_uint16(&data[0], xferlen - 2); -+ scsi_set_uint16(&data[2], xferlen - 8); - for (i = 0; i < list_len; i++) { -- *((uint32_t *)&data[8 + 16 * i]) = htonl(list[0].lba >> 32); -- *((uint32_t *)&data[8 + 16 * i + 4]) = htonl(list[0].lba & 0xffffffff); -- *((uint32_t *)&data[8 + 16 * i + 8]) = htonl(list[0].num); -+ scsi_set_uint32(&data[8 + 16 * i], list[0].lba >> 32); -+ scsi_set_uint32(&data[8 + 16 * i + 4], list[0].lba & 0xffffffff); -+ scsi_set_uint32(&data[8 + 16 * i + 8], list[0].num); - } - - outdata.data = data; -@@ -1462,9 +1472,9 @@ iscsi_get_user_in_buffer(struct iscsi_context *iscsi, struct iscsi_in_pdu *in, u - return NULL; - } - -- offset = ntohl(*(uint32_t *)&in->hdr[40]); -+ offset = scsi_get_uint32(&in->hdr[40]); - -- itt = ntohl(*(uint32_t *)&in->hdr[16]); -+ itt = scsi_get_uint32(&in->hdr[16]); - for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) { - if (pdu->itt == itt) { - break; -diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c -index 3787072..a67144b 100644 ---- a/lib/scsi-lowlevel.c -+++ b/lib/scsi-lowlevel.c -@@ -15,8 +15,8 @@ - along with this program; if not, see . - */ - /* -- * would be nice if this could grow into a full blown library for scsi to -- * 1, build a CDB -+ * would be nice if this could grow into a full blown library to -+ * 1, build and unmarshall a CDB - * 2, check how big a complete data-in structure needs to be - * 3, unmarshall data-in into a real structure - * 4, marshall a real structure into a data-out blob -@@ -165,6 +165,91 @@ scsi_sense_ascq_str(int ascq) - return value_string_find(ascqs, ascq); - } - -+inline uint64_t -+scsi_get_uint64(const unsigned char *c) -+{ -+ uint64_t val; -+ -+ val = scsi_get_uint32(c); -+ val <<= 32; -+ c += 4; -+ val |= scsi_get_uint32(c); -+ -+ return val; -+} -+ -+inline uint32_t -+scsi_get_uint32(const unsigned char *c) -+{ -+ uint32_t val; -+ val = c[0]; -+ val = (val << 8) | c[1]; -+ val = (val << 8) | c[2]; -+ val = (val << 8) | c[3]; -+ return val; -+} -+ -+inline uint16_t -+scsi_get_uint16(const unsigned char *c) -+{ -+ uint16_t val; -+ val = c[0]; -+ val = (val << 8) | c[1]; -+ return val; -+} -+ -+static inline uint64_t -+task_get_uint64(struct scsi_task *task, int offset) -+{ -+ if (offset <= task->datain.size - 8) { -+ const unsigned char *c = &task->datain.data[offset]; -+ -+ return scsi_get_uint64(c); -+ } else { -+ return 0; -+ } -+} -+ -+static inline uint32_t -+task_get_uint32(struct scsi_task *task, int offset) -+{ -+ if (offset <= task->datain.size - 4) { -+ const unsigned char *c = &task->datain.data[offset]; -+ -+ return scsi_get_uint32(c); -+ } else { -+ return 0; -+ } -+} -+ -+static inline uint16_t -+task_get_uint16(struct scsi_task *task, int offset) -+{ -+ if (offset <= task->datain.size - 2) { -+ const unsigned char *c = &task->datain.data[offset]; -+ -+ return scsi_get_uint16(c); -+ } else { -+ return 0; -+ } -+} -+ -+inline void -+scsi_set_uint32(unsigned char *c, uint32_t val) -+{ -+ c[0] = val >> 24; -+ c[1] = val >> 16; -+ c[2] = val >> 8; -+ c[3] = val; -+} -+ -+inline void -+scsi_set_uint16(unsigned char *c, uint16_t val) -+{ -+ c[0] = val >> 8; -+ c[1] = val; -+} -+ - /* - * TESTUNITREADY - */ -@@ -205,7 +290,7 @@ scsi_reportluns_cdb(int report_type, int alloc_len) - memset(task, 0, sizeof(struct scsi_task)); - task->cdb[0] = SCSI_OPCODE_REPORTLUNS; - task->cdb[2] = report_type; -- *(uint32_t *)&task->cdb[6] = htonl(alloc_len); -+ scsi_set_uint32(&task->cdb[6], alloc_len); - - task->cdb_size = 12; - if (alloc_len != 0) { -@@ -229,7 +314,7 @@ scsi_reportluns_datain_getfullsize(struct scsi_task *task) - { - uint32_t list_size; - -- list_size = htonl(*(uint32_t *)&(task->datain.data[0])) + 8; -+ list_size = task_get_uint32(task, 0) + 8; - - return list_size; - } -@@ -248,7 +333,7 @@ scsi_reportluns_datain_unmarshall(struct scsi_task *task) - return NULL; - } - -- list_size = htonl(*(uint32_t *)&(task->datain.data[0])) + 8; -+ list_size = task_get_uint32(task, 0) + 8; - if (list_size < task->datain.size) { - return NULL; - } -@@ -262,8 +347,7 @@ scsi_reportluns_datain_unmarshall(struct scsi_task *task) - - list->num = num_luns; - for (i = 0; i < num_luns; i++) { -- list->luns[i] = htons(*(uint16_t *) -- &(task->datain.data[i*8+8])); -+ list->luns[i] = task_get_uint16(task, i * 8 + 8); - } - - return list; -@@ -286,7 +370,7 @@ scsi_cdb_readcapacity10(int lba, int pmi) - memset(task, 0, sizeof(struct scsi_task)); - task->cdb[0] = SCSI_OPCODE_READCAPACITY10; - -- *(uint32_t *)&task->cdb[2] = htonl(lba); -+ scsi_set_uint32(&task->cdb[2], lba); - - if (pmi) { - task->cdb[8] |= 0x01; -@@ -335,7 +419,7 @@ scsi_cdb_readtoc(int msf, int format, int track_session, uint16_t alloc_len) - task->cdb[6] = 0xff & track_session; - } - -- *(uint16_t *)&task->cdb[7] = htons(alloc_len); -+ scsi_set_uint16(&task->cdb[7], alloc_len); - - task->cdb_size = 10; - if (alloc_len != 0) { -@@ -361,7 +445,7 @@ scsi_readtoc_datain_getfullsize(struct scsi_task *task) - { - uint16_t toc_data_len; - -- toc_data_len = ntohs(*((uint16_t *)&task->datain.data[0])) + 2; -+ toc_data_len = task_get_uint16(task, 0) + 2; - - return toc_data_len; - } -@@ -377,8 +461,8 @@ scsi_readtoc_desc_unmarshall(struct scsi_task *task, struct scsi_readtoc_list *l - = task->datain.data[4+8*i+1] & 0x0f; - list->desc[i].desc.toc.track - = task->datain.data[4+8*i+2]; -- list->desc[i].desc.toc.lba -- = ntohl(*(uint32_t *)&task->datain.data[4+8*i+4]); -+ list->desc[i].desc.toc.lba -+ = task_get_uint32(task, 4 + 8 * i + 4); - break; - case SCSI_READ_SESSION_INFO: - list->desc[i].desc.ses.adr -@@ -387,8 +471,8 @@ scsi_readtoc_desc_unmarshall(struct scsi_task *task, struct scsi_readtoc_list *l - = task->datain.data[4+8*i+1] & 0x0f; - list->desc[i].desc.ses.first_in_last - = task->datain.data[4+8*i+2]; -- list->desc[i].desc.ses.lba -- = ntohl(*(uint32_t *)&task->datain.data[4+8*i+4]); -+ list->desc[i].desc.ses.lba -+ = task_get_uint32(task, 4 + 8 * i + 4); - break; - case SCSI_READ_FULL_TOC: - list->desc[i].desc.full.session -@@ -509,8 +593,6 @@ static void * - scsi_serviceactionin_datain_unmarshall(struct scsi_task *task) - { - struct scsi_readcapacity16 *rc16; -- struct scsi_get_lba_status *gls; -- int32_t len; - int i; - - switch (task->params.serviceactionin.sa) { -@@ -519,28 +601,32 @@ scsi_serviceactionin_datain_unmarshall(struct scsi_task *task) - if (rc16 == NULL) { - return NULL; - } -- rc16->returned_lba = ntohl(*(uint32_t *)&(task->datain.data[0])); -- rc16->returned_lba = (rc16->returned_lba << 32) | ntohl(*(uint32_t *)&(task->datain.data[4])); -- rc16->block_length = ntohl(*(uint32_t *)&(task->datain.data[8])); -+ rc16->returned_lba = task_get_uint32(task, 0); -+ rc16->returned_lba = (rc16->returned_lba << 32) | task_get_uint32(task, 4); -+ rc16->block_length = task_get_uint32(task, 8); - rc16->p_type = (task->datain.data[12] >> 1) & 0x07; - rc16->prot_en = task->datain.data[12] & 0x01; - rc16->p_i_exp = (task->datain.data[13] >> 4) & 0x0f; - rc16->lbppbe = task->datain.data[13] & 0x0f; - rc16->lbpme = !!(task->datain.data[14] & 0x80); - rc16->lbprz = !!(task->datain.data[14] & 0x40); -- rc16->lalba = ntohs(*(uint16_t *)&(task->datain.data[14])) & 0x3fff; -+ rc16->lalba = task_get_uint16(task, 14) & 0x3fff; - return rc16; -- case SCSI_GET_LBA_STATUS: -- len = ntohl(*(uint32_t *)&(task->datain.data[0])); -+ case SCSI_GET_LBA_STATUS: { -+ struct scsi_get_lba_status *gls = scsi_malloc(task, -+ sizeof(*gls)); -+ int32_t len = task_get_uint32(task, 0); -+ int i; -+ -+ if (gls == NULL) { -+ return NULL; -+ } -+ - if (len > task->datain.size - 4) { - len = task->datain.size - 4; - } - len = len / 16; - -- gls = scsi_malloc(task, sizeof(struct scsi_get_lba_status)); -- if (gls == NULL) { -- return NULL; -- } - gls->num_descriptors = len; - gls->descriptors = scsi_malloc(task, sizeof(struct scsi_lba_status_descriptor) * gls->num_descriptors); - if (gls->descriptors == NULL) { -@@ -548,11 +635,11 @@ scsi_serviceactionin_datain_unmarshall(struct scsi_task *task) - } - - for (i = 0; i < (int)gls->num_descriptors; i++) { -- gls->descriptors[i].lba = ntohl(*(uint32_t *)&(task->datain.data[8 + i * sizeof(struct scsi_lba_status_descriptor) + 0])); -+ gls->descriptors[i].lba = task_get_uint32(task, 8 + i * sizeof(struct scsi_lba_status_descriptor) + 0); - gls->descriptors[i].lba <<= 32; -- gls->descriptors[i].lba |= ntohl(*(uint32_t *)&(task->datain.data[8 + i * sizeof(struct scsi_lba_status_descriptor) + 4])); -+ gls->descriptors[i].lba |= task_get_uint32(task, 8 + i * sizeof(struct scsi_lba_status_descriptor) + 4); - -- gls->descriptors[i].num_blocks = ntohl(*(uint32_t *)&(task->datain.data[8 + i * sizeof(struct scsi_lba_status_descriptor) + 8])); -+ gls->descriptors[i].num_blocks = task_get_uint32(task, 8 + i * sizeof(struct scsi_lba_status_descriptor) + 8); - - gls->descriptors[i].provisioning = task->datain.data[8 + i * sizeof(struct scsi_lba_status_descriptor) + 12] & 0x0f; - } -@@ -558,6 +645,7 @@ scsi_serviceactionin_datain_unmarshall(struct scsi_task *task) - - return gls; - } -+ } - - return NULL; - } -@@ -573,8 +660,8 @@ scsi_maintenancein_datain_getfullsize(struct scsi_task *task) - { - - switch (task->params.maintenancein.sa) { -- case SCSI_REPORT_SUPPORTED_OP_CODES: -- return ntohl(*(uint32_t *)&(task->datain.data[0])) + 4; -+ case SCSI_REPORT_SUPPORTED_OP_CODES: -+ return task_get_uint32(task, 0) + 4; - default: - return -1; - } -@@ -599,7 +686,7 @@ scsi_maintenancein_datain_unmarshall(struct scsi_task *task) - return NULL; - } - -- len = ntohl(*(uint32_t *)&(task->datain.data[0])); -+ len = task_get_uint32(task, 0); - rsoc = scsi_malloc(task, sizeof(struct scsi_report_supported_op_codes) + len); - if (rsoc == NULL) { - return NULL; -@@ -661,7 +748,7 @@ scsi_cdb_report_supported_opcodes(int return_timeouts, uint32_t alloc_len) - task->cdb[2] |= 0x80; - } - -- *(uint32_t *)&task->cdb[6] = htonl(alloc_len); -+ scsi_set_uint32(&task->cdb[6], alloc_len); - - task->cdb_size = 12; - if (alloc_len != 0) { -@@ -703,8 +790,8 @@ scsi_readcapacity10_datain_unmarshall(struct scsi_task *task) - return NULL; - } - -- rc10->lba = htonl(*(uint32_t *)&(task->datain.data[0])); -- rc10->block_size = htonl(*(uint32_t *)&(task->datain.data[4])); -+ rc10->lba = task_get_uint32(task, 0); -+ rc10->block_size = task_get_uint32(task, 4); - - return rc10; - } -@@ -735,7 +822,7 @@ scsi_cdb_inquiry(int evpd, int page_code, int alloc_len) - - task->cdb[2] = page_code; - -- *(uint16_t *)&task->cdb[3] = htons(alloc_len); -+ scsi_set_uint16(&task->cdb[3], alloc_len); - - task->cdb_size = 6; - if (alloc_len != 0) { -@@ -770,7 +857,7 @@ scsi_inquiry_datain_getfullsize(struct scsi_task *task) - case SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION: - case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS: - case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING: -- return ntohs(*(uint16_t *)&task->datain.data[2]) + 4; -+ return task_get_uint16(task, 2) + 4; - default: - return -1; - } -@@ -871,7 +958,7 @@ scsi_inquiry_datain_unmarshall(struct scsi_task *task) - } else if (task->params.inquiry.page_code - == SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION) { - struct scsi_inquiry_device_identification *inq; -- int remaining = ntohs(*(uint16_t *)&task->datain.data[2]); -+ int remaining = task_get_uint16(task, 2); - unsigned char *dptr; - - inq = scsi_malloc(task, -@@ -933,17 +1020,16 @@ scsi_inquiry_datain_unmarshall(struct scsi_task *task) - - inq->wsnz = task->datain.data[4] & 0x01; - inq->max_cmp = task->datain.data[5]; -- inq->opt_gran = ntohs(*(uint16_t *)&task->datain.data[6]); -- inq->max_xfer_len = ntohl(*(uint32_t *)&task->datain.data[8]); -- inq->opt_xfer_len = ntohl(*(uint32_t *)&task->datain.data[12]); -- inq->max_prefetch = ntohl(*(uint32_t *)&task->datain.data[16]); -- inq->max_unmap = ntohl(*(uint32_t *)&task->datain.data[20]); -- inq->max_unmap_bdc = ntohl(*(uint32_t *)&task->datain.data[24]); -- inq->opt_unmap_gran = ntohl(*(uint32_t *)&task->datain.data[28]); -+ inq->opt_gran = task_get_uint16(task, 6); -+ inq->max_xfer_len = task_get_uint32(task, 8); -+ inq->opt_xfer_len = task_get_uint32(task, 12); -+ inq->max_prefetch = task_get_uint32(task, 16); -+ inq->max_unmap = task_get_uint32(task, 20); -+ inq->max_unmap_bdc = task_get_uint32(task, 24); -+ inq->opt_unmap_gran = task_get_uint32(task, 28); - inq->ugavalid = !!(task->datain.data[32]&0x80); -- inq->unmap_gran_align = ntohl(*(uint32_t *)&task->datain.data[32]) & 0x7fffffff; -- inq->max_ws_len = ntohl(*(uint32_t *)&task->datain.data[36]); -- inq->max_ws_len = (inq->max_ws_len << 32) | ntohl(*(uint32_t *)&task->datain.data[40]); -+ inq->unmap_gran_align = task_get_uint32(task, 32) & 0x7fffffff; -+ inq->max_ws_len = task_get_uint64(task, 36); - - return inq; - } else if (task->params.inquiry.page_code -@@ -959,7 +1045,7 @@ scsi_inquiry_datain_unmarshall(struct scsi_task *task) - inq->device_type = task->datain.data[0]&0x1f; - inq->pagecode = task->datain.data[1]; - -- inq->medium_rotation_rate = ntohs(*(uint16_t *)&task->datain.data[4]); -+ inq->medium_rotation_rate = task_get_uint16(task, 4); - return inq; - } else if (task->params.inquiry.page_code - == SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING) { -@@ -1064,8 +1150,8 @@ scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, in - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba); -- *(uint16_t *)&task->cdb[7] = htons(xferlen/blocksize); -+ scsi_set_uint32(&task->cdb[2], lba); -+ scsi_set_uint16(&task->cdb[7], xferlen/blocksize); - - task->cdb[6] |= (group_number & 0x1f); - -@@ -1110,8 +1196,8 @@ scsi_cdb_read12(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, in - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba); -- *(uint32_t *)&task->cdb[6] = htonl(xferlen/blocksize); -+ scsi_set_uint32(&task->cdb[2], lba); -+ scsi_set_uint32(&task->cdb[6], xferlen/blocksize); - - task->cdb[10] |= (group_number & 0x1f); - -@@ -1156,9 +1242,9 @@ scsi_cdb_read16(uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, in - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba >> 32); -- *(uint32_t *)&task->cdb[6] = htonl(lba & 0xffffffff); -- *(uint32_t *)&task->cdb[10] = htonl(xferlen/blocksize); -+ scsi_set_uint32(&task->cdb[2], lba >> 32); -+ scsi_set_uint32(&task->cdb[6], lba & 0xffffffff); -+ scsi_set_uint32(&task->cdb[10], xferlen/blocksize); - - task->cdb[14] |= (group_number & 0x1f); - -@@ -1203,8 +1289,8 @@ scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, i - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba); -- *(uint16_t *)&task->cdb[7] = htons(xferlen/blocksize); -+ scsi_set_uint32(&task->cdb[2], lba); -+ scsi_set_uint16(&task->cdb[7], xferlen/blocksize); - - task->cdb[6] |= (group_number & 0x1f); - -@@ -1249,8 +1335,8 @@ scsi_cdb_write12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, i - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba); -- *(uint32_t *)&task->cdb[6] = htonl(xferlen/blocksize); -+ scsi_set_uint32(&task->cdb[2], lba); -+ scsi_set_uint32(&task->cdb[6], xferlen/blocksize); - - task->cdb[10] |= (group_number & 0x1f); - -@@ -1295,9 +1381,9 @@ scsi_cdb_write16(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, i - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba >> 32); -- *(uint32_t *)&task->cdb[6] = htonl(lba & 0xffffffff); -- *(uint32_t *)&task->cdb[10] = htonl(xferlen/blocksize); -+ scsi_set_uint32(&task->cdb[2], lba >> 32); -+ scsi_set_uint32(&task->cdb[6], lba & 0xffffffff); -+ scsi_set_uint32(&task->cdb[10], xferlen/blocksize); - - task->cdb[14] |= (group_number & 0x1f); - -@@ -1342,9 +1428,9 @@ scsi_cdb_orwrite(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, i - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba >> 32); -- *(uint32_t *)&task->cdb[6] = htonl(lba & 0xffffffff); -- *(uint32_t *)&task->cdb[10] = htonl(xferlen/blocksize); -+ scsi_set_uint32(&task->cdb[2], lba >> 32); -+ scsi_set_uint32(&task->cdb[6], lba & 0xffffffff); -+ scsi_set_uint32(&task->cdb[10], xferlen/blocksize); - - task->cdb[14] |= (group_number & 0x1f); - -@@ -1389,8 +1475,8 @@ scsi_cdb_compareandwrite(uint64_t lba, uint32_t xferlen, int blocksize, int wrpr - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba >> 32); -- *(uint32_t *)&task->cdb[6] = htonl(lba & 0xffffffff); -+ scsi_set_uint32(&task->cdb[2], lba >> 32); -+ scsi_set_uint32(&task->cdb[6], lba & 0xffffffff); - task->cdb[13] = xferlen/blocksize; - - task->cdb[14] |= (group_number & 0x1f); -@@ -1434,8 +1520,8 @@ scsi_cdb_verify10(uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int byt - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba); -- *(uint16_t *)&task->cdb[7] = htons(xferlen/blocksize); -+ scsi_set_uint32(&task->cdb[2], lba); -+ scsi_set_uint16(&task->cdb[7], xferlen/blocksize); - - task->cdb_size = 10; - if (xferlen != 0) { -@@ -1480,8 +1566,8 @@ scsi_cdb_verify12(uint32_t lba, uint32_t xferlen, int vprotect, int dpo, int byt - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba); -- *(uint32_t *)&task->cdb[6] = htonl(xferlen/blocksize); -+ scsi_set_uint32(&task->cdb[2], lba); -+ scsi_set_uint32(&task->cdb[6], xferlen/blocksize); - - task->cdb_size = 12; - if (xferlen != 0) { -@@ -1526,9 +1612,9 @@ scsi_cdb_verify16(uint64_t lba, uint32_t xferlen, int vprotect, int dpo, int byt - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba >> 32); -- *(uint32_t *)&task->cdb[6] = htonl(lba & 0xffffffff); -- *(uint32_t *)&task->cdb[10] = htonl(xferlen/blocksize); -+ scsi_set_uint32(&task->cdb[2], lba >> 32); -+ scsi_set_uint32(&task->cdb[6], lba & 0xffffffff); -+ scsi_set_uint32(&task->cdb[10], xferlen/blocksize); - - task->cdb_size = 16; - if (xferlen != 0) { -@@ -1568,7 +1654,7 @@ scsi_cdb_unmap(int anchor, int group, uint16_t xferlen) - } - task->cdb[6] |= group & 0x1f; - -- *(uint16_t *)&task->cdb[7] = htons(xferlen); -+ scsi_set_uint16(&task->cdb[7], xferlen); - - task->cdb_size = 10; - if (xferlen != 0) { -@@ -1612,11 +1698,11 @@ scsi_cdb_writesame10(int wrprotect, int anchor, int unmap, int pbdata, int lbdat - if (lbdata) { - task->cdb[1] |= 0x02; - } -- *(uint32_t *)&task->cdb[2] = htonl(lba); -+ scsi_set_uint32(&task->cdb[2], lba); - if (group) { - task->cdb[6] |= (group & 0x1f); - } -- *(uint16_t *)&task->cdb[7] = htons(num_blocks); -+ scsi_set_uint16(&task->cdb[7], num_blocks); - - task->cdb_size = 10; - task->xfer_dir = SCSI_XFER_WRITE; -@@ -1656,9 +1742,9 @@ scsi_cdb_writesame16(int wrprotect, int anchor, int unmap, int pbdata, int lbdat - if (lbdata) { - task->cdb[1] |= 0x02; - } -- *(uint32_t *)&task->cdb[2] = htonl(lba >> 32); -- *(uint32_t *)&task->cdb[6] = htonl(lba & 0xffffffff); -- *(uint32_t *)&task->cdb[10] = htonl(num_blocks); -+ scsi_set_uint32(&task->cdb[2], lba >> 32); -+ scsi_set_uint32(&task->cdb[6], lba & 0xffffffff); -+ scsi_set_uint32(&task->cdb[10], num_blocks); - if (group) { - task->cdb[14] |= (group & 0x1f); - } -@@ -1740,10 +1826,10 @@ scsi_parse_mode_caching(struct scsi_task *task, int pos, struct scsi_mode_page * - mp->caching.demand_read_retention_priority = (task->datain.data[pos+1] >> 4) & 0x0f; - mp->caching.write_retention_priority = task->datain.data[pos+1] & 0x0f; - -- mp->caching.disable_prefetch_transfer_length = htons(*(uint16_t *)&(task->datain.data[pos+2])); -- mp->caching.minimum_prefetch = htons(*(uint16_t *)&(task->datain.data[pos+4])); -- mp->caching.maximum_prefetch = htons(*(uint16_t *)&(task->datain.data[pos+6])); -- mp->caching.maximum_prefetch_ceiling = htons(*(uint16_t *)&(task->datain.data[pos+8])); -+ mp->caching.disable_prefetch_transfer_length = task_get_uint16(task, pos + 2); -+ mp->caching.minimum_prefetch = task_get_uint16(task, pos + 4); -+ mp->caching.maximum_prefetch = task_get_uint16(task, pos + 6); -+ mp->caching.maximum_prefetch_ceiling = task_get_uint16(task, pos + 8); - - mp->caching.fsw = task->datain.data[pos+10] & 0x80; - mp->caching.lbcss = task->datain.data[pos+10] & 0x40; -@@ -1751,7 +1837,7 @@ scsi_parse_mode_caching(struct scsi_task *task, int pos, struct scsi_mode_page * - mp->caching.nv_dis = task->datain.data[pos+10] & 0x01; - - mp->caching.number_of_cache_segments = task->datain.data[pos+11]; -- mp->caching.cache_segment_size = htons(*(uint16_t *)&(task->datain.data[pos+12])); -+ mp->caching.cache_segment_size = task_get_uint16(task, pos + 12); - } - - static void -@@ -1759,15 +1845,15 @@ scsi_parse_mode_disconnect_reconnect(struct scsi_task *task, int pos, struct scs - { - mp->disconnect_reconnect.buffer_full_ratio = task->datain.data[pos]; - mp->disconnect_reconnect.buffer_empty_ratio = task->datain.data[pos+1]; -- mp->disconnect_reconnect.bus_inactivity_limit = htons(*(uint16_t *)&(task->datain.data[pos+2])); -- mp->disconnect_reconnect.disconnect_time_limit = htons(*(uint16_t *)&(task->datain.data[pos+4])); -- mp->disconnect_reconnect.connect_time_limit = htons(*(uint16_t *)&(task->datain.data[pos+6])); -- mp->disconnect_reconnect.maximum_burst_size = htons(*(uint16_t *)&(task->datain.data[pos+8])); -+ mp->disconnect_reconnect.bus_inactivity_limit = task_get_uint16(task, pos + 2); -+ mp->disconnect_reconnect.disconnect_time_limit = task_get_uint16(task, pos + 4); -+ mp->disconnect_reconnect.connect_time_limit = task_get_uint16(task, pos + 6); -+ mp->disconnect_reconnect.maximum_burst_size = task_get_uint16(task, pos + 8); - mp->disconnect_reconnect.emdp = task->datain.data[pos+10] & 0x80; - mp->disconnect_reconnect.fair_arbitration = (task->datain.data[pos+10]>>4) & 0x0f; - mp->disconnect_reconnect.dimm = task->datain.data[pos+10] & 0x08; - mp->disconnect_reconnect.dtdc = task->datain.data[pos+10] & 0x07; -- mp->disconnect_reconnect.first_burst_size = htons(*(uint16_t *)&(task->datain.data[pos+12])); -+ mp->disconnect_reconnect.first_burst_size = task_get_uint16(task, pos + 12); - } - - static void -@@ -1781,8 +1867,8 @@ scsi_parse_mode_informational_exceptions_control(struct scsi_task *task, int pos - mp->iec.ebackerr = task->datain.data[pos] & 0x02; - mp->iec.logerr = task->datain.data[pos] & 0x01; - mp->iec.mrie = task->datain.data[pos+1] & 0x0f; -- mp->iec.interval_timer = htonl(*(uint32_t *)&(task->datain.data[pos+2])); -- mp->iec.report_count = htonl(*(uint32_t *)&(task->datain.data[pos+6])); -+ mp->iec.interval_timer = task_get_uint32(task, pos + 2); -+ mp->iec.report_count = task_get_uint32(task, pos + 6); - } - - -@@ -1829,7 +1915,7 @@ scsi_modesense_datain_unmarshall(struct scsi_task *task) - - if (mp->spf) { - mp->subpage_code = task->datain.data[pos++]; -- mp->len = ntohs(*(uint16_t *)&task->datain.data[pos]); -+ mp->len = task_get_uint16(task, pos); - pos += 2; - } else { - mp->subpage_code = 0; -@@ -1956,8 +2042,8 @@ scsi_cdb_synchronizecache10(int lba, int num_blocks, int syncnv, int immed) - if (immed) { - task->cdb[1] |= 0x02; - } -- *(uint32_t *)&task->cdb[2] = htonl(lba); -- *(uint16_t *)&task->cdb[7] = htons(num_blocks); -+ scsi_set_uint32(&task->cdb[2], lba); -+ scsi_set_uint16(&task->cdb[7], num_blocks); - - task->cdb_size = 10; - task->xfer_dir = SCSI_XFER_NONE; -@@ -1988,9 +2074,9 @@ scsi_cdb_synchronizecache16(uint64_t lba, uint32_t num_blocks, int syncnv, int i - if (immed) { - task->cdb[1] |= 0x02; - } -- *(uint32_t *)&task->cdb[2] = htonl(lba >> 32); -- *(uint32_t *)&task->cdb[6] = htonl(lba & 0xffffffff); -- *(uint32_t *)&task->cdb[10] = htonl(num_blocks); -+ scsi_set_uint32(&task->cdb[2], lba >> 32); -+ scsi_set_uint32(&task->cdb[6], lba & 0xffffffff); -+ scsi_set_uint32(&task->cdb[10], num_blocks); - - task->cdb_size = 16; - task->xfer_dir = SCSI_XFER_NONE; -@@ -2018,9 +2104,9 @@ scsi_cdb_prefetch10(uint32_t lba, int num_blocks, int immed, int group) - if (immed) { - task->cdb[1] |= 0x02; - } -- *(uint32_t *)&task->cdb[2] = htonl(lba); -+ scsi_set_uint32(&task->cdb[2], lba); - task->cdb[6] |= group & 0x1f; -- *(uint16_t *)&task->cdb[7] = htons(num_blocks); -+ scsi_set_uint16(&task->cdb[7], num_blocks); - - task->cdb_size = 10; - task->xfer_dir = SCSI_XFER_NONE; -@@ -2048,9 +2134,9 @@ scsi_cdb_prefetch16(uint64_t lba, int num_blocks, int immed, int group) - if (immed) { - task->cdb[1] |= 0x02; - } -- *(uint32_t *)&task->cdb[2] = htonl(lba >> 32); -- *(uint32_t *)&task->cdb[6] = htonl(lba & 0xffffffff); -- *(uint32_t *)&task->cdb[10] = htonl(num_blocks); -+ scsi_set_uint32(&task->cdb[2], lba >> 32); -+ scsi_set_uint32(&task->cdb[6], lba & 0xffffffff); -+ scsi_set_uint32(&task->cdb[10], num_blocks); - - task->cdb[14] |= group & 0x1f; - -@@ -2079,7 +2165,7 @@ scsi_cdb_serviceactionin16(enum scsi_service_action_in sa, uint32_t xferlen) - - task->cdb[1] = sa; - -- *(uint32_t *)&task->cdb[10] = htonl(xferlen); -+ scsi_set_uint32(&task->cdb[10], xferlen); - - task->cdb_size = 16; - if (xferlen != 0) { -@@ -2121,9 +2207,9 @@ scsi_cdb_get_lba_status(uint64_t starting_lba, uint32_t alloc_len) - - task->cdb[1] = SCSI_GET_LBA_STATUS; - -- *(uint32_t *)&task->cdb[2] = htonl(starting_lba >> 32); -- *(uint32_t *)&task->cdb[6] = htonl(starting_lba & 0xffffffff); -- *(uint32_t *)&task->cdb[10] = htonl(alloc_len); -+ scsi_set_uint32(&task->cdb[2], starting_lba >> 32); -+ scsi_set_uint32(&task->cdb[6], starting_lba & 0xffffffff); -+ scsi_set_uint32(&task->cdb[10], alloc_len); - - task->cdb_size = 16; - if (alloc_len != 0) { -@@ -2162,8 +2248,8 @@ scsi_cdb_writeverify10(uint32_t lba, uint32_t xferlen, int blocksize, int wrprot - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba); -- *(uint16_t *)&task->cdb[7] = htons(xferlen/blocksize); -+ scsi_set_uint32(&task->cdb[2], lba); -+ scsi_set_uint16(&task->cdb[7], xferlen/blocksize); - - task->cdb[6] |= (group_number & 0x1f); - -@@ -2205,8 +2291,8 @@ scsi_cdb_writeverify12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprot - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba); -- *(uint32_t *)&task->cdb[6] = htonl(xferlen/blocksize); -+ scsi_set_uint32(&task->cdb[2], lba); -+ scsi_set_uint32(&task->cdb[6], xferlen/blocksize); - - task->cdb[10] |= (group_number & 0x1f); - -@@ -2248,9 +2334,9 @@ scsi_cdb_writeverify16(uint64_t lba, uint32_t xferlen, int blocksize, int wrprot - task->cdb[1] |= 0x02; - } - -- *(uint32_t *)&task->cdb[2] = htonl(lba >> 32); -- *(uint32_t *)&task->cdb[6] = htonl(lba & 0xffffffff); -- *(uint32_t *)&task->cdb[10] = htonl(xferlen/blocksize); -+ scsi_set_uint32(&task->cdb[2], lba >> 32); -+ scsi_set_uint32(&task->cdb[6], lba & 0xffffffff); -+ scsi_set_uint32(&task->cdb[10], xferlen/blocksize); - - task->cdb[14] |= (group_number & 0x1f); - -diff --git a/lib/task_mgmt.c b/lib/task_mgmt.c -index 286072d..50dc3f1 100644 ---- a/lib/task_mgmt.c -+++ b/lib/task_mgmt.c -@@ -87,7 +87,7 @@ iscsi_process_task_mgmt_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu - - response = in->hdr[2]; - -- maxcmdsn = ntohl(*(uint32_t *)&in->hdr[32]); -+ maxcmdsn = scsi_get_uint32(&in->hdr[32]); - if (maxcmdsn > iscsi->maxcmdsn) { - iscsi->maxcmdsn = maxcmdsn; - } diff --git a/0005-fix-bug-in-md5-code.patch b/0005-fix-bug-in-md5-code.patch new file mode 100644 index 0000000..5baeb49 --- /dev/null +++ b/0005-fix-bug-in-md5-code.patch @@ -0,0 +1,25 @@ +From cc742279d0c83523f03a93882fce6bc820851750 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 3 May 2013 12:43:50 +0200 +Subject: [PATCH] fix bug in md5 code + +--- + lib/md5.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/md5.c b/lib/md5.c +index daab76c..893956d 100644 +--- a/lib/md5.c ++++ b/lib/md5.c +@@ -134,7 +134,7 @@ MD5Final(md5byte digest[16], struct MD5Context *ctx) + + byteSwap(ctx->buf, 4); + memcpy(digest, ctx->buf, 16); +- memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ ++ memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ + } + + #ifndef ASM_MD5 +-- +1.8.1.4 + diff --git a/0002-use-libgcrypt-for-MD5.patch b/0006-use-libgcrypt-for-MD5.patch similarity index 78% rename from 0002-use-libgcrypt-for-MD5.patch rename to 0006-use-libgcrypt-for-MD5.patch index 9bb7224..362bd92 100644 --- a/0002-use-libgcrypt-for-MD5.patch +++ b/0006-use-libgcrypt-for-MD5.patch @@ -1,4 +1,4 @@ -From 8217ffdc2af8b412949d0d21a6ff3777c8e4953f Mon Sep 17 00:00:00 2001 +From bcb2950d8ded9ec3a2e3ada8428aeaf725ea2171 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 3 May 2013 12:47:12 +0200 Subject: [PATCH] use libgcrypt for MD5 @@ -8,27 +8,24 @@ is running in FIPS 140-2 mode. MD5 is not a secure algorithm according to the standard. Signed-off-by: Paolo Bonzini - -Conflicts: - Makefile.am - lib/login.c --- Makefile.am | 6 +++++- configure.ac | 3 +++ - lib/login.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- - 3 files changed, 61 insertions(+), 8 deletions(-) + lib/login.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- + 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/Makefile.am b/Makefile.am -index b750cdb..e308552 100644 +index 5fea7c8..9a8b2b4 100644 --- a/Makefile.am +++ b/Makefile.am -@@ -25,9 +25,13 @@ dist_noinst_DATA = lib/libiscsi.syms +@@ -34,10 +34,14 @@ dist_noinst_DATA = lib/libiscsi.syms lib_LTLIBRARIES = lib/libiscsi.la lib_libiscsi_la_SOURCES = \ lib/connect.c lib/crc32c.c lib/discovery.c lib/init.c \ -- lib/login.c lib/md5.c lib/nop.c lib/pdu.c lib/scsi-command.c \ -+ lib/login.c lib/nop.c lib/pdu.c lib/scsi-command.c \ - lib/scsi-lowlevel.c lib/socket.c lib/sync.c lib/task_mgmt.c +- lib/login.c lib/md5.c lib/nop.c lib/pdu.c lib/iscsi-command.c \ ++ lib/login.c lib/nop.c lib/pdu.c lib/iscsi-command.c \ + lib/scsi-lowlevel.c lib/socket.c lib/sync.c lib/task_mgmt.c \ + lib/logging.c +if !HAVE_LIBGCRYPT +lib_libiscsi_la_SOURCES += lib/md5.c @@ -38,10 +35,10 @@ index b750cdb..e308552 100644 SOREL=$(shell printf "%d%02d%02d" $(subst ., ,$(VERSION))) lib_libiscsi_la_LDFLAGS = \ diff --git a/configure.ac b/configure.ac -index bb95018..95d4ec6 100644 +index 0b45f91..9d06e3a 100644 --- a/configure.ac +++ b/configure.ac -@@ -28,6 +28,9 @@ AC_SUBST(WARN_CFLAGS) +@@ -18,6 +18,9 @@ AC_SUBST(WARN_CFLAGS) AC_CONFIG_HEADER(config.h) @@ -52,10 +49,10 @@ index bb95018..95d4ec6 100644 AC_TRY_COMPILE([#include #include diff --git a/lib/login.c b/lib/login.c -index 5da4d21..39ae237 100644 +index 07ca3dd..29fe4b3 100644 --- a/lib/login.c +++ b/lib/login.c -@@ -25,12 +25,17 @@ +@@ -35,13 +35,18 @@ #include #endif @@ -66,6 +63,7 @@ index 5da4d21..39ae237 100644 #include #include "iscsi.h" #include "iscsi-private.h" + #include "scsi-lowlevel.h" #include "md5.h" +#ifdef HAVE_LIBGCRYPT +#include @@ -73,7 +71,7 @@ index 5da4d21..39ae237 100644 static int iscsi_login_add_initiatorname(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) -@@ -649,13 +654,48 @@ i2h(int i) +@@ -628,6 +632,41 @@ i2h(int i) return i + '0'; } @@ -115,7 +113,8 @@ index 5da4d21..39ae237 100644 static int iscsi_login_add_chap_response(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) { - char *str; +@@ -635,7 +674,7 @@ iscsi_login_add_chap_response(struct iscsi_context *iscsi, struct iscsi_pdu *pdu + char * strp; unsigned char c, cc[2]; unsigned char digest[16]; - struct MD5Context ctx; @@ -123,7 +122,7 @@ index 5da4d21..39ae237 100644 int i; if (iscsi->current_phase != ISCSI_PDU_LOGIN_CSG_SECNEG -@@ -663,21 +703,27 @@ iscsi_login_add_chap_response(struct iscsi_context *iscsi, struct iscsi_pdu *pdu +@@ -643,22 +682,27 @@ iscsi_login_add_chap_response(struct iscsi_context *iscsi, struct iscsi_pdu *pdu return 0; } @@ -141,13 +140,14 @@ index 5da4d21..39ae237 100644 - c = iscsi->chap_i; - MD5Update(&ctx, &c, 1); - MD5Update(&ctx, (unsigned char *)iscsi->passwd, strlen(iscsi->passwd)); +- + gcry_md_putc(ctx, iscsi->chap_i); + gcry_md_write(ctx, (unsigned char *)iscsi->passwd, strlen(iscsi->passwd)); + - str = iscsi->chap_c; - while (*str != 0) { - c = (h2i(str[0]) << 4) | h2i(str[1]); - str += 2; + strp = iscsi->chap_c; + while (*strp != 0) { + c = (h2i(strp[0]) << 4) | h2i(strp[1]); + strp += 2; - MD5Update(&ctx, &c, 1); + gcry_md_putc(ctx, c); } @@ -155,8 +155,8 @@ index 5da4d21..39ae237 100644 + memcpy(digest, gcry_md_read(ctx, 0), sizeof(digest)); + gcry_md_close(ctx); - str = (char *)"CHAP_R=0x"; + strncpy(str,"CHAP_R=0x",MAX_STRING_SIZE); if (iscsi_pdu_add_data(iscsi, pdu, (unsigned char *)str, strlen(str)) -- -1.8.2 +1.8.1.4 diff --git a/0007-URL-encoded-Targetnames.patch b/0007-URL-encoded-Targetnames.patch new file mode 100644 index 0000000..062914e --- /dev/null +++ b/0007-URL-encoded-Targetnames.patch @@ -0,0 +1,228 @@ +From e061cba1b91650ab08ae8fa50e8cadb13ac3d97d Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Sun, 16 Jun 2013 11:35:14 -0700 +Subject: [PATCH] URL encoded Targetnames + +Assume target names are URL encoded with '%' as the special character. + +Any sequence of '%' followed by two bytes in the target name will be replaced +with the byte that the second two bytes represent in hexadecimal. + +Example +iqn.ronnie.test%3A1234 +will be translated to iqn.ronnie.test:1234 +--- + include/iscsi.h | 12 ++++-- + lib/init.c | 114 +++++++++++++++++++++++++++++++++++++++----------------- + lib/login.c | 1 + + 3 files changed, 88 insertions(+), 39 deletions(-) + +diff --git a/include/iscsi.h b/include/iscsi.h +index f14d404..a4ed932 100644 +--- a/include/iscsi.h ++++ b/include/iscsi.h +@@ -125,6 +125,10 @@ iscsi_set_initial_r2t(struct iscsi_context *iscsi, enum iscsi_initial_r2t initia + * iSCSI URL format : + * iscsi://[[%]@][:]// + * ++ * Target names are url encoded with '%' as a special character. ++ * Example: ++ * "iqn.ronnie.test%3A1234" will be translated to "iqn.ronnie.test:1234" ++ * + * Function will return a pointer to an iscsi url structure if successful, + * or it will return NULL and set iscsi_get_error() accrodingly if there was a problem + * with the URL. +diff --git a/lib/init.c b/lib/init.c +index 18f3fb2..60a1b6d 100644 +--- a/lib/init.c ++++ b/lib/init.c +@@ -358,6 +358,45 @@ iscsi_is_logged_in(struct iscsi_context *iscsi) + return iscsi->is_loggedin; + } + ++static int ++h2i(int h) ++{ ++ if (h >= 'a' && h <= 'f') { ++ return h - 'a' + 10; ++ } ++ if (h >= 'A' && h <= 'F') { ++ return h - 'A' + 10; ++ } ++ return h - '0'; ++} ++ ++static void ++iscsi_decode_url_string(char *str) ++{ ++ while (*str) { ++ char *tmp = str; ++ char c; ++ ++ if (*str++ != '%') { ++ continue; ++ } ++ ++ if (*str == 0) { ++ return; ++ } ++ c = h2i(*str++) << 4; ++ ++ if (*str == 0) { ++ return; ++ } ++ c |= h2i(*str++); ++ ++ *tmp++ = c; ++ memmove(tmp, str, strlen(str)); ++ tmp[strlen(str)] = 0; ++ } ++} ++ + struct iscsi_url * + iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full) + { +@@ -373,15 +412,18 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full) + + if (strncmp(url, "iscsi://", 8)) { + if (full) { +- iscsi_set_error(iscsi, "Invalid URL %s\niSCSI URL must be of " +- "the form: %s",url,ISCSI_URL_SYNTAX); } +- else { +- iscsi_set_error(iscsi, "Invalid URL %s\niSCSI Portal URL must be of " +- "the form: %s",url,ISCSI_PORTAL_URL_SYNTAX); } ++ iscsi_set_error(iscsi, "Invalid URL %s\niSCSI URL must " ++ "be of the form: %s", ++ url, ISCSI_URL_SYNTAX); ++ } else { ++ iscsi_set_error(iscsi, "Invalid URL %s\niSCSI Portal " ++ "URL must be of the form: %s", ++ url, ISCSI_PORTAL_URL_SYNTAX); ++ } + return NULL; + } + +- strncpy(str,url + 8,MAX_STRING_SIZE); ++ strncpy(str,url + 8, MAX_STRING_SIZE); + portal = str; + + user = getenv("LIBISCSI_CHAP_USERNAME"); +@@ -406,56 +448,56 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full) + if (full) { + target = strchr(portal, '/'); + if (target == NULL) { +- iscsi_set_error(iscsi, "Invalid URL %s\nCould not parse " +- "''\niSCSI URL must be of the " +- "form: %s", +- url, +- ISCSI_URL_SYNTAX); ++ iscsi_set_error(iscsi, "Invalid URL %s\nCould not " ++ "parse ''\niSCSI URL must be of " ++ "the form: %s", ++ url, ISCSI_URL_SYNTAX); + return NULL; + } + *target++ = 0; + + if (*target == 0) { +- iscsi_set_error(iscsi, "Invalid URL %s\nCould not parse " +- "\n" +- "iSCSI URL must be of the form: %s", +- url, +- ISCSI_URL_SYNTAX); ++ iscsi_set_error(iscsi, "Invalid URL %s\nCould not " ++ "parse \niSCSI URL must be of the " ++ "form: %s", ++ url, ISCSI_URL_SYNTAX); + return NULL; + } + + lun = strchr(target, '/'); + if (lun == NULL) { +- iscsi_set_error(iscsi, "Invalid URL %s\nCould not parse \n" +- "iSCSI URL must be of the form: %s", +- url, +- ISCSI_URL_SYNTAX); ++ iscsi_set_error(iscsi, "Invalid URL %s\nCould not " ++ "parse \niSCSI URL must be of the form: " ++ "%s", ++ url, ISCSI_URL_SYNTAX); + return NULL; + } + *lun++ = 0; + + l = strtol(lun, &tmp, 10); + if (*lun == 0 || *tmp != 0) { +- iscsi_set_error(iscsi, "Invalid URL %s\nCould not parse \n" +- "iSCSI URL must be of the form: %s", +- url, +- ISCSI_URL_SYNTAX); ++ iscsi_set_error(iscsi, "Invalid URL %s\nCould not " ++ "parse \niSCSI URL must be of the form: " ++ "%s", ++ url, ISCSI_URL_SYNTAX); + return NULL; + } +- } +- else +- { ++ } else { + tmp=strchr(portal,'/'); +- if (tmp) *tmp=0; ++ if (tmp) { ++ *tmp=0; ++ } + } + +- if (iscsi != NULL) ++ if (iscsi != NULL) { + iscsi_url = iscsi_malloc(iscsi, sizeof(struct iscsi_url)); +- else ++ } else { + iscsi_url = malloc(sizeof(struct iscsi_url)); +- ++ } ++ + if (iscsi_url == NULL) { +- iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate iscsi_url structure"); ++ iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate " ++ "iscsi_url structure"); + return NULL; + } + memset(iscsi_url, 0, sizeof(struct iscsi_url)); +@@ -464,15 +506,17 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full) + strncpy(iscsi_url->portal,portal,MAX_STRING_SIZE); + + if (user != NULL && passwd != NULL) { +- strncpy(iscsi_url->user,user,MAX_STRING_SIZE); +- strncpy(iscsi_url->passwd,passwd,MAX_STRING_SIZE); ++ strncpy(iscsi_url->user, user, MAX_STRING_SIZE); ++ strncpy(iscsi_url->passwd, passwd, MAX_STRING_SIZE); + } + + if (full) { +- strncpy(iscsi_url->target,target,MAX_STRING_SIZE); ++ strncpy(iscsi_url->target, target, MAX_STRING_SIZE); + iscsi_url->lun = l; + } + ++ iscsi_decode_url_string(&iscsi_url->target[0]); ++ + return iscsi_url; + } + +diff --git a/lib/login.c b/lib/login.c +index 29fe4b3..0448ce2 100644 +--- a/lib/login.c ++++ b/lib/login.c +@@ -622,6 +622,7 @@ h2i(int h) + } + return h - '0'; + } ++ + static int + i2h(int i) + { +-- +1.8.1.4 + diff --git a/0008-SCSI-add-a-safe-function-to-read-a-byte-from-the-dat.patch b/0008-SCSI-add-a-safe-function-to-read-a-byte-from-the-dat.patch new file mode 100644 index 0000000..659224a --- /dev/null +++ b/0008-SCSI-add-a-safe-function-to-read-a-byte-from-the-dat.patch @@ -0,0 +1,537 @@ +From 704e0f6448f4a9ce0c4c9a030679ab97a37850e8 Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Sun, 12 May 2013 13:57:15 -0700 +Subject: [PATCH] SCSI: add a safe function to read a byte from the datain + buffer and use it throughout the unmarshalling code + +--- + lib/scsi-lowlevel.c | 302 ++++++++++++++++++++++++++++------------------------ + 1 file changed, 163 insertions(+), 139 deletions(-) + +diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c +index 85f7b1d..1f51f32 100644 +--- a/lib/scsi-lowlevel.c ++++ b/lib/scsi-lowlevel.c +@@ -274,6 +274,16 @@ task_get_uint16(struct scsi_task *task, int offset) + } + } + ++static inline uint8_t ++task_get_uint8(struct scsi_task *task, int offset) ++{ ++ if (offset <= task->datain.size - 1) { ++ return task->datain.data[offset]; ++ } else { ++ return 0; ++ } ++} ++ + inline void + scsi_set_uint64(unsigned char *c, uint64_t v) + { +@@ -501,49 +511,49 @@ scsi_readtoc_desc_unmarshall(struct scsi_task *task, struct scsi_readtoc_list *l + switch(scsi_readtoc_format(task)) { + case SCSI_READ_TOC: + list->desc[i].desc.toc.adr +- = task->datain.data[4+8*i+1] & 0xf0; ++ = task_get_uint8(task, 4 + 8 * i + 1) & 0xf0; + list->desc[i].desc.toc.control +- = task->datain.data[4+8*i+1] & 0x0f; ++ = task_get_uint8(task, 4 + 8 * i + 1) & 0x0f; + list->desc[i].desc.toc.track +- = task->datain.data[4+8*i+2]; ++ = task_get_uint8(task, 4 + 8 * i + 2); + list->desc[i].desc.toc.lba + = task_get_uint32(task, 4 + 8 * i + 4); + break; + case SCSI_READ_SESSION_INFO: + list->desc[i].desc.ses.adr +- = task->datain.data[4+8*i+1] & 0xf0; ++ = task_get_uint8(task, 4 + 8 * i + 1) & 0xf0; + list->desc[i].desc.ses.control +- = task->datain.data[4+8*i+1] & 0x0f; ++ = task_get_uint8(task, 4 + 8 * i + 1) & 0x0f; + list->desc[i].desc.ses.first_in_last +- = task->datain.data[4+8*i+2]; ++ = task_get_uint8(task, 4 + 8 * i + 2); + list->desc[i].desc.ses.lba + = task_get_uint32(task, 4 + 8 * i + 4); + break; + case SCSI_READ_FULL_TOC: + list->desc[i].desc.full.session +- = task->datain.data[4+11*i+0] & 0xf0; ++ = task_get_uint8(task, 4 + 11 * i + 0) & 0xf0; + list->desc[i].desc.full.adr +- = task->datain.data[4+11*i+1] & 0xf0; ++ = task_get_uint8(task, 4 + 11 * i + 1) & 0xf0; + list->desc[i].desc.full.control +- = task->datain.data[4+11*i+1] & 0x0f; ++ = task_get_uint8(task, 4 + 11 * i + 1) & 0x0f; + list->desc[i].desc.full.tno +- = task->datain.data[4+11*i+2]; ++ = task_get_uint8(task, 4 + 11 * i + 2); + list->desc[i].desc.full.point +- = task->datain.data[4+11*i+3]; ++ = task_get_uint8(task, 4 + 11 * i + 3); + list->desc[i].desc.full.min +- = task->datain.data[4+11*i+4]; ++ = task_get_uint8(task, 4 + 11 * i + 4); + list->desc[i].desc.full.sec +- = task->datain.data[4+11*i+5]; ++ = task_get_uint8(task, 4 + 11 * i + 5); + list->desc[i].desc.full.frame +- = task->datain.data[4+11*i+6]; ++ = task_get_uint8(task, 4 + 11 * i + 6); + list->desc[i].desc.full.zero +- = task->datain.data[4+11*i+7]; ++ = task_get_uint8(task, 4 + 11 * i + 7); + list->desc[i].desc.full.pmin +- = task->datain.data[4+11*i+8]; ++ = task_get_uint8(task, 4 + 11 * i + 8); + list->desc[i].desc.full.psec +- = task->datain.data[4+11*i+9]; ++ = task_get_uint8(task, 4 + 11 * i + 9); + list->desc[i].desc.full.pframe +- = task->datain.data[4+11*i+10]; ++ = task_get_uint8(task, 4 + 11 * i + 10); + break; + default: + break; +@@ -580,8 +590,8 @@ scsi_readtoc_datain_unmarshall(struct scsi_task *task) + } + + list->num = num_desc; +- list->first = task->datain.data[2]; +- list->last = task->datain.data[3]; ++ list->first = task_get_uint8(task, 2); ++ list->last = task_get_uint8(task, 3); + + for (i = 0; i < num_desc; i++) { + scsi_readtoc_desc_unmarshall(task, list, i); +@@ -655,12 +665,12 @@ scsi_serviceactionin_datain_unmarshall(struct scsi_task *task) + rc16->returned_lba = task_get_uint32(task, 0); + rc16->returned_lba = (rc16->returned_lba << 32) | task_get_uint32(task, 4); + rc16->block_length = task_get_uint32(task, 8); +- rc16->p_type = (task->datain.data[12] >> 1) & 0x07; +- rc16->prot_en = task->datain.data[12] & 0x01; +- rc16->p_i_exp = (task->datain.data[13] >> 4) & 0x0f; +- rc16->lbppbe = task->datain.data[13] & 0x0f; +- rc16->lbpme = !!(task->datain.data[14] & 0x80); +- rc16->lbprz = !!(task->datain.data[14] & 0x40); ++ rc16->p_type = (task_get_uint8(task, 12) >> 1) & 0x07; ++ rc16->prot_en = task_get_uint8(task, 12) & 0x01; ++ rc16->p_i_exp = (task_get_uint8(task, 13) >> 4) & 0x0f; ++ rc16->lbppbe = task_get_uint8(task, 13) & 0x0f; ++ rc16->lbpme = !!(task_get_uint8(task, 14) & 0x80); ++ rc16->lbprz = !!(task_get_uint8(task, 14) & 0x40); + rc16->lalba = task_get_uint16(task, 14) & 0x3fff; + return rc16; + } +@@ -694,7 +704,7 @@ scsi_serviceactionin_datain_unmarshall(struct scsi_task *task) + + gls->descriptors[i].num_blocks = task_get_uint32(task, 8 + i * sizeof(struct scsi_lba_status_descriptor) + 8); + +- gls->descriptors[i].provisioning = task->datain.data[8 + i * sizeof(struct scsi_lba_status_descriptor) + 12] & 0x0f; ++ gls->descriptors[i].provisioning = task_get_uint8(task, 8 + i * sizeof(struct scsi_lba_status_descriptor) + 12) & 0x0f; + } + + return gls; +@@ -771,7 +781,7 @@ scsi_persistentreservein_datain_unmarshall(struct scsi_task *task) + rr->reserved = 1; + rr->reservation_key = + task_get_uint64(task, 8); +- rr->pr_type = task->datain.data[21] & 0xff; ++ rr->pr_type = task_get_uint8(task, 21) & 0xff; + } + + return rr; +@@ -782,12 +792,12 @@ scsi_persistentreservein_datain_unmarshall(struct scsi_task *task) + return NULL; + } + rc->length = task_get_uint16(task, 0); +- rc->crh = !!(task->datain.data[2] & 0x10); +- rc->sip_c = !!(task->datain.data[2] & 0x08); +- rc->atp_c = !!(task->datain.data[2] & 0x04); +- rc->ptpl_c = !!(task->datain.data[2] & 0x01); +- rc->tmv = !!(task->datain.data[3] & 0x80); +- rc->allow_commands = task->datain.data[3] >> 4; ++ rc->crh = !!(task_get_uint8(task, 2) & 0x10); ++ rc->sip_c = !!(task_get_uint8(task, 2) & 0x08); ++ rc->atp_c = !!(task_get_uint8(task, 2) & 0x04); ++ rc->ptpl_c = !!(task_get_uint8(task, 2) & 0x01); ++ rc->tmv = !!(task_get_uint8(task, 3) & 0x80); ++ rc->allow_commands = task_get_uint8(task, 3) >> 4; + rc->persistent_reservation_type_mask = task_get_uint16(task, 4); + + return rc; +@@ -1003,14 +1013,14 @@ static int + scsi_inquiry_datain_getfullsize(struct scsi_task *task) + { + if (scsi_inquiry_evpd_set(task) == 0) { +- return task->datain.data[4] + 5; ++ return task_get_uint8(task, 4) + 5; + } + + switch (scsi_inquiry_page_code(task)) { + case SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES: + case SCSI_INQUIRY_PAGECODE_BLOCK_DEVICE_CHARACTERISTICS: + case SCSI_INQUIRY_PAGECODE_UNIT_SERIAL_NUMBER: +- return task->datain.data[3] + 4; ++ return task_get_uint8(task, 3) + 4; + case SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION: + case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS: + case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING: +@@ -1030,28 +1040,28 @@ scsi_inquiry_unmarshall_standard(struct scsi_task *task) + return NULL; + } + +- inq->qualifier = (task->datain.data[0]>>5)&0x07; +- inq->device_type = task->datain.data[0]&0x1f; +- inq->rmb = !!(task->datain.data[1]&0x80); +- inq->version = task->datain.data[2]; +- inq->normaca = !!(task->datain.data[3]&0x20); +- inq->hisup = !!(task->datain.data[3]&0x10); +- inq->response_data_format = task->datain.data[3]&0x0f; ++ inq->qualifier = (task_get_uint8(task, 0) >> 5) & 0x07; ++ inq->device_type = task_get_uint8(task, 0) & 0x1f; ++ inq->rmb = !!(task_get_uint8(task, 1) & 0x80); ++ inq->version = task_get_uint8(task, 2); ++ inq->normaca = !!(task_get_uint8(task, 3) & 0x20); ++ inq->hisup = !!(task_get_uint8(task, 3) & 0x10); ++ inq->response_data_format = task_get_uint8(task, 3) & 0x0f; + +- inq->additional_length = task->datain.data[4]; ++ inq->additional_length = task_get_uint8(task, 4); + +- inq->sccs = !!(task->datain.data[5]&0x80); +- inq->acc = !!(task->datain.data[5]&0x40); +- inq->tpgs = (task->datain.data[5]>>4)&0x03; +- inq->threepc = !!(task->datain.data[5]&0x08); +- inq->protect = !!(task->datain.data[5]&0x01); ++ inq->sccs = !!(task_get_uint8(task, 5) & 0x80); ++ inq->acc = !!(task_get_uint8(task, 5) & 0x40); ++ inq->tpgs = (task_get_uint8(task, 5) >> 4) & 0x03; ++ inq->threepc = !!(task_get_uint8(task, 5) & 0x08); ++ inq->protect = !!(task_get_uint8(task, 5) & 0x01); + +- inq->encserv = !!(task->datain.data[6]&0x40); +- inq->multip = !!(task->datain.data[6]&0x10); +- inq->addr16 = !!(task->datain.data[6]&0x01); +- inq->wbus16 = !!(task->datain.data[7]&0x20); +- inq->sync = !!(task->datain.data[7]&0x10); +- inq->cmdque = !!(task->datain.data[7]&0x02); ++ inq->encserv = !!(task_get_uint8(task, 6) & 0x40); ++ inq->multip = !!(task_get_uint8(task, 6) & 0x10); ++ inq->addr16 = !!(task_get_uint8(task, 6) & 0x01); ++ inq->wbus16 = !!(task_get_uint8(task, 7) & 0x20); ++ inq->sync = !!(task_get_uint8(task, 7) & 0x10); ++ inq->cmdque = !!(task_get_uint8(task, 7) & 0x02); + + memcpy(&inq->vendor_identification[0], + &task->datain.data[8], 8); +@@ -1060,9 +1070,9 @@ scsi_inquiry_unmarshall_standard(struct scsi_task *task) + memcpy(&inq->product_revision_level[0], + &task->datain.data[32], 4); + +- inq->clocking = (task->datain.data[56]>>2)&0x03; +- inq->qas = !!(task->datain.data[56]&0x02); +- inq->ius = !!(task->datain.data[56]&0x01); ++ inq->clocking = (task_get_uint8(task, 56) >> 2) & 0x03; ++ inq->qas = !!(task_get_uint8(task, 56) & 0x02); ++ inq->ius = !!(task_get_uint8(task, 56) & 0x01); + + return inq; + } +@@ -1079,11 +1089,11 @@ scsi_inquiry_unmarshall_supported_pages(struct scsi_task *task) + if (inq == NULL) { + return NULL; + } +- inq->qualifier = (task->datain.data[0]>>5)&0x07; +- inq->device_type = task->datain.data[0]&0x1f; +- inq->pagecode = task->datain.data[1]; ++ inq->qualifier = (task_get_uint8(task, 0) >> 5) & 0x07; ++ inq->device_type = task_get_uint8(task, 0) & 0x1f; ++ inq->pagecode = task_get_uint8(task, 1); + +- inq->num_pages = task->datain.data[3]; ++ inq->num_pages = task_get_uint8(task, 3); + inq->pages = scsi_malloc(task, inq->num_pages); + if (inq->pages == NULL) { + free (inq); +@@ -1101,17 +1111,17 @@ scsi_inquiry_unmarshall_unit_serial_number(struct scsi_task* task) + if (inq == NULL) { + return NULL; + } +- inq->qualifier = (task->datain.data[0]>>5)&0x07; +- inq->device_type = task->datain.data[0]&0x1f; +- inq->pagecode = task->datain.data[1]; ++ inq->qualifier = (task_get_uint8(task, 0) >> 5) & 0x07; ++ inq->device_type = task_get_uint8(task, 0) & 0x1f; ++ inq->pagecode = task_get_uint8(task, 1); + +- inq->usn = scsi_malloc(task, task->datain.data[3]+1); ++ inq->usn = scsi_malloc(task, task_get_uint8(task, 3) + 1); + if (inq->usn == NULL) { + free(inq); + return NULL; + } +- memcpy(inq->usn, &task->datain.data[4], task->datain.data[3]); +- inq->usn[task->datain.data[3]] = 0; ++ memcpy(inq->usn, &task->datain.data[4], task_get_uint8(task, 3)); ++ inq->usn[task_get_uint8(task, 3)] = 0; + return inq; + } + +@@ -1119,16 +1129,16 @@ static struct scsi_inquiry_device_identification * + scsi_inquiry_unmarshall_device_identification(struct scsi_task *task) + { + struct scsi_inquiry_device_identification *inq = scsi_malloc(task, +- sizeof(*inq)); ++ sizeof(*inq)); + int remaining = task_get_uint16(task, 2); + unsigned char *dptr; + + if (inq == NULL) { + return NULL; + } +- inq->qualifier = (task->datain.data[0]>>5)&0x07; +- inq->device_type = task->datain.data[0]&0x1f; +- inq->pagecode = task->datain.data[1]; ++ inq->qualifier = (task_get_uint8(task, 0) >> 5) & 0x07; ++ inq->device_type = task_get_uint8(task, 0) & 0x1f; ++ inq->pagecode = task_get_uint8(task, 1); + + dptr = &task->datain.data[4]; + while (remaining > 0) { +@@ -1183,12 +1193,12 @@ scsi_inquiry_unmarshall_block_limits(struct scsi_task *task) + if (inq == NULL) { + return NULL; + } +- inq->qualifier = (task->datain.data[0]>>5)&0x07; +- inq->device_type = task->datain.data[0]&0x1f; +- inq->pagecode = task->datain.data[1]; ++ inq->qualifier = (task_get_uint8(task, 0) >> 5) & 0x07; ++ inq->device_type = task_get_uint8(task, 0) & 0x1f; ++ inq->pagecode = task_get_uint8(task, 1); + +- inq->wsnz = task->datain.data[4] & 0x01; +- inq->max_cmp = task->datain.data[5]; ++ inq->wsnz = task_get_uint8(task, 4) & 0x01; ++ inq->max_cmp = task_get_uint8(task, 5); + inq->opt_gran = task_get_uint16(task, 6); + inq->max_xfer_len = task_get_uint32(task, 8); + inq->opt_xfer_len = task_get_uint32(task, 12); +@@ -1196,7 +1206,7 @@ scsi_inquiry_unmarshall_block_limits(struct scsi_task *task) + inq->max_unmap = task_get_uint32(task, 20); + inq->max_unmap_bdc = task_get_uint32(task, 24); + inq->opt_unmap_gran = task_get_uint32(task, 28); +- inq->ugavalid = !!(task->datain.data[32]&0x80); ++ inq->ugavalid = !!(task_get_uint8(task, 32)&0x80); + inq->unmap_gran_align = task_get_uint32(task, 32) & 0x7fffffff; + inq->max_ws_len = task_get_uint32(task, 36); + inq->max_ws_len = (inq->max_ws_len << 32) +@@ -1213,9 +1223,9 @@ scsi_inquiry_unmarshall_block_device_characteristics(struct scsi_task *task) + if (inq == NULL) { + return NULL; + } +- inq->qualifier = (task->datain.data[0]>>5)&0x07; +- inq->device_type = task->datain.data[0]&0x1f; +- inq->pagecode = task->datain.data[1]; ++ inq->qualifier = (task_get_uint8(task, 0) >> 5) & 0x07; ++ inq->device_type = task_get_uint8(task, 0) & 0x1f; ++ inq->pagecode = task_get_uint8(task, 1); + + inq->medium_rotation_rate = task_get_uint16(task, 4); + return inq; +@@ -1229,18 +1239,18 @@ scsi_inquiry_unmarshall_logical_block_provisioning(struct scsi_task *task) + if (inq == NULL) { + return NULL; + } +- inq->qualifier = (task->datain.data[0]>>5)&0x07; +- inq->device_type = task->datain.data[0]&0x1f; +- inq->pagecode = task->datain.data[1]; ++ inq->qualifier = (task_get_uint8(task, 0) >> 5) & 0x07; ++ inq->device_type = task_get_uint8(task, 0) & 0x1f; ++ inq->pagecode = task_get_uint8(task, 1); + +- inq->threshold_exponent = task->datain.data[4]; +- inq->lbpu = !!(task->datain.data[5] & 0x80); +- inq->lbpws = !!(task->datain.data[5] & 0x40); +- inq->lbpws10 = !!(task->datain.data[5] & 0x20); +- inq->lbprz = !!(task->datain.data[5] & 0x04); +- inq->anc_sup = !!(task->datain.data[5] & 0x02); +- inq->dp = !!(task->datain.data[5] & 0x01); +- inq->provisioning_type = task->datain.data[6] & 0x07; ++ inq->threshold_exponent = task_get_uint8(task, 4); ++ inq->lbpu = !!(task_get_uint8(task, 5) & 0x80); ++ inq->lbpws = !!(task_get_uint8(task, 5) & 0x40); ++ inq->lbpws10 = !!(task_get_uint8(task, 5) & 0x20); ++ inq->lbprz = !!(task_get_uint8(task, 5) & 0x04); ++ inq->anc_sup = !!(task_get_uint8(task, 5) & 0x02); ++ inq->dp = !!(task_get_uint8(task, 5) & 0x01); ++ inq->provisioning_type = task_get_uint8(task, 6) & 0x07; + + return inq; + } +@@ -2062,7 +2072,7 @@ scsi_modesense6_datain_getfullsize(struct scsi_task *task) + { + int len; + +- len = task->datain.data[0] + 1; ++ len = task_get_uint8(task, 0) + 1; + + return len; + } +@@ -2070,59 +2080,73 @@ scsi_modesense6_datain_getfullsize(struct scsi_task *task) + static void + scsi_parse_mode_caching(struct scsi_task *task, int pos, struct scsi_mode_page *mp) + { +- mp->caching.ic = task->datain.data[pos] & 0x80; +- mp->caching.abpf = task->datain.data[pos] & 0x40; +- mp->caching.cap = task->datain.data[pos] & 0x20; +- mp->caching.disc = task->datain.data[pos] & 0x10; +- mp->caching.size = task->datain.data[pos] & 0x08; +- mp->caching.wce = task->datain.data[pos] & 0x04; +- mp->caching.mf = task->datain.data[pos] & 0x02; +- mp->caching.rcd = task->datain.data[pos] & 0x01; +- +- mp->caching.demand_read_retention_priority = (task->datain.data[pos+1] >> 4) & 0x0f; +- mp->caching.write_retention_priority = task->datain.data[pos+1] & 0x0f; +- +- mp->caching.disable_prefetch_transfer_length = task_get_uint16(task, pos + 2); ++ mp->caching.ic = task_get_uint8(task, pos) & 0x80; ++ mp->caching.abpf = task_get_uint8(task, pos) & 0x40; ++ mp->caching.cap = task_get_uint8(task, pos) & 0x20; ++ mp->caching.disc = task_get_uint8(task, pos) & 0x10; ++ mp->caching.size = task_get_uint8(task, pos) & 0x08; ++ mp->caching.wce = task_get_uint8(task, pos) & 0x04; ++ mp->caching.mf = task_get_uint8(task, pos) & 0x02; ++ mp->caching.rcd = task_get_uint8(task, pos) & 0x01; ++ ++ mp->caching.demand_read_retention_priority = ++ (task_get_uint8(task, pos + 1) >> 4) & 0x0f; ++ mp->caching.write_retention_priority = ++ task_get_uint8(task, pos + 1) & 0x0f; ++ ++ mp->caching.disable_prefetch_transfer_length = ++ task_get_uint16(task, pos + 2); + mp->caching.minimum_prefetch = task_get_uint16(task, pos + 4); + mp->caching.maximum_prefetch = task_get_uint16(task, pos + 6); + mp->caching.maximum_prefetch_ceiling = task_get_uint16(task, pos + 8); + +- mp->caching.fsw = task->datain.data[pos+10] & 0x80; +- mp->caching.lbcss = task->datain.data[pos+10] & 0x40; +- mp->caching.dra = task->datain.data[pos+10] & 0x20; +- mp->caching.nv_dis = task->datain.data[pos+10] & 0x01; ++ mp->caching.fsw = task_get_uint8(task, pos + 10) & 0x80; ++ mp->caching.lbcss = task_get_uint8(task, pos + 10) & 0x40; ++ mp->caching.dra = task_get_uint8(task, pos + 10) & 0x20; ++ mp->caching.nv_dis = task_get_uint8(task, pos + 10) & 0x01; + +- mp->caching.number_of_cache_segments = task->datain.data[pos+11]; ++ mp->caching.number_of_cache_segments = task_get_uint8(task, pos + 11); + mp->caching.cache_segment_size = task_get_uint16(task, pos + 12); + } + + static void + scsi_parse_mode_disconnect_reconnect(struct scsi_task *task, int pos, struct scsi_mode_page *mp) + { +- mp->disconnect_reconnect.buffer_full_ratio = task->datain.data[pos]; +- mp->disconnect_reconnect.buffer_empty_ratio = task->datain.data[pos+1]; +- mp->disconnect_reconnect.bus_inactivity_limit = task_get_uint16(task, pos + 2); +- mp->disconnect_reconnect.disconnect_time_limit = task_get_uint16(task, pos + 4); +- mp->disconnect_reconnect.connect_time_limit = task_get_uint16(task, pos + 6); +- mp->disconnect_reconnect.maximum_burst_size = task_get_uint16(task, pos + 8); +- mp->disconnect_reconnect.emdp = task->datain.data[pos+10] & 0x80; +- mp->disconnect_reconnect.fair_arbitration = (task->datain.data[pos+10]>>4) & 0x0f; +- mp->disconnect_reconnect.dimm = task->datain.data[pos+10] & 0x08; +- mp->disconnect_reconnect.dtdc = task->datain.data[pos+10] & 0x07; +- mp->disconnect_reconnect.first_burst_size = task_get_uint16(task, pos + 12); ++ mp->disconnect_reconnect.buffer_full_ratio = ++ task_get_uint8(task, pos); ++ mp->disconnect_reconnect.buffer_empty_ratio = ++ task_get_uint8(task, pos + 1); ++ mp->disconnect_reconnect.bus_inactivity_limit = ++ task_get_uint16(task, pos + 2); ++ mp->disconnect_reconnect.disconnect_time_limit = ++ task_get_uint16(task, pos + 4); ++ mp->disconnect_reconnect.connect_time_limit = ++ task_get_uint16(task, pos + 6); ++ mp->disconnect_reconnect.maximum_burst_size = ++ task_get_uint16(task, pos + 8); ++ mp->disconnect_reconnect.emdp = ++ task_get_uint8(task, pos + 10) & 0x80; ++ mp->disconnect_reconnect.fair_arbitration = ++ (task_get_uint8(task, pos + 10) >> 4) & 0x0f; ++ mp->disconnect_reconnect.dimm = ++ task_get_uint8(task, pos + 10) & 0x08; ++ mp->disconnect_reconnect.dtdc = ++ task_get_uint8(task, pos + 10) & 0x07; ++ mp->disconnect_reconnect.first_burst_size = ++ task_get_uint16(task, pos + 12); + } + + static void + scsi_parse_mode_informational_exceptions_control(struct scsi_task *task, int pos, struct scsi_mode_page *mp) + { +- mp->iec.perf = task->datain.data[pos] & 0x80; +- mp->iec.ebf = task->datain.data[pos] & 0x20; +- mp->iec.ewasc = task->datain.data[pos] & 0x10; +- mp->iec.dexcpt = task->datain.data[pos] & 0x08; +- mp->iec.test = task->datain.data[pos] & 0x04; +- mp->iec.ebackerr = task->datain.data[pos] & 0x02; +- mp->iec.logerr = task->datain.data[pos] & 0x01; +- mp->iec.mrie = task->datain.data[pos+1] & 0x0f; ++ mp->iec.perf = task_get_uint8(task, pos) & 0x80; ++ mp->iec.ebf = task_get_uint8(task, pos) & 0x20; ++ mp->iec.ewasc = task_get_uint8(task, pos) & 0x10; ++ mp->iec.dexcpt = task_get_uint8(task, pos) & 0x08; ++ mp->iec.test = task_get_uint8(task, pos) & 0x04; ++ mp->iec.ebackerr = task_get_uint8(task, pos) & 0x02; ++ mp->iec.logerr = task_get_uint8(task, pos) & 0x01; ++ mp->iec.mrie = task_get_uint8(task, pos + 1) & 0x0f; + mp->iec.interval_timer = task_get_uint32(task, pos + 2); + mp->iec.report_count = task_get_uint32(task, pos + 6); + } +@@ -2146,10 +2170,10 @@ scsi_modesense_datain_unmarshall(struct scsi_task *task) + return NULL; + } + +- ms->mode_data_length = task->datain.data[0]; +- ms->medium_type = task->datain.data[1]; +- ms->device_specific_parameter = task->datain.data[2]; +- ms->block_descriptor_length = task->datain.data[3]; ++ ms->mode_data_length = task_get_uint8(task, 0); ++ ms->medium_type = task_get_uint8(task, 1); ++ ms->device_specific_parameter = task_get_uint8(task, 2); ++ ms->block_descriptor_length = task_get_uint8(task, 3); + ms->pages = NULL; + + if (ms->mode_data_length + 1 > task->datain.size) { +@@ -2164,18 +2188,18 @@ scsi_modesense_datain_unmarshall(struct scsi_task *task) + if (mp == NULL) { + return ms; + } +- mp->ps = task->datain.data[pos] & 0x80; +- mp->spf = task->datain.data[pos] & 0x40; +- mp->page_code = task->datain.data[pos] & 0x3f; ++ mp->ps = task_get_uint8(task, pos) & 0x80; ++ mp->spf = task_get_uint8(task, pos) & 0x40; ++ mp->page_code = task_get_uint8(task, pos) & 0x3f; + pos++; + + if (mp->spf) { +- mp->subpage_code = task->datain.data[pos++]; ++ mp->subpage_code = task_get_uint8(task, pos++); + mp->len = task_get_uint16(task, pos); + pos += 2; + } else { + mp->subpage_code = 0; +- mp->len = task->datain.data[pos++]; ++ mp->len = task_get_uint8(task, pos++); + } + + switch (mp->page_code) { +-- +1.8.1.4 + diff --git a/0009-scsi-lowlevel-do-not-use-unsafe-pointer-casts.patch b/0009-scsi-lowlevel-do-not-use-unsafe-pointer-casts.patch new file mode 100644 index 0000000..2acc93e --- /dev/null +++ b/0009-scsi-lowlevel-do-not-use-unsafe-pointer-casts.patch @@ -0,0 +1,113 @@ +From 0a7c084603663a1e63b01bd677429a20bc7d4c62 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Mon, 1 Jul 2013 15:57:44 +0200 +Subject: [PATCH] scsi-lowlevel: do not use unsafe pointer casts + +Casting unsigned char * pointers to uint32_t * may cause wrong +results if the pointers are not correctly aligned. Instead, +build up the big-endian values from each byte with multiple +dereferences of the original pointer. + +Signed-off-by: Paolo Bonzini +--- + lib/scsi-lowlevel.c | 36 +++++++++++++++++++++--------------- + 1 file changed, 21 insertions(+), 15 deletions(-) + +diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c +index ad94eef..37f41d5 100644 +--- a/lib/scsi-lowlevel.c ++++ b/lib/scsi-lowlevel.c +@@ -212,10 +212,10 @@ scsi_get_uint64(const unsigned char *c) + { + uint64_t val; + +- val = ntohl(*(uint32_t *)c); ++ val = scsi_get_uint32(c); + val <<= 32; + c += 4; +- val |= ntohl(*(uint32_t *)c); ++ val |= scsi_get_uint32(c); + + return val; + } +@@ -223,13 +223,21 @@ scsi_get_uint64(const unsigned char *c) + inline uint32_t + scsi_get_uint32(const unsigned char *c) + { +- return ntohl(*(uint32_t *)c); ++ uint32_t val; ++ val = c[0]; ++ val = (val << 8) | c[1]; ++ val = (val << 8) | c[2]; ++ val = (val << 8) | c[3]; ++ return val; + } + + inline uint16_t + scsi_get_uint16(const unsigned char *c) + { +- return ntohs(*(uint16_t *)c); ++ uint16_t val; ++ val = c[0]; ++ val = (val << 8) | c[1]; ++ return val; + } + + static inline uint64_t +@@ -237,14 +245,8 @@ task_get_uint64(struct scsi_task *task, int offset) + { + if (offset <= task->datain.size - 8) { + const unsigned char *c = &task->datain.data[offset]; +- uint64_t val; + +- val = ntohl(*(uint32_t *)c); +- val <<= 32; +- c += 4; +- val |= ntohl(*(uint32_t *)c); +- +- return val; ++ return scsi_get_uint64(c); + } else { + return 0; + } +@@ -256,7 +258,7 @@ task_get_uint32(struct scsi_task *task, int offset) + if (offset <= task->datain.size - 4) { + const unsigned char *c = &task->datain.data[offset]; + +- return ntohl(*(uint32_t *)c); ++ return scsi_get_uint32(c); + } else { + return 0; + } +@@ -268,7 +270,7 @@ task_get_uint16(struct scsi_task *task, int offset) + if (offset <= task->datain.size - 2) { + const unsigned char *c = &task->datain.data[offset]; + +- return ntohs(*(uint16_t *)c); ++ return scsi_get_uint16(c); + } else { + return 0; + } +@@ -300,13 +302,17 @@ scsi_set_uint64(unsigned char *c, uint64_t v) + inline void + scsi_set_uint32(unsigned char *c, uint32_t val) + { +- *(uint32_t *)c = htonl(val); ++ c[0] = val >> 24; ++ c[1] = val >> 16; ++ c[2] = val >> 8; ++ c[3] = val; + } + + inline void + scsi_set_uint16(unsigned char *c, uint16_t val) + { +- *(uint16_t *)c = htons(val); ++ c[0] = val >> 8; ++ c[1] = val; + } + + /* +-- +1.8.1.4 + diff --git a/0010-Add-a-cast-to-ssize_t.patch b/0010-Add-a-cast-to-ssize_t.patch new file mode 100644 index 0000000..7b76270 --- /dev/null +++ b/0010-Add-a-cast-to-ssize_t.patch @@ -0,0 +1,25 @@ +From b555bbebdd1c92b025a44955a988cc2eed646c2b Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Sat, 29 Jun 2013 11:12:41 -0700 +Subject: [PATCH] Add a cast to ssize_t + +--- + lib/socket.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/socket.c b/lib/socket.c +index a855f92..6fc3b41 100644 +--- a/lib/socket.c ++++ b/lib/socket.c +@@ -517,7 +517,7 @@ iscsi_read_from_socket(struct iscsi_context *iscsi) + } + + data_size = iscsi_get_pdu_data_size(&in->hdr[0]); +- if (data_size < 0 || data_size > iscsi->initiator_max_recv_data_segment_length) { ++ if (data_size < 0 || data_size > (ssize_t)iscsi->initiator_max_recv_data_segment_length) { + iscsi_set_error(iscsi, "Invalid data size received from target (%d)", (int)data_size); + return -1; + } +-- +1.8.1.4 + diff --git a/0011-Use-PRIu64-for-format-string.patch b/0011-Use-PRIu64-for-format-string.patch new file mode 100644 index 0000000..1728940 --- /dev/null +++ b/0011-Use-PRIu64-for-format-string.patch @@ -0,0 +1,26 @@ +From dcb223badcf36e7dd6b826fa41c3ee24fe0e6a4b Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Sat, 29 Jun 2013 12:23:55 -0700 +Subject: [PATCH] Use PRIu64 for format string + +--- + test-tool/iscsi-support.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/test-tool/iscsi-support.c b/test-tool/iscsi-support.c +index e61b97c..0f3e2e8 100644 +--- a/test-tool/iscsi-support.c ++++ b/test-tool/iscsi-support.c +@@ -917,7 +917,8 @@ prin_verify_reserved_as(struct iscsi_context *iscsi, int lun, + } + if (rr->reservation_key != key) { + logging(LOG_NORMAL, +- "[FAILED] Failed to find reservation key 0x%llx: found 0x%lx.", ++ "[FAILED] Failed to find reservation key 0x%llx: found 0x%" ++ PRIu64 ".", + key, rr->reservation_key); + ret = -1; + goto dun; +-- +1.8.1.4 + diff --git a/0012-bump-soname.patch b/0012-bump-soname.patch new file mode 100644 index 0000000..3c11ca9 --- /dev/null +++ b/0012-bump-soname.patch @@ -0,0 +1,15 @@ +ABI was not preserved between 1.7.0 and 1.9.0. + +diff --git a/Makefile.am b/Makefile.am +index 50dfe11..4ccb52c 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -37,7 +37,7 @@ if !HAVE_LIBGCRYPT + lib_libiscsi_la_SOURCES += lib/md5.c + endif + +-SONAME=$(firstword $(subst ., ,$(VERSION))) ++SONAME=2 + SOREL=$(shell printf "%d%02d%02d" $(subst ., ,$(VERSION))) + lib_libiscsi_la_LDFLAGS = \ + -version-info $(SONAME):$(SOREL):0 -bindir $(bindir) -no-undefined \ diff --git a/0013-disable-ld_iscsi.patch b/0013-disable-ld_iscsi.patch new file mode 100644 index 0000000..880a3ad --- /dev/null +++ b/0013-disable-ld_iscsi.patch @@ -0,0 +1,13 @@ +diff --git a/Makefile.am b/Makefile.am +index 50dfe11..1a76d12 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -320,7 +320,7 @@ bin/ld_iscsi.o: src/bin_ld_iscsi-ld_iscsi.o lib/libiscsi_convenience.la + $(LIBTOOL) --mode=link $(CC) -o $@ $^ + + # 3) Manually create the .so file. +-bin_SCRIPTS = bin/ld_iscsi.so ++#bin_SCRIPTS = bin/ld_iscsi.so + bin/ld_iscsi.so: bin/ld_iscsi.o + $(CC) -shared -o bin/ld_iscsi.so bin/ld_iscsi.o -ldl + endif diff --git a/0014-fix-another-aliasing-problem.patch b/0014-fix-another-aliasing-problem.patch new file mode 100644 index 0000000..b95f68b --- /dev/null +++ b/0014-fix-another-aliasing-problem.patch @@ -0,0 +1,18 @@ +diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c +index 0989f0f..1bb03af 100644 +--- a/lib/scsi-lowlevel.c ++++ b/lib/scsi-lowlevel.c +@@ -300,11 +300,11 @@ scsi_set_uint64(unsigned char *c, uint64_t v) + uint32_t val; + + val = (v >> 32) & 0xffffffff; +- *(uint32_t *)c = htonl(val); ++ scsi_set_uint32(c, val); + + c += 4; + val = v & 0xffffffff; +- *(uint32_t *)c = htonl(val); ++ scsi_set_uint32(c, val); + } + + inline void diff --git a/0015-fix-arm-aliasing-problem.patch b/0015-fix-arm-aliasing-problem.patch new file mode 100644 index 0000000..523a0e4 --- /dev/null +++ b/0015-fix-arm-aliasing-problem.patch @@ -0,0 +1,212 @@ +Fixes these errors in ARM compilation: + +lib/scsi-lowlevel.c: In function 'scsi_maintenancein_datain_unmarshall': +lib/scsi-lowlevel.c:862:12: error: cast increases required alignment of target type [-Werror=cast-align] + datain = (struct scsi_command_descriptor *)&task->datain.data[4]; + ^ +lib/scsi-lowlevel.c:876:11: error: cast increases required alignment of target type [-Werror=cast-align] + desc = (struct scsi_command_descriptor *)((char *)desc + desc_size); + ^ +lib/scsi-lowlevel.c:877:13: error: cast increases required alignment of target type [-Werror=cast-align] + datain = (struct scsi_command_descriptor *)((char *)datain + desc_size); + ^ + +Based on this patch: + +From 709410b1d7f3d0b2b4e342cc46de2b45453d6c5c Mon Sep 17 00:00:00 2001 +From: Ronnie Sahlberg +Date: Sat, 18 May 2013 13:56:02 -0700 +Subject: [PATCH] TESTS: Add some REPORT SUPPORTED OPCODES tests + +Add a simple test that it works or is not implemented. + +Add a RCTD test to verify that with this flag clear we get command descriptors without CTDP set and with it set we get command descriptors with CTDP set and a timeout descriptor +--- + include/scsi-lowlevel.h | 60 +++++++------- + lib/scsi-lowlevel.c | 77 +++++++++--------- + +diff --git a/include/scsi-lowlevel.h b/include/scsi-lowlevel.h +index 5693129..acdc936 100644 +--- a/include/scsi-lowlevel.h ++++ b/include/scsi-lowlevel.h +@@ -739,24 +739,24 @@ struct scsi_get_lba_status { + + struct scsi_op_timeout_descriptor { + uint16_t descriptor_length; +- uint8_t reserved; + uint8_t command_specific; + uint32_t nominal_processing_timeout; + uint32_t recommended_timeout; + + }; + struct scsi_command_descriptor { +- uint8_t op_code; +- uint8_t reserved1; +- uint16_t service_action; +- uint8_t reserved2; +- uint8_t reserved3; +- uint16_t cdb_length; +- struct scsi_op_timeout_descriptor to[0]; ++ uint8_t opcode; ++ uint16_t sa; ++ uint8_t ctdp; ++ uint8_t servactv; ++ uint16_t cdb_len; ++ ++ /* only present if CTDP==1 */ ++ struct scsi_op_timeout_descriptor to; + }; + + struct scsi_report_supported_op_codes { +- uint32_t num_descriptors; ++ int num_descriptors; + struct scsi_command_descriptor descriptors[0]; + }; + +diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c +index 3c02ace..c091539 100644 +--- a/lib/scsi-lowlevel.c ++++ b/lib/scsi-lowlevel.c +@@ -806,12 +806,6 @@ scsi_persistentreservein_datain_unmarshall(struct scsi_task *task) + } + } + +-static inline int +-scsi_maintenancein_return_timeouts(const struct scsi_task *task) +-{ +- return task->cdb[2] & 0x80; +-} +- + static inline uint8_t + scsi_maintenancein_sa(const struct scsi_task *task) + { +@@ -841,9 +835,7 @@ static void * + scsi_maintenancein_datain_unmarshall(struct scsi_task *task) + { + struct scsi_report_supported_op_codes *rsoc; +- struct scsi_command_descriptor *desc, *datain; +- uint32_t len, i; +- int return_timeouts, desc_size; ++ int len, i; + + switch (scsi_maintenancein_sa(task)) { + case SCSI_REPORT_SUPPORTED_OP_CODES: +@@ -852,37 +844,52 @@ scsi_maintenancein_datain_unmarshall(struct scsi_task *task) + } + + len = task_get_uint32(task, 0); +- rsoc = scsi_malloc(task, sizeof(struct scsi_report_supported_op_codes) + len); ++ /* len / 8 is not always correct since if CTDP==1 then the ++ * descriptor is 20 bytes in size intead of 8. ++ * It doesnt matter here though since it just means we would ++ * allocate more descriptors at the end of the structure than ++ * we strictly need. This avoids having to traverse the ++ * datain buffer twice. ++ */ ++ rsoc = scsi_malloc(task, ++ offsetof(struct scsi_report_supported_op_codes, ++ descriptors) + ++ len / 8 * sizeof(struct scsi_command_descriptor)); + if (rsoc == NULL) { + return NULL; + } +- /* Does the descriptor include command timeout info? */ +- return_timeouts = scsi_maintenancein_return_timeouts(task); + +- /* Size of descriptor depends on whether timeout included. */ +- desc_size = sizeof (struct scsi_command_descriptor); +- if (return_timeouts) { +- desc_size += sizeof (struct scsi_op_timeout_descriptor); +- } +- rsoc->num_descriptors = len / desc_size; +- +- desc = &rsoc->descriptors[0]; +- datain = (struct scsi_command_descriptor *)&task->datain.data[4]; +- +- for (i=0; i < rsoc->num_descriptors; i++) { +- desc->op_code = datain->op_code; +- desc->service_action = ntohs(datain->service_action); +- desc->cdb_length = ntohs(datain->cdb_length); +- if (return_timeouts) { +- desc->to[0].descriptor_length = ntohs(datain->to[0].descriptor_length); +- desc->to[0].command_specific = datain->to[0].command_specific; +- desc->to[0].nominal_processing_timeout +- = ntohl(datain->to[0].nominal_processing_timeout); +- desc->to[0].recommended_timeout +- = ntohl(datain->to[0].recommended_timeout); ++ rsoc->num_descriptors = 0; ++ i = 4; ++ while (len >= 8) { ++ struct scsi_command_descriptor *desc; ++ ++ desc = &rsoc->descriptors[rsoc->num_descriptors++]; ++ desc->opcode = task_get_uint8(task, i); ++ desc->sa = task_get_uint16(task, i + 2); ++ desc->ctdp = !!(task_get_uint8(task, i + 5) & 0x02); ++ desc->servactv = !!(task_get_uint8(task, i + 5) & 0x01); ++ desc->cdb_len = task_get_uint16(task, i + 6); ++ ++ len -= 8; ++ i += 8; ++ ++ /* No tiemout description */ ++ if (!desc->ctdp) { ++ continue; + } +- desc = (struct scsi_command_descriptor *)((char *)desc + desc_size); +- datain = (struct scsi_command_descriptor *)((char *)datain + desc_size); ++ ++ desc->to.descriptor_length = ++ task_get_uint16(task, i); ++ desc->to.command_specific = ++ task_get_uint8(task, i + 3); ++ desc->to.nominal_processing_timeout = ++ task_get_uint32(task, i + 4); ++ desc->to.recommended_timeout = ++ task_get_uint32(task, i + 8); ++ ++ len -= desc->to.descriptor_length + 2; ++ i += desc->to.descriptor_length + 2; + } + + return rsoc; + +diff --git a/Makefile.am b/Makefile.am +index 1a76d12..b0d5224 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -152,7 +152,6 @@ bin_iscsi_test_SOURCES = test-tool/iscsi-test.c \ + test-tool/0422_reserve6_logout.c \ + test-tool/0423_reserve6_sessionloss.c \ + test-tool/0424_reserve6_target_reset.c \ +- test-tool/0430_report_all_supported_ops.c \ + \ + test-tool/1000_cmdsn_invalid.c \ + test-tool/1010_datasn_invalid.c \ +diff --git a/test-tool/iscsi-test.c b/test-tool/iscsi-test.c +index 1e6bcfa..3250b56 100644 +--- a/test-tool/iscsi-test.c ++++ b/test-tool/iscsi-test.c +@@ -230,9 +230,6 @@ static struct scsi_test tests[] = { + { "T0423_reserve6_sessionloss", T0423_reserve6_sessionloss }, + { "T0424_reserve6_target_reset", T0424_reserve6_target_reset }, + +-/* Maintenance In - Report Supported Operations */ +-{ "T0430_report_all_supported_ops", T0430_report_all_supported_ops }, +- + /* iSCSI protocol tests */ + + /* invalid cmdsn from initiator */ +diff --git a/test-tool/iscsi-test.h b/test-tool/iscsi-test.h +index d214fda..bb179ee 100644 +--- a/test-tool/iscsi-test.h ++++ b/test-tool/iscsi-test.h +@@ -173,8 +173,6 @@ int T0422_reserve6_logout(const char *initiator, const char *url); + int T0423_reserve6_sessionloss(const char *initiator, const char *url); + int T0424_reserve6_target_reset(const char *initiator, const char *url); + +-int T0430_report_all_supported_ops(const char *initiator, const char *url); +- + int T1000_cmdsn_invalid(const char *initiator, const char *url); + int T1010_datasn_invalid(const char *initiator, const char *url); + int T1020_bufferoffset_invalid(const char *initiator, const char *url); diff --git a/0016-avoid-casting-struct-sockaddr.patch b/0016-avoid-casting-struct-sockaddr.patch new file mode 100644 index 0000000..04dc58c --- /dev/null +++ b/0016-avoid-casting-struct-sockaddr.patch @@ -0,0 +1,76 @@ +From 4874e24d0e5ea1f930e8d8ea60a1df78f2cc814c Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 2 Aug 2013 14:19:29 +0200 +Subject: [PATCH] avoid casting struct sockaddr + +On ARM, this produces a warning. Use a union instead. + +Signed-off-by: Paolo Bonzini +--- + lib/socket.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/lib/socket.c b/lib/socket.c +index 5d98783..2c65a4a 100644 +--- a/lib/socket.c ++++ b/lib/socket.c +@@ -171,6 +171,12 @@ int set_tcp_syncnt(struct iscsi_context *iscsi) + return 0; + } + ++union socket_address { ++ struct sockaddr_in sin; ++ struct sockaddr_in6 sin6; ++ struct sockaddr sa; ++}; ++ + int + iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, + iscsi_command_cb cb, void *private_data) +@@ -179,6 +185,7 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, + char *str; + char *addr, *host; + struct addrinfo *ai = NULL; ++ union socket_address sa; + int socksize; + + ISCSI_LOG(iscsi, 2, "connecting to portal %s",portal); +@@ -238,19 +245,22 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, + } + iscsi_free(iscsi, addr); + ++ memset(&sa, 0, sizeof(sa)); + switch (ai->ai_family) { + case AF_INET: + socksize = sizeof(struct sockaddr_in); +- ((struct sockaddr_in *)(ai->ai_addr))->sin_port = htons(port); ++ memcpy(&sa.sin, ai->ai_addr, socksize); ++ sa.sin.sin_port = htons(port); + #ifdef HAVE_SOCK_SIN_LEN +- ((struct sockaddr_in *)(ai->ai_addr))->sin_len = socksize; ++ sa.sin.sin_len = socksize; + #endif + break; + case AF_INET6: + socksize = sizeof(struct sockaddr_in6); +- ((struct sockaddr_in6 *)(ai->ai_addr))->sin6_port = htons(port); ++ memcpy(&sa.sin6, ai->ai_addr, socksize); ++ sa.sin6.sin6_port = htons(port); + #ifdef HAVE_SOCK_SIN_LEN +- ((struct sockaddr_in6 *)(ai->ai_addr))->sin6_len = socksize; ++ sa.sin6.sin6_len = socksize; + #endif + break; + default: +@@ -316,7 +325,7 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, + ISCSI_LOG(iscsi,3,"TCP_NODELAY set to 1"); + } + +- if (connect(iscsi->fd, ai->ai_addr, socksize) != 0 ++ if (connect(iscsi->fd, &sa.sa, socksize) != 0 + && errno != EINPROGRESS) { + iscsi_set_error(iscsi, "Connect failed with errno : " + "%s(%d)", strerror(errno), errno); +-- +1.8.1.4 + diff --git a/0017-use-scsi_get-set_uint16-32-64-in-tests.patch b/0017-use-scsi_get-set_uint16-32-64-in-tests.patch new file mode 100644 index 0000000..0e134e0 --- /dev/null +++ b/0017-use-scsi_get-set_uint16-32-64-in-tests.patch @@ -0,0 +1,209 @@ +From d901509bcbecc912ce79087915cae355d75ca03c Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 2 Aug 2013 16:24:34 +0200 +Subject: [PATCH] use scsi_get/set_uint16/32/64 in tests + +Fixes ARM problems too. + +Signed-off-by: Paolo Bonzini +--- + lib/libiscsi.syms | 6 ++++++ + test-tool/1000_cmdsn_invalid.c | 4 ++-- + test-tool/1010_datasn_invalid.c | 10 +++++----- + test-tool/1020_bufferoffset_invalid.c | 6 +++--- + test-tool/1031_unsolicited_data_out.c | 7 +++---- + test-tool/1041_unsolicited_immediate_data.c | 2 +- + test-tool/1042_unsolicited_nonimmediate_data.c | 4 ++-- + test-tool/1100_persistent_reserve_in_read_keys_simple.c | 2 +- + test-tool/test_prin_read_keys_simple.c | 2 +- + 9 files changed, 24 insertions(+), 19 deletions(-) + +diff --git a/lib/libiscsi.syms b/lib/libiscsi.syms +index f0ca8cd..e887506 100644 +--- a/lib/libiscsi.syms ++++ b/lib/libiscsi.syms +@@ -202,6 +202,9 @@ scsi_devqualifier_to_str + scsi_devtype_to_str + scsi_free_scsi_task + scsi_get_task_private_ptr ++scsi_get_uint16 ++scsi_get_uint32 ++scsi_get_uint64 + scsi_inquiry_pagecode_to_str + scsi_protocol_identifier_to_str + scsi_reportluns_cdb +@@ -211,6 +214,9 @@ scsi_sense_ascq_str + scsi_pr_type_str + scsi_sense_key_str + scsi_set_task_private_ptr ++scsi_set_uint16 ++scsi_set_uint32 ++scsi_set_uint64 + scsi_task_add_data_in_buffer + scsi_task_add_data_out_buffer + scsi_task_set_iov_in +diff --git a/test-tool/1000_cmdsn_invalid.c b/test-tool/1000_cmdsn_invalid.c +index 3c88d2c..5b50a56 100644 +--- a/test-tool/1000_cmdsn_invalid.c ++++ b/test-tool/1000_cmdsn_invalid.c +@@ -29,11 +29,11 @@ static int my_iscsi_queue_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu + switch (change_cmdsn) { + case 1: + /* change the cmdsn so it becomes too big */ +- *(uint32_t *)&pdu->outdata.data[24] = htonl(iscsi->maxcmdsn + 1); ++ scsi_set_uint32(&pdu->outdata.data[24], iscsi->maxcmdsn + 1); + break; + case 2: + /* change the cmdsn so it becomes too small */ +- *(uint32_t *)&pdu->outdata.data[24] = 0; ++ scsi_set_uint32(&pdu->outdata.data[24], 0); + break; + } + +diff --git a/test-tool/1010_datasn_invalid.c b/test-tool/1010_datasn_invalid.c +index f605354..e9e027d 100644 +--- a/test-tool/1010_datasn_invalid.c ++++ b/test-tool/1010_datasn_invalid.c +@@ -34,20 +34,20 @@ static int my_iscsi_queue_pdu(struct iscsi_context *iscsi _U_, struct iscsi_pdu + switch (clamp_datasn) { + case 1: + /* change datasn to 0 */ +- *(uint32_t *)&pdu->outdata.data[36] = 0; ++ scsi_set_uint32(&pdu->outdata.data[36], 0); + break; + case 2: + /* change datasn to 27 */ +- *(uint32_t *)&pdu->outdata.data[36] = htonl(27); ++ scsi_set_uint32(&pdu->outdata.data[36], 27); + break; + case 3: + /* change datasn to -1 */ +- *(uint32_t *)&pdu->outdata.data[36] = htonl(-1); ++ scsi_set_uint32(&pdu->outdata.data[36], -1); + break; + case 4: + /* change datasn from (0,1) to (1,0) */ +- datasn = ntohl(*(uint32_t *)&pdu->outdata.data[36]); +- *(uint32_t *)&pdu->outdata.data[36] = htonl(1 - datasn); ++ datasn = scsi_get_uint32(&pdu->outdata.data[36]); ++ scsi_set_uint32(&pdu->outdata.data[36], 1 - datasn); + break; + } + return 0; +diff --git a/test-tool/1020_bufferoffset_invalid.c b/test-tool/1020_bufferoffset_invalid.c +index c044094..6260dec 100644 +--- a/test-tool/1020_bufferoffset_invalid.c ++++ b/test-tool/1020_bufferoffset_invalid.c +@@ -31,15 +31,15 @@ static int my_iscsi_queue_pdu(struct iscsi_context *iscsi _U_, struct iscsi_pdu + if (pdu->outdata.data[0] != ISCSI_PDU_DATA_OUT) { + return 0; + } +- buffer_offset = ntohl(*(uint32_t *)&pdu->outdata.data[40]); ++ buffer_offset = scsi_get_uint32(&pdu->outdata.data[40]); + switch (change_bufferoffset) { + case 1: + /* Add 1M to the buffer offset */ +- *(uint32_t *)&pdu->outdata.data[40] = htonl(buffer_offset + 1024*1024); ++ scsi_set_uint32(&pdu->outdata.data[40], buffer_offset + 1024*1024); + break; + case 2: + /* Add -'block_size' to the buffer offset */ +- *(uint32_t *)&pdu->outdata.data[40] = htonl(buffer_offset - block_size); ++ scsi_set_uint32(&pdu->outdata.data[40], buffer_offset - block_size); + break; + } + return 0; +diff --git a/test-tool/1031_unsolicited_data_out.c b/test-tool/1031_unsolicited_data_out.c +index fca38c8..39a1ff9 100644 +--- a/test-tool/1031_unsolicited_data_out.c ++++ b/test-tool/1031_unsolicited_data_out.c +@@ -74,8 +74,7 @@ my_iscsi_pdu_add_data(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, + } + + /* update data segment length */ +- *(uint32_t *)&pdu->outdata.data[4] = htonl(pdu->outdata.size +- - ISCSI_HEADER_SIZE); ++ scsi_set_uint32(&pdu->outdata.data[4], pdu->outdata.size - ISCSI_HEADER_SIZE); + + return 0; + } +@@ -83,13 +82,13 @@ my_iscsi_pdu_add_data(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, + static void + my_iscsi_pdu_set_itt(struct iscsi_pdu *pdu, uint32_t itt) + { +- *(uint32_t *)&pdu->outdata.data[16] = htonl(itt); ++ scsi_set_uint32(&pdu->outdata.data[16], itt); + } + + static void + my_iscsi_pdu_set_expstatsn(struct iscsi_pdu *pdu, uint32_t expstatsnsn) + { +- *(uint32_t *)&pdu->outdata.data[28] = htonl(expstatsnsn); ++ scsi_set_uint32(&pdu->outdata.data[28], expstatsnsn); + } + + static void +diff --git a/test-tool/1041_unsolicited_immediate_data.c b/test-tool/1041_unsolicited_immediate_data.c +index 3bb4d28..2959236 100644 +--- a/test-tool/1041_unsolicited_immediate_data.c ++++ b/test-tool/1041_unsolicited_immediate_data.c +@@ -37,7 +37,7 @@ static int my_queue_immediate_data(struct iscsi_context *iscsi _U_, struct iscsi + pdu_was_valid = 0; + return 0; + } +- if ( (*(uint32_t *)&pdu->outdata.data[4] & 0x00ffffff) != htonl(block_size)) { ++ if ( (scsi_get_uint32(&pdu->outdata.data[4]) & 0x00ffffff) != block_size) { + printf("SCSI-Command PDU did not have one block of immediate data.\n"); + pdu_was_valid = 0; + return 0; +diff --git a/test-tool/1042_unsolicited_nonimmediate_data.c b/test-tool/1042_unsolicited_nonimmediate_data.c +index bb2112b..ec36c41 100644 +--- a/test-tool/1042_unsolicited_nonimmediate_data.c ++++ b/test-tool/1042_unsolicited_nonimmediate_data.c +@@ -37,7 +37,7 @@ static int my_queue_immediate_data(struct iscsi_context *iscsi _U_, struct iscsi + pdu_was_valid = 0; + return 0; + } +- if ( *(uint32_t *)&pdu->outdata.data[4] & 0x00ffffff ) { ++ if ( scsi_get_uint32(&pdu->outdata.data[4]) & 0x00ffffff ) { + printf("SCSI-Command PDU had non-zero datasegmentsize.\n"); + pdu_was_valid = 0; + return 0; +@@ -50,7 +50,7 @@ static int my_queue_immediate_data(struct iscsi_context *iscsi _U_, struct iscsi + pdu_was_valid = 0; + return 0; + } +- if ( (*(uint32_t *)&pdu->outdata.data[4] & 0x00ffffff) != htonl(block_size)) { ++ if ( (scsi_get_uint32(&pdu->outdata.data[4]) & 0x00ffffff) != block_size) { + printf("The DATA-OUT PDU did not carry a full block.\n"); + pdu_was_valid = 0; + return 0; +diff --git a/test-tool/1100_persistent_reserve_in_read_keys_simple.c b/test-tool/1100_persistent_reserve_in_read_keys_simple.c +index 24de2ff..86bb83b 100644 +--- a/test-tool/1100_persistent_reserve_in_read_keys_simple.c ++++ b/test-tool/1100_persistent_reserve_in_read_keys_simple.c +@@ -90,7 +90,7 @@ int T1100_persistent_reserve_in_read_keys_simple(const char *initiator, const ch + + /* Verify that ADDITIONAL_LENGTH matches DATA-IN size */ + printf("Verify that ADDITIONAL_LENGTH matches DATA-IN size ... "); +- al = ntohl(*(uint32_t *)&task->datain.data[4]); ++ al = scsi_get_uint32(&task->datain.data[4]); + if (al != task->datain.size - 8) { + printf("[FAILED]\n"); + printf("ADDITIONAL_LENGTH was %d bytes but %d was expected.\n", +diff --git a/test-tool/test_prin_read_keys_simple.c b/test-tool/test_prin_read_keys_simple.c +index ba7b81e..0cf6edc 100644 +--- a/test-tool/test_prin_read_keys_simple.c ++++ b/test-tool/test_prin_read_keys_simple.c +@@ -47,7 +47,7 @@ test_prin_read_keys_simple(void) + } + + logging(LOG_VERBOSE, "Test ADDITIONAL_LENGTH matches DATA_IN size."); +- al = ntohl(*(uint32_t *)&task->datain.data[4]); ++ al = scsi_get_uint32(&task->datain.data[4]); + if (al != task->datain.size - 8) { + logging(LOG_NORMAL, + "[FAILED] ADDITIONAL_LENGTH was %d bytes but %d was expected.", +-- +1.8.1.4 + diff --git a/libiscsi.spec b/libiscsi.spec index 9808704..1cbe98f 100644 --- a/libiscsi.spec +++ b/libiscsi.spec @@ -1,22 +1,36 @@ Name: libiscsi Summary: iSCSI client library -Version: 1.7.0 -Release: 5%{?dist} +Version: 1.9.0 +Release: 1%{?dist} License: LGPLv2+ Group: System Environment/Libraries URL: https://github.com/sahlberg/%{name} Source: https://github.com/downloads/sahlberg/%{name}/%{name}-%{version}.tar.gz -Patch1: 0001-distribute-pkgconfig-file.patch -Patch2: 0002-use-libgcrypt-for-MD5.patch -Patch3: 0003-fix-crash-in-iscsi-tools.patch -Patch4: 0004-install-iscsi-test.patch -Patch5: 0005-Use-the-un-marshalling-functions-scsi_get-set_uint16.patch +Patch0: 0000-install-iscsi-test.patch +Patch1: 0001-do-not-reconnect-if-reconnect-is-already-defered.patch +Patch2: 0002-fix-leak-of-iscsi_context-in-iscsi_reconnect.patch +Patch3: 0003-Add-ASCQ-codes-related-to-thin-provisioning.patch +Patch4: 0004-Create-safe-16-32-64-bit-accessors-for-reading-from-.patch +Patch5: 0005-fix-bug-in-md5-code.patch +Patch6: 0006-use-libgcrypt-for-MD5.patch +Patch7: 0007-URL-encoded-Targetnames.patch +Patch8: 0008-SCSI-add-a-safe-function-to-read-a-byte-from-the-dat.patch +Patch9: 0009-scsi-lowlevel-do-not-use-unsafe-pointer-casts.patch +Patch10: 0010-Add-a-cast-to-ssize_t.patch +Patch11: 0011-Use-PRIu64-for-format-string.patch +Patch12: 0012-bump-soname.patch +Patch13: 0013-disable-ld_iscsi.patch +Patch14: 0014-fix-another-aliasing-problem.patch +Patch15: 0015-fix-arm-aliasing-problem.patch +Patch16: 0016-avoid-casting-struct-sockaddr.patch +Patch17: 0017-use-scsi_get-set_uint16-32-64-in-tests.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: libtool BuildRequires: popt-devel +BuildRequires: CUnit-devel BuildRequires: libgcrypt-devel %description @@ -33,15 +47,27 @@ a network. %prep %setup -q +%patch0 -p1 %patch1 -p1 %patch2 -p1 %patch3 -p1 %patch4 -p1 %patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 %build -## always run autogen.sh -./autogen.sh +sh autogen.sh %configure --libdir=%{libiscsi_libdir} make %{?_smp_mflags} @@ -51,7 +77,6 @@ mkdir -p $RPM_BUILD_ROOT/etc/ld.so.conf.d echo %{libiscsi_libdir} > $RPM_BUILD_ROOT/etc/ld.so.conf.d/%{name}-%{_arch}.conf rm $RPM_BUILD_ROOT/%{libiscsi_libdir}/libiscsi.a rm $RPM_BUILD_ROOT/%{libiscsi_libdir}/libiscsi.la -rm $RPM_BUILD_ROOT/%{_bindir}/ld_iscsi.so # Remove "*.old" files find $RPM_BUILD_ROOT -name "*.old" -exec rm -f {} \; @@ -100,6 +125,10 @@ The libiscsi-devel package includes the header files for libiscsi. %{_libdir}/pkgconfig/libiscsi.pc %changelog +* Fri Aug 2 2013 Paolo Bonzini - 1.9.0-1 +- Rebase to 1.9.0 +- Cherry-pick selected patches from upstream + * Mon Jul 1 2013 Paolo Bonzini - 1.7.0-6 - Add patch 5 to silence strict aliasing warnings diff --git a/sources b/sources index 6b87245..43f1b49 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -4ba621f47d016d48ab93d5301ae5a363 libiscsi-1.7.0.tar.gz +827a76e958815faf199078052791d8c4 libiscsi-1.9.0.tar.gz