Why do ES and DS zero out eventually on 64 bit kernel when set to TLS selectors?

不羁岁月 提交于 2019-12-07 17:33:49

问题


The 32-bit program below calls set_thread_area(2) to create an entry in GDT, which is meant to be used for TLS. Typically the resulting selector is put into FS or GS and successfully used. But if it is put into DS or ES, running on a 64-bit kernel, eventually (after context switch I guess) this selector zeroes out.

But if I instead use modify_ldt(2) and put selector of the resulting LDT entry into these segment registers, they appear to hold their values!

Also, if I put e.g. selector of 64-bit code segment (0x33) or 32-bit code segment (0x23), both of which refer to GDT, into DS or ES, they don't get zeroed out.

Here's the source (compiles with fasm), demonstrating the strange behavior:

format ELF executable
segment readable executable

SYS_WRITE=4
STDERR=2
SYS_SET_THREAD_AREA=243
SYS_EXIT=1

entry $
start:
    mov eax, SYS_SET_THREAD_AREA
    mov ebx, user_desc_TLS1
    int 0x80
    mov ecx,[entry_number_TLS1]
    lea ecx,[ecx*8+3]
    mov ds,cx
; let's wait until DS spontaneously zeroes...
    xor eax,eax
checkDsZero:
    mov ax,ds
    test eax,eax
    jnz checkDsZero

    mov eax, SYS_WRITE
    mov ebx, STDERR
    mov ecx, dsZeroedMsg
    mov edx, dsZeroedMsgLen
    int 0x80

    xor ebx, ebx
    mov eax, SYS_EXIT
    int 0x80

segment readable writable
dsZeroedMsg:
    db "DS zeroed. Exiting",0xa
dsZeroedMsgLen=$-dsZeroedMsg

SEGMENT_32BIT=1
CONTENTS_DATA=0*2
CONTENTS_STACK=1*2
CONTENTS_CODE=2*2
READ_EXEC_ONLY=0x8
LIMIT_IN_PAGES=0x10
NOT_PRESENT=0x20
USABLE_BIT=0x40
LONG_MODE=0x80
user_desc_TLS1:
entry_number_TLS1:
    dd -1
base_addr_TLS1:
    dd start+0x345
limit_TLS1:
    dd 0x123
properties_TLS1:
    dd SEGMENT_32BIT+CONTENTS_DATA

This seems to be somehow related to the fact that 64-bit processes have NULL selector in these two segment registers by default.

This happens on Linux 3.16.0 and earlier, but doesn't on 4.2.0 and newer.

What's going on here? Why do ES and DS zero out when having TLS selectors in them, but do not with any other selector?

来源:https://stackoverflow.com/questions/32937701/why-do-es-and-ds-zero-out-eventually-on-64-bit-kernel-when-set-to-tls-selectors

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!