From 2fbe0f704e39ade4859f978c55d848255db41b89 Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 11 Mar 2021 17:13:20 -0500 Subject: [PATCH 1/2] Fix memory overwrite in smp_acc_io.c send_req_aac correctly calculates the maximum response size it can process at a time with a 512 byte FIB data buffer, but inadvertanly ignores this value and uses the full response length in the response memcpy, corrupting memory when the response is greater than 512 bytes [minus headers] as with eg zone control requests. --- lib/smp_aac_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/smp_aac_io.c b/lib/smp_aac_io.c index aba5423..ca1a9ef 100644 --- a/lib/smp_aac_io.c +++ b/lib/smp_aac_io.c @@ -275,7 +275,7 @@ if((aSmpResult->header.status != SMP_PASS_THRU_SUCCESS) } - memcpy(rresp->response + aSmpCmdRespOff ,&aFib->data[sizeof(SmpPassThruHeader)],aSmpResult->header.dataReceiveLength); + memcpy(rresp->response + aSmpCmdRespOff ,&aFib->data[sizeof(SmpPassThruHeader)],bytesToSave); aSmpCmdRespOff += bytesToSave; aSmpCmdRespLen -= bytesToSave; From 909b789aef2b7304b980507319e358cce8fdec63 Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 11 Mar 2021 17:31:28 -0500 Subject: [PATCH 2/2] Initialize i_params to avoid decisions based on stack garbage Although the gpio utils already initialize the i_params buffers, the other utilities do not. In several places (eg, in smp_initiator_open) this results in request decisions being made based on preexisting stack contents when no interface parameter is explicitly specified. Patch kills this pattern globally and always initializes i_params. --- src/smp_conf_general.c | 1 + src/smp_conf_phy_event.c | 1 + src/smp_conf_route_info.c | 1 + src/smp_conf_zone_man_pass.c | 1 + src/smp_conf_zone_perm_tbl.c | 1 + src/smp_conf_zone_phy_info.c | 1 + src/smp_discover.c | 1 + src/smp_discover_list.c | 1 + src/smp_ena_dis_zoning.c | 1 + src/smp_phy_control.c | 1 + src/smp_phy_test.c | 1 + src/smp_rep_broadcast.c | 1 + src/smp_rep_exp_route_tbl.c | 1 + src/smp_rep_manufacturer.c | 1 + src/smp_rep_phy_err_log.c | 1 + src/smp_rep_phy_event.c | 1 + src/smp_rep_phy_event_list.c | 1 + src/smp_rep_phy_sata.c | 1 + src/smp_rep_route_info.c | 1 + src/smp_rep_self_conf_stat.c | 1 + src/smp_rep_zone_man_pass.c | 1 + src/smp_rep_zone_perm_tbl.c | 1 + src/smp_zone_activate.c | 1 + src/smp_zone_lock.c | 1 + src/smp_zone_unlock.c | 1 + src/smp_zoned_broadcast.c | 1 + 26 files changed, 26 insertions(+) diff --git a/src/smp_conf_general.c b/src/smp_conf_general.c index 639d0f1..8e1ad96 100644 --- a/src/smp_conf_general.c +++ b/src/smp_conf_general.c @@ -173,6 +173,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_conf_phy_event.c b/src/smp_conf_phy_event.c index 6599829..6f2b7a9 100644 --- a/src/smp_conf_phy_event.c +++ b/src/smp_conf_phy_event.c @@ -483,6 +483,7 @@ main(int argc, char * argv[]) smp_req[0] = SMP_FRAME_TYPE_REQ; smp_req[1] = SMP_FN_CONFIG_PHY_EVENT; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_conf_route_info.c b/src/smp_conf_route_info.c index 51e2cd5..616500f 100644 --- a/src/smp_conf_route_info.c +++ b/src/smp_conf_route_info.c @@ -148,6 +148,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_conf_zone_man_pass.c b/src/smp_conf_zone_man_pass.c index d0755ba..5744f48 100644 --- a/src/smp_conf_zone_man_pass.c +++ b/src/smp_conf_zone_man_pass.c @@ -327,6 +327,7 @@ main(int argc, char * argv[]) memset(password, 0, sizeof password); memset(npassword, 0, sizeof npassword); memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_conf_zone_perm_tbl.c b/src/smp_conf_zone_perm_tbl.c index 02589c2..ab0a670 100644 --- a/src/smp_conf_zone_perm_tbl.c +++ b/src/smp_conf_zone_perm_tbl.c @@ -322,6 +322,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_conf_zone_phy_info.c b/src/smp_conf_zone_phy_info.c index 3d874dd..5ac9420 100644 --- a/src/smp_conf_zone_phy_info.c +++ b/src/smp_conf_zone_phy_info.c @@ -270,6 +270,7 @@ main(int argc, char * argv[]) smp_req[0] = SMP_FRAME_TYPE_REQ; smp_req[1] = SMP_FN_CONFIG_ZONE_PHY_INFO; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_discover.c b/src/smp_discover.c index 0957e74..51f7b75 100644 --- a/src/smp_discover.c +++ b/src/smp_discover.c @@ -1203,6 +1203,7 @@ main(int argc, char * argv[]) op = &opts; memset(op, 0, sizeof(opts)); memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_discover_list.c b/src/smp_discover_list.c index c6736f5..799d362 100644 --- a/src/smp_discover_list.c +++ b/src/smp_discover_list.c @@ -1125,6 +1125,7 @@ main(int argc, char * argv[]) op = &opts; memset(op, 0, sizeof(opts)); memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_ena_dis_zoning.c b/src/smp_ena_dis_zoning.c index b5ebee6..3971aa4 100644 --- a/src/smp_ena_dis_zoning.c +++ b/src/smp_ena_dis_zoning.c @@ -147,6 +147,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_phy_control.c b/src/smp_phy_control.c index 4201327..61d0162 100644 --- a/src/smp_phy_control.c +++ b/src/smp_phy_control.c @@ -217,6 +217,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_phy_test.c b/src/smp_phy_test.c index 0c33bf6..858c110 100644 --- a/src/smp_phy_test.c +++ b/src/smp_phy_test.c @@ -162,6 +162,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_rep_broadcast.c b/src/smp_rep_broadcast.c index 064b64e..91d9bf5 100644 --- a/src/smp_rep_broadcast.c +++ b/src/smp_rep_broadcast.c @@ -157,6 +157,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_rep_exp_route_tbl.c b/src/smp_rep_exp_route_tbl.c index 7df959d..ea024df 100644 --- a/src/smp_rep_exp_route_tbl.c +++ b/src/smp_rep_exp_route_tbl.c @@ -253,6 +253,7 @@ main(int argc, char * argv[]) memset(&opts, 0, sizeof(opts)); opts.do_num = 62; /* maximum fitting in one response */ memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_rep_manufacturer.c b/src/smp_rep_manufacturer.c index c8c5749..6859a12 100644 --- a/src/smp_rep_manufacturer.c +++ b/src/smp_rep_manufacturer.c @@ -132,6 +132,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_rep_phy_err_log.c b/src/smp_rep_phy_err_log.c index 98bb7f2..3503411 100644 --- a/src/smp_rep_phy_err_log.c +++ b/src/smp_rep_phy_err_log.c @@ -135,6 +135,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_rep_phy_event.c b/src/smp_rep_phy_event.c index f0657e7..753d32a 100644 --- a/src/smp_rep_phy_event.c +++ b/src/smp_rep_phy_event.c @@ -314,6 +314,7 @@ main(int argc, char * argv[]) const struct pes_name_t * pnp; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_rep_phy_event_list.c b/src/smp_rep_phy_event_list.c index b671658..bc6e756 100644 --- a/src/smp_rep_phy_event_list.c +++ b/src/smp_rep_phy_event_list.c @@ -328,6 +328,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_rep_phy_sata.c b/src/smp_rep_phy_sata.c index 0d813e0..5351943 100644 --- a/src/smp_rep_phy_sata.c +++ b/src/smp_rep_phy_sata.c @@ -143,6 +143,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_rep_route_info.c b/src/smp_rep_route_info.c index 55d1a64..8522ffe 100644 --- a/src/smp_rep_route_info.c +++ b/src/smp_rep_route_info.c @@ -325,6 +325,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_rep_self_conf_stat.c b/src/smp_rep_self_conf_stat.c index 05a641d..3a6efdf 100644 --- a/src/smp_rep_self_conf_stat.c +++ b/src/smp_rep_self_conf_stat.c @@ -203,6 +203,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_rep_zone_man_pass.c b/src/smp_rep_zone_man_pass.c index 933125f..1b87def 100644 --- a/src/smp_rep_zone_man_pass.c +++ b/src/smp_rep_zone_man_pass.c @@ -140,6 +140,7 @@ main(int argc, char * argv[]) int ret = 0; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_rep_zone_perm_tbl.c b/src/smp_rep_zone_perm_tbl.c index 66804cb..fba15d0 100644 --- a/src/smp_rep_zone_perm_tbl.c +++ b/src/smp_rep_zone_perm_tbl.c @@ -195,6 +195,7 @@ main(int argc, char * argv[]) memset(device_name, 0, sizeof device_name); memset(smp_resp, 0, sizeof smp_resp); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_zone_activate.c b/src/smp_zone_activate.c index ad4ffe6..e5d7f72 100644 --- a/src/smp_zone_activate.c +++ b/src/smp_zone_activate.c @@ -129,6 +129,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_zone_lock.c b/src/smp_zone_lock.c index cbcf6ce..5ca9884 100644 --- a/src/smp_zone_lock.c +++ b/src/smp_zone_lock.c @@ -307,6 +307,7 @@ main(int argc, char * argv[]) memset(password, 0, sizeof password); memset(device_name, 0, sizeof device_name); memset(smp_resp, 0, sizeof smp_resp); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_zone_unlock.c b/src/smp_zone_unlock.c index 8151ff4..3d2e1a1 100644 --- a/src/smp_zone_unlock.c +++ b/src/smp_zone_unlock.c @@ -134,6 +134,7 @@ main(int argc, char * argv[]) struct smp_target_obj tobj; memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0; diff --git a/src/smp_zoned_broadcast.c b/src/smp_zoned_broadcast.c index 7e5a0e7..0d852e1 100644 --- a/src/smp_zoned_broadcast.c +++ b/src/smp_zoned_broadcast.c @@ -249,6 +249,7 @@ main(int argc, char * argv[]) memset(smp_req, 0, sizeof smp_req); memset(device_name, 0, sizeof device_name); + memset(i_params, 0, sizeof i_params); while (1) { int option_index = 0;