From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.6 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1,USER_IN_DEF_DKIM_WL autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D0AD0C433E0 for ; Sun, 2 Aug 2020 22:59:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AC12B20738 for ; Sun, 2 Aug 2020 22:59:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="pT2y52UB" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727812AbgHBW7C (ORCPT ); Sun, 2 Aug 2020 18:59:02 -0400 Received: from linux.microsoft.com ([13.77.154.182]:57188 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726257AbgHBW7C (ORCPT ); Sun, 2 Aug 2020 18:59:02 -0400 Received: from [192.168.254.32] (unknown [47.187.206.220]) by linux.microsoft.com (Postfix) with ESMTPSA id 2BD5420B4908; Sun, 2 Aug 2020 15:59:00 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 2BD5420B4908 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1596409140; bh=Q7q31WyGpO6J3iZ6HoTSTxcyY2RYOO3HoBrVjNyqpPA=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=pT2y52UBji3W0nv8oaWqlXsVHl+hqxrTJnSZ5683V0Vq7481OEdHqda3OONYprXUp pUvC7Ja7yH7A7A7PnhVPoN4/nCrqBhOuCsyTs5k8KgsuxVR6rM+c6V/PJxlx37f+KW 8krLq5y3aSQx9KIXxSdL4F/U4BEfCPv/l8nRqqTQ= Subject: Re: [PATCH v1 0/4] [RFC] Implement Trampoline File Descriptor To: Andy Lutomirski Cc: Kernel Hardening , Linux API , linux-arm-kernel , Linux FS Devel , linux-integrity , LKML , LSM List , Oleg Nesterov , X86 ML References: <20200728131050.24443-1-madvenka@linux.microsoft.com> <3b916198-3a98-bd19-9a1c-f2d8d44febe8@linux.microsoft.com> From: "Madhavan T. Venkataraman" Message-ID: <0fa7d888-c4fd-aeb3-db08-151ea648558d@linux.microsoft.com> Date: Sun, 2 Aug 2020 17:58:59 -0500 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-Transfer-Encoding: 8bit Content-Language: en-US Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 8/2/20 3:00 PM, Andy Lutomirski wrote: > On Sun, Aug 2, 2020 at 11:54 AM Madhavan T. Venkataraman > wrote: >> More responses inline.. >> >> On 7/28/20 12:31 PM, Andy Lutomirski wrote: >>>> On Jul 28, 2020, at 6:11 AM, madvenka@linux.microsoft.com wrote: >>>> >>>> From: "Madhavan T. Venkataraman" >>>> >>> 2. Use existing kernel functionality. Raise a signal, modify the >>> state, and return from the signal. This is very flexible and may not >>> be all that much slower than trampfd. >> Let me understand this. You are saying that the trampoline code >> would raise a signal and, in the signal handler, set up the context >> so that when the signal handler returns, we end up in the target >> function with the context correctly set up. And, this trampoline code >> can be generated statically at build time so that there are no >> security issues using it. >> >> Have I understood your suggestion correctly? > yes. > >> So, my argument would be that this would always incur the overhead >> of a trip to the kernel. I think twice the overhead if I am not mistaken. >> With trampfd, we can have the kernel generate the code so that there >> is no performance penalty at all. > I feel like trampfd is too poorly defined at this point to evaluate. > There are three general things it could do. It could generate actual > code that varies by instance. It could have static code that does not > vary. And it could actually involve a kernel entry. > > If it involves a kernel entry, then it's slow. Maybe this is okay for > some use cases. Yes. IMO, it is OK for most cases except where dynamic code is used specifically for enhancing performance such as interpreters using JIT code for frequently executed sequences and dynamic binary translation. > If it involves only static code, I see no good reason that it should > be in the kernel. It does not involve only static code. This is meant for dynamic code. However, see below. > If it involves dynamic code, then I think it needs a clearly defined > use case that actually requires dynamic code. Fair enough. I will work on this and get back to you. This might take a little time. So, bear with me. But I would like to make one point here. There are many applications and libraries out there that use trampolines. They may all require the same sort of things:     - set register context     - push stuff on stack     - jump to a target PC But in each case, the context would be different:     - only register context     - only stack context     - both register and stack contexts     - different registers     - different values pushed on the stack     - different target PCs If we had to do this purely at user level, each application/library would need to roll its own solution, the solution has to be implemented for each supported architecture and maintained. While the code is static in each separate case, it is dynamic across all of them. That is, the kernel will generate the code on the fly for each trampoline instance based on its current context. It will not maintain any static trampoline code at all. Basically, it will supply the context to an arch-specific function and say:     - generate instructions for loading these regs with these values     - generate instructions to push these values on the stack     - generate an instruction to jump to this target PC It will place all of those generated instructions on a page and return the address. So, even with the static case, there is a lot of value in the kernel providing this. Plus, it has the framework to handle dynamic code. >> Also, signals are asynchronous. So, they are vulnerable to race conditions. >> To prevent other signals from coming in while handling the raised signal, >> we would need to block and unblock signals. This will cause more >> overhead. > If you're worried about raise() racing against signals from out of > thread, you have bigger problems to deal with. Agreed. The signal blocking is just one example of problems related to signals. There are other bigger problems as well. So, let us remove the signal-based approach from our discussions. Thanks. Madhavan From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A73ACC433E0 for ; Sun, 2 Aug 2020 23:00:58 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7EBDB2064B for ; Sun, 2 Aug 2020 23:00:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="pQ81ffj7"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="pT2y52UB" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7EBDB2064B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date:Message-ID:From: References:To:Subject:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=kqAuCyvwIXrRyqGso++vbdDQg8bBvhxuc3RMFRU2iGc=; b=pQ81ffj70w9JRayIU2lhpy6md 8BXmrKlan/Z21gwQHM6qVrKNOts9F4bC1cBqaeehbVSdrgcVEs5GyyxNLJRDq4UDu3fkvFUvnX7Rw FExEp3qOMHHWhc1+MtVxpQLLJPXd8vr+ar8wA4K78JQttdTeNxwOY8CR91sMPOD7lXJrVPtnglYks /XdYTpuAdRy2hI0KOCEQmSkeoMbDIMiD7io2GdlX2vn5wQnC0eG2UAWc6wfRLPJCi+avhLNiZx13I BiRWn4k+2LMqJuHDEEF2JudrTZdFJHyQeMlQiyXgxxkgnmhE6taIz2dN7ZinEcZ0BhDMQi/2kwX7e /q8Cd9grA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1k2Mwb-0001Ph-2B; Sun, 02 Aug 2020 22:59:05 +0000 Received: from linux.microsoft.com ([13.77.154.182]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1k2MwY-0001Oy-7A for linux-arm-kernel@lists.infradead.org; Sun, 02 Aug 2020 22:59:03 +0000 Received: from [192.168.254.32] (unknown [47.187.206.220]) by linux.microsoft.com (Postfix) with ESMTPSA id 2BD5420B4908; Sun, 2 Aug 2020 15:59:00 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 2BD5420B4908 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1596409140; bh=Q7q31WyGpO6J3iZ6HoTSTxcyY2RYOO3HoBrVjNyqpPA=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=pT2y52UBji3W0nv8oaWqlXsVHl+hqxrTJnSZ5683V0Vq7481OEdHqda3OONYprXUp pUvC7Ja7yH7A7A7PnhVPoN4/nCrqBhOuCsyTs5k8KgsuxVR6rM+c6V/PJxlx37f+KW 8krLq5y3aSQx9KIXxSdL4F/U4BEfCPv/l8nRqqTQ= Subject: Re: [PATCH v1 0/4] [RFC] Implement Trampoline File Descriptor To: Andy Lutomirski References: <20200728131050.24443-1-madvenka@linux.microsoft.com> <3b916198-3a98-bd19-9a1c-f2d8d44febe8@linux.microsoft.com> From: "Madhavan T. Venkataraman" Message-ID: <0fa7d888-c4fd-aeb3-db08-151ea648558d@linux.microsoft.com> Date: Sun, 2 Aug 2020 17:58:59 -0500 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-Language: en-US X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200802_185902_530018_D43E60C8 X-CRM114-Status: GOOD ( 29.10 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kernel Hardening , Linux API , X86 ML , LKML , Oleg Nesterov , LSM List , Linux FS Devel , linux-integrity , linux-arm-kernel Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org CgpPbiA4LzIvMjAgMzowMCBQTSwgQW5keSBMdXRvbWlyc2tpIHdyb3RlOgo+IE9uIFN1biwgQXVn IDIsIDIwMjAgYXQgMTE6NTQgQU0gTWFkaGF2YW4gVC4gVmVua2F0YXJhbWFuCj4gPG1hZHZlbmth QGxpbnV4Lm1pY3Jvc29mdC5jb20+IHdyb3RlOgo+PiBNb3JlIHJlc3BvbnNlcyBpbmxpbmUuLgo+ Pgo+PiBPbiA3LzI4LzIwIDEyOjMxIFBNLCBBbmR5IEx1dG9taXJza2kgd3JvdGU6Cj4+Pj4gT24g SnVsIDI4LCAyMDIwLCBhdCA2OjExIEFNLCBtYWR2ZW5rYUBsaW51eC5taWNyb3NvZnQuY29tIHdy b3RlOgo+Pj4+Cj4+Pj4g77u/RnJvbTogIk1hZGhhdmFuIFQuIFZlbmthdGFyYW1hbiIgPG1hZHZl bmthQGxpbnV4Lm1pY3Jvc29mdC5jb20+Cj4+Pj4KPj4+IDIuIFVzZSBleGlzdGluZyBrZXJuZWwg ZnVuY3Rpb25hbGl0eS4gIFJhaXNlIGEgc2lnbmFsLCBtb2RpZnkgdGhlCj4+PiBzdGF0ZSwgYW5k IHJldHVybiBmcm9tIHRoZSBzaWduYWwuICBUaGlzIGlzIHZlcnkgZmxleGlibGUgYW5kIG1heSBu b3QKPj4+IGJlIGFsbCB0aGF0IG11Y2ggc2xvd2VyIHRoYW4gdHJhbXBmZC4KPj4gTGV0IG1lIHVu ZGVyc3RhbmQgdGhpcy4gWW91IGFyZSBzYXlpbmcgdGhhdCB0aGUgdHJhbXBvbGluZSBjb2RlCj4+ IHdvdWxkIHJhaXNlIGEgc2lnbmFsIGFuZCwgaW4gdGhlIHNpZ25hbCBoYW5kbGVyLCBzZXQgdXAg dGhlIGNvbnRleHQKPj4gc28gdGhhdCB3aGVuIHRoZSBzaWduYWwgaGFuZGxlciByZXR1cm5zLCB3 ZSBlbmQgdXAgaW4gdGhlIHRhcmdldAo+PiBmdW5jdGlvbiB3aXRoIHRoZSBjb250ZXh0IGNvcnJl Y3RseSBzZXQgdXAuIEFuZCwgdGhpcyB0cmFtcG9saW5lIGNvZGUKPj4gY2FuIGJlIGdlbmVyYXRl ZCBzdGF0aWNhbGx5IGF0IGJ1aWxkIHRpbWUgc28gdGhhdCB0aGVyZSBhcmUgbm8KPj4gc2VjdXJp dHkgaXNzdWVzIHVzaW5nIGl0Lgo+Pgo+PiBIYXZlIEkgdW5kZXJzdG9vZCB5b3VyIHN1Z2dlc3Rp b24gY29ycmVjdGx5Pwo+IHllcy4KPgo+PiBTbywgbXkgYXJndW1lbnQgd291bGQgYmUgdGhhdCB0 aGlzIHdvdWxkIGFsd2F5cyBpbmN1ciB0aGUgb3ZlcmhlYWQKPj4gb2YgYSB0cmlwIHRvIHRoZSBr ZXJuZWwuIEkgdGhpbmsgdHdpY2UgdGhlIG92ZXJoZWFkIGlmIEkgYW0gbm90IG1pc3Rha2VuLgo+ PiBXaXRoIHRyYW1wZmQsIHdlIGNhbiBoYXZlIHRoZSBrZXJuZWwgZ2VuZXJhdGUgdGhlIGNvZGUg c28gdGhhdCB0aGVyZQo+PiBpcyBubyBwZXJmb3JtYW5jZSBwZW5hbHR5IGF0IGFsbC4KPiBJIGZl ZWwgbGlrZSB0cmFtcGZkIGlzIHRvbyBwb29ybHkgZGVmaW5lZCBhdCB0aGlzIHBvaW50IHRvIGV2 YWx1YXRlLgo+IFRoZXJlIGFyZSB0aHJlZSBnZW5lcmFsIHRoaW5ncyBpdCBjb3VsZCBkby4gIEl0 IGNvdWxkIGdlbmVyYXRlIGFjdHVhbAo+IGNvZGUgdGhhdCB2YXJpZXMgYnkgaW5zdGFuY2UuICBJ dCBjb3VsZCBoYXZlIHN0YXRpYyBjb2RlIHRoYXQgZG9lcyBub3QKPiB2YXJ5LiAgQW5kIGl0IGNv dWxkIGFjdHVhbGx5IGludm9sdmUgYSBrZXJuZWwgZW50cnkuCj4KPiBJZiBpdCBpbnZvbHZlcyBh IGtlcm5lbCBlbnRyeSwgdGhlbiBpdCdzIHNsb3cuICBNYXliZSB0aGlzIGlzIG9rYXkgZm9yCj4g c29tZSB1c2UgY2FzZXMuCgpZZXMuIElNTywgaXQgaXMgT0sgZm9yIG1vc3QgY2FzZXMgZXhjZXB0 IHdoZXJlIGR5bmFtaWMgY29kZQppcyB1c2VkIHNwZWNpZmljYWxseSBmb3IgZW5oYW5jaW5nIHBl cmZvcm1hbmNlIHN1Y2ggYXMgaW50ZXJwcmV0ZXJzCnVzaW5nIEpJVCBjb2RlIGZvciBmcmVxdWVu dGx5IGV4ZWN1dGVkIHNlcXVlbmNlcyBhbmQgZHluYW1pYwpiaW5hcnkgdHJhbnNsYXRpb24uCgo+ IElmIGl0IGludm9sdmVzIG9ubHkgc3RhdGljIGNvZGUsIEkgc2VlIG5vIGdvb2QgcmVhc29uIHRo YXQgaXQgc2hvdWxkCj4gYmUgaW4gdGhlIGtlcm5lbC4KCkl0IGRvZXMgbm90IGludm9sdmUgb25s eSBzdGF0aWMgY29kZS4gVGhpcyBpcyBtZWFudCBmb3IgZHluYW1pYyBjb2RlLgpIb3dldmVyLCBz ZWUgYmVsb3cuCgo+IElmIGl0IGludm9sdmVzIGR5bmFtaWMgY29kZSwgdGhlbiBJIHRoaW5rIGl0 IG5lZWRzIGEgY2xlYXJseSBkZWZpbmVkCj4gdXNlIGNhc2UgdGhhdCBhY3R1YWxseSByZXF1aXJl cyBkeW5hbWljIGNvZGUuCgpGYWlyIGVub3VnaC4gSSB3aWxsIHdvcmsgb24gdGhpcyBhbmQgZ2V0 IGJhY2sgdG8geW91LiBUaGlzIG1pZ2h0IHRha2UKYSBsaXR0bGUgdGltZS4gU28sIGJlYXIgd2l0 aCBtZS4KCkJ1dCBJIHdvdWxkIGxpa2UgdG8gbWFrZSBvbmUgcG9pbnQgaGVyZS4gVGhlcmUgYXJl IG1hbnkgYXBwbGljYXRpb25zCmFuZCBsaWJyYXJpZXMgb3V0IHRoZXJlIHRoYXQgdXNlIHRyYW1w b2xpbmVzLiBUaGV5IG1heSBhbGwgcmVxdWlyZSB0aGUKc2FtZSBzb3J0IG9mIHRoaW5nczoKCsKg wqDCoCAtIHNldCByZWdpc3RlciBjb250ZXh0CsKgwqDCoCAtIHB1c2ggc3R1ZmYgb24gc3RhY2sK wqDCoMKgIC0ganVtcCB0byBhIHRhcmdldCBQQwoKQnV0IGluIGVhY2ggY2FzZSwgdGhlIGNvbnRl eHQgd291bGQgYmUgZGlmZmVyZW50OgoKwqDCoMKgIC0gb25seSByZWdpc3RlciBjb250ZXh0CsKg wqDCoCAtIG9ubHkgc3RhY2sgY29udGV4dArCoMKgwqAgLSBib3RoIHJlZ2lzdGVyIGFuZCBzdGFj ayBjb250ZXh0cwrCoMKgwqAgLSBkaWZmZXJlbnQgcmVnaXN0ZXJzCsKgwqDCoCAtIGRpZmZlcmVu dCB2YWx1ZXMgcHVzaGVkIG9uIHRoZSBzdGFjawrCoMKgwqAgLSBkaWZmZXJlbnQgdGFyZ2V0IFBD cwoKSWYgd2UgaGFkIHRvIGRvIHRoaXMgcHVyZWx5IGF0IHVzZXIgbGV2ZWwsIGVhY2ggYXBwbGlj YXRpb24vbGlicmFyeSB3b3VsZApuZWVkIHRvIHJvbGwgaXRzIG93biBzb2x1dGlvbiwgdGhlIHNv bHV0aW9uIGhhcyB0byBiZSBpbXBsZW1lbnRlZCBmb3IKZWFjaCBzdXBwb3J0ZWQgYXJjaGl0ZWN0 dXJlIGFuZCBtYWludGFpbmVkLiBXaGlsZSB0aGUgY29kZSBpcyBzdGF0aWMKaW4gZWFjaCBzZXBh cmF0ZSBjYXNlLCBpdCBpcyBkeW5hbWljIGFjcm9zcyBhbGwgb2YgdGhlbS4KClRoYXQgaXMsIHRo ZSBrZXJuZWwgd2lsbCBnZW5lcmF0ZSB0aGUgY29kZSBvbiB0aGUgZmx5IGZvciBlYWNoIHRyYW1w b2xpbmUKaW5zdGFuY2UgYmFzZWQgb24gaXRzIGN1cnJlbnQgY29udGV4dC4gSXQgd2lsbCBub3Qg bWFpbnRhaW4gYW55IHN0YXRpYwp0cmFtcG9saW5lIGNvZGUgYXQgYWxsLgoKQmFzaWNhbGx5LCBp dCB3aWxsIHN1cHBseSB0aGUgY29udGV4dCB0byBhbiBhcmNoLXNwZWNpZmljIGZ1bmN0aW9uIGFu ZCBzYXk6CgrCoMKgwqAgLSBnZW5lcmF0ZSBpbnN0cnVjdGlvbnMgZm9yIGxvYWRpbmcgdGhlc2Ug cmVncyB3aXRoIHRoZXNlIHZhbHVlcwrCoMKgwqAgLSBnZW5lcmF0ZSBpbnN0cnVjdGlvbnMgdG8g cHVzaCB0aGVzZSB2YWx1ZXMgb24gdGhlIHN0YWNrCsKgwqDCoCAtIGdlbmVyYXRlIGFuIGluc3Ry dWN0aW9uIHRvIGp1bXAgdG8gdGhpcyB0YXJnZXQgUEMKCkl0IHdpbGwgcGxhY2UgYWxsIG9mIHRo b3NlIGdlbmVyYXRlZCBpbnN0cnVjdGlvbnMgb24gYSBwYWdlIGFuZCByZXR1cm4gdGhlIGFkZHJl c3MuCgpTbywgZXZlbiB3aXRoIHRoZSBzdGF0aWMgY2FzZSwgdGhlcmUgaXMgYSBsb3Qgb2YgdmFs dWUgaW4gdGhlIGtlcm5lbCBwcm92aWRpbmcKdGhpcy4gUGx1cywgaXQgaGFzIHRoZSBmcmFtZXdv cmsgdG8gaGFuZGxlIGR5bmFtaWMgY29kZS4KCj4+IEFsc28sIHNpZ25hbHMgYXJlIGFzeW5jaHJv bm91cy4gU28sIHRoZXkgYXJlIHZ1bG5lcmFibGUgdG8gcmFjZSBjb25kaXRpb25zLgo+PiBUbyBw cmV2ZW50IG90aGVyIHNpZ25hbHMgZnJvbSBjb21pbmcgaW4gd2hpbGUgaGFuZGxpbmcgdGhlIHJh aXNlZCBzaWduYWwsCj4+IHdlIHdvdWxkIG5lZWQgdG8gYmxvY2sgYW5kIHVuYmxvY2sgc2lnbmFs cy4gVGhpcyB3aWxsIGNhdXNlIG1vcmUKPj4gb3ZlcmhlYWQuCj4gSWYgeW91J3JlIHdvcnJpZWQg YWJvdXQgcmFpc2UoKSByYWNpbmcgYWdhaW5zdCBzaWduYWxzIGZyb20gb3V0IG9mCj4gdGhyZWFk LCB5b3UgaGF2ZSBiaWdnZXIgcHJvYmxlbXMgdG8gZGVhbCB3aXRoLgoKQWdyZWVkLiBUaGUgc2ln bmFsIGJsb2NraW5nIGlzIGp1c3Qgb25lIGV4YW1wbGUgb2YgcHJvYmxlbXMgcmVsYXRlZAp0byBz aWduYWxzLiBUaGVyZSBhcmUgb3RoZXIgYmlnZ2VyIHByb2JsZW1zIGFzIHdlbGwuIFNvLCBsZXQg dXMgcmVtb3ZlCnRoZSBzaWduYWwtYmFzZWQgYXBwcm9hY2ggZnJvbSBvdXIgZGlzY3Vzc2lvbnMu CgpUaGFua3MuCgpNYWRoYXZhbgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5l bEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4v bGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=