From 5c2565765480697771497772fe7f6da76dd6b1e2 Mon Sep 17 00:00:00 2001 From: pabs Date: Thu, 6 Dec 2007 01:42:29 +0000 Subject: [PATCH] Minor security fix: mod_dv used popen to run the DV encoder, change it to use pipe, fork and exec. Strangely named sif files could previously have executed arbitrary shell commands. git-svn-id: http://svn.voria.com/code@1177 1f10aa63-cdf2-0310-b900-c93c546f37ac --- synfig-core/trunk/src/modules/mod_dv/trgt_dv.cpp | 63 ++++++++++++++++++++---- 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/synfig-core/trunk/src/modules/mod_dv/trgt_dv.cpp b/synfig-core/trunk/src/modules/mod_dv/trgt_dv.cpp index 18dc1cd..bc3c181 100644 --- a/synfig-core/trunk/src/modules/mod_dv/trgt_dv.cpp +++ b/synfig-core/trunk/src/modules/mod_dv/trgt_dv.cpp @@ -122,18 +122,61 @@ dv_trgt::init() string command; - if(wide_aspect) - command=strprintf("encodedv -w 1 - > \"%s\"\n",filename.c_str()); - else - command=strprintf("encodedv - > \"%s\"\n",filename.c_str()); - - // Open the pipe to encodedv - file=popen(command.c_str(),POPEN_BINARY_WRITE_TYPE); - - if(!file) - { + int p[2]; + + if (pipe(p)) { + synfig::error(_("Unable to open pipe to encodedv")); + return false; + }; + + pid_t pid = fork(); + + if (pid == -1) { + synfig::error(_("Unable to open pipe to encodedv")); + return false; + } + + if (pid == 0){ + // Child process + // Dup pipeout to stdin + if( dup2( p[0], STDIN_FILENO ) == -1 ){ + synfig::error(_("Unable to open pipe to encodedv")); + return false; + } + + // Open filename to stdout + FILE* outfile = fopen(filename.c_str(),"wb"); + if( outfile == NULL ){ + synfig::error(_("Unable to open pipe to encodedv")); + return false; + } + int outfilefd = fileno(outfile); + if( outfilefd == -1 ){ + synfig::error(_("Unable to open pipe to encodedv")); + return false; + } + if( dup2( outfilefd, STDOUT_FILENO ) == -1 ){ + synfig::error(_("Unable to open pipe to encodedv")); + return false; + } + + if(wide_aspect) + execlp("encodedv", "encodedv", "-w", "1", "-"); + else + execlp("encodedv", "encodedv", "-"); + // We should never reach here unless the exec failed synfig::error(_("Unable to open pipe to encodedv")); return false; + } else { + // Parent process + // Close pipein, not needed + close(p[0]); + // Save pipeout to file handle, will write to it later + file = fdopen(p[1], "wb"); + if (file == NULL) { + synfig::error(_("Unable to open pipe to encodedv")); + return false; + } } // Sleep for a moment to let the pipe catch up -- 2.7.4