From 7d17a328eb77548f4d0f140bfb6549737073a6c9 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 10 Nov 2015 01:07:26 +0000 Subject: [PATCH] scst_copy_mgr: Verify maximum number of segments git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6645 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/include/scst_const.h | 1 + scst/src/scst_copy_mgr.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h index 6dc9597b0..b0a2fc51b 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -319,6 +319,7 @@ static inline int scst_sense_response_code(const uint8_t *sense) #define scst_sense_invalid_release ILLEGAL_REQUEST, 0x26, 4 #define scst_sense_too_many_target_descriptors ILLEGAL_REQUEST, 0x26, 6 #define scst_sense_unsupported_tgt_descr_type ILLEGAL_REQUEST, 0x26, 7 +#define scst_sense_too_many_segment_descriptors ILLEGAL_REQUEST, 0x26, 8 #define scst_sense_unsupported_seg_descr_type ILLEGAL_REQUEST, 0x26, 9 #define scst_sense_inline_data_length_exceeded ILLEGAL_REQUEST, 0x26, 0xB #define scst_sense_saving_params_unsup ILLEGAL_REQUEST, 0x39, 0 diff --git a/scst/src/scst_copy_mgr.c b/scst/src/scst_copy_mgr.c index 517bbe5be..8b0ffb2f3 100644 --- a/scst/src/scst_copy_mgr.c +++ b/scst/src/scst_copy_mgr.c @@ -35,6 +35,10 @@ /* Too big value is not too good for the blocking machinery */ #define SCST_CM_MAX_TGT_DESCR_CNT 5 +#define SCST_CM_MAX_SEG_DESCR_CNT \ + (((PAGE_SIZE * 2) - sizeof(struct scst_cm_ec_cmd_priv)) / \ + sizeof(struct scst_ext_copy_seg_descr)) + /* MAXIMUM DESCRIPTOR LIST LENGTH */ #define SCST_MAX_SEG_DESC_LEN 0xFFFF @@ -2213,8 +2217,7 @@ static void scst_cm_oper_parameters(struct scst_cmd *cmd) put_unaligned_be16(SCST_CM_MAX_TGT_DESCR_CNT, &tbuf[8]); /* MAXIMUM SEGMENT DESCRIPTOR COUNT */ - put_unaligned_be16(((PAGE_SIZE * 2) - sizeof(struct scst_cm_ec_cmd_priv)) / - sizeof(struct scst_ext_copy_seg_descr), &tbuf[10]); + put_unaligned_be16(SCST_CM_MAX_SEG_DESCR_CNT, &tbuf[10]); /* MAXIMUM DESCRIPTOR LIST LENGTH */ put_unaligned_be32(SCST_MAX_SEG_DESC_LEN, &tbuf[12]); @@ -3280,6 +3283,13 @@ int scst_cm_parse_descriptors(struct scst_cmd *ec_cmd) t = offs; seg_cnt = 0; while (offs < length) { + if (seg_cnt == SCST_CM_MAX_SEG_DESCR_CNT) { + PRINT_WARNING("Too many segment descriptors"); + scst_set_cmd_error(ec_cmd, + SCST_LOAD_SENSE( + scst_sense_too_many_segment_descriptors)); + goto out_free_tgt_descr; + } switch (buf[offs]) { case 2: /* block device to block device segment descriptor */ offs += 28;