Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5762061
  • 博文数量: 675
  • 博客积分: 20301
  • 博客等级: 上将
  • 技术积分: 7671
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-31 16:15
文章分类

全部博文(675)

文章存档

2012年(1)

2011年(20)

2010年(14)

2009年(63)

2008年(118)

2007年(141)

2006年(318)

分类: LINUX

2009-09-05 23:29:12

Personality

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.

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
personality可以设置的flag包括:
/* 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
  };
其他的什么PER_SVR4等都是这些的flag的与。


写了简单的测试例子,向0地址写值,常规情况下肯定是要SEGV的,但是设置了MMAP_PAGE_ZERO就可以将0地值映射到地址空间中了,当然前提是/proc/sys/vm/mmap_min_addr应该设置为0;-)
#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;
}


参考:
~aeb/linux/lk/lk-3.html
阅读(2520) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~