From 98b59da9adff0580df5325a931585e9eea71d588 Mon Sep 17 00:00:00 2001 From: Mark Spencer <markster@digium.com> Date: Sun, 21 Mar 2004 18:15:37 +0000 Subject: [PATCH] Create ast_safe_system which closes off file descriptors before spawning system() and so on. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2514 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_voicemail.c | 25 +++++++++++++++++------ asterisk.c | 45 ++++++++++++++++++++++++++++++++++++++---- include/asterisk/app.h | 3 +++ 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 5a4196b7d7..f67d03c646 100755 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -825,7 +825,7 @@ static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *m } fclose(p); snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); - system(tmp2); + ast_safe_system(tmp2); ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", who, mailcmd); } else { ast_log(LOG_WARNING, "Unable to launch '%s'\n", mailcmd); @@ -836,16 +836,27 @@ static int sendmail(char *srcemail, struct ast_vm_user *vmu, int msgnum, char *m static int sendpage(char *srcemail, char *pager, int msgnum, char *mailbox, char *callerid, long duration, struct ast_vm_user *vmu) { - FILE *p; + FILE *p=NULL; + int pfd; char date[256]; char host[256]; char who[256]; char dur[256]; + char tmp[80] = "/tmp/astmail-XXXXXX"; + char tmp2[256]; time_t t; struct tm tm; struct vm_zone *the_zone = NULL; p = popen(mailcmd, "w"); + if (pfd > -1) { + p = fdopen(pfd, "w"); + if (!p) { + close(pfd); + pfd = -1; + } + } + if (p) { gethostname(host, sizeof(host)); if (strchr(srcemail, '@')) @@ -883,7 +894,9 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *mailbox, char strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm); fprintf(p, "New %s long msg in box %s\n" "from %s, on %s", dur, mailbox, (callerid ? callerid : "unknown"), date); - pclose(p); + fclose(p); + snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", mailcmd, tmp, tmp); + ast_safe_system(tmp2); ast_log(LOG_DEBUG, "Sent mail to %s with command '%s'\n", who, mailcmd); } else { ast_log(LOG_WARNING, "Unable to launch '%s'\n", mailcmd); @@ -2296,7 +2309,7 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i snprintf(todir, sizeof(todir), "%s/voicemail/%s/%s/INBOX", (char *)ast_config_AST_SPOOL_DIR, vmtmp->context, vmtmp->mailbox); snprintf(sys, sizeof(sys), "mkdir -p %s\n", todir); ast_log(LOG_DEBUG, sys); - system(sys); + ast_safe_system(sys); todircount = count_messages(todir); strncpy(tmp, fmt, sizeof(tmp) - 1); @@ -2307,11 +2320,11 @@ static int forward_message(struct ast_channel *chan, char *context, char *dir, i s = "WAV"; snprintf(sys, sizeof(sys), "cp %s/msg%04d.%s %s/msg%04d.%s\n", dir, curmsg, s, todir, todircount, s); ast_log(LOG_DEBUG, sys); - system(sys); + ast_safe_system(sys); } snprintf(sys, sizeof(sys), "cp %s/msg%04d.txt %s/msg%04d.txt\n", dir, curmsg, todir, todircount); ast_log(LOG_DEBUG, sys); - system(sys); + ast_safe_system(sys); snprintf(fn, sizeof(fn), "%s/msg%04d", todir,todircount); /* load the information on the source message so we can send an e-mail like a new message */ diff --git a/asterisk.c b/asterisk.c index 2811a7cad4..5e1d812153 100755 --- a/asterisk.c +++ b/asterisk.c @@ -28,6 +28,7 @@ #include <asterisk/pbx.h> #include <asterisk/enum.h> #include <asterisk/rtp.h> +#include <asterisk/app.h> #include <sys/resource.h> #include <fcntl.h> #include <stdio.h> @@ -153,6 +154,42 @@ static int fdprint(int fd, const char *s) return write(fd, s, strlen(s) + 1); } +int ast_safe_system(const char *s) +{ + /* XXX This function needs some optimization work XXX */ + pid_t pid; + int x; + int res; + struct rusage rusage; + int status; + pid = fork(); + if (pid == 0) { + /* Close file descriptors and launch system command */ + for (x=STDERR_FILENO + 1; x<4096;x++) { + close(x); + } + res = system(s); + exit(res); + } else if (pid > 0) { + for(;;) { + res = wait4(pid, &status, 0, &rusage); + if (res > -1) { + if (WIFEXITED(status)) + res = WEXITSTATUS(status); + else + res = -1; + } else { + if (errno != EINTR) + break; + } + } + } else { + ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno)); + res = -1; + } + return res; +} + /* * write the string to all attached console clients */ @@ -607,9 +644,9 @@ static void consolehandler(char *s) /* The real handler for bang */ if (s[0] == '!') { if (s[1]) - system(s+1); + ast_safe_system(s+1); else - system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh"); + ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh"); } else ast_cli_command(STDOUT_FILENO, s); } else @@ -627,9 +664,9 @@ static int remoteconsolehandler(char *s) /* The real handler for bang */ if (s[0] == '!') { if (s[1]) - system(s+1); + ast_safe_system(s+1); else - system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh"); + ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh"); ret = 1; } if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) && diff --git a/include/asterisk/app.h b/include/asterisk/app.h index ef7b05c27d..d32575be9d 100755 --- a/include/asterisk/app.h +++ b/include/asterisk/app.h @@ -45,6 +45,9 @@ extern int ast_app_has_voicemail(const char *mailbox); //! Determine number of new/old messages in a mailbox extern int ast_app_messagecount(const char *mailbox, int *newmsgs, int *oldmsgs); +//! Safely spawn an external program while closingn file descriptors +extern int ast_safe_system(const char *s); + #if defined(__cplusplus) || defined(c_plusplus) } #endif -- GitLab