diff options
Diffstat (limited to 'sys-cluster/torque/files/CVE-2013-4495.4.1.patch')
-rw-r--r-- | sys-cluster/torque/files/CVE-2013-4495.4.1.patch | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/sys-cluster/torque/files/CVE-2013-4495.4.1.patch b/sys-cluster/torque/files/CVE-2013-4495.4.1.patch new file mode 100644 index 000000000000..810a4f0944a5 --- /dev/null +++ b/sys-cluster/torque/files/CVE-2013-4495.4.1.patch @@ -0,0 +1,343 @@ +From 2aad72c3d2ac612ecbb66828ac6ed5ab51eff5f3 Mon Sep 17 00:00:00 2001 +From: David Beer <dbeer@adaptivecomputing.com> +Date: Mon, 11 Nov 2013 11:55:58 -0700 +Subject: [PATCH] Fix CVE 2013-4495. Note: this patch has been verified as + fixing this security hole but has not received other regression testing. + Could not cherry-pick as 2.5 and 4.1 are very different. + +--- + src/server/svr_mail.c | 265 ++++++++++++++++++++++++++++++++------------------ + 1 file changed, 170 insertions(+), 95 deletions(-) + +diff --git a/src/server/svr_mail.c b/src/server/svr_mail.c +index b269e82..52f2f1f 100644 +--- a/src/server/svr_mail.c ++++ b/src/server/svr_mail.c +@@ -89,6 +89,7 @@ + #include <stdio.h> + #include <stdlib.h> + #include <string.h> ++#include <unistd.h> + #include "list_link.h" + #include "attribute.h" + #include "server_limits.h" +@@ -136,6 +137,77 @@ void free_mail_info( + + + ++void add_body_info( ++ ++ char *bodyfmtbuf /* I */, ++ mail_info *mi /* I */) ++ ++ { ++ char *bodyfmt = NULL; ++ bodyfmt = strcpy(bodyfmtbuf, "PBS Job Id: %i\n" ++ "Job Name: %j\n"); ++ if (mi->exec_host != NULL) ++ { ++ strcat(bodyfmt, "Exec host: %h\n"); ++ } ++ ++ strcat(bodyfmt, "%m\n"); ++ ++ if (mi->text != NULL) ++ { ++ strcat(bodyfmt, "%d\n"); ++ } ++ } ++ ++ ++/* ++ * write_email() ++ * ++ * In emailing, the mail body is written to a pipe connected to ++ * standard input for sendmail. This function supplies the body ++ * of the message. ++ * ++ */ ++void write_email( ++ ++ FILE *outmail_input, ++ mail_info *mi) ++ ++ { ++ char *bodyfmt = NULL; ++ char *subjectfmt = NULL; ++ ++ /* Pipe in mail headers: To: and Subject: */ ++ fprintf(outmail_input, "To: %s\n", mi->mailto); ++ ++ /* mail subject line formating statement */ ++ get_svr_attr_str(SRV_ATR_MailSubjectFmt, (char **)&subjectfmt); ++ if (subjectfmt == NULL) ++ { ++ subjectfmt = "PBS JOB %i"; ++ } ++ ++ fprintf(outmail_input, "Subject: "); ++ svr_format_job(outmail_input, mi, subjectfmt); ++ fprintf(outmail_input, "\n"); ++ ++ /* Set "Precedence: bulk" to avoid vacation messages, etc */ ++ fprintf(outmail_input, "Precedence: bulk\n\n"); ++ ++ /* mail body formating statement */ ++ get_svr_attr_str(SRV_ATR_MailBodyFmt, &bodyfmt); ++ if (bodyfmt == NULL) ++ { ++ char bodyfmtbuf[MAXLINE]; ++ add_body_info(bodyfmtbuf, mi); ++ bodyfmt = bodyfmtbuf; ++ } ++ ++ /* Now pipe in the email body */ ++ svr_format_job(outmail_input, mi, bodyfmt); ++ ++ } /* write_email() */ ++ + + + void *send_the_mail( +@@ -143,15 +215,19 @@ void *send_the_mail( + void *vp) + + { +- mail_info *mi = (mail_info *)vp; +- +- int i; +- char *mailfrom = NULL; +- char *subjectfmt = NULL; +- char *bodyfmt = NULL; +- char *cmdbuf = NULL; +- char bodyfmtbuf[MAXLINE]; +- FILE *outmail; ++ mail_info *mi = (mail_info *)vp; ++ ++ int status = 0; ++ int numargs = 0; ++ int pipes[2]; ++ int counter; ++ pid_t pid; ++ char *mailptr; ++ char *mailfrom = NULL; ++ char tmpBuf[LOG_BUF_SIZE]; ++ // We call sendmail with cmd_name + 2 arguments + # of mailto addresses + 1 for null ++ char *sendmail_args[100]; ++ FILE *stream; + + /* Who is mail from, if SRV_ATR_mailfrom not set use default */ + get_svr_attr_str(SRV_ATR_mailfrom, &mailfrom); +@@ -173,124 +249,123 @@ void *send_the_mail( + mailfrom = PBS_DEFAULT_MAIL; + } + +- /* mail subject line formating statement */ +- get_svr_attr_str(SRV_ATR_MailSubjectFmt, &subjectfmt); +- if (subjectfmt == NULL) +- { +- subjectfmt = "PBS JOB %i"; +- } ++ sendmail_args[numargs++] = (char *)SENDMAIL_CMD; ++ sendmail_args[numargs++] = (char *)"-f"; ++ sendmail_args[numargs++] = (char *)mailfrom; + +- /* mail body formating statement */ +- get_svr_attr_str(SRV_ATR_MailBodyFmt, &bodyfmt); +- if (bodyfmt == NULL) ++ /* Add the e-mail addresses to the command line */ ++ mailptr = strdup(mi->mailto); ++ sendmail_args[numargs++] = mailptr; ++ for (counter=0; counter < (int)strlen(mailptr); counter++) + { +- bodyfmt = strcpy(bodyfmtbuf, "PBS Job Id: %i\n" +- "Job Name: %j\n"); +- if (mi->exec_host != NULL) ++ if (mailptr[counter] == ',') + { +- strcat(bodyfmt, "Exec host: %h\n"); +- } +- +- strcat(bodyfmt, "%m\n"); +- +- if (mi->text != NULL) +- { +- strcat(bodyfmt, "%d\n"); ++ mailptr[counter] = '\0'; ++ sendmail_args[numargs++] = mailptr + counter + 1; ++ if (numargs >= 99) ++ break; + } + } + +- /* setup sendmail command line with -f from_whom */ +- i = strlen(SENDMAIL_CMD) + strlen(mailfrom) + strlen(mi->mailto) + 6; +- +- if ((cmdbuf = calloc(1, i + 1)) == NULL) ++ sendmail_args[numargs] = NULL; ++ ++ /* Create a pipe to talk to the sendmail process we are about to fork */ ++ if (pipe(pipes) == -1) + { +- char tmpBuf[LOG_BUF_SIZE]; +- +- snprintf(tmpBuf,sizeof(tmpBuf), +- "Unable to popen() command '%s' for writing: '%s' (error %d)\n", +- SENDMAIL_CMD, +- strerror(errno), +- errno); ++ snprintf(tmpBuf, sizeof(tmpBuf), "Unable to pipes for sending e-mail\n"); + log_event(PBSEVENT_ERROR | PBSEVENT_ADMIN | PBSEVENT_JOB, + PBS_EVENTCLASS_JOB, + mi->jobid, + tmpBuf); +- +- free_mail_info(mi); + ++ free_mail_info(mi); ++ free(mailptr); + return(NULL); + } + +- sprintf(cmdbuf, "%s -f %s %s", +- SENDMAIL_CMD, +- mailfrom, +- mi->mailto); +- +- outmail = popen(cmdbuf, "w"); +- +- if (outmail == NULL) ++ if ((pid=fork()) == -1) + { +- char tmpBuf[LOG_BUF_SIZE]; +- +- snprintf(tmpBuf,sizeof(tmpBuf), +- "Unable to popen() command '%s' for writing: '%s' (error %d)\n", +- cmdbuf, +- strerror(errno), +- errno); ++ snprintf(tmpBuf, sizeof(tmpBuf), "Unable to fork for sending e-mail\n"); + log_event(PBSEVENT_ERROR | PBSEVENT_ADMIN | PBSEVENT_JOB, + PBS_EVENTCLASS_JOB, + mi->jobid, + tmpBuf); + + free_mail_info(mi); +- free(cmdbuf); +- ++ free(mailptr); ++ close(pipes[0]); ++ close(pipes[1]); + return(NULL); + } ++ else if (pid == 0) ++ { ++ /* CHILD */ + +- /* Pipe in mail headers: To: and Subject: */ +- fprintf(outmail, "To: %s\n", mi->mailto); ++ /* Make stdin the read end of the pipe */ ++ dup2(pipes[0], 0); + +- fprintf(outmail, "Subject: "); +- svr_format_job(outmail, mi, subjectfmt); +- fprintf(outmail, "\n"); ++ /* Close the rest of the open file descriptors */ ++ int numfds = sysconf(_SC_OPEN_MAX); ++ while (--numfds > 0) ++ close(numfds); + +- /* Set "Precedence: bulk" to avoid vacation messages, etc */ +- fprintf(outmail, "Precedence: bulk\n\n"); ++ execv(SENDMAIL_CMD, sendmail_args); ++ /* This never returns, but if the execv fails the child should exit */ ++ exit(1); ++ } ++ else ++ { ++ /* This is the parent */ + +- /* Now pipe in the email body */ +- svr_format_job(outmail, mi, bodyfmt); ++ /* Close the read end of the pipe */ ++ close(pipes[0]); + +- errno = 0; +- if ((i = pclose(outmail)) != 0) +- { +- char tmpBuf[LOG_BUF_SIZE]; ++ /* Write the body to the pipe */ ++ stream = fdopen(pipes[1], "w"); ++ write_email(stream, mi); + +- snprintf(tmpBuf,sizeof(tmpBuf), +- "Email '%c' to %s failed: Child process '%s' %s %d (errno %d:%s)\n", +- mi->mail_point, +- mi->mailto, +- cmdbuf, +- ((WIFEXITED(i)) ? ("returned") : ((WIFSIGNALED(i)) ? ("killed by signal") : ("croaked"))), +- ((WIFEXITED(i)) ? (WEXITSTATUS(i)) : ((WIFSIGNALED(i)) ? (WTERMSIG(i)) : (i))), +- errno, +- strerror(errno)); +- log_event(PBSEVENT_ERROR | PBSEVENT_ADMIN | PBSEVENT_JOB, +- PBS_EVENTCLASS_JOB, +- mi->jobid, +- tmpBuf); +- } +- else if (LOGLEVEL >= 4) +- { +- log_event(PBSEVENT_ERROR | PBSEVENT_ADMIN | PBSEVENT_JOB, +- PBS_EVENTCLASS_JOB, +- mi->jobid, +- "Email sent successfully\n"); +- } ++ fflush(stream); ++ ++ /* Close and wait for the command to finish */ ++ if (fclose(stream) != 0) ++ { ++ snprintf(tmpBuf,sizeof(tmpBuf), ++ "Piping mail body to sendmail closed: errno %d:%s\n", ++ errno, strerror(errno)); ++ ++ log_event(PBSEVENT_ERROR | PBSEVENT_ADMIN | PBSEVENT_JOB, ++ PBS_EVENTCLASS_JOB, ++ mi->jobid, ++ tmpBuf); ++ } ++ ++ // we aren't going to block in order to find out whether or not sendmail worked ++ if ((waitpid(pid, &status, WNOHANG) != 0) && ++ (status != 0)) ++ { ++ snprintf(tmpBuf,sizeof(tmpBuf), ++ "Sendmail command returned %d. Mail may not have been sent\n", ++ status); ++ ++ log_event(PBSEVENT_ERROR | PBSEVENT_ADMIN | PBSEVENT_JOB, ++ PBS_EVENTCLASS_JOB, ++ mi->jobid, ++ tmpBuf); ++ } + +- free_mail_info(mi); +- free(cmdbuf); ++ // don't leave zombies ++ while (waitpid(-1, &status, WNOHANG) != 0) ++ { ++ // zombie reaped, NO-OP ++ } ++ ++ free_mail_info(mi); ++ free(mailptr); ++ return(NULL); ++ } + ++ /* NOT REACHED */ ++ + return(NULL); + } /* END send_the_mail() */ + +-- +1.8.3.2 + |