Subject: [alpine-devel] fortify-headers needs replacement

From: alpine-mips-patches <[email-masked]>
Date: Mon, 25 Feb 2019 16:24:29 +0300

(this e-mail is a resend triggered by the aports commit 228579f6c7663dc4107b1b418367e968513277f9)

This is some dumb program:

#include <string.h>
int main(int argc, char **argv)
{
        int x;
        memcpy(&x, &argc, sizeof x);
        return x;
}

This is what it turns into when compiled with "gcc -Os -fomit-frame-pointer" on edge (or 3.8.1):

0000000000001068 <main>:
    1068:       48 83 ec 28             sub    $0x28,%rsp
    106c:       89 7c 24 0c             mov    %edi,0xc(%rsp)
    1070:       48 8d 7c 24 14          lea    0x14(%rsp),%rdi
    1075:       48 8d 74 24 0c          lea    0xc(%rsp),%rsi
    107a:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
    1081:       00 00 
    1083:       48 89 44 24 18          mov    %rax,0x18(%rsp)
    1088:       31 c0                   xor    %eax,%eax
    108a:       48 8d 47 04             lea    0x4(%rdi),%rax
    108e:       48 39 c6                cmp    %rax,%rsi
    1091:       73 05                   jae    1098 <main+0x30>
    1093:       48 39 f7                cmp    %rsi,%rdi
    1096:       72 0e                   jb     10a6 <main+0x3e>
    1098:       48 8d 46 04             lea    0x4(%rsi),%rax
    109c:       48 39 c7                cmp    %rax,%rdi
    109f:       73 07                   jae    10a8 <main+0x40>
    10a1:       48 39 f7                cmp    %rsi,%rdi
    10a4:       76 02                   jbe    10a8 <main+0x40>
    10a6:       0f 0b                   ud2    
    10a8:       ba 04 00 00 00          mov    $0x4,%edx
    10ad:       e8 6e ff ff ff          callq  1020 <memcpy@plt>
    10b2:       8b 44 24 14             mov    0x14(%rsp),%eax
    10b6:       48 8b 4c 24 18          mov    0x18(%rsp),%rcx
    10bb:       64 48 33 0c 25 28 00    xor    %fs:0x28,%rcx
    10c2:       00 00 
    10c4:       74 05                   je     10cb <main+0x63>
    10c6:       e8 65 ff ff ff          callq  1030 <__stack_chk_fail@plt>
    10cb:       48 83 c4 28             add    $0x28,%rsp
    10cf:       c3                      retq   

Now when compiled with "gcc -U_FORTIFY_SOURCE -Os -fomit-frame-pointer":

0000000000001048 <main>:
    1048:       89 f8                   mov    %edi,%eax
    104a:       c3                      retq   

-O2, -O3 make no difference of course.

Is this considered acceptable? What is the point of such bounds checking?

The example is quite realistic actually, there are tons of code that use
memcpy(&same_type_struct1, &same_type_struct0, sizeof(same_type_struct1))
in critical paths instead of copy assignments.

Or compressors that depend heavily on efficient memcpy within buffer with
pre-verified boundaries. E.g. commenting out just fortify/string.h:memcpy
and rebuilding lz4 gives 10x decompression speed-up (or merely restores
the designed performance).

Nothing like this happens with glibc implementation of _FORTIFY_HEADERS=2.

---
Unsubscribe:  [email-masked]
Help:         [email-masked]
---

---

From: "A. Wilcox" <[email-masked]>
Date: Mon, 25 Feb 2019 11:26:52 -0600

>    107a:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax

FWIW, we (Adélie) dropped fortify-headers entirely. GCC has gotten good enough at detecting egregious errors and warn/error on them. It not only causes slow downs but over a dozen compilation errors in our package tree.

--
A. Wilcox (Sent from my iPhone - not signed)
Project Lead, Adélie Linux
https://www.adelielinux.org