Fixing 0000280: stack smashing detected
authorMuhammad Usama <m.usama@gmail.com>
Thu, 26 Jan 2017 20:53:42 +0000 (01:53 +0500)
committerMuhammad Usama <m.usama@gmail.com>
Thu, 26 Jan 2017 20:53:42 +0000 (01:53 +0500)
It was a buffer overflow in wd_get_cmd function

src/include/watchdog/wd_utils.h
src/watchdog/wd_if.c
src/watchdog/wd_utils.c

index 211c8381356382f4f4284599a1f8bd711d5338e6..69bdbd0d029e8cf5de8aea92808a8372f30f971c 100644 (file)
@@ -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);
index 34e08cdc94510c4caa8e347827976a70203f487e..9ab451b50cc8cf18396922cbc98982e12cadebb2 100644 (file)
@@ -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
index 24cefb3dc409ad5d57d2c4eb2294aad48266d4f2..e3c5db2a209f74216a89cf3024fd553c56dbc60a 100644 (file)
@@ -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)));
+       }
+
 }
 
 /*