diff --git a/READMEs/README.fault-injection.md b/READMEs/README.fault-injection.md index 33d791f80..781067949 100644 --- a/READMEs/README.fault-injection.md +++ b/READMEs/README.fault-injection.md @@ -307,6 +307,15 @@ thing by giving, eg, `"myfault(10%),myfault_delay(123..456)"` |ssproxy|`wsi`|`sspc_dsh_ss2p_oom`|Cause ss->proxy dsh allocation to fail| |ssproxy|`ss`|`ssproxy_onward_conn_fail`|Act as if proxy onward client connection failed immediately| |ssproxy|`ss`|`ssproxy_dsh_c2p_pay_oom`|Cause proxy's DSH alloc for C->P payload to fail| +|ss|`ss`|`ss_create_smd`|SMD: ss creation smd registration fail| +|ss|`ss`|`ss_create_vhost`|Server: ss creation acts like no vhost matching typename (only for `!vhost`)| +|ss|`ss`|`ss_create_pcol`|Server: ss creation acts like no protocol given in policy| +|ss|`ss`|`ss_srv_vh_fail`|Server: ss creation acts like unable to create vhost| +|ss|`ss`|`ss_create_destroy_me`|ss creation acts like CREATING state returned DESTROY_ME| +|ss|`ss`|`ss_create_no_ts`|Static Policy: ss creation acts like no trust store| +|ss|`ss`|`ss_create_smd_1`|SMD: ss creation acts like CONNECTING said DESTROY_ME| +|ss|`ss`|`ss_create_smd_2`|SMD: ss creation acts like CONNECTED said DESTROY_ME| +|ss|`ss`|`ss_create_conn`|Nailed up: ss creation client connection fails with DESTROY_ME| |wsi|`wsi`|`timedclose`|(see next) Cause wsi to close after some time| |wsi|`wsi`|`timedclose_ms`|Range of ms for timedclose (eg, "timedclose_ms(10..250)"| diff --git a/lib/secure-streams/secure-streams.c b/lib/secure-streams/secure-streams.c index 7cfb993a1..6df37246c 100644 --- a/lib/secure-streams/secure-streams.c +++ b/lib/secure-streams/secure-streams.c @@ -1131,7 +1131,7 @@ lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi, h->u.smd.smd_peer = lws_smd_register(context, h, 0, (lws_smd_class_t)ssi->manual_initial_tx_credit, lws_smd_ss_cb); - if (!h->u.smd.smd_peer) + if (!h->u.smd.smd_peer || lws_fi(&h->fic, "ss_create_smd")) goto fail_creation; lwsl_cx_info(context, "registered SS SMD"); } @@ -1156,7 +1156,7 @@ lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi, vho = lws_get_vhost_by_name(context, &h->policy->endpoint[1]); - if (!vho) { + if (!vho || lws_fi(&h->fic, "ss_create_vhost")) { lwsl_err("%s: no vhost %s\n", __func__, &h->policy->endpoint[1]); goto fail_creation; @@ -1181,7 +1181,8 @@ lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi, i.options |= LWS_SERVER_OPTION_UNIX_SOCK; } - if (!ss_pcols[h->policy->protocol]) { + if (!ss_pcols[h->policy->protocol] || + lws_fi(&h->fic, "ss_create_pcol")) { lwsl_err("%s: unsupp protocol", __func__); goto fail_creation; } @@ -1212,9 +1213,10 @@ lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi, } #endif - - if (!lws_fi(&ssi->fic, "ss_srv_vh_fail")) + if (!lws_fi(&h->fic, "ss_srv_vh_fail")) vho = lws_create_vhost(context, &i); + else + vho = NULL; if (!vho) { lwsl_cx_err(context, "failed to create vh"); goto fail_creation; @@ -1230,7 +1232,8 @@ extant: r = lws_ss_event_helper(h, LWSSSCS_CREATING); lwsl_cx_info(context, "CREATING returned status %d", (int)r); - if (r == LWSSSSRET_DESTROY_ME) + if (r == LWSSSSRET_DESTROY_ME || + lws_fi(&h->fic, "ss_create_destroy_me")) goto fail_creation; lwsl_cx_notice(context, "created server %s", @@ -1252,7 +1255,8 @@ extant: * to the ss connect code instead. */ - if (!lws_ss_policy_ref_trust_store(context, h->policy, 1 /* do the ref */)) { + if (!lws_ss_policy_ref_trust_store(context, h->policy, 1 /* do the ref */) || + lws_fi(&h->fic, "ss_create_no_ts")) { lwsl_err("%s: unable to get vhost / trust store\n", __func__); goto fail_creation; } @@ -1260,20 +1264,19 @@ extant: r = lws_ss_event_helper(h, LWSSSCS_CREATING); lwsl_ss_info(h, "CREATING returned status %d", (int)r); - if (r == LWSSSSRET_DESTROY_ME) + if (r == LWSSSSRET_DESTROY_ME || + lws_fi(&h->fic, "ss_create_destroy_me")) goto fail_creation; #if defined(LWS_WITH_SYS_SMD) if (!(ssi->flags & LWSSSINFLAGS_PROXIED) && pol == &pol_smd) { - lws_ss_state_return_t r; - r = lws_ss_event_helper(h, LWSSSCS_CONNECTING); - if (r) - return r; + if (r || lws_fi(&h->fic, "ss_create_smd_1")) + goto fail_creation; r = lws_ss_event_helper(h, LWSSSCS_CONNECTED); - if (r) - return r; + if (r || lws_fi(&h->fic, "ss_create_smd_2")) + goto fail_creation; } #endif @@ -1284,8 +1287,11 @@ extant: //(ssi->flags & LWSSSINFLAGS_PROXIED)) ) #endif - )) - switch (_lws_ss_client_connect(h, 0, 0)) { + )) { + r = _lws_ss_client_connect(h, 0, 0); + if (lws_fi(&h->fic, "ss_create_conn")) + r = LWSSSSRET_DESTROY_ME; + switch (r) { case LWSSSSRET_OK: break; case LWSSSSRET_TX_DONT_SEND: @@ -1296,6 +1302,7 @@ extant: case LWSSSSRET_DESTROY_ME: goto fail_creation; } + } return 0; diff --git a/minimal-examples/secure-streams/minimal-secure-streams-server/main.c b/minimal-examples/secure-streams/minimal-secure-streams-server/main.c index 0b8a13bed..91d7b0cf0 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams-server/main.c +++ b/minimal-examples/secure-streams/minimal-secure-streams-server/main.c @@ -226,6 +226,9 @@ smd_cb(void *opaque, lws_smd_class_t c, lws_usec_t ts, void *buf, size_t len) NULL, NULL)) { lwsl_err("%s: failed to create secure stream\n", __func__); + bad = 1; + interrupted = 1; + lws_cancel_service(context); return -1; } #if 0 diff --git a/minimal-examples/secure-streams/minimal-secure-streams-smd/CMakeLists.txt b/minimal-examples/secure-streams/minimal-secure-streams-smd/CMakeLists.txt index 3440a24e0..db2f9ebc9 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams-smd/CMakeLists.txt +++ b/minimal-examples/secure-streams/minimal-secure-streams-smd/CMakeLists.txt @@ -13,6 +13,8 @@ require_lws_config(LWS_WITH_SYS_SMD 1 requirements) require_lws_config(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY 0 requirements) require_lws_config(LWS_WITH_SYS_STATE 1 requirements) +require_lws_config(LWS_WITH_SYS_FAULT_INJECTION 1 has_fault_injection) + if (requirements) add_executable(${PROJECT_NAME} minimal-secure-streams-smd.c) @@ -32,7 +34,47 @@ if (requirements) PROPERTIES WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/minimal-examples/secure-streams/minimal-secure-streams-smd TIMEOUT 10) - endif() + + if (has_fault_injection) + if (VALGRIND) + add_test(NAME ss-smd-fi1 COMMAND + ${VALGRIND} --tool=memcheck --leak-check=yes --num-callers=20 + $ + --fault-injection "ss/ss_create_smd" + --expected-exit 1) + add_test(NAME ss-smd-fi2 COMMAND + ${VALGRIND} --tool=memcheck --leak-check=yes --num-callers=20 + $ + --fault-injection "ss/ss_create_smd_1" + --expected-exit 1) + add_test(NAME ss-smd-fi3 COMMAND + ${VALGRIND} --tool=memcheck --leak-check=yes --num-callers=20 + $ + --fault-injection "ss/ss_create_smd_2" + --expected-exit 1) + else() + add_test(NAME ss-smd-fi1 COMMAND lws-minimal-secure-streams-smd + --fault-injection "ss/ss_create_smd" + --expected-exit 1) + add_test(NAME ss-smd-fi2 COMMAND lws-minimal-secure-streams-smd + --fault-injection "ss/ss_create_smd_1" + --expected-exit 1) + add_test(NAME ss-smd-fi3 COMMAND lws-minimal-secure-streams-smd + --fault-injection "ss/ss_create_smd_2" + --expected-exit 1) + endif() + + set_tests_properties(ss-smd-fi1 + ss-smd-fi2 + ss-smd-fi3 + PROPERTIES + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/minimal-examples/secure-streams/minimal-secure-streams-smd + TIMEOUT 5) + endif() + + + + endif() if (websockets_shared) target_link_libraries(${PROJECT_NAME} websockets_shared ${LIBWEBSOCKETS_DEP_LIBS}) diff --git a/minimal-examples/secure-streams/minimal-secure-streams-smd/minimal-secure-streams-smd.c b/minimal-examples/secure-streams/minimal-secure-streams-smd/minimal-secure-streams-smd.c index 3a9577f23..10bd5f3b3 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams-smd/minimal-secure-streams-smd.c +++ b/minimal-examples/secure-streams/minimal-secure-streams-smd/minimal-secure-streams-smd.c @@ -15,7 +15,7 @@ #include #include -static int interrupted, bad = 1, count_p1, count_p2, count_tx; +static int interrupted, bad = 1, count_p1, count_p2, count_tx, expected = 0; static unsigned int how_many_msg = 100, usec_interval = 1000; static lws_sorted_usec_list_t sul_timeout; @@ -225,7 +225,8 @@ direct_smd_cb(void *opaque, lws_smd_class_t _class, lws_usec_t timestamp, if (lws_ss_create(*pctx, 0, &ssi_lws_smd, NULL, NULL, NULL, NULL)) { lwsl_err("%s: failed to create secure stream\n", __func__); - + interrupted = 1; + lws_cancel_service(*pctx); return -1; } } @@ -359,7 +360,15 @@ bail: #endif lws_context_destroy(context); - lwsl_user("Completed: %s\n", bad ? "failed" : "OK"); + if ((p = lws_cmdline_option(argc, argv, "--expected-exit"))) + expected = atoi(p); - return bad; + if (bad == expected) { + lwsl_user("Completed: OK (seen expected %d)\n", expected); + return 0; + } + + lwsl_err("Completed: failed: exit %d, expected %d\n", bad, expected); + + return 1; } diff --git a/minimal-examples/secure-streams/minimal-secure-streams/CMakeLists.txt b/minimal-examples/secure-streams/minimal-secure-streams/CMakeLists.txt index 93bf34fdb..b7233cb89 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams/CMakeLists.txt +++ b/minimal-examples/secure-streams/minimal-secure-streams/CMakeLists.txt @@ -14,6 +14,8 @@ require_lws_config(LWS_WITH_SECURE_STREAMS 1 requirements) require_lws_config(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY 0 requirements) require_lws_config(LWS_WITH_SYS_STATE 1 requirements) +require_lws_config(LWS_WITH_SYS_FAULT_INJECTION 1 has_fault_injection) + if (requirements) add_executable(${SAMP} minimal-secure-streams.c) @@ -56,6 +58,36 @@ if (requirements) set_tests_properties(ss-warmcat PROPERTIES FIXTURES_REQUIRED "res_sspcmin") endif() + if (has_fault_injection) + if (VALGRIND) + add_test(NAME ss-warmcat-fi1 COMMAND + ${VALGRIND} --tool=memcheck --leak-check=yes --num-callers=20 + $ + --fault-injection "ss/ss_create_destroy_me" + --expected-exit 1) + add_test(NAME ss-warmcat-fi2 COMMAND + ${VALGRIND} --tool=memcheck --leak-check=yes --num-callers=20 + $ + --fault-injection "ss/ss_no_streamtype_policy" + --expected-exit 1) + else() + add_test(NAME ss-warmcat-fi1 COMMAND lws-minimal-secure-streams + --fault-injection "ss/ss_create_destroy_me" + --expected-exit 1) + add_test(NAME ss-warmcat-fi2 COMMAND lws-minimal-secure-streams + --fault-injection "ss/ss_no_streamtype_policy" + --expected-exit 1) + endif() + + set_tests_properties(ss-warmcat-fi1 + ss-warmcat-fi2 + PROPERTIES + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/minimal-examples/secure-streams/minimal-secure-streams + TIMEOUT 5) + + endif() + + if (HAS_LWS_WITH_SECURE_STREAMS_PROXY_API OR LWS_WITH_SECURE_STREAMS_PROXY_API) # diff --git a/minimal-examples/secure-streams/minimal-secure-streams/minimal-secure-streams.c b/minimal-examples/secure-streams/minimal-secure-streams/minimal-secure-streams.c index c51f5eac5..a2330b218 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams/minimal-secure-streams.c +++ b/minimal-examples/secure-streams/minimal-secure-streams/minimal-secure-streams.c @@ -472,6 +472,8 @@ app_system_state_nf(lws_state_manager_t *mgr, lws_state_notify_link_t *link, NULL, NULL)) { lwsl_err("%s: failed to create secure stream\n", __func__); + interrupted = 1; + lws_cancel_service(context); return -1; } }