Unexpected exec permission from mmap when assembly files included in the project

烂漫一生 提交于 2020-01-30 14:11:58

问题


I am banging my head into the wall with this.

In my project, when I'm allocating memory with mmap the mapping (/proc/self/maps) shows that it is an readable and executable region despite I requested only readable memory.

After looking into strace (which was looking good) and other debugging, I was able to identify the only thing that seems to avoid this strange problem: removing assembly files from the project and leaving only pure C. (what?!)

So here is my strange example, I am working on Ubunbtu 19.04 and default gcc.

If you compile the target executable with the ASM file (which is empty) then mmap returns a readable and executable region, if you build without then it behave correctly. See the output of /proc/self/maps which I have embedded in my example.

example.c

#include <stdio.h>
#include <string.h>
#include <sys/mman.h>

int main()
{
    void* p;
    p = mmap(NULL, 8192,PROT_READ,MAP_ANONYMOUS|MAP_PRIVATE,-1,0);

    {
        FILE *f;
        char line[512], s_search[17];
        snprintf(s_search,16,"%lx",(long)p);
        f = fopen("/proc/self/maps","r");
        while (fgets(line,512,f))
        {
            if (strstr(line,s_search)) fputs(line,stderr);
        }

        fclose(f);
    }

    return 0;
}

example.s: Is an empty file!

Outputs

With the ASM included version

VirtualBox:~/mechanics/build$ gcc example.c example.s -o example && ./example
7f78d6e08000-7f78d6e0a000 r-xp 00000000 00:00 0 

Without the ASM included version

VirtualBox:~/mechanics/build$ gcc example.c -o example && ./example
7f1569296000-7f1569298000 r--p 00000000 00:00 0 

回答1:


Linux has an execution domain called READ_IMPLIES_EXEC, which causes all pages allocated with PROT_READ to also be given PROT_EXEC. This program will show you whether that's enabled for itself:

#include <stdio.h>
#include <sys/personality.h>

int main(void) {
    printf("Read-implies-exec is %s\n", personality(0xffffffff) & READ_IMPLIES_EXEC ? "true" : "false");
    return 0;
}

If you compile that along with an empty .s file, you'll see that it's enabled, but without one, it'll be disabled. The initial value of this comes from the ELF meta-information in your binary. Do readelf -Wl example. You'll see this line when you compiled without the empty .s file:

  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10

But this one when you compiled with it:

  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RWE 0x10

Note RWE instead of just RW. The reason for this is that the linker assumes that your assembly files require read-implies-exec unless it's explicitly told that they don't, and if any part of your program requires read-implies-exec, then it's enabled for your whole program. The assembly files that GCC compiles tell it that it doesn't need this, with this line (you'll see this if you compile with -S):

        .section        .note.GNU-stack,"",@progbits

Put that line in example.s, and it will serve to tell the linker that it doesn't need it either, and your program will then work as expected.




回答2:


As an alternative to modifying your assembly files with GNU-specific section directive variants, you can add -Wa,--noexecstack to your command line for building assembly files. For example, see how I do it in musl's configure:

https://git.musl-libc.org/cgit/musl/commit/configure?id=adefe830dd376be386df5650a09c313c483adf1a

I believe at least some versions of clang with integrated-assembler may require it to be passed as --noexecstack (without the -Wa), so your configure script should probably check both and see which is accepted.

You can also use -Wl,-z,noexecstack at link time (in LDFLAGS) to get the same result. The disadvantage of this is that it doesn't help if your project produces static (.a) library files for use by other software, since you then don't control the link-time options when it's used by other programs.



来源:https://stackoverflow.com/questions/58260465/unexpected-exec-permission-from-mmap-when-assembly-files-included-in-the-project

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!