From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by sourceware.org (Postfix) with ESMTP id CBF46386F036 for ; Wed, 27 Jan 2021 19:45:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org CBF46386F036 Received: from [192.168.254.32] (unknown [47.187.219.45]) by linux.microsoft.com (Postfix) with ESMTPSA id 21FFB20B7192; Wed, 27 Jan 2021 11:45:11 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 21FFB20B7192 Subject: Re: [RFC PATCH v3 0/5] Libffi Static Trampolines To: Anthony Green Cc: libffi-discuss , fweimer@redhat.com, DJ Delorie References: <20210115184653.124913-1-madvenka@linux.microsoft.com> <849643ba-5c3e-31e6-b784-d0fc2345ce00@linux.microsoft.com> From: "Madhavan T. Venkataraman" Message-ID: <811113c4-7bda-ee21-cdb9-4ab20d1fd291@linux.microsoft.com> Date: Wed, 27 Jan 2021 13:45:10 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-21.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, ENV_AND_HDR_SPF_MATCH, NICE_REPLY_A, SPF_HELO_PASS, SPF_PASS, TXREP, USER_IN_DEF_DKIM_WL, USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libffi-discuss@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libffi-discuss mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Jan 2021 19:45:14 -0000 On 1/27/21 12:00 PM, Anthony Green wrote: > Thanks, Madhaven.   I think I understand now.   Are these statements true?: > > (a) These patches implement trampoline tables, similar to what is implemented in the iOS port.  This hardens the library by eliminating the requirement for writable executable memory. > (b) These patches expose a new public API for hardened trampolines.  (a) uses (b), but doesn't require that (b) be public. > (c) We can release libffi with (a) and not (b). > > Is this correct?   > Yes. This is correct. The public API part is not required. It is just to provide the open source community with a way to help convert their dynamic code. We could also consider exposing the public API at a later time when the changes are considered well exercised. Madhavan > AG > > On Wed, Jan 27, 2021 at 12:20 PM Madhavan T. Venkataraman > wrote: > > > > On 1/26/21 5:41 PM, Anthony Green wrote: > > Madhaven, > > > >   Thank you for your continued efforts here. > > > > On Fri, Jan 15, 2021 at 1:47 PM >> wrote: > > > >     Trampoline API > >     ============== > > > >     There is a lot of dynamic code out there. They all have the same security > >     issue. Dynamic code can be re-written into static code provided the data > >     required by the static code can be passed to it just like we pass the closure > >     pointer to an ABI handler. > > > >     So, the same trampoline functions used by libffi internally need to be > >     made available to the rest of the world in the form of an API. The > >     following API has been defined in this solution: > > > > > > > > I need a better explanation around why this new API is required, and this new capability isn't just an implementation detail supporting the old API. > > > > Example 1 > ========= > > Let us say that an application or a library has a simple trampoline - load a value or > an address in a register or the stack and transfer control to some target function. > It would have dynamic code to do that just like libffi currently does. > > Dynamic code has a security issue as I have explained in the cover letter. It needs > to be loaded in an executable page. A clever hacker may be able to inject his code > in that page. To prevent that, dynamic code has to be converted into static code > so that it is in a read-only text segment. > > I have solved this problem for libffi and I have provided statically defined trampolines. > > The application or library that is currently using dynamic code for its trampoline could > instead use the libffi API and replace its trampoline. This would eliminate dynamic code > from that application or library and make it more secure. > > The only thing is that the target function should now expect its data in the libffi > designated scratch register instead of whatever it was using. This is trivial to do. > > Example 2 > ========== > > Let us say that an application or library uses something more complicated than the > libffi trampoline. For example, a piece of dynamic code that unmarshalls parameters > from a structure and calls a target function. > > The application developer is interested in eliminating this piece of dynamic code > for security purposes. The developer could rewrite the dynamic code into static > code. The only thing is that the structure pointer needs to be passed to the static > code. Either the application developer can write his own code (using PC-relative > accesses, etc) to pass data. Or, he can use the libffi API to do it. > > So, the only effort for the developer/maintainer of the application/library is to > rewrite the unmarshalling dynamic code into static code. That should be straight forward. > > Example 3 > ========= > > Let us say that an application or library has a piece of dynamic code to perform > some computation and produce results. It is written as dynamic code because > the exact set of arguments and the exact computation is known only at runtime. > So, the dynamic code is generated at runtime accordingly. When the code is > generated, the data needed by the code is embedded in the generated code. > > In this case, the developer needs to do a little extra work. E.g., > > - Define a union of structures with each structure defining a particular >   computation and set of arguments. > > - Write static code to accept a pointer to the union and perform >   different computations and return results in that union. > > - Then, the static code can be invoked using the libffi API and the union >   pointer can be passed to it. > > Summary > ======= > > There are a lot of applications that use dynamic code out there. Dynamic code > should be eliminated as far as possible for security purposes. > > I believe most of them can be converted to static code by the maintainers. All > they need is a method to pass data to their static code without having to implement > the method themselves. The libffi API provides that. > > The libffi API can also be supported easily for multiple architectures so that > applications can use the API in an architecture-independent way. > > Is this sufficient justification for the API? > > Madhavan >