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

[Bug libc/20480] New: Patch: ifunc not executable, crashes sudo qemu


https://sourceware.org/bugzilla/show_bug.cgi?id=20480

            Bug ID: 20480
           Summary: Patch: ifunc not executable, crashes sudo qemu
           Product: glibc
           Version: 2.24
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: libc
          Assignee: unassigned at sourceware dot org
          Reporter: adam_richter2004 at yahoo dot com
                CC: drepper.fsp at gmail dot com
  Target Milestone: ---

Created attachment 9447
  --> https://sourceware.org/bugzilla/attachment.cgi?id=9447&action=edit
Change the code that makes sections temporarily writable for relocation
preserve execute permission

Recent versions of the GNU C compiler provide a function attribute "ifunc" for
access to an ELF facility that allows user provided code to be run at link time
to determine the address of a symbol.  However, during relocation, glibc
temporarily maps some section executable by that code as PROT_READ|PROT_WRITE
without setting PROT_EXEC.

A real world consequence of this problem is that, on Linux i686, Qemu versions
2.6.0-rc0 and later crash during relocation (before main) if run from sudo on
i686 Linux, which I think is because setuid programs clear the
READ_IMPLIES_EXEC inheritable process flag, at least guessing from my reading
of of linux-4.7/fs/exec.c, wherebprm_fill_uid does "bprm->per_clear |=
PER_CLEAR_ON_SETID".  PER_CLEAR_ON_SETID is bit mask defined in
linux-4.7/include/uapi/linux/personality.h that includes READ_IMPLIES_EXEC.

Single stepping through the Qemu crash seems to indicate that the permission
violation is not in the first instruction of the ifunc code (which Qemu uses to
select between functions with and without some special CPU instructions), but
rather a helper function that pushes %ebx on the stack.  Also, my attempt at
making the most trivial test case failed.  So, I think I need the ifunc to
something slightly more complex to make a better case.

I see from reading the code that the git glibc also appears to have this bug,
but I have not tried it.

Anyhow, I have attached a patch that works and that I like.  It happens that
the necessary permissions were computed immediately after the bad mprotect()
call anyhow, so my patch just uses that with PROT_READ | PROT_WRITE masked in. 
Whether PROT_READ is necessary, I am not sure, but it is the least difference
from the previous version of the code.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

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