delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2012/11/29/17:29:21

X-Recipient: archive-cygwin AT delorie DOT com
X-SWARE-Spam-Status: No, hits=-3.3 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,RP_MATCHES_RCVD,SPF_HELO_PASS
X-Spam-Check-By: sourceware.org
X-IronPortListener: Outbound_SMTP
X-IronPort-Anti-Spam-Filtered: true
X-IronPort-Anti-Spam-Result: AhwLAKPgt1CcKEes/2dsb2JhbABEwAUWbAeCIAEEEihRARUVFC8TFwEOAQQbGodunWCESZxukCBhA401hRqEToRxijeCcoIh
From: "Lavrentiev, Anton (NIH/NLM/NCBI) [C]" <lavr AT ncbi DOT nlm DOT nih DOT gov>
To: "cygwin AT cygwin DOT com" <cygwin AT cygwin DOT com>
Subject: A bug in CYGWIN exec() and revision of argument values
Date: Thu, 29 Nov 2012 22:28:59 +0000
Message-ID: <5F8AAC04F9616747BC4CC0E803D5907D043F3096@MLBXV09.nih.gov>
MIME-Version: 1.0
X-IsSubscribed: yes
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id qATMTHqU030652

Hi,

I stumbled across yet another problem (or two), now in CYGWIN exec() implementation,
which is demonstrated by the test case.

1. Using CMD.EXE as a command with the "/C" switch (note the capital letter
   just as Windows documents this switch for CMD.EXE) does not trigger the special
   handing in cygwin/spawn.cc, because of this case-sensitive comparison with
   the lowercase 'c' (around line 392):

  if (ac == 3 && argv[1][0] == '/' && argv[1][1] == 'c' &&
      (iscmd (argv[0], "command.com") || iscmd (argv[0], "cmd.exe")))

   It's interesting that the iscmd() calls that follow, do treat "command.com" or
   "cmd.exe" case-insensitively.  So I guess, tolower() is in order for the 'c'
   comparison.

2. Due to the bug in 1., the flow control in the "else" clause then reveals the
   following problem:  if a single backslash was given in the command, it would
   be doubled.

   To prove this, consider executing the program like this:

   ./a 'C:\Windows\System32\CMD.EXE' '/C' 'ECHO C:\'

   You'll see:

   About to exec(C:\Windows\System32\cmd.exe /C ECHO C:\)
   C:\\

   Try it with small '/c' to see the difference and bypass the bug.

   strace confirms the argument modification:

21508   36588 [main] a 7132 child_info_spawn::worker: pid 7132, prog_arg C:\Windows\System32\CMD.EXE, cmd line C:\Windows\System32\CMD.EXE /C "ECHO C:\\")

   Implementation of linebuf::fromargv (file winf.cc) suggests that the observed
   doubling of a backslash occurs only if the backslash is the last character in the
   argument (which is also to contain spaces or quotes), so it won't accidentally glue
   to the enveloping quote character, which is injected by CYGWIN when forming the
   command line.

   Indeed, this works (try it without the space to see what I initially saw in
   my application and that prompted all the above analysis):

   ./a 'C:\Windows\System32\CMD.EXE' '/C' 'DIR C:\ '

   Any insight will be much appreciated.

Thanks,

Anton Lavrentiev
Contractor NIH/NLM/NCBI

#include <errno.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
   printf("About to exec(%s %s %s)\n", argv[1], argv[2], argv[3]);

   execvp(argv[1], &argv[1]);

   fprintf(stderr, "Exec failed, error = %d\n", errno);
   return 0;
}


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019