This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils 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] elflint: Check relro flags are a subset of the load segment.


    If the RELRO segment doesn't fully overlap with the load segment then the
    load segment might have more flags sets. This happens for example on sparc
    when the .plt, which is executable, is also part of the load segment that
    RELRO covers.

Tested in sparc64 and sparc.  Works just fine.
    
    Signed-off-by: Mark Wielaard <mjw@redhat.com>
    ---
     src/ChangeLog |  5 +++++
     src/elflint.c | 22 +++++++++++++++++++---
     2 files changed, 24 insertions(+), 3 deletions(-)
    
    diff --git a/src/ChangeLog b/src/ChangeLog
    index 796878f..8ba2539 100644
    --- a/src/ChangeLog
    +++ b/src/ChangeLog
    @@ -1,3 +1,8 @@
    +2015-10-13  Mark Wielaard  <mjw@redhat.com>
    +
    +	* elflint.c (check_program_header): Check relro flags are a subset
    +	of the load segment if they don't fully overlap.
    +
     2015-10-07  Mark Wielaard  <mjw@redhat.com>
     
     	* Makefile.am (ldlex_no_Wstack_usage): New.
    diff --git a/src/elflint.c b/src/elflint.c
    index fac457e..63192bb 100644
    --- a/src/elflint.c
    +++ b/src/elflint.c
    @@ -4459,10 +4459,26 @@ more than one GNU_RELRO entry in program header\n"));
     		      if ((phdr2->p_flags & PF_W) == 0)
     			ERROR (gettext ("\
     loadable segment GNU_RELRO applies to is not writable\n"));
    -		      if ((phdr2->p_flags & ~PF_W) != (phdr->p_flags & ~PF_W))
    -			ERROR (gettext ("\
    +		      /* Unless fully covered, relro flags could be a
    +			 subset of the phdrs2 flags.  For example the load
    +			 segment could also have PF_X set.  */
    +		      if (phdr->p_vaddr == phdr2->p_vaddr
    +			  && (phdr->p_vaddr + phdr->p_memsz
    +			      == phdr2->p_vaddr + phdr2->p_memsz))
    +			{
    +			  if ((phdr2->p_flags & ~PF_W)
    +			      != (phdr->p_flags & ~PF_W))
    +			    ERROR (gettext ("\
     loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"),
    -			       cnt, inner);
    +				   cnt, inner);
    +			}
    +		      else
    +			{
    +			  if ((phdr->p_flags & ~phdr2->p_flags) != 0)
    +			    ERROR (gettext ("\
    +GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n"),
    +				   inner, cnt);
    +			}
     		      break;
     		    }
     		}

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