]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: checks: segfault with external checks in a backend section
authorCyril Bonté <cyril.bonte@free.fr>
Wed, 6 Aug 2014 23:55:38 +0000 (01:55 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 7 Aug 2014 05:23:51 +0000 (07:23 +0200)
The documentation indicates that external checks can be used in a backend
section, but the code requires a listener to provide information in the script
arguments.
External checks were initialized lately, during the first check, leaving some
variables uninitialized in such a scenario, which trigger the segfault when
accessed to collect errors information.

To prevent the segfault, currently we should initialize the external checks
earlier, during the process initialiation itself and quit if the error occurs.

This fix is specific to the 1.6 branch.

src/checks.c

index 2c9958acab6264f1b4c472d7101a84d3d531efba..aad2037caa16a962904fafb2a0678ac99333f526 100644 (file)
@@ -1627,7 +1627,7 @@ static int prepare_external_check(struct check *check)
                if (!check->argv[i])
                        goto err;
 
-       return 0;
+       return 1;
 err:
        if (check->envp) {
                free(check->envp[1]);
@@ -1642,7 +1642,7 @@ err:
                check->argv = NULL;
        }
        Alert(err_fmt, px->id, s->id);
-       return -1;
+       return 0;
 }
 
 /*
@@ -1667,12 +1667,6 @@ static int connect_proc_chk(struct task *t)
        int status;
        pid_t pid;
 
-       if (!check->argv) {
-               status = prepare_external_check(check);
-               if (status < 0)
-                       return SN_ERR_RESOURCE;
-       }
-
        status = SN_ERR_RESOURCE;
 
        block_sigchld();
@@ -2140,6 +2134,10 @@ int start_checks() {
                for (s = px->srv; s; s = s->next) {
                        /* A task for the main check */
                        if (s->check.state & CHK_ST_CONFIGURED) {
+                               if (s->check.type == PR_O2_EXT_CHK) {
+                                       if (!prepare_external_check(&s->check))
+                                               return -1;
+                               }
                                if (!start_check_task(&s->check, mininter, nbcheck, srvpos))
                                        return -1;
                                srvpos++;