From 4e9977507dd2da9b820593902d11b193b28fb6a0 Mon Sep 17 00:00:00 2001 From: Mark Lipscombe Date: Sun, 15 Nov 2015 10:40:20 +1100 Subject: [PATCH] FS-8537: Passing nil to various lua functions causes segfault Various functions exposed via lua do not check their parameters for null causing freeswitch to segfault. This change adds checking for null parameters and returns an error instead of segfaulting. --- src/mod/languages/mod_lua/freeswitch_lua.cpp | 25 ++++++++++++++-- src/switch_core.c | 20 ++++++++----- src/switch_cpp.cpp | 31 +++++++++++++++----- src/switch_utils.c | 5 ++++ 4 files changed, 63 insertions(+), 18 deletions(-) diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index 593ff8a6c4..0f2071aec0 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -88,6 +88,11 @@ void Session::setLUA(lua_State * state) int Session::originate(CoreSession *a_leg_session, char *dest, int timeout) { + if (zstr(dest)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing destination.\n"); + return 0; + } + int x = CoreSession::originate(a_leg_session, dest, timeout); if (x) { @@ -356,7 +361,7 @@ Dbh::Dbh(char *dsn, char *user, char *pass) dsn = tmp; } - if (switch_cache_db_get_db_handle_dsn(&dbh, dsn) == SWITCH_STATUS_SUCCESS) { + if (!zstr(dsn) && switch_cache_db_get_db_handle_dsn(&dbh, dsn) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "DBH handle %p Connected.\n", (void *) dbh); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Connection failed. DBH NOT Connected.\n"); @@ -391,8 +396,12 @@ bool Dbh::connected() bool Dbh::test_reactive(char *test_sql, char *drop_sql, char *reactive_sql) { if (dbh) { - if (switch_cache_db_test_reactive(dbh, test_sql, drop_sql, reactive_sql) == SWITCH_TRUE) { - return true; + if (!zstr(test_sql) && !zstr(reactive_sql)) { + if (switch_cache_db_test_reactive(dbh, test_sql, drop_sql, reactive_sql) == SWITCH_TRUE) { + return true; + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing parameters.\n"); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DBH NOT Connected.\n"); @@ -431,6 +440,11 @@ int Dbh::query_callback(void *pArg, int argc, char **argv, char **cargv) bool Dbh::query(char *sql, SWIGLUA_FN lua_fun) { + if (zstr(sql)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing SQL query.\n"); + return false; + } + if (dbh) { if (lua_fun.L) { if (switch_cache_db_execute_sql_callback(dbh, sql, query_callback, &lua_fun, NULL) == SWITCH_STATUS_SUCCESS) { @@ -459,6 +473,11 @@ int Dbh::affected_rows() int Dbh::load_extension(const char *extension) { + if (zstr(extension)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing extension name.\n"); + return 0; + } + if (dbh) { return switch_cache_db_load_extension(dbh, extension); } diff --git a/src/switch_core.c b/src/switch_core.c index 88ae93aab7..2d342fb33b 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -393,11 +393,13 @@ SWITCH_DECLARE(char *) switch_core_get_variable_dup(const char *varname) { char *val = NULL, *v; - switch_thread_rwlock_rdlock(runtime.global_var_rwlock); - if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { - val = strdup(v); + if (varname) { + switch_thread_rwlock_rdlock(runtime.global_var_rwlock); + if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { + val = strdup(v); + } + switch_thread_rwlock_unlock(runtime.global_var_rwlock); } - switch_thread_rwlock_unlock(runtime.global_var_rwlock); return val; } @@ -406,11 +408,13 @@ SWITCH_DECLARE(char *) switch_core_get_variable_pdup(const char *varname, switch { char *val = NULL, *v; - switch_thread_rwlock_rdlock(runtime.global_var_rwlock); - if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { - val = switch_core_strdup(pool, v); + if (varname) { + switch_thread_rwlock_rdlock(runtime.global_var_rwlock); + if ((v = (char *) switch_event_get_header(runtime.global_vars, varname))) { + val = switch_core_strdup(pool, v); + } + switch_thread_rwlock_unlock(runtime.global_var_rwlock); } - switch_thread_rwlock_unlock(runtime.global_var_rwlock); return val; } diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index df9c5dbd98..0467109926 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -266,17 +266,24 @@ SWITCH_DECLARE(const char *) API::executeString(const char *cmd) this_check(""); - mycmd = strdup(cmd); + SWITCH_STANDARD_STREAM(stream); - switch_assert(mycmd); + if (zstr(cmd)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No application specified\n"); + stream.write_function(&stream, "-ERR No application specified"); + } else { + mycmd = strdup(cmd); - if ((arg = strchr(mycmd, ' '))) { - *arg++ = '\0'; + switch_assert(mycmd); + + if ((arg = strchr(mycmd, ' '))) { + *arg++ = '\0'; + } + + switch_api_execute(mycmd, arg, session, &stream); + switch_safe_free(mycmd); } - SWITCH_STANDARD_STREAM(stream); - switch_api_execute(mycmd, arg, session, &stream); - switch_safe_free(mycmd); return (char *) stream.data; } @@ -425,6 +432,11 @@ SWITCH_DECLARE(const char *)Event::getHeader(const char *header_name) { this_check(""); + if (zstr(header_name)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Trying to getHeader an invalid header!\n"); + return NULL; + } + if (event) { return switch_event_get_header(event, header_name); } else { @@ -450,6 +462,11 @@ SWITCH_DECLARE(bool) Event::delHeader(const char *header_name) { this_check(false); + if (zstr(header_name)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Trying to delHeader an invalid header!\n"); + return false; + } + if (event) { return switch_event_del_header(event, header_name) == SWITCH_STATUS_SUCCESS ? true : false; } else { diff --git a/src/switch_utils.c b/src/switch_utils.c index 056b28c7bb..707b782feb 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -996,6 +996,11 @@ SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, switch_bool_t rval = SWITCH_FALSE; const char *err = NULL; + if (zstr(to)) { + err = "No to address specified"; + goto end; + } + if (!zstr(file) && !zstr(convert_cmd) && !zstr(convert_ext)) { if ((ext = strrchr(file, '.'))) { dupfile = strdup(file);