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

后端 未结 2 1291
甜味超标
甜味超标 2020-11-28 07:36

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

2条回答
  •  星月不相逢
    2020-11-28 08:27

    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 
    #include 
    
    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.

提交回复
热议问题