If mad_dump_field() exhausts the buffer, _dump_fields() would accidentally write 1 byte beyond its end. Additionally, several functions call _dump_fields() repeatedly without checking for a negative return; these could clobber memory before the buffer.
Signed-off-by: Jim Foraker <[email protected]> --- src/dump.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/dump.c b/src/dump.c index d4512c0..9937a82 100644 --- a/src/dump.c +++ b/src/dump.c @@ -731,7 +731,7 @@ static int _dump_fields(char *buf, int bufsz, void *data, int start, int end) for (field = start; field < end && bufsz > 0; field++) { mad_decode_field(data, field, val); - if (!mad_dump_field(field, s, bufsz, val)) + if (!mad_dump_field(field, s, bufsz-1, val)) return -1; n = strlen(s); s += n; @@ -768,6 +768,9 @@ void mad_dump_portinfo(char *buf, int bufsz, void *val, int valsz) int cnt; cnt = _dump_fields(buf, bufsz, val, IB_PORT_FIRST_F, IB_PORT_LAST_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PORT_CAPMASK2_F, IB_PORT_LINK_SPEED_EXT_LAST_F); } @@ -798,6 +801,9 @@ void mad_dump_perfcounters_xmt_sl(char *buf, int bufsz, void *val, int valsz) cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_XMT_DATA_SL_FIRST_F, IB_PC_XMT_DATA_SL_LAST_F); } @@ -808,6 +814,9 @@ void mad_dump_perfcounters_rcv_sl(char *buf, int bufsz, void *val, int valsz) cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_RCV_DATA_SL_FIRST_F, IB_PC_RCV_DATA_SL_LAST_F); } @@ -818,6 +827,9 @@ void mad_dump_perfcounters_xmt_disc(char *buf, int bufsz, void *val, int valsz) cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_XMT_INACT_DISC_F, IB_PC_XMT_DISC_LAST_F); } @@ -828,6 +840,9 @@ void mad_dump_perfcounters_rcv_err(char *buf, int bufsz, void *val, int valsz) cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_RCV_LOCAL_PHY_ERR_F, IB_PC_RCV_ERR_LAST_F); } @@ -848,6 +863,9 @@ void mad_dump_perfcounters_port_op_rcv_counters(char *buf, int bufsz, void *val, cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_OP_RCV_COUNTERS_FIRST_F, IB_PC_PORT_OP_RCV_COUNTERS_LAST_F); } @@ -858,6 +876,9 @@ void mad_dump_perfcounters_port_flow_ctl_counters(char *buf, int bufsz, void *va cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_FLOW_CTL_COUNTERS_FIRST_F, IB_PC_PORT_FLOW_CTL_COUNTERS_LAST_F); } @@ -868,6 +889,9 @@ void mad_dump_perfcounters_port_vl_op_packet(char *buf, int bufsz, void *val, in cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_VL_OP_PACKETS_FIRST_F, IB_PC_PORT_VL_OP_PACKETS_LAST_F); } @@ -878,6 +902,9 @@ void mad_dump_perfcounters_port_vl_op_data(char *buf, int bufsz, void *val, int cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_VL_OP_DATA_FIRST_F, IB_PC_PORT_VL_OP_DATA_LAST_F); } @@ -888,6 +915,9 @@ void mad_dump_perfcounters_port_vl_xmit_flow_ctl_update_errors(char *buf, int bu cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_FIRST_F, IB_PC_PORT_VL_XMIT_FLOW_CTL_UPDATE_ERRORS_LAST_F); } @@ -898,6 +928,9 @@ void mad_dump_perfcounters_port_vl_xmit_wait_counters(char *buf, int bufsz, void cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_FIRST_F, IB_PC_PORT_VL_XMIT_WAIT_COUNTERS_LAST_F); } @@ -908,6 +941,9 @@ void mad_dump_perfcounters_sw_port_vl_congestion(char *buf, int bufsz, void *val cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_SW_PORT_VL_CONGESTION_FIRST_F, IB_PC_SW_PORT_VL_CONGESTION_LAST_F); } @@ -918,6 +954,9 @@ void mad_dump_perfcounters_rcv_con_ctrl(char *buf, int bufsz, void *val, int val cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_RCV_CON_CTRL_FIRST_F, IB_PC_RCV_CON_CTRL_LAST_F); } @@ -929,6 +968,9 @@ void mad_dump_perfcounters_sl_rcv_fecn(char *buf, int bufsz, void *val, int vals cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_SL_RCV_FECN_FIRST_F, IB_PC_SL_RCV_FECN_LAST_F); } @@ -939,6 +981,9 @@ void mad_dump_perfcounters_sl_rcv_becn(char *buf, int bufsz, void *val, int vals cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_SL_RCV_BECN_FIRST_F, IB_PC_SL_RCV_BECN_LAST_F); } @@ -949,6 +994,9 @@ void mad_dump_perfcounters_xmit_con_ctrl(char *buf, int bufsz, void *val, int va cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_XMIT_CON_CTRL_FIRST_F, IB_PC_XMIT_CON_CTRL_LAST_F); } @@ -959,6 +1007,9 @@ void mad_dump_perfcounters_vl_xmit_time_cong(char *buf, int bufsz, void *val, in cnt = _dump_fields(buf, bufsz, val, IB_PC_EXT_PORT_SELECT_F, IB_PC_EXT_XMT_BYTES_F); + if (cnt < 0) + return; + _dump_fields(buf + cnt, bufsz - cnt, val, IB_PC_VL_XMIT_TIME_CONG_FIRST_F, IB_PC_VL_XMIT_TIME_CONG_LAST_F); } -- 1.7.9.2 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
