From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/10508 Path: news.gmane.org!.POSTED!not-for-mail From: "LeMay, Michael" Newsgroups: gmane.linux.lib.musl.general Subject: [RFC] Support for segmentation-hardened SafeStack Date: Thu, 22 Sep 2016 23:00:45 +0000 Message-ID: <390CE752059EB848A71F4F676EBAB76D3AC0B184@ORSMSX114.amr.corp.intel.com> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="_000_390CE752059EB848A71F4F676EBAB76D3AC0B184ORSMSX114amrcor_" X-Trace: blaine.gmane.org 1474585281 17459 195.159.176.226 (22 Sep 2016 23:01:21 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 22 Sep 2016 23:01:21 +0000 (UTC) To: "musl@lists.openwall.com" Original-X-From: musl-return-10521-gllmg-musl=m.gmane.org@lists.openwall.com Fri Sep 23 01:01:16 2016 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1bnCzM-0003CE-CI for gllmg-musl@m.gmane.org; Fri, 23 Sep 2016 01:01:08 +0200 Original-Received: (qmail 5265 invoked by uid 550); 22 Sep 2016 23:01:01 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 5224 invoked from network); 22 Sep 2016 23:00:58 -0000 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.30,379,1470726000"; d="scan'208,217";a="1044400139" Thread-Topic: [RFC] Support for segmentation-hardened SafeStack Thread-Index: AdIVEWcUrO+iPZHmR+6QOo5oCsEeuQ== Deferred-Delivery: Thu, 22 Sep 2016 23:00:00 +0000 Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.22.254.138] Xref: news.gmane.org gmane.linux.lib.musl.general:10508 Archived-At: --_000_390CE752059EB848A71F4F676EBAB76D3AC0B184ORSMSX114amrcor_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi, I submitted several patches to LLVM and Clang to harden SafeStack using seg= mentation on x86-32 [1]. See [2] for general background on SafeStack. On = Linux, I have been testing my compiler changes with a modified version of m= usl. I currently plan to submit my musl patches if and when the prerequisi= te LLVM and Clang patches are accepted. One of my LLVM patches depends on = the details of my musl patches, which is the main reason that I am sending = this RFC now. Specifically, https://reviews.llvm.org/D19762 assumes that the unsafe stack= pointer is stored at offset 0x24 in the musl thread control block. This w= ould be between the pid and tsd_used variables that are currently defined. = I also propose storing the base address of the unsafe stack at offset 0x28= , but the compiler would not depend on that. Here is an overview of some other changes that I plan to propose with my mu= sl patches: The segmentation-hardened SafeStack support would be enabled with a new con= figuration option, "--enable-safe-stack". When this is enabled, many libraries routines require that both a safe stac= k and an unsafe stack be available. I modified _start_c in crt1.c to tempo= rarily setup a small, pre-allocated unsafe stack for the early initializati= on routines to use. I also made similar changes in dlstart.c. A larger un= safe stack is allocated and setup later from either __libc_start_main or __= dls3, depending on whether static or dynamic linking is used. I split __dl= s3 so that it only performs minimal initialization before allocating the la= rger unsafe stack and then performing the rest of its work in a new __dls4 = function. After the larger unsafe stack is allocated, I invoke the modify_ldt syscall= to insert a segment descriptor with a limit that is below the beginning of= the safe stacks. I load that segment descriptor into the DS and ES segmen= t registers to block memory accesses to DS and ES from accessing the safe s= tacks. One purpose of my LLVM and Clang patches is to insert the necessary= segment override prefixes to direct accesses to the appropriate segments. Many instructions expect that argc, argv, the environment, and auxv are acc= essible in the DS and ES segments. These are stored on the initial stack, which is above the limit of the rest= ricted DS and ES segments. I annotated auxv with an attribute to cause the= compiler to emit SS segment-override prefixes when accessing auxv. I copi= ed the other data to the heap, which is accessible in DS and ES. I modified the pthread routines to allocate and deallocate additional stack= s as needed in the appropriate memory ranges. The safe stacks are allocate= d at high addresses so that they are above the limit of the modified DS and= ES segments. The unsafe stack for each new thread is allocated below its = TLS region and thread control block, which is where the stack is currently = located by default. The Linux vDSO code may be incompatible with programs that enable segmentat= ion-hardened SafeStack. For example, it may allocate data on the safe stac= k and then attempt to access it in DS or ES, which would result in an excep= tion due to the segment limit violation. My patches prevent the vDSO from = being invoked when segmentation-hardened SafeStack is enabled. Finally, the i386 __clone implementation is written in assembly language, s= o the compiler is unable to automatically add a stack segment override pref= ix to an instruction in that routine that accesses a safe stack. I added t= hat prefix manually in the source code. Comments appreciated. Thanks, Michael [1] http://lists.llvm.org/pipermail/llvm-dev/2016-May/100346.html [2] http://clang.llvm.org/docs/SafeStack.html --_000_390CE752059EB848A71F4F676EBAB76D3AC0B184ORSMSX114amrcor_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

