From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25198 invoked by alias); 3 Mar 2020 16:51:36 -0000 Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org Received: (qmail 25190 invoked by uid 89); 3 Mar 2020 16:51:36 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-4.3 required=5.0 tests=AWL,BAYES_00,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=no version=3.3.1 spammy=sk:stackc, sk:stack-c, blog, H*i:OQUN X-HELO: mail-il1-f173.google.com Received: from mail-il1-f173.google.com (HELO mail-il1-f173.google.com) (209.85.166.173) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 03 Mar 2020 16:51:34 +0000 Received: by mail-il1-f173.google.com with SMTP id n11so3393642ild.1 for ; Tue, 03 Mar 2020 08:51:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=2gNn+C9H56AWlyswm6zIw+oSbZUuqNGNKxuIL73PLhs=; b=dmCVEfvYJxZKUwQ0gIxHgk/ozO2VAReVquTVPEOCpgijELoDJlm/7uKvUbcDodBnOm /Srm6kQuYzyyixTeyPNZUECyoYZg+K+vzux4J/CVbumG01kwge/pkzzw6TdhxeXm3dj2 yl6v2Z3HfHVjC9kIaaTwPhDWZm7k5gq25VDpJxjSCGy7o7dCODIJ2GWuqb9Mg87NZl/z irGx2+RudCuOZL6KX3B0+m9Bnx4EQtml8zmLuYxdlrjnefqeQpzuRn9/LNHA0ImnW06f +GlAp9AOIciP0xEr+wkF+J4ZSNzuRP7ImuY7hYL19NUuq98aKlD2xeSoc0vaPs03zxDa TYyg== MIME-Version: 1.0 References: In-Reply-To: From: Ruslan Kabatsayev Date: Tue, 03 Mar 2020 16:51:00 -0000 Message-ID: Subject: Re: use of %fs segment register in x86_64 with -fstack-check To: Maxim Blinov Cc: gdb@sourceware.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2020-03/txt/msg00003.txt Hi, On Tue, 3 Mar 2020 at 17:53, Maxim Blinov wrote: > > Hi all, > > I'm looking at some -fstack-check'ed code, and would appreciate it if > some gdb x86_64 gurus could double check my understanding of a trivial > example > > here is the source: > > big-access.c: > ``` > #include > #include > #include > > extern void foo(char *); > > int main() > { > char ch[8000]; > foo (ch); > > return 0; > } > ``` > > foo.c: > ``` > void foo(char *ch) { } > ``` > > And the compilation line: > > $ gcc -O2 -fstack-check -o big-access big-access.c foo.c -fdump-rtl-final > > And here is the gdb view (ignore the breakpoint and current insn caret): > ``` > B+ =E2=94=820x555555554560
sub $0x2f78,%rsp > =E2=94=820x555555554567 orq $0x0,0xf58(%rsp) > =E2=94=820x555555554570 orq $0x0,(%rsp) > =E2=94=820x555555554575 add $0x1020,%rsp > =E2=94=820x55555555457c mov %rsp,%rdi > =E2=94=820x55555555457f mov %fs:0x28,%rax > >=E2=94=820x555555554588 mov %rax,0x1f48(%rsp) > =E2=94=820x555555554590 xor %eax,%eax > =E2=94=820x555555554592 callq 0x5555555546d0 > =E2=94=820x555555554597 mov 0x1f48(%rsp),%rdx > =E2=94=820x55555555459f xor %fs:0x28,%rdx > =E2=94=820x5555555545a8 jne 0x5555555545b4 > =E2=94=820x5555555545aa xor %eax,%eax > =E2=94=820x5555555545ac add $0x1f58,%rsp > =E2=94=820x5555555545b3 retq > =E2=94=820x5555555545b4 callq 0x555555554540 <__stac= k_chk_fail@plt> > =E2=94=820x5555555545b9 nopl 0x0(%rax) > ``` > > I would just like someone who knows their stuff to double check my > understanding: > > The "orq" at the start are purposefully causing a "dummy" load/store > event so the VMM can decide whether or not it is sane for us to have > used those pages for the stack, right? Not quite. As noted at [1] this OR is to ensure that stack hasn't overflowed. This is the part added by -fstack-check (you can see it go away when you remove this option). See [2] for documentation. > > Another question, is at address 0x55555555457f. I presume that > %fs:0x28 is a memory address that points to a sentinel value. We load > it into %rax, and then we store it in strategic locations in our stack > to serve as sentinel values. Before we leave, we check that the memory > location hasn't changed at 0x55555555459f. That implies, that the > memory location %fs:0x28 is pointing to a globally-used sentinel > value? Right. But note that this is enabled not by -fstack-check, but rather by some of the -fstack-protector* options that are on by default on modern Linux distributions. You can confirm this by explicitly passing -fno-stack-protector and seeing this sentinel checking gone. > > But who sets %fs? Indeed what is the ABI usage of %fs in the context > of linux x86_64? The FS segment base points to the TLS. See [3] and links therein. > And why 0x28 offset? It's the offset of stack_guard member of tcbhead_t. See the corresponding glibc source [4]. > > Thankyou for reading, > Maxim [1]: https://stackoverflow.com/a/44670648/673852 [2]: https://gcc.gnu.org/onlinedocs/gccint/Stack-Checking.html [3]: https://chao-tic.github.io/blog/2018/12/25/tls [4]: https://code.woboq.org/userspace/glibc/sysdeps/x86_64/nptl/tls.h.html#= 42 Regards, Ruslan