X-Original-To: alpine-devel@lists.alpinelinux.org Received: from mail.wilcox-tech.com (mail.wilcox-tech.com [45.32.83.9]) by lists.alpinelinux.org (Postfix) with ESMTP id 94146F8319C for ; Mon, 25 Feb 2019 17:27:13 +0000 (UTC) Received: (qmail 21992 invoked from network); 25 Feb 2019 17:27:01 -0000 Received: from localhost (HELO ?IPv6:2600:380:563a:1775:3dda:8bbf:7abc:8bcb?) (AWilcox@Wilcox-Tech.com@127.0.0.1) by localhost with ESMTPA; 25 Feb 2019 17:27:01 -0000 Content-Type: multipart/alternative; boundary=Apple-Mail-2AB9638B-6A42-47C5-9DB2-926B04DC7801 X-Mailinglist: alpine-devel Precedence: list List-Id: Alpine Development List-Unsubscribe: List-Post: List-Help: List-Subscribe: Mime-Version: 1.0 (1.0) Subject: Re: [alpine-devel] fortify-headers needs replacement From: "A. Wilcox" X-Mailer: iPhone Mail (15E302) In-Reply-To: <1394950117.20190225162429@mobile-stream.com> Date: Mon, 25 Feb 2019 11:26:52 -0600 Cc: alpine-devel@lists.alpinelinux.org Content-Transfer-Encoding: 7bit Message-Id: <1E8EE98E-FBEC-460A-AD48-A9EB1BA0CFA9@adelielinux.org> References: <1394950117.20190225162429@mobile-stream.com> To: alpine-mips-patches --Apple-Mail-2AB9638B-6A42-47C5-9DB2-926B04DC7801 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Feb 25, 2019, at 7:24 AM, alpine-mips-patches wr= ote: >=20 > (this e-mail is a resend triggered by the aports commit 228579f6c7663dc410= 7b1b418367e968513277f9) >=20 > This is some dumb program: >=20 > #include > int main(int argc, char **argv) > { > int x; > memcpy(&x, &argc, sizeof x); > return x; > } >=20 > This is what it turns into when compiled with "gcc -Os -fomit-frame-pointe= r" on edge (or 3.8.1): >=20 > 0000000000001068
: > 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=20 > 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 > 1093: 48 39 f7 cmp %rsi,%rdi > 1096: 72 0e jb 10a6 > 1098: 48 8d 46 04 lea 0x4(%rsi),%rax > 109c: 48 39 c7 cmp %rax,%rdi > 109f: 73 07 jae 10a8 > 10a1: 48 39 f7 cmp %rsi,%rdi > 10a4: 76 02 jbe 10a8 > 10a6: 0f 0b ud2 =20 > 10a8: ba 04 00 00 00 mov $0x4,%edx > 10ad: e8 6e ff ff ff callq 1020 > 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=20 > 10c4: 74 05 je 10cb > 10c6: e8 65 ff ff ff callq 1030 <__stack_chk_fail@plt> > 10cb: 48 83 c4 28 add $0x28,%rsp > 10cf: c3 retq =20 >=20 > Now when compiled with "gcc -U_FORTIFY_SOURCE -Os -fomit-frame-pointer": >=20 > 0000000000001048
: > 1048: 89 f8 mov %edi,%eax > 104a: c3 retq =20 >=20 >=20 > -O2, -O3 make no difference of course. >=20 > Is this considered acceptable? What is the point of such bounds checking? >=20 > 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. >=20 > 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). >=20 > Nothing like this happens with glibc implementation of _FORTIFY_HEADERS=3D= 2. FWIW, we (Ad=C3=A9lie) dropped fortify-headers entirely. GCC has gotten good= enough at detecting egregious errors and warn/error on them. It not only ca= uses slow downs but over a dozen compilation errors in our package tree. -- A. Wilcox (Sent from my iPhone - not signed) Project Lead, Ad=C3=A9lie Linux https://www.adelielinux.org= --Apple-Mail-2AB9638B-6A42-47C5-9DB2-926B04DC7801 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Feb 25, 2019, at 7:24 AM, alpine-mips-pa= tches <info@mobile-stream.com> wrote:

(t= his e-mail is a resend triggered by the aports commit 228579f6c7663dc4107b1b= 418367e968513277f9)

