分类: LINUX
2009-09-05 23:29:12
Linux has the concept of personality of an executable (since 1.1.20). The purpose is to make the Linux environment more similar to some other environment, like BSD or SCO or Solaris or older Linux, so that foreign or old binaries have better chances of working without modification.
For example, the Linux select()
system call will update
its timeout parameter to reflect the amount of time left.
With the STICKY_TIMEOUTS flag set in the personality this is not done,
following BSD behaviour.
For example, dereferencing a NULL pointer is sign of a program bug and causes a segfault because 0 is not in mapped memory. But SVr4 maps page 0 read-only (filled with zeroes) and some programs depend on this. With the MMAP_PAGE_ZERO flag set in the personality Linux will also do this.
Or, for example, the Linux mmap()
system call will nowadays
randomize the assigned addresses as a defense against hacking attempts,
but with the ADDR_NO_RANDOMIZE flag set in the personality this is not done
(since 2.6.12).
The personality value is composed of a 2-byte value identifying the system
(Linux, SVR4, SUNOS, HPUX etc), and a number of 1-bit flags.
See
.
The personality is inherited from the parent process, and
changed using the personality()
system call.
The setarch
utility is a convenient tool for starting
a process with a given personality.
/* Flags for bug emulation. These occupy the top three bytes. */ enum { ADDR_NO_RANDOMIZE = 0x0040000, MMAP_PAGE_ZERO = 0x0100000, ADDR_LIMIT_32BIT = 0x0800000, SHORT_INODE = 0x1000000, WHOLE_SECONDS = 0x2000000, STICKY_TIMEOUTS = 0x4000000, ADDR_LIMIT_3GB = 0x8000000 }; |
#include #include #include int main() { volatile char * pointer = NULL; //MMAP_PAGE_ZERO if( personality(MMAP_PAGE_ZERO) == -1) { perror("personality"); } //MAP_FIXED if( mmap(0x00000000,0x1000,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE,0,0) == MAP_FAILED ) { perror("mmap"); return -1; } *pointer = 'A'; printf("0:%c\n", *pointer); return 0; } |