This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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]

Committed: Do not make non-regular files executable.


Hi Guys,

  I am applying the attached patch which is based on a bug report
  submitted to the Fedora bugzilla database (BZ 503426).  The problem
  was that the linker would attempt to add execute permission to a
  non-regular file if was given that file as an output.  This does not
  make a lot of sense and can trigger an exception in a secure
  system.  (The particular scenario where this happens was part of
  the kernel build process on an SELinux system where the linker was
  being invoked as "ld [...] -o /dev/null".

  Tested by building and regression checking all the usual toolchains.

Cheers
  Nick

bfd/ChangeLog
2009-06-11  Eric Paris  <eparis@redhat.com>
	    Nick Clifton  <nickc@redhat.com>

	* opncls.c (_maybe_make_executable): New function.  Gives execute
	permission to an executable bfd that was opened for writing
	provided that it is a regular file.  Replaces common code found in...
	(bfd_close): here and ...
	(bfd_close_all_done): here.

Index: bfd/opncls.c
===================================================================
RCS file: /cvs/src/src/bfd/opncls.c,v
retrieving revision 1.54
diff -c -3 -p -r1.54 opncls.c
*** bfd/opncls.c	11 Jun 2009 00:41:03 -0000	1.54
--- bfd/opncls.c	11 Jun 2009 14:56:58 -0000
*************** bfd_openw (const char *filename, const c
*** 629,634 ****
--- 629,660 ----
    return nbfd;
  }
  
+ static inline void
+ _maybe_make_executable (bfd * abfd)
+ {
+   /* If the file was open for writing and is now executable,
+      make it so.  */
+   if (abfd->direction == write_direction
+       && abfd->flags & EXEC_P)
+     {
+       struct stat buf;
+ 
+       if (stat (abfd->filename, &buf) == 0
+ 	  /* Do not attempt to change non-regular files.  This is
+ 	     here especially for configure scripts and kernel builds
+ 	     which run tests with "ld [...] -o /dev/null".  */
+ 	  && S_ISREG(buf.st_mode))
+ 	{
+ 	  unsigned int mask = umask (0);
+ 
+ 	  umask (mask);
+ 	  chmod (abfd->filename,
+ 		 (0777
+ 		  & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
+ 	}
+     }
+ }
+ 
  /*
  
  FUNCTION
*************** bfd_close (bfd *abfd)
*** 684,707 ****
    else
      ret = TRUE;
  
!   /* If the file was open for writing and is now executable,
!      make it so.  */
!   if (ret
!       && abfd->direction == write_direction
!       && abfd->flags & EXEC_P)
!     {
!       struct stat buf;
! 
!       if (stat (abfd->filename, &buf) == 0)
! 	{
! 	  unsigned int mask = umask (0);
! 
! 	  umask (mask);
! 	  chmod (abfd->filename,
! 		 (0777
! 		  & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
! 	}
!     }
  
    _bfd_delete_bfd (abfd);
  
--- 710,717 ----
    else
      ret = TRUE;
  
!   if (ret)
!     _maybe_make_executable (abfd);
  
    _bfd_delete_bfd (abfd);
  
*************** bfd_close_all_done (bfd *abfd)
*** 737,760 ****
  
    ret = bfd_cache_close (abfd);
  
!   /* If the file was open for writing and is now executable,
!      make it so.  */
!   if (ret
!       && abfd->direction == write_direction
!       && abfd->flags & EXEC_P)
!     {
!       struct stat buf;
! 
!       if (stat (abfd->filename, &buf) == 0)
! 	{
! 	  unsigned int mask = umask (0);
! 
! 	  umask (mask);
! 	  chmod (abfd->filename,
! 		 (0777
! 		  & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
! 	}
!     }
  
    _bfd_delete_bfd (abfd);
  
--- 747,754 ----
  
    ret = bfd_cache_close (abfd);
  
!   if (ret)
!     _maybe_make_executable (abfd);
  
    _bfd_delete_bfd (abfd);
  

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