pgpool2.git / summary / log / commit / refs

commit    b0232aba484ef80a025f677f13c5112e44ee65fb
Author:   Muhammad Usama <m.usama@gmail.com>
Date:     Thu Jan 26 20:53:42 2017 +0000

    Fixing 0000280: stack smashing detected
    
    It was a buffer overflow in wd_get_cmd function


src/include/watchdog/wd_utils.h | 2 +- src/watchdog/wd_if.c | 81 +++++++++++++++++++++++++++++------------ src/watchdog/wd_utils.c | 73 ++++++++++++++++++++++++++----------- 3 files changed, 110 insertions(+), 46 deletions(-) diff --git a/src/include/watchdog/wd_utils.h b/src/include/watchdog/wd_utils.h index 211c83813..69bdbd0d0 100644 --- a/src/include/watchdog/wd_utils.h +++ b/src/include/watchdog/wd_utils.h @@ -53,7 +53,7 @@ extern pid_t wd_issue_ping_command(char* hostname, int* outfd); extern List* get_all_local_ips(void); extern int wd_IP_up(void); extern int wd_IP_down(void); -extern int wd_get_cmd(char * buf, char * cmd); +extern char* wd_get_cmd(char* cmd); extern int create_monitoring_socket(void); extern bool read_interface_change_event(int sock, bool* link_event, bool* deleted); extern bool is_interface_up(struct ifaddrs *ifa); diff --git a/src/watchdog/wd_if.c b/src/watchdog/wd_if.c index 34e08cdc9..9ab451b50 100644 --- a/src/watchdog/wd_if.c +++ b/src/watchdog/wd_if.c @@ -103,22 +103,45 @@ wd_IP_up(void) { int rtn = WD_OK; char path[WD_MAX_PATH_LEN]; - char cmd[128]; + char* command; int i; if (strlen(pool_config->delegate_IP) == 0) return WD_NG; - wd_get_cmd(cmd,pool_config->if_up_cmd); - snprintf(path,sizeof(path),"%s/%s",pool_config->if_cmd_path,cmd); - rtn = exec_if_cmd(path,pool_config->if_up_cmd); + command = wd_get_cmd(pool_config->if_up_cmd); + if (command) + { + snprintf(path,sizeof(path),"%s/%s",pool_config->if_cmd_path,command); + rtn = exec_if_cmd(path,pool_config->if_up_cmd); + pfree(command); + } + else + { + ereport(LOG, + (errmsg("watchdog failed to bring up delegate IP"), + errdetail("command not found in if_up_cmd:\"%s\" configuration",pool_config->if_up_cmd))); + return WD_NG; + } if (rtn == WD_OK) { - wd_get_cmd(cmd,pool_config->arping_cmd); - snprintf(path,sizeof(path),"%s/%s",pool_config->arping_path,cmd); - rtn = exec_if_cmd(path,pool_config->arping_cmd); + command = wd_get_cmd(pool_config->arping_cmd); + if (command) + { + snprintf(path,sizeof(path),"%s/%s",pool_config->arping_path,command); + rtn = exec_if_cmd(path,pool_config->arping_cmd); + pfree(command); + } + else + { + rtn = WD_NG; + ereport(LOG, + (errmsg("watchdog failed to bring up delegate IP"), + errdetail("command not found in arping_cmd:\"%s\" configuration",pool_config->arping_cmd))); + } } + if (rtn == WD_OK) { for (i = 0; i < WD_TRY_PING_AT_IPUP; i++) @@ -149,15 +172,27 @@ wd_IP_down(void) { int rtn = WD_OK; char path[WD_MAX_PATH_LEN]; - char cmd[128]; + char* command; int i; if (strlen(pool_config->delegate_IP) == 0) return WD_NG; - wd_get_cmd(cmd,pool_config->if_down_cmd); - snprintf(path, sizeof(path), "%s/%s", pool_config->if_cmd_path, cmd); - rtn = exec_if_cmd(path,pool_config->if_down_cmd); + command = wd_get_cmd(pool_config->if_down_cmd); + if (command) + { + snprintf(path, sizeof(path), "%s/%s", pool_config->if_cmd_path, command); + rtn = exec_if_cmd(path,pool_config->if_down_cmd); + pfree(command); + } + else + { + ereport(LOG, + (errmsg("watchdog failed to bring down delegate IP"), + errdetail("command not found in if_down_cmd:\"%s\" configuration",pool_config->if_down_cmd))); + return WD_NG; + } + if (rtn == WD_OK) { @@ -186,22 +221,20 @@ wd_IP_down(void) } -int -wd_get_cmd(char * buf, char * cmd) +char* +wd_get_cmd(char* cmd) { - int i,j; - i = 0; - while(isspace(cmd[i]) != 0) - { - i++; - } - j = 0; - while(isspace(cmd[i]) == 0) + char *command = NULL; + + if (cmd && *cmd) { - buf[j++] = cmd[i++]; + char* tmp_str = pstrdup(cmd); + char* token = strtok(tmp_str," "); + if (token) + command = pstrdup(token); + pfree(tmp_str); } - buf[j] = '\0'; - return strlen(buf); + return command; } static int diff --git a/src/watchdog/wd_utils.c b/src/watchdog/wd_utils.c index 24cefb3dc..e3c5db2a2 100644 --- a/src/watchdog/wd_utils.c +++ b/src/watchdog/wd_utils.c @@ -55,7 +55,7 @@ typedef struct { void wd_check_network_command_configurations(void) { char path[128]; - char cmd[128]; + char* command; if (pool_config->use_watchdog == 0) return; @@ -67,34 +67,65 @@ void wd_check_network_command_configurations(void) return; /* check setuid bit of ifup command */ - wd_get_cmd(cmd, pool_config->if_up_cmd); - snprintf(path, sizeof(path), "%s/%s", pool_config->if_cmd_path, cmd); - if (! has_setuid_bit(path)) + command = wd_get_cmd(pool_config->if_up_cmd); + if (command) { - ereport(WARNING, - (errmsg("checking setuid bit of if_up_cmd"), - errdetail("ifup[%s] doesn't have setuid bit", path))); + snprintf(path, sizeof(path), "%s/%s", pool_config->if_cmd_path, command); + pfree(command); + if (! has_setuid_bit(path)) + { + ereport(WARNING, + (errmsg("checking setuid bit of if_up_cmd"), + errdetail("ifup[%s] doesn't have setuid bit", path))); + } + } + else + { + ereport(FATAL, + (errmsg("invalid configuration for if_up_cmd parameter"), + errdetail("unable to get command from \"%s\"",pool_config->if_up_cmd))); } /* check setuid bit of ifdown command */ - wd_get_cmd(cmd, pool_config->if_down_cmd); - snprintf(path, sizeof(path), "%s/%s", pool_config->if_cmd_path, cmd); - if (! has_setuid_bit(path)) + + command = wd_get_cmd(pool_config->if_down_cmd); + if (command) { - ereport(WARNING, - (errmsg("checking setuid bit of if_down_cmd"), - errdetail("ifdown[%s] doesn't have setuid bit", path))); + snprintf(path, sizeof(path), "%s/%s", pool_config->if_cmd_path, command); + pfree(command); + if (! has_setuid_bit(path)) + { + ereport(WARNING, + (errmsg("checking setuid bit of if_down_cmd"), + errdetail("ifdown[%s] doesn't have setuid bit", path))); + } } - + else + { + ereport(FATAL, + (errmsg("invalid configuration for if_down_cmd parameter"), + errdetail("unable to get command from \"%s\"",pool_config->if_down_cmd))); + } + /* check setuid bit of arping command */ - wd_get_cmd(cmd, pool_config->arping_cmd); - snprintf(path, sizeof(path), "%s/%s", pool_config->arping_path, cmd); - if (! has_setuid_bit(path)) + command = wd_get_cmd(pool_config->arping_cmd); + if (command) { - ereport(WARNING, - (errmsg("checking setuid bit of arping command"), - errdetail("arping[%s] doesn't have setuid bit", path))); - + snprintf(path, sizeof(path), "%s/%s", pool_config->arping_path, command); + pfree(command); + if (! has_setuid_bit(path)) + { + ereport(WARNING, + (errmsg("checking setuid bit of arping command"), + errdetail("arping[%s] doesn't have setuid bit", path))); + } } + else + { + ereport(FATAL, + (errmsg("invalid configuration for arping_cmd parameter"), + errdetail("unable to get command from \"%s\"",pool_config->arping_cmd))); + } + } /* [parent: 89572adbcbee]