This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Committed: Do not make non-regular files executable.
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sourceware dot org
- Date: Thu, 11 Jun 2009 16:18:33 +0100
- Subject: 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);