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=-4.0 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS 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 E596AC433E0 for ; Wed, 12 Aug 2020 10:06:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B978A20781 for ; Wed, 12 Aug 2020 10:06:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727816AbgHLKG5 (ORCPT ); Wed, 12 Aug 2020 06:06:57 -0400 Received: from foss.arm.com ([217.140.110.172]:43570 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726722AbgHLKG5 (ORCPT ); Wed, 12 Aug 2020 06:06:57 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id AAB2AD6E; Wed, 12 Aug 2020 03:06:55 -0700 (PDT) Received: from C02TD0UTHF1T.local (unknown [10.57.41.8]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 521E23F22E; Wed, 12 Aug 2020 03:06:53 -0700 (PDT) Date: Wed, 12 Aug 2020 11:06:50 +0100 From: Mark Rutland To: "Madhavan T. Venkataraman" Cc: kernel-hardening@lists.openwall.com, linux-api@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-fsdevel@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, oleg@redhat.com, x86@kernel.org Subject: Re: [PATCH v1 0/4] [RFC] Implement Trampoline File Descriptor Message-ID: <20200812100650.GB28154@C02TD0UTHF1T.local> References: <20200728131050.24443-1-madvenka@linux.microsoft.com> <20200731180955.GC67415@C02TD0UTHF1T.local> <6236adf7-4bed-534e-0956-fddab4fd96b6@linux.microsoft.com> <20200804143018.GB7440@C02TD0UTHF1T.local> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Aug 06, 2020 at 12:26:02PM -0500, Madhavan T. Venkataraman wrote: > Thanks for the lively discussion. I have tried to answer some of the > comments below. > > On 8/4/20 9:30 AM, Mark Rutland wrote: > > > >> So, the context is - if security settings in a system disallow a page to have > >> both write and execute permissions, how do you allow the execution of > >> genuine trampolines that are runtime generated and placed in a data > >> page or a stack page? > > There are options today, e.g. > > > > a) If the restriction is only per-alias, you can have distinct aliases > > where one is writable and another is executable, and you can make it > > hard to find the relationship between the two. > > > > b) If the restriction is only temporal, you can write instructions into > > an RW- buffer, transition the buffer to R--, verify the buffer > > contents, then transition it to --X. > > > > c) You can have two processes A and B where A generates instrucitons into > > a buffer that (only) B can execute (where B may be restricted from > > making syscalls like write, mprotect, etc). > > The general principle of the mitigation is W^X. I would argue that > the above options are violations of the W^X principle. If they are > allowed today, they must be fixed. And they will be. So, we cannot > rely on them. Hold on. Contemporary W^X means that a given virtual alias cannot be writeable and executeable simultaneously, permitting (a) and (b). If you read the references on the Wikipedia page for W^X you'll see the OpenBSD 3.3 release notes and related presentation make this clear, and further they expect (b) to occur with JITS flipping W/X with mprotect(). Please don't conflate your assumed stronger semantics with the general principle. It not matching you expectations does not necessarily mean that it is wrong. If you want a stronger W^X semantics, please refer to this specifically with a distinct name. > a) This requires a remap operation. Two mappings point to the same >      physical page. One mapping has W and the other one has X. This >      is a violation of W^X. > > b) This is again a violation. The kernel should refuse to give execute >      permission to a page that was writeable in the past and refuse to >      give write permission to a page that was executable in the past. > > c) This is just a variation of (a). As above, this is not true. If you have a rationale for why this is desirable or necessary, please justify that before using this as justification for additional features. > In general, the problem with user-level methods to map and execute > dynamic code is that the kernel cannot tell if a genuine application is > using them or an attacker is using them or piggy-backing on them. Yes, and as I pointed out the same is true for trampfd unless you can somehow authenticate the calls are legitimate (in both callsite and the set of arguments), and I don't see any reasonable way of doing that. If you relax your threat model to an attacker not being able to make arbitrary syscalls, then your suggestion that userspace can perorm chceks between syscalls may be sufficient, but as I pointed out that's equally true for a sealed memfd or similar. > Off the top of my head, I have tried to identify some examples > where we can have more trust on dynamic code and have the kernel > permit its execution. > > 1. If the kernel can do the job, then that is one safe way. Here, the kernel >     is the code. There is no code generation involved. This is what I >     have presented in the patch series as the first cut. This is sleight-of-hand; it doesn't matter where the logic is performed if the power is identical. Practically speaking this is equivalent to some dynamic code generation. I think that it's misleading to say that because the kernel emulates something it is safe when the provenance of the syscall arguments cannot be verified. [...] > Anyway, these are just examples. The principle is - if we can identify > dynamic code that has a certain measure of trust, can the kernel > permit their execution? My point generally is that the kernel cannot identify this, and if usrspace code is trusted to dynamically generate trampfd arguments it can equally be trusted to dyncamilly generate code. [...] > As I have mentioned above, I intend to have the kernel generate code > only if the code generation is simple enough. For more complicated cases, > I plan to use a user-level code generator that is for exclusive kernel use. > I have yet to work out the details on how this would work. Need time. This reads to me like trampfd is only dealing with a few special cases and we know that we need a more general solution. I hope I am mistaken, but I get the strong impression that you're trying to justify your existing solution rather than trying to understand the problem space. To be clear, my strong opinion is that we should not be trying to do this sort of emulation or code generation within the kernel. I do think it's worthwhile to look at mechanisms to make it harder to subvert dynamic userspace code generation, but I think the code generation itself needs to live in userspace (e.g. for ABI reasons I previously mentioned). Mark. 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=-4.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS 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 5BD39C433DF for ; Wed, 12 Aug 2020 10:09:07 +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 26CBE20781 for ; Wed, 12 Aug 2020 10:09:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="WQY51S6r" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 26CBE20781 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=arm.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:References:Message-ID: Subject:To:From:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=QqIRe/gDn5pz5j3shOlMvIpGEwwbBbMHyt0oEWkUfkU=; b=WQY51S6rvTOkwz2zk0sHS5IzO xdlY0FV/Wt3SPNTO/oJp3Rsm9ceRYW7nxHE6c+Hlhb8raCcAW5eaaMGkOVthuj/b08TsmHJMRQTOz 6W+Lj9gmBrfuMPq6XWFsnsJZvfwnpihHAMUrHHXIG52rPSDcCULNwCdNllyqNMFNv4kKls49VDQ3H t6iX0UmAzRKEmI/sapD85DqZxxDZ5tkYYplIS+96/kt3JClVJZXfMRhYZ/wPlY3CnKtCXnJnfn2TQ xNSLMZTxbSmFYCsnTAL6RaceRYU8L0XkcgwWe7Cm84Oi1rb2HiPHh0juxjHqhGQRZo5qaNG9Agwcd fB9Y9nfzg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1k5nf1-0003z2-1k; Wed, 12 Aug 2020 10:07:07 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1k5ney-0003yf-Mz for linux-arm-kernel@lists.infradead.org; Wed, 12 Aug 2020 10:07:05 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id AAB2AD6E; Wed, 12 Aug 2020 03:06:55 -0700 (PDT) Received: from C02TD0UTHF1T.local (unknown [10.57.41.8]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 521E23F22E; Wed, 12 Aug 2020 03:06:53 -0700 (PDT) Date: Wed, 12 Aug 2020 11:06:50 +0100 From: Mark Rutland To: "Madhavan T. Venkataraman" Subject: Re: [PATCH v1 0/4] [RFC] Implement Trampoline File Descriptor Message-ID: <20200812100650.GB28154@C02TD0UTHF1T.local> References: <20200728131050.24443-1-madvenka@linux.microsoft.com> <20200731180955.GC67415@C02TD0UTHF1T.local> <6236adf7-4bed-534e-0956-fddab4fd96b6@linux.microsoft.com> <20200804143018.GB7440@C02TD0UTHF1T.local> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200812_060704_855371_6F63CEBA X-CRM114-Status: GOOD ( 36.46 ) 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@lists.openwall.com, linux-api@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org, oleg@redhat.com, linux-security-module@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-integrity@vger.kernel.org, linux-arm-kernel@lists.infradead.org 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 T24gVGh1LCBBdWcgMDYsIDIwMjAgYXQgMTI6MjY6MDJQTSAtMDUwMCwgTWFkaGF2YW4gVC4gVmVu a2F0YXJhbWFuIHdyb3RlOgo+IFRoYW5rcyBmb3IgdGhlIGxpdmVseSBkaXNjdXNzaW9uLiBJIGhh dmUgdHJpZWQgdG8gYW5zd2VyIHNvbWUgb2YgdGhlCj4gY29tbWVudHMgYmVsb3cuCj4gCj4gT24g OC80LzIwIDk6MzAgQU0sIE1hcmsgUnV0bGFuZCB3cm90ZToKPiA+Cj4gPj4gU28sIHRoZSBjb250 ZXh0IGlzIC0gaWYgc2VjdXJpdHkgc2V0dGluZ3MgaW4gYSBzeXN0ZW0gZGlzYWxsb3cgYSBwYWdl IHRvIGhhdmUKPiA+PiBib3RoIHdyaXRlIGFuZCBleGVjdXRlIHBlcm1pc3Npb25zLCBob3cgZG8g eW91IGFsbG93IHRoZSBleGVjdXRpb24gb2YKPiA+PiBnZW51aW5lIHRyYW1wb2xpbmVzIHRoYXQg YXJlIHJ1bnRpbWUgZ2VuZXJhdGVkIGFuZCBwbGFjZWQgaW4gYSBkYXRhCj4gPj4gcGFnZSBvciBh IHN0YWNrIHBhZ2U/Cj4gPiBUaGVyZSBhcmUgb3B0aW9ucyB0b2RheSwgZS5nLgo+ID4KPiA+IGEp IElmIHRoZSByZXN0cmljdGlvbiBpcyBvbmx5IHBlci1hbGlhcywgeW91IGNhbiBoYXZlIGRpc3Rp bmN0IGFsaWFzZXMKPiA+ICAgIHdoZXJlIG9uZSBpcyB3cml0YWJsZSBhbmQgYW5vdGhlciBpcyBl eGVjdXRhYmxlLCBhbmQgeW91IGNhbiBtYWtlIGl0Cj4gPiAgICBoYXJkIHRvIGZpbmQgdGhlIHJl bGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSB0d28uCj4gPgo+ID4gYikgSWYgdGhlIHJlc3RyaWN0aW9u IGlzIG9ubHkgdGVtcG9yYWwsIHlvdSBjYW4gd3JpdGUgaW5zdHJ1Y3Rpb25zIGludG8KPiA+ICAg IGFuIFJXLSBidWZmZXIsIHRyYW5zaXRpb24gdGhlIGJ1ZmZlciB0byBSLS0sIHZlcmlmeSB0aGUg YnVmZmVyCj4gPiAgICBjb250ZW50cywgdGhlbiB0cmFuc2l0aW9uIGl0IHRvIC0tWC4KPiA+Cj4g PiBjKSBZb3UgY2FuIGhhdmUgdHdvIHByb2Nlc3NlcyBBIGFuZCBCIHdoZXJlIEEgZ2VuZXJhdGVz IGluc3RydWNpdG9ucyBpbnRvCj4gPiAgICBhIGJ1ZmZlciB0aGF0IChvbmx5KSBCIGNhbiBleGVj dXRlICh3aGVyZSBCIG1heSBiZSByZXN0cmljdGVkIGZyb20KPiA+ICAgIG1ha2luZyBzeXNjYWxs cyBsaWtlIHdyaXRlLCBtcHJvdGVjdCwgZXRjKS4KPiAKPiBUaGUgZ2VuZXJhbCBwcmluY2lwbGUg b2YgdGhlIG1pdGlnYXRpb24gaXMgV15YLiBJIHdvdWxkIGFyZ3VlIHRoYXQKPiB0aGUgYWJvdmUg b3B0aW9ucyBhcmUgdmlvbGF0aW9ucyBvZiB0aGUgV15YIHByaW5jaXBsZS4gSWYgdGhleSBhcmUK PiBhbGxvd2VkIHRvZGF5LCB0aGV5IG11c3QgYmUgZml4ZWQuIEFuZCB0aGV5IHdpbGwgYmUuIFNv LCB3ZSBjYW5ub3QKPiByZWx5IG9uIHRoZW0uCgpIb2xkIG9uLgoKQ29udGVtcG9yYXJ5IFdeWCBt ZWFucyB0aGF0IGEgZ2l2ZW4gdmlydHVhbCBhbGlhcyBjYW5ub3QgYmUgd3JpdGVhYmxlCmFuZCBl eGVjdXRlYWJsZSBzaW11bHRhbmVvdXNseSwgcGVybWl0dGluZyAoYSkgYW5kIChiKS4gSWYgeW91 IHJlYWQgdGhlCnJlZmVyZW5jZXMgb24gdGhlIFdpa2lwZWRpYSBwYWdlIGZvciBXXlggeW91J2xs IHNlZSB0aGUgT3BlbkJTRCAzLjMKcmVsZWFzZSBub3RlcyBhbmQgcmVsYXRlZCBwcmVzZW50YXRp b24gbWFrZSB0aGlzIGNsZWFyLCBhbmQgZnVydGhlciB0aGV5CmV4cGVjdCAoYikgdG8gb2NjdXIg d2l0aCBKSVRTIGZsaXBwaW5nIFcvWCB3aXRoIG1wcm90ZWN0KCkuCgpQbGVhc2UgZG9uJ3QgY29u ZmxhdGUgeW91ciBhc3N1bWVkIHN0cm9uZ2VyIHNlbWFudGljcyB3aXRoIHRoZSBnZW5lcmFsCnBy aW5jaXBsZS4gSXQgbm90IG1hdGNoaW5nIHlvdSBleHBlY3RhdGlvbnMgZG9lcyBub3QgbmVjZXNz YXJpbHkgbWVhbgp0aGF0IGl0IGlzIHdyb25nLgoKSWYgeW91IHdhbnQgYSBzdHJvbmdlciBXXlgg c2VtYW50aWNzLCBwbGVhc2UgcmVmZXIgdG8gdGhpcyBzcGVjaWZpY2FsbHkKd2l0aCBhIGRpc3Rp bmN0IG5hbWUuCgo+IGEpIFRoaXMgcmVxdWlyZXMgYSByZW1hcCBvcGVyYXRpb24uIFR3byBtYXBw aW5ncyBwb2ludCB0byB0aGUgc2FtZQo+IMKgwqDCoMKgIHBoeXNpY2FsIHBhZ2UuIE9uZSBtYXBw aW5nIGhhcyBXIGFuZCB0aGUgb3RoZXIgb25lIGhhcyBYLiBUaGlzCj4gwqDCoMKgwqAgaXMgYSB2 aW9sYXRpb24gb2YgV15YLgo+IAo+IGIpIFRoaXMgaXMgYWdhaW4gYSB2aW9sYXRpb24uIFRoZSBr ZXJuZWwgc2hvdWxkIHJlZnVzZSB0byBnaXZlIGV4ZWN1dGUKPiDCoMKgwqDCoCBwZXJtaXNzaW9u IHRvIGEgcGFnZSB0aGF0IHdhcyB3cml0ZWFibGUgaW4gdGhlIHBhc3QgYW5kIHJlZnVzZSB0bwo+ IMKgwqDCoMKgIGdpdmUgd3JpdGUgcGVybWlzc2lvbiB0byBhIHBhZ2UgdGhhdCB3YXMgZXhlY3V0 YWJsZSBpbiB0aGUgcGFzdC4KPiAKPiBjKSBUaGlzIGlzIGp1c3QgYSB2YXJpYXRpb24gb2YgKGEp LgoKQXMgYWJvdmUsIHRoaXMgaXMgbm90IHRydWUuCgpJZiB5b3UgaGF2ZSBhIHJhdGlvbmFsZSBm b3Igd2h5IHRoaXMgaXMgZGVzaXJhYmxlIG9yIG5lY2Vzc2FyeSwgcGxlYXNlCmp1c3RpZnkgdGhh dCBiZWZvcmUgdXNpbmcgdGhpcyBhcyBqdXN0aWZpY2F0aW9uIGZvciBhZGRpdGlvbmFsIGZlYXR1 cmVzLgoKPiBJbiBnZW5lcmFsLCB0aGUgcHJvYmxlbSB3aXRoIHVzZXItbGV2ZWwgbWV0aG9kcyB0 byBtYXAgYW5kIGV4ZWN1dGUKPiBkeW5hbWljIGNvZGUgaXMgdGhhdCB0aGUga2VybmVsIGNhbm5v dCB0ZWxsIGlmIGEgZ2VudWluZSBhcHBsaWNhdGlvbiBpcwo+IHVzaW5nIHRoZW0gb3IgYW4gYXR0 YWNrZXIgaXMgdXNpbmcgdGhlbSBvciBwaWdneS1iYWNraW5nIG9uIHRoZW0uCgpZZXMsIGFuZCBh cyBJIHBvaW50ZWQgb3V0IHRoZSBzYW1lIGlzIHRydWUgZm9yIHRyYW1wZmQgdW5sZXNzIHlvdSBj YW4Kc29tZWhvdyBhdXRoZW50aWNhdGUgdGhlIGNhbGxzIGFyZSBsZWdpdGltYXRlIChpbiBib3Ro IGNhbGxzaXRlIGFuZCB0aGUKc2V0IG9mIGFyZ3VtZW50cyksIGFuZCBJIGRvbid0IHNlZSBhbnkg cmVhc29uYWJsZSB3YXkgb2YgZG9pbmcgdGhhdC4KCklmIHlvdSByZWxheCB5b3VyIHRocmVhdCBt b2RlbCB0byBhbiBhdHRhY2tlciBub3QgYmVpbmcgYWJsZSB0byBtYWtlCmFyYml0cmFyeSBzeXNj YWxscywgdGhlbiB5b3VyIHN1Z2dlc3Rpb24gdGhhdCB1c2Vyc3BhY2UgY2FuIHBlcm9ybQpjaGNl a3MgYmV0d2VlbiBzeXNjYWxscyBtYXkgYmUgc3VmZmljaWVudCwgYnV0IGFzIEkgcG9pbnRlZCBv dXQgdGhhdCdzCmVxdWFsbHkgdHJ1ZSBmb3IgYSBzZWFsZWQgbWVtZmQgb3Igc2ltaWxhci4KCj4g T2ZmIHRoZSB0b3Agb2YgbXkgaGVhZCwgSSBoYXZlIHRyaWVkIHRvIGlkZW50aWZ5IHNvbWUgZXhh bXBsZXMKPiB3aGVyZSB3ZSBjYW4gaGF2ZSBtb3JlIHRydXN0IG9uIGR5bmFtaWMgY29kZSBhbmQg aGF2ZSB0aGUga2VybmVsCj4gcGVybWl0IGl0cyBleGVjdXRpb24uCj4gCj4gMS4gSWYgdGhlIGtl cm5lbCBjYW4gZG8gdGhlIGpvYiwgdGhlbiB0aGF0IGlzIG9uZSBzYWZlIHdheS4gSGVyZSwgdGhl IGtlcm5lbAo+IMKgwqDCoCBpcyB0aGUgY29kZS4gVGhlcmUgaXMgbm8gY29kZSBnZW5lcmF0aW9u IGludm9sdmVkLiBUaGlzIGlzIHdoYXQgSQo+IMKgwqDCoCBoYXZlIHByZXNlbnRlZCBpbiB0aGUg cGF0Y2ggc2VyaWVzIGFzIHRoZSBmaXJzdCBjdXQuCgpUaGlzIGlzIHNsZWlnaHQtb2YtaGFuZDsg aXQgZG9lc24ndCBtYXR0ZXIgd2hlcmUgdGhlIGxvZ2ljIGlzIHBlcmZvcm1lZAppZiB0aGUgcG93 ZXIgaXMgaWRlbnRpY2FsLiBQcmFjdGljYWxseSBzcGVha2luZyB0aGlzIGlzIGVxdWl2YWxlbnQg dG8Kc29tZSBkeW5hbWljIGNvZGUgZ2VuZXJhdGlvbi4KCkkgdGhpbmsgdGhhdCBpdCdzIG1pc2xl YWRpbmcgdG8gc2F5IHRoYXQgYmVjYXVzZSB0aGUga2VybmVsIGVtdWxhdGVzCnNvbWV0aGluZyBp dCBpcyBzYWZlIHdoZW4gdGhlIHByb3ZlbmFuY2Ugb2YgdGhlIHN5c2NhbGwgYXJndW1lbnRzIGNh bm5vdApiZSB2ZXJpZmllZC4KClsuLi5dCgo+IEFueXdheSwgdGhlc2UgYXJlIGp1c3QgZXhhbXBs ZXMuIFRoZSBwcmluY2lwbGUgaXMgLSBpZiB3ZSBjYW4gaWRlbnRpZnkKPiBkeW5hbWljIGNvZGUg dGhhdCBoYXMgYSBjZXJ0YWluIG1lYXN1cmUgb2YgdHJ1c3QsIGNhbiB0aGUga2VybmVsCj4gcGVy bWl0IHRoZWlyIGV4ZWN1dGlvbj8KCk15IHBvaW50IGdlbmVyYWxseSBpcyB0aGF0IHRoZSBrZXJu ZWwgY2Fubm90IGlkZW50aWZ5IHRoaXMsIGFuZCBpZgp1c3JzcGFjZSBjb2RlIGlzIHRydXN0ZWQg dG8gZHluYW1pY2FsbHkgZ2VuZXJhdGUgdHJhbXBmZCBhcmd1bWVudHMgaXQKY2FuIGVxdWFsbHkg YmUgdHJ1c3RlZCB0byBkeW5jYW1pbGx5IGdlbmVyYXRlIGNvZGUuCgpbLi4uXQoKPiBBcyBJIGhh dmUgbWVudGlvbmVkIGFib3ZlLCBJIGludGVuZCB0byBoYXZlIHRoZSBrZXJuZWwgZ2VuZXJhdGUg Y29kZQo+IG9ubHkgaWYgdGhlIGNvZGUgZ2VuZXJhdGlvbiBpcyBzaW1wbGUgZW5vdWdoLiBGb3Ig bW9yZSBjb21wbGljYXRlZCBjYXNlcywKPiBJIHBsYW4gdG8gdXNlIGEgdXNlci1sZXZlbCBjb2Rl IGdlbmVyYXRvciB0aGF0IGlzIGZvciBleGNsdXNpdmUga2VybmVsIHVzZS4KPiBJIGhhdmUgeWV0 IHRvIHdvcmsgb3V0IHRoZSBkZXRhaWxzIG9uIGhvdyB0aGlzIHdvdWxkIHdvcmsuIE5lZWQgdGlt ZS4KClRoaXMgcmVhZHMgdG8gbWUgbGlrZSB0cmFtcGZkIGlzIG9ubHkgZGVhbGluZyB3aXRoIGEg ZmV3IHNwZWNpYWwgY2FzZXMKYW5kIHdlIGtub3cgdGhhdCB3ZSBuZWVkIGEgbW9yZSBnZW5lcmFs IHNvbHV0aW9uLgoKSSBob3BlIEkgYW0gbWlzdGFrZW4sIGJ1dCBJIGdldCB0aGUgc3Ryb25nIGlt cHJlc3Npb24gdGhhdCB5b3UncmUgdHJ5aW5nCnRvIGp1c3RpZnkgeW91ciBleGlzdGluZyBzb2x1 dGlvbiByYXRoZXIgdGhhbiB0cnlpbmcgdG8gdW5kZXJzdGFuZCB0aGUKcHJvYmxlbSBzcGFjZS4K ClRvIGJlIGNsZWFyLCBteSBzdHJvbmcgb3BpbmlvbiBpcyB0aGF0IHdlIHNob3VsZCBub3QgYmUg dHJ5aW5nIHRvIGRvCnRoaXMgc29ydCBvZiBlbXVsYXRpb24gb3IgY29kZSBnZW5lcmF0aW9uIHdp dGhpbiB0aGUga2VybmVsLiBJIGRvIHRoaW5rCml0J3Mgd29ydGh3aGlsZSB0byBsb29rIGF0IG1l Y2hhbmlzbXMgdG8gbWFrZSBpdCBoYXJkZXIgdG8gc3VidmVydApkeW5hbWljIHVzZXJzcGFjZSBj b2RlIGdlbmVyYXRpb24sIGJ1dCBJIHRoaW5rIHRoZSBjb2RlIGdlbmVyYXRpb24KaXRzZWxmIG5l ZWRzIHRvIGxpdmUgaW4gdXNlcnNwYWNlIChlLmcuIGZvciBBQkkgcmVhc29ucyBJIHByZXZpb3Vz bHkKbWVudGlvbmVkKS4KCk1hcmsuCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fXwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlzdApsaW51eC1hcm0ta2Vy bmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1h bi9saXN0aW5mby9saW51eC1hcm0ta2VybmVsCg==