CTL: Add length validation for incoming HA messages.
This should fix uninitialized memory reads when working with broken
HA peer, like one fixed in 1a8d8a3a90
. Instead print error message
and kill the HA link.
MFC after: 3 days
Sponsored by: iXsystems, Inc.
This commit is contained in:
parent
e8553be9bc
commit
530d274c15
@ -1101,7 +1101,14 @@ static void
|
||||
ctl_isc_ua(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
|
||||
{
|
||||
struct ctl_lun *lun;
|
||||
uint32_t iid = ctl_get_initindex(&msg->hdr.nexus);
|
||||
uint32_t iid;
|
||||
|
||||
if (len < sizeof(msg->ua)) {
|
||||
printf("%s: Received truncated message %d < %lu\n",
|
||||
__func__, len, sizeof(msg->ua));
|
||||
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
|
||||
return;
|
||||
}
|
||||
|
||||
mtx_lock(&softc->ctl_lock);
|
||||
if (msg->hdr.nexus.targ_mapped_lun >= ctl_max_luns ||
|
||||
@ -1113,6 +1120,7 @@ ctl_isc_ua(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
|
||||
mtx_unlock(&softc->ctl_lock);
|
||||
if (msg->ua.ua_type == CTL_UA_THIN_PROV_THRES && msg->ua.ua_set)
|
||||
memcpy(lun->ua_tpt_info, msg->ua.ua_info, 8);
|
||||
iid = ctl_get_initindex(&msg->hdr.nexus);
|
||||
if (msg->ua.ua_all) {
|
||||
if (msg->ua.ua_set)
|
||||
ctl_est_ua_all(lun, iid, msg->ua.ua_type);
|
||||
@ -1136,6 +1144,20 @@ ctl_isc_lun_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
|
||||
ctl_lun_flags oflags;
|
||||
uint32_t targ_lun;
|
||||
|
||||
if (len < offsetof(struct ctl_ha_msg_lun, data[0])) {
|
||||
printf("%s: Received truncated message %d < %lu\n",
|
||||
__func__, len, offsetof(struct ctl_ha_msg_lun, data[0]));
|
||||
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
|
||||
return;
|
||||
}
|
||||
i = msg->lun.lun_devid_len + msg->lun.pr_key_count * sizeof(pr_key);
|
||||
if (len < offsetof(struct ctl_ha_msg_lun, data[i])) {
|
||||
printf("%s: Received truncated message data %d < %lu\n",
|
||||
__func__, len, offsetof(struct ctl_ha_msg_lun, data[i]));
|
||||
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
|
||||
return;
|
||||
}
|
||||
|
||||
targ_lun = msg->hdr.nexus.targ_mapped_lun;
|
||||
mtx_lock(&softc->ctl_lock);
|
||||
if (targ_lun >= ctl_max_luns ||
|
||||
@ -1206,6 +1228,22 @@ ctl_isc_port_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
|
||||
struct ctl_lun *lun;
|
||||
int i, new;
|
||||
|
||||
if (len < offsetof(struct ctl_ha_msg_port, data[0])) {
|
||||
printf("%s: Received truncated message %d < %lu\n",
|
||||
__func__, len, offsetof(struct ctl_ha_msg_port, data[0]));
|
||||
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
|
||||
return;
|
||||
}
|
||||
i = msg->port.name_len + msg->port.lun_map_len +
|
||||
msg->port.port_devid_len + msg->port.target_devid_len +
|
||||
msg->port.init_devid_len;
|
||||
if (len < offsetof(struct ctl_ha_msg_port, data[i])) {
|
||||
printf("%s: Received truncated message data %d < %lu\n",
|
||||
__func__, len, offsetof(struct ctl_ha_msg_port, data[i]));
|
||||
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
|
||||
return;
|
||||
}
|
||||
|
||||
port = softc->ctl_ports[msg->hdr.nexus.targ_port];
|
||||
if (port == NULL) {
|
||||
CTL_DEBUG_PRINT(("%s: New port %d\n", __func__,
|
||||
@ -1317,7 +1355,21 @@ static void
|
||||
ctl_isc_iid_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
|
||||
{
|
||||
struct ctl_port *port;
|
||||
int iid;
|
||||
int i, iid;
|
||||
|
||||
if (len < offsetof(struct ctl_ha_msg_iid, data[0])) {
|
||||
printf("%s: Received truncated message %d < %lu\n",
|
||||
__func__, len, offsetof(struct ctl_ha_msg_iid, data[0]));
|
||||
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
|
||||
return;
|
||||
}
|
||||
i = msg->iid.name_len;
|
||||
if (len < offsetof(struct ctl_ha_msg_iid, data[i])) {
|
||||
printf("%s: Received truncated message data %d < %lu\n",
|
||||
__func__, len, offsetof(struct ctl_ha_msg_iid, data[i]));
|
||||
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
|
||||
return;
|
||||
}
|
||||
|
||||
port = softc->ctl_ports[msg->hdr.nexus.targ_port];
|
||||
if (port == NULL) {
|
||||
@ -1343,6 +1395,13 @@ static void
|
||||
ctl_isc_login(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
|
||||
{
|
||||
|
||||
if (len < sizeof(msg->login)) {
|
||||
printf("%s: Received truncated message %d < %lu\n",
|
||||
__func__, len, sizeof(msg->login));
|
||||
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg->login.version != CTL_HA_VERSION) {
|
||||
printf("CTL HA peers have different versions %d != %d\n",
|
||||
msg->login.version, CTL_HA_VERSION);
|
||||
@ -1376,6 +1435,20 @@ ctl_isc_mode_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
|
||||
u_int i;
|
||||
uint32_t initidx, targ_lun;
|
||||
|
||||
if (len < offsetof(struct ctl_ha_msg_mode, data[0])) {
|
||||
printf("%s: Received truncated message %d < %lu\n",
|
||||
__func__, len, offsetof(struct ctl_ha_msg_mode, data[0]));
|
||||
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
|
||||
return;
|
||||
}
|
||||
i = msg->mode.page_len;
|
||||
if (len < offsetof(struct ctl_ha_msg_mode, data[i])) {
|
||||
printf("%s: Received truncated message data %d < %lu\n",
|
||||
__func__, len, offsetof(struct ctl_ha_msg_mode, data[i]));
|
||||
ctl_ha_msg_abort(CTL_HA_CHAN_CTL);
|
||||
return;
|
||||
}
|
||||
|
||||
targ_lun = msg->hdr.nexus.targ_mapped_lun;
|
||||
mtx_lock(&softc->ctl_lock);
|
||||
if (targ_lun >= ctl_max_luns ||
|
||||
@ -1400,7 +1473,7 @@ ctl_isc_mode_sync(struct ctl_softc *softc, union ctl_ha_msg *msg, int len)
|
||||
return;
|
||||
}
|
||||
memcpy(lun->mode_pages.index[i].page_data, msg->mode.data,
|
||||
lun->mode_pages.index[i].page_len);
|
||||
min(lun->mode_pages.index[i].page_len, msg->mode.page_len));
|
||||
initidx = ctl_get_initindex(&msg->hdr.nexus);
|
||||
if (initidx != -1)
|
||||
ctl_est_ua_all(lun, initidx, CTL_UA_MODE_CHANGE);
|
||||
@ -1437,7 +1510,8 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
|
||||
return;
|
||||
}
|
||||
|
||||
CTL_DEBUG_PRINT(("CTL: msg_type %d\n", msg->hdr.msg_type));
|
||||
CTL_DEBUG_PRINT(("CTL: msg_type %d len %d\n",
|
||||
msg->hdr.msg_type, param));
|
||||
switch (msg->hdr.msg_type) {
|
||||
case CTL_MSG_SERIALIZE:
|
||||
io = ctl_alloc_io(softc->othersc_pool);
|
||||
|
Loading…
Reference in New Issue
Block a user