• cannary


    canary是Linux为防止栈溢出的一种保护机制,接着我们分析glibc对canary的实现过程,首先给出跟canary相关的调用栈:

    • security_init()  //在elf/rtld.c中
    • dl_main() 在elf/rtld.c中
    • _dl_sysdep_start() 在elf/dl-sysdep.c中
    • _dl_start_final() 在rtld.c中
    • _dl_start() 在rtld.c中
    • _start() /lib/ld-linux.so.2
    static void security_init (void)
    {
      /* Set up the stack checker's canary.  */
         //一般情况下此时_dl_random的值是由kernel写入的,glibc直接使用了里面的值, uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random); //把canary的最后一位设为'x00' #ifdef THREAD_SET_STACK_GUARD
         //TLS会进入这里.macro的定义及其详细展开见下面 THREAD_SET_STACK_GUARD (stack_chk_guard); #else __stack_chk_guard = stack_chk_guard; #endif /* Set up the pointer guard as well, if necessary. */ uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random, stack_chk_guard); #ifdef THREAD_SET_POINTER_GUARD THREAD_SET_POINTER_GUARD (pointer_chk_guard); //有TLS结构就会进入这里 #endif __pointer_chk_guard_local = pointer_chk_guard; /* We do not need the _dl_random value anymore. The less information we leave behind, the better, so clear the variable. */ _dl_random = NULL; }

     THREAD_SET_STACK_GUARD()宏的定义

    #define THREAD_SET_STACK_GUARD(VALUE) THREAD_SETMEM(THREAD_SELF, header.stack_guard, value)
    

     header的定义,TLS相关的数据结构,注意元素stack_guard的偏移是20也就是0x14

    typedef struct
    {
      void *tcb;		/* Pointer to the TCB.  Not necessarily the
    			   thread descriptor used by libpthread.  */
      dtv_t *dtv;
      void *self;		/* Pointer to the thread descriptor.  */
      int multiple_threads;
      uintptr_t sysinfo;
      uintptr_t stack_guard;
      uintptr_t pointer_guard;
      int gscope_flag;
    #ifndef __ASSUME_PRIVATE_FUTEX
      int private_futex;
    #else
      int __unused1;
    #endif
      /* Reservation of some values for the TM ABI.  */
      void *__private_tm[4];
      /* GCC split stack support.  */
      void *__private_ss;
    } tcbhead_t;
    

     将cananry的值写入gs:0x14,此处gs寄存器指向TLS结构体,gs:0x14就是将canary写入结构体中偏移为0x14处,也就是写入stack_guard中

    /* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
    # define THREAD_SETMEM(descr, member, value)   ({if (sizeof (descr->member) == 4)				                     asm volatile ("movl %0,%%gs:%P1" :				      		     : "ir" (value),	
    "i" (offsetof (struct pthread, member))); })

     生成TLS结构体的函数位于glibc-2.23/elf/dl-tls.c,可以看到,程序事实上是调用了__libc_memalign函数来分配内存,而__libc_memalign函数最终调用的是mmap函数。如果程序定义了THREAD_SET_STACK_GUARD则canary会被放在TLS,否则canary会被放在.bss中。

  • 相关阅读:
    Can't use Subversion command line client: svn
    SpringMVC配置easyui-datagrid
    找不到提交和更新按钮,subversion不见了,无法更新和上传代码
    静态资源[org.springframework.web.servlet.PageNotFound]
    Field 'id' doesn't have a default value
    MySql 插入数据中文乱码
    Junit 测试 Spring
    mybatis动态SQL
    Mybatis 3.3.0 Log4j配置
    MappingJacksonHttpMessageConverter过期
  • 原文地址:https://www.cnblogs.com/countfatcode/p/11796476.html
Copyright © 2020-2023  润新知