https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78433

            Bug ID: 78433
           Summary: [7 Regression] glibc posix/execvpe.c gets miscompiled
                    with -O3
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: trippels at gcc dot gnu.org
  Target Milestone: ---

Created attachment 40088
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40088&action=edit
unreduced testcase

glibc's posix/execvpe.c gets miscompiled with -O3:

markus@x4 posix % ./tst-vfork3
script 1
script 1
script 1
script 1
script 1
/bin/sh: : No such file or directory
script2.sh failed with status 32512

12912 execve("/tmp/tst-vfork3.Ox2RZ9/script2.sh", ["script2.sh", "2"], [/* 53
vars */]) = -1 ENOEXEC (Exec format error)                                      
12912 execve("/bin/sh", ["/bin/sh", "\1", "2"], [/* 53 vars */] <unfinished
...> 

Notice the bogus "\1" in the second execve call.

 36 /* The file is accessible but it is not an executable file.  Invoke         
 37    the shell to interpret it as a script.  */                               
 38 static void                                                                 
 39 maybe_script_execute (const char *file, char *const argv[], char *const
envp[])                                                                         
 40 {                                                                           
 41   ptrdiff_t argc = 0;                                                       
 42   while (argv[argc++] != NULL)                                              
 43     {                                                                       
 44       if (argc == INT_MAX - 1)                                              
 45         {                                                                   
 46           errno = E2BIG;                                                    
 47           return;                                                           
 48         }                                                                   
 49     }                                                                       
 50                                                                             
 51   /* Construct an argument list for the shell.  */                          
 52   char *new_argv[argc + 1];                                                 
 53   new_argv[0] = (char *) _PATH_BSHELL;                                      
 54   new_argv[1] = (char *) file;                                              
 55   if (argc > 1)                                                             
 56     memcpy (new_argv + 2, argv + 1, argc * sizeof(char *));                 
 57   else                                                                      
 58     new_argv[2] = NULL;                                                     
 59                                                                             
 60   /* Execute the shell.  */                                                 
 61   __execve (new_argv[0], new_argv, envp);                                   
 62 }                                                                           
 63                                                                             
 64                                                                             
 65 /* Execute FILE, searching in the `PATH' environment variable if it
contains                                                                        
 66    no slashes, with arguments ARGV and environment from ENVP.  */           
 67 int                                                                         
 68 __execvpe (const char *file, char *const argv[], char *const envp[])        
 69 {                                                                           
 70   /* We check the simple case first. */                                     
 71   if (*file == '\0')                                                        
 72     {                                                                       
 73       __set_errno (ENOENT);                                                 
 74       return -1;                                                            
 75     }                                                                       
 76                                                                             
 77   /* Don't search when it contains a slash.  */                             
 78   if (strchr (file, '/') != NULL)                                           
 79     {                                                                       
 80       __execve (file, argv, envp);                                          
 81                                                                             
 82       if (errno == ENOEXEC)                                                 
 83         maybe_script_execute (file, argv, envp);                            
 84                                                                             
 85       return -1;                                                            
 86     }                                                                       
 87       

I haven't looked deeper yet.

Reply via email to