Minor security fix: mod_dv used popen to run the DV encoder, change it to use pipe...
authorpabs <pabs@1f10aa63-cdf2-0310-b900-c93c546f37ac>
Thu, 6 Dec 2007 01:42:29 +0000 (01:42 +0000)
committerpabs <pabs@1f10aa63-cdf2-0310-b900-c93c546f37ac>
Thu, 6 Dec 2007 01:42:29 +0000 (01:42 +0000)
git-svn-id: http://svn.voria.com/code@1177 1f10aa63-cdf2-0310-b900-c93c546f37ac

synfig-core/trunk/src/modules/mod_dv/trgt_dv.cpp

index 18dc1cd..bc3c181 100644 (file)
@@ -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