Changeset: 79ce5a8417ef for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=79ce5a8417ef Modified Files: tools/merovingian/daemon/controlrunner.c tools/merovingian/daemon/forkmserver.c tools/merovingian/daemon/merovingian.c tools/merovingian/daemon/merovingian.h Branch: Jun2016 Log Message:
Fix potential use-after-free. If the child dies and the childhandler cleans it up after its corresponding record was found in the _mero_topdp linked list, but before it could be killed in terminateProcess, this function might use the record after it was freed by childhandler. diffs (91 lines): diff --git a/tools/merovingian/daemon/controlrunner.c b/tools/merovingian/daemon/controlrunner.c --- a/tools/merovingian/daemon/controlrunner.c +++ b/tools/merovingian/daemon/controlrunner.c @@ -340,7 +340,7 @@ static void ctl_handle_client( if (dp->type == MERODB && strcmp(dp->dbname, q) == 0) { pthread_mutex_unlock(&_mero_topdp_lock); if (strcmp(p, "stop") == 0) { - terminateProcess(dp, 1); + terminateProcess(dp->pid, strdup(dp->dbname), dp->type, 1); Mfprintf(_mero_ctlout, "%s: stopped " "database '%s'\n", origin, q); } else { diff --git a/tools/merovingian/daemon/forkmserver.c b/tools/merovingian/daemon/forkmserver.c --- a/tools/merovingian/daemon/forkmserver.c +++ b/tools/merovingian/daemon/forkmserver.c @@ -36,15 +36,12 @@ static pthread_mutex_t fork_lock = PTHRE * sends the deadly SIGKILL signal to the mserver process and returns. */ void -terminateProcess(dpair d, int lock) +terminateProcess(pid_t pid, char *dbname, mtype type, int lock) { sabdb *stats; char *er; int i; confkeyval *kv; - /* make local copies since d will disappear when killed */ - pid_t pid = d->pid; - char *dbname = strdup(d->dbname); if (lock) pthread_mutex_lock(&fork_lock); @@ -107,14 +104,14 @@ terminateProcess(dpair d, int lock) return; } - if (d->type == MEROFUN) { + if (type == MEROFUN) { if (lock) pthread_mutex_unlock(&fork_lock); multiplexDestroy(dbname); msab_freeStatus(&stats); free(dbname); return; - } else if (d->type != MERODB) { + } else if (type != MERODB) { /* barf */ if (lock) pthread_mutex_unlock(&fork_lock); @@ -648,14 +645,14 @@ forkMserver(char *database, sabdb** stat if (scen == NULL) { /* we don't know what it's doing, but we don't like it * any case, so kill it */ - terminateProcess(dp, 0); + terminateProcess(pid, strdup(database), MERODB, 0); msab_freeStatus(stats); pthread_mutex_unlock(&fork_lock); return(newErr("database '%s' did not initialise the sql " "scenario", database)); } } else if (dp != NULL) { - terminateProcess(dp, 0); + terminateProcess(pid, strdup(database), MERODB, 0); msab_freeStatus(stats); pthread_mutex_unlock(&fork_lock); return(newErr( diff --git a/tools/merovingian/daemon/merovingian.c b/tools/merovingian/daemon/merovingian.c --- a/tools/merovingian/daemon/merovingian.c +++ b/tools/merovingian/daemon/merovingian.c @@ -265,7 +265,8 @@ newErr(const char *fmt, ...) static void * doTerminateProcess(void *p) { - terminateProcess((dpair) p, 1); + dpair dp = p; + terminateProcess(dp->pid, strdup(dp->dbname), dp->type, 1); return NULL; } diff --git a/tools/merovingian/daemon/merovingian.h b/tools/merovingian/daemon/merovingian.h --- a/tools/merovingian/daemon/merovingian.h +++ b/tools/merovingian/daemon/merovingian.h @@ -60,7 +60,7 @@ typedef struct _dpair { char *newErr(_In_z_ _Printf_format_string_ const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2))); -void terminateProcess(dpair d, int lock); +void terminateProcess(pid_t pid, char *dbname, mtype type, int lock); void logFD(int fd, char *type, char *dbname, long long int pid, FILE *stream); extern char *_mero_mserver; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list