assemblyx86-64reverse-engineeringglibcthread-local-storage

What does fs:0x30 provide in Linux?


I am trying to understand the source code of atexit() function,but I stuck on this (line 409 ~ line 415, PTR_DEMANGLE())

I can understand the inline asm need do a vital progress

xor    rdx,QWORD PTR fs:0x30

But I didn't really get what's fs:0x30 meaning for

So I searched for google but only got the meaning of fs:0x30 on Windows ,which is reletive to PEB

And I also tried search for PTR_DEMANGLE() function directly,and found this,but it didn't help

And this also raise me a new question:

Say,I need to know usage of fs:0xXX,that is few-used. which manual-book should I refer to ,directly? ELF standard document?

BTW,English is not my first language,this post may have some syntax or spelling mistakes,please forgive me,thx very much!


Solution

  • The fs segment register is used in x86-64 Linux to point to thread-local storage. See How are the fs/gs registers used in Linux AMD64? So this instruction will xor the rdx register with the value found at offset 0x30 in the thread-local storage block.

    This code is part of a pointer encryption mechanism in glibc to help harden against certain exploits. There is some explanation of it at https://sourceware.org/glibc/wiki/PointerEncryption. The value at fs:0x30 is an "key" for a trivial "encryption" algorithm; pointers are xor'ed with this value (and then rotated) when they are stored, and rotated back and xor'ed again when they are retrieved from memory, which recovers the original pointer.

    There is no particular significance to the number 0x30; it just happens to be the offset where that value is stored. You can see in the inline assembly that this number comes from offsetof (tcbhead_t, pointer_guard); so the storage at the fs base address is laid out as a tcbhead_t struct, and given the other members that it contains, the pointer_guard member has ended up at offset 0x30. So looking at the name pointer_guard for the member is more informative than its numerical offset.