This is some dumb progr= am:

#include <string.h>
int main(int argc, char **argv)
{
 =       int x;
  &nbs= p;    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):
<= br>0000000000001068 <main>:
   1= 068:       48 83 ec 28     = ;        sub    $0x28= ,%rsp
   106c:      = ; 89 7c 24 0c          &nb= sp;  mov    %edi,0xc(%rsp)
 &= nbsp; 1070:       48 8d 7c 24 14  &n= bsp;       lea    0x14(%rs= p),%rdi
   1075:     &nb= sp; 48 8d 74 24 0c         &nbs= p;lea    0xc(%rsp),%rsi
   10= 7a:       64 48 8b 04 25 28 00   &nb= sp;mov    %fs:0x28,%rax
   10= 81:       00 00
  =  1083:       48 89 44 24 18   &= nbsp;      mov    %rax,0x18(%rs= p)
   1088:      &n= bsp;31 c0            =        xor    %eax,%eax
   108a:       4= 8 8d 47 04            = ; lea    0x4(%rdi),%rax
  &nb= sp;108e:       48 39 c6    &nbs= p;           cmp &nbs= p;  %rax,%rsi
   1091:   = ;    73 05        &nb= sp;          jae  &nb= sp; 1098 <main+0x30>
   1093: &nb= sp;     48 39 f7      &nbs= p;         cmp   &nbs= p;%rsi,%rdi
   1096:     = ;  72 0e          &nb= sp;        jb    &nbs= p;10a6 <main+0x3e>
   1098:  &nbs= p;    48 8d 46 04       &n= bsp;     lea    0x4(%rsi),%rax
   109c:       48 3= 9 c7             = ;   cmp    %rax,%rdi
 &n= bsp; 109f:       73 07    =             &nbs= p;  jae    10a8 <main+0x40>
&= nbsp;  10a1:       48 39 f7  &n= bsp;            =  cmp    %rsi,%rdi
   10a= 4:       76 02      &= nbsp;            = ;jbe    10a8 <main+0x40>
  &= nbsp;10a6:       0f 0b     = ;            &nb= sp; ud2    
   10a8: &nb= sp;     ba 04 00 00 00     &nbs= p;    mov    $0x4,%edx
&= nbsp;  10ad:       e8 6e ff ff ff &n= bsp;        callq  1020 <mem= cpy@plt>
   10b2:     = ;  8b 44 24 14         &nb= sp;   mov    0x14(%rsp),%eax
&= nbsp;  10b6:       48 8b 4c 24 18 &n= bsp;        mov    0x= 18(%rsp),%rcx
   10bb:    &nb= sp;  64 48 33 0c 25 28 00    xor    = %fs:0x28,%rcx
   10c2:    &nb= sp;  00 00
   10c4:   &= nbsp;   74 05         = ;          je   =   10cb <main+0x63>
   10c6: &= nbsp;     e8 65 ff ff ff     &n= bsp;    callq  1030 <__stack_chk_fail@plt>
   10cb:       4= 8 83 c4 28            = ; add    $0x28,%rsp
   1= 0cf:       c3      &n= bsp;            =    retq   

Now whe= n compiled with "gcc -U_FORTIFY_SOURCE -Os -fomit-frame-pointer":
=
0000000000001048 <main>:
 = ;  1048:       89 f8   &nb= sp;            &= nbsp;  mov    %edi,%eax
 &nbs= p; 104a:       c3     = ;            &nb= sp;    retq   


-O2, -O3 make no difference of course.

Is this considered acceptable? What is the point of such boun= ds 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))
<= span>in critical paths instead of copy assignments.

<= br>Or compressors that depend heavily on efficient memcpy within buffe= r with
pre-verified boundaries. E.g. commenting out just for= tify/string.h:memcpy
and rebuilding lz4 gives 10x decompress= ion speed-up (or merely restores
the designed performance).<= /span>

Nothing like this happens with glibc implem= entation of _FORTIFY_HEADERS=3D2.


= --Apple-Mail-2AB9638B-6A42-47C5-9DB2-926B04DC7801-- --- Unsubscribe: alpine-devel+unsubscribe@lists.alpinelinux.org Help: alpine-devel+help@lists.alpinelinux.org ---