CVE-2021-3139 (Closes: #980007)
Sébastien Delafond
3 years ago
0 | Author: Jason Dillaman <dillaman@redhat.com> | |
1 | Forwarded: b4a986b0d1233a8a6f2d340133c2efaa1d9e8c14 | |
2 | Description: fail cross-device XCOPY requests (CVE-2021-3139) | |
3 | Forwarded: https://github.com/open-iscsi/tcmu-runner/pull/644 | |
4 | Forwarded: https://github.com/open-iscsi/tcmu-runner/pull/646 | |
5 | ||
6 | diff --git a/tcmur_cmd_handler.c b/tcmur_cmd_handler.c | |
7 | index ca5e21c..dfffc30 100644 | |
8 | --- a/tcmur_cmd_handler.c | |
9 | +++ b/tcmur_cmd_handler.c | |
10 | @@ -1349,6 +1349,18 @@ static int xcopy_parse_parameter_list(struct tcmu_device *dev, | |
11 | if (ret != TCMU_STS_OK) | |
12 | goto err; | |
13 | ||
14 | + /* | |
15 | + * tcmu-runner can't determine whether the device(s) referred to in an | |
16 | + * XCOPY request should be accessible to the initiator via transport | |
17 | + * settings, ACLs, etc. XXX Consequently, we need to fail any | |
18 | + * cross-device requests for safety reasons. | |
19 | + */ | |
20 | + if (dev != xcopy->src_dev || dev != xcopy->dst_dev) { | |
21 | + tcmu_dev_err(dev, "Cross-device XCOPY not supported\n"); | |
22 | + ret = TCMU_STS_CP_TGT_DEV_NOTCONN; | |
23 | + goto err; | |
24 | + } | |
25 | + | |
26 | if (tcmu_dev_get_block_size(xcopy->src_dev) != | |
27 | tcmu_dev_get_block_size(xcopy->dst_dev)) { | |
28 | tcmu_dev_err(dev, "The block size of src dev %u != dst dev %u\n", | |
29 | diff --git a/tcmur_cmd_handler.c b/tcmur_cmd_handler.c | |
30 | index dfffc30..3a07dda 100644 | |
31 | --- a/tcmur_cmd_handler.c | |
32 | +++ b/tcmur_cmd_handler.c | |
33 | @@ -1161,6 +1161,12 @@ static int xcopy_parse_target_descs(struct tcmu_device *udev, | |
34 | { | |
35 | int i, ret; | |
36 | ||
37 | + if (tdll % XCOPY_TARGET_DESC_LEN) { | |
38 | + tcmu_dev_err(udev, | |
39 | + "CSCD descriptor list length %u not a multiple of %u\n", | |
40 | + (unsigned int)tdll, XCOPY_TARGET_DESC_LEN); | |
41 | + return TCMU_STS_NOTSUPP_TGT_DESC_TYPE; | |
42 | + } | |
43 | /* From spc4r36q,section 6.4.3.4 CSCD DESCRIPTOR LIST LENGTH field | |
44 | * If the number of CSCD descriptors exceeds the allowed number, the copy | |
45 | * manager shall terminate the command with CHECK CONDITION status, with | |
46 | @@ -1173,7 +1179,7 @@ static int xcopy_parse_target_descs(struct tcmu_device *udev, | |
47 | return TCMU_STS_TOO_MANY_TGT_DESC; | |
48 | } | |
49 | ||
50 | - for (i = 0; i < RCR_OP_MAX_TARGET_DESC_COUNT; i++) { | |
51 | + for (i = 0; tdll >= XCOPY_TARGET_DESC_LEN; i++) { | |
52 | /* | |
53 | * Only Identification Descriptor Target Descriptor support | |
54 | * for now. | |
55 | @@ -1184,6 +1190,7 @@ static int xcopy_parse_target_descs(struct tcmu_device *udev, | |
56 | return ret; | |
57 | ||
58 | tgt_desc += XCOPY_TARGET_DESC_LEN; | |
59 | + tdll -= XCOPY_TARGET_DESC_LEN; | |
60 | } else { | |
61 | tcmu_dev_err(udev, "Unsupport target descriptor type code 0x%x\n", | |
62 | tgt_desc[0]); | |
63 | @@ -1191,6 +1198,7 @@ static int xcopy_parse_target_descs(struct tcmu_device *udev, | |
64 | } | |
65 | } | |
66 | ||
67 | + ret = TCMU_STS_CP_TGT_DEV_NOTCONN; | |
68 | if (xcopy->src_dev) | |
69 | ret = xcopy_locate_udev(udev->ctx, xcopy->dst_tid_wwn, | |
70 | &xcopy->dst_dev); | |
71 | @@ -1308,6 +1316,12 @@ static int xcopy_parse_parameter_list(struct tcmu_device *dev, | |
72 | * data, after the last segment descriptor. | |
73 | * */ | |
74 | inline_dl = be32toh(*(uint32_t *)&par[12]); | |
75 | + if (inline_dl != 0) { | |
76 | + tcmu_dev_err(dev, "non-zero xcopy inline_dl %u unsupported\n", | |
77 | + inline_dl); | |
78 | + ret = TCMU_STS_INVALID_PARAM_LIST_LEN; | |
79 | + goto err; | |
80 | + } | |
81 | ||
82 | /* From spc4r31, section 6.3.1 EXTENDED COPY command introduction | |
83 | * |