Hi,

 

I submitted several patches to LLVM and Clang to har= den SafeStack using segmentation on x86-32 [1].  See [2] for general b= ackground on SafeStack.  On Linux, I have been testing my compiler cha= nges with a modified version of musl.  I currently plan to submit my musl patches if and when the prerequisite LLVM and Clang= patches are accepted.  One of my LLVM patches depends on the details = of my musl patches, which is the main reason that I am sending this RFC now= .

 

Specifically, https://reviews.llvm.org/D19762 assumes that the unsafe stack poi= nter is stored at offset 0x24 in the musl thread control block.  This = would be between the pid and tsd_used variables that are currently defined.  I also propose storing the base address = of the unsafe stack at offset 0x28, but the compiler would not depend on th= at.

 

Here is an overview of some other changes that I pla= n to propose with my musl patches:

 

The segmentation-hardened SafeStack support would be= enabled with a new configuration option, “--enable-safe-stack”= .

 

When this is enabled, many libraries routines requir= e that both a safe stack and an unsafe stack be available.  I modified= _start_c in crt1.c to temporarily setup a small, pre-allocated unsa= fe stack for the early initialization routines to use.  I also made similar changes in dlstart.c.  A larger uns= afe stack is allocated and setup later from either __libc_start_main or __d= ls3, depending on whether static or dynamic linking is used.  I split = __dls3 so that it only performs minimal initialization before allocating the larger unsafe stack and then performing the rest of = its work in a new __dls4 function.

 

After the larger unsafe stack is allocated, I invoke= the modify_ldt syscall to insert a segment descriptor with a limit that is= below the beginning of the safe stacks.  I load that segment descript= or into the DS and ES segment registers to block memory accesses to DS and ES from accessing the safe stacks. = ; One purpose of my LLVM and Clang patches is to insert the necessary segme= nt override prefixes to direct accesses to the appropriate segments.

 

Many instructions expect that argc, argv, the enviro= nment, and auxv are accessible in the DS and ES segments. 

These are stored on the initial stack, which is abov= e the limit of the restricted DS and ES segments.  I annotated auxv wi= th an attribute to cause the compiler to emit SS segment-override prefixes = when accessing auxv.  I copied the other data to the heap, which is accessible in DS and ES.

 

I modified the pthread routines to allocate and deal= locate additional stacks as needed in the appropriate memory ranges.  = The safe stacks are allocated at high addresses so that they are above the = limit of the modified DS and ES segments.  The unsafe stack for each new thread is allocated below its TLS region and= thread control block, which is where the stack is currently located by def= ault.

 

The Linux vDSO code may be incompatible with program= s that enable segmentation-hardened SafeStack.  For example, it may al= locate data on the safe stack and then attempt to access it in DS or ES, wh= ich would result in an exception due to the segment limit violation.  My patches prevent the vDSO from being = invoked when segmentation-hardened SafeStack is enabled.

 

Finally, the i386 __clone implementation is written = in assembly language, so the compiler is unable to automatically add a stac= k segment override prefix to an instruction in that routine that accesses a= safe stack.  I added that prefix manually in the source code.

 

Comments appreciated.

 

Thanks,

Michael

 

[1] http://lists.llvm.org/pipermail/llvm-dev/2016-May/100346.html

[2] http://clang.llvm.org/docs/SafeStack.html

--_000_390CE752059EB848A71F4F676EBAB76D3AC0B184ORSMSX114amrcor_--