This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix PR43021


On Wed, 10 Feb 2010, Richard Guenther wrote:

> 
> This fixes a regression in the driver where we no longer accept
> input files which contain a '@'.  This is due to the LTO static
> archive special-casing of name@offset.  The following patch
> simply makes some extra checks before going that path.

Instead of the very simple-minded fix I've gone to the following
which more properly detects name@offset.  First it uses strrchr
to allow @ in name, second it verifies that after offset there
is no junk and that offset is an offset.  By that it avoids
a security issue by not blindly skipping @0x without checking
it is really there.

It also makes sure to report the full name as missing instead of
a crippled one.

Bootstrapped and tested on x86_64-unknown-linux-gnu.  I verified
that archives still work properly with -fuse-linker-plugin and
that the filenames in the PR are now accepted.

The new behavior follows that of response-files in that if there
isn't a response file the original file is kept and diagnosed.

Installed to trunk.

Richard.

2010-02-11  Richard Guenther  <rguenther@suse.de>

	PR driver/43021
	* gcc.c (process_command): Handle LTO file@offset case more
	appropriately.

	lto/
	* lto-elf.c (lto_elf_file_open): Handle file@offset case more
	appropriately.

Index: gcc/gcc.c
===================================================================
*** gcc/gcc.c	(revision 156693)
--- gcc/gcc.c	(working copy)
*************** process_command (int argc, const char **
*** 4575,4594 ****
  	}
        else
  	{
!           const char *p = strchr (argv[i], '@');
            char *fname;
  #ifdef HAVE_TARGET_OBJECT_SUFFIX
  	  argv[i] = convert_filename (argv[i], 0, access (argv[i], F_OK));
  #endif
!           if (!p)
!             fname = xstrdup (argv[i]);
!           else
!             {
                fname = (char *)xmalloc (p - argv[i] + 1);
                memcpy (fname, argv[i], p - argv[i]);
                fname[p - argv[i]] = '\0';
!             }
! 
            if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0)
              {
                perror_with_name (fname);
--- 4575,4609 ----
  	}
        else
  	{
!           const char *p = strrchr (argv[i], '@');
            char *fname;
+ 	  long offset;
+ 	  int consumed;
  #ifdef HAVE_TARGET_OBJECT_SUFFIX
  	  argv[i] = convert_filename (argv[i], 0, access (argv[i], F_OK));
  #endif
! 	  /* For LTO static archive support we handle input file
! 	     specifications that are composed of a filename and
! 	     an offset like FNAME@OFFSET.  */
! 	  if (p
! 	      && p != argv[i]
! 	      && sscanf (p, "@%li%n", &offset, &consumed) >= 1
! 	      && strlen (p) == (unsigned int)consumed)
! 	    {
                fname = (char *)xmalloc (p - argv[i] + 1);
                memcpy (fname, argv[i], p - argv[i]);
                fname[p - argv[i]] = '\0';
! 	      /* Only accept non-stdin and existing FNAME parts, otherwise
! 		 try with the full name.  */
! 	      if (strcmp (fname, "-") == 0 || access (fname, F_OK) < 0)
! 		{
! 		  free (fname);
! 		  fname = xstrdup (argv[i]);
! 		}
! 	    }
! 	  else
! 	    fname = xstrdup (argv[i]);
!  
            if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0)
              {
                perror_with_name (fname);
Index: gcc/lto/lto-elf.c
===================================================================
*** gcc/lto/lto-elf.c	(revision 156693)
--- gcc/lto/lto-elf.c	(working copy)
*************** lto_elf_file_open (const char *filename,
*** 550,584 ****
    lto_elf_file *elf_file;
    lto_file *result = NULL;
    off_t offset;
    off_t header_offset;
    const char *offset_p;
    char *fname;
  
!   offset_p = strchr (filename, '@');
!   if (!offset_p)
      {
-       fname = xstrdup (filename);
-       offset = 0;
-       header_offset = 0;
-     }
-   else
-     {
-       /* The file started with '@' is a file containing command line
- 	 options.  Stop if it doesn't exist.  */
-       if (offset_p == filename)
- 	fatal_error ("command line option file '%s' does not exist",
- 		     filename);
- 
        fname = (char *) xmalloc (offset_p - filename + 1);
        memcpy (fname, filename, offset_p - filename);
        fname[offset_p - filename] = '\0';
!       offset_p += 3; /* skip the @0x */
!       offset = lto_parse_hex (offset_p);
        /* elf_rand expects the offset to point to the ar header, not the
           object itself. Subtract the size of the ar header (60 bytes).
           We don't uses sizeof (struct ar_hd) to avoid including ar.h */
        header_offset = offset - 60;
      }
  
    /* Set up.  */
    elf_file = XCNEW (lto_elf_file);
--- 550,582 ----
    lto_elf_file *elf_file;
    lto_file *result = NULL;
    off_t offset;
+   long loffset;
    off_t header_offset;
    const char *offset_p;
    char *fname;
+   int consumed;
  
!   offset_p = strrchr (filename, '@');
!   if (offset_p
!       && offset_p != filename
!       && sscanf (offset_p, "@%li%n", &loffset, &consumed) >= 1
!       && strlen (offset_p) == (unsigned int)consumed)
      {
        fname = (char *) xmalloc (offset_p - filename + 1);
        memcpy (fname, filename, offset_p - filename);
        fname[offset_p - filename] = '\0';
!       offset = (off_t)loffset;
        /* elf_rand expects the offset to point to the ar header, not the
           object itself. Subtract the size of the ar header (60 bytes).
           We don't uses sizeof (struct ar_hd) to avoid including ar.h */
        header_offset = offset - 60;
      }
+   else
+     {
+       fname = xstrdup (filename);
+       offset = 0;
+       header_offset = 0;
+     }
  
    /* Set up.  */
    elf_file = XCNEW (lto_elf_file);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]