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 87049C433E0 for ; Sun, 2 Aug 2020 18:54:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6D4A1206DA for ; Sun, 2 Aug 2020 18:54:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="fHpnzFOJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726883AbgHBSyj (ORCPT ); Sun, 2 Aug 2020 14:54:39 -0400 Received: from linux.microsoft.com ([13.77.154.182]:55680 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725801AbgHBSyi (ORCPT ); Sun, 2 Aug 2020 14:54:38 -0400 Received: from [192.168.254.32] (unknown [47.187.206.220]) by linux.microsoft.com (Postfix) with ESMTPSA id 8B20620B4908; Sun, 2 Aug 2020 11:54:36 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 8B20620B4908 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1596394477; bh=Bi0Avm087nVKLtlYIbtSWKURIDHCpmDKtLVQ5vuWflc=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=fHpnzFOJOlzwXKwSY8zPf6k+L+PvjjAKdLTYmh86GcRZ1GlLSdgkG9g2/aH5jJhcq rLnj76Yu6QdnUO6KTpkXFwOCQ9jicshEkSNSDxcUKT9TPhmvEepbEQ05Wq5VephZTP PadVn+hOSExc6VqPzwe7hlZHes7rqpGKqv+UP3nE= 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> From: "Madhavan T. Venkataraman" Message-ID: <3b916198-3a98-bd19-9a1c-f2d8d44febe8@linux.microsoft.com> Date: Sun, 2 Aug 2020 13:54:35 -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 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? 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. Signals have many problems. Which signal number should we use for this purpose? If we use an existing one, that might conflict with what the application is already handling. Getting a new signal number for this could meet with resistance from the community. 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. > 3. Use a syscall. Instead of having the kernel handle page faults, > have the trampoline code push the syscall nr register, load a special > new syscall nr into the syscall nr register, and do a syscall. On > x86_64, this would be: > > pushq %rax > movq __NR_magic_trampoline, %rax > syscall > > with some adjustment if the stack slot you're clobbering is important. How is this better than the kernel handling an address fault? The system call still needs to do the same work as the fault handler. We do need to specify the register and stack contexts before hand so the system call can do its job. Also, this always incurs a trip to the kernel. With trampfd, the kernel could generate the code to avoid the performance penalty. > > Also, will using trampfd cause issues with various unwinders? I can > easily imagine unwinders expecting code to be readable, although this > is slowly going away for other reasons. I need to study unwinders a little before I respond to this question. So, bear with me. > All this being said, I think that the kernel should absolutely add a > sensible interface for JITs to use to materialize their code. This > would integrate sanely with LSMs and wouldn't require hacks like using > files, etc. A cleverly designed JIT interface could function without > seriailization IPIs, and even lame architectures like x86 could > potentially avoid shootdown IPIs if the interface copied code instead > of playing virtual memory games. At its very simplest, this could be: > > void *jit_create_code(const void *source, size_t len); > > and the result would be a new anonymous mapping that contains exactly > the code requested. There could also be: > > int jittfd_create(...); > > that does something similar but creates a memfd. A nicer > implementation for short JIT sequences would allow appending more code > to an existing JIT region. On x86, an appendable JIT region would > start filled with 0xCC, and I bet there's a way to materialize new > code into a previously 0xcc-filled virtual page wthout any > synchronization. One approach would be to start with: > > > 0xcc > 0xcc > ... > 0xcc > > and to create a whole new page like: > > > > 0xcc > ... > 0xcc > > so that the only difference is that some code changed to some more > code. Then replace the PTE to swap from the old page to the new page, > and arrange to avoid freeing the old page until we're sure it's gone > from all TLBs. This may not work if spans a page > boundary. The #BP fixup would zap the TLB and retry. Even just > directly copying code over some 0xcc bytes almost works, but there's a > nasty corner case involving instructions that fetch I$ fetch > boundaries. I'm not sure to what extent I$ snooping helps. I am thinking that the trampfd API can be used for addressing JIT code as well. I have not yet started thinking about the details. But I think the API is sufficient. E.g.,     struct trampfd_jit {         void    *source;         size_t    len;     };     struct trampfd_jit    jit;     struct trampfd_map    map;     void    *addr;     jit.source = blah;     jit.size = blah;     fd = syscall(440, TRAMPFD_JIT, &jit, flags);     pread(fd, &map, sizeof(map), TRAMPFD_MAP_OFFSET);     addr = mmap(NULL, map.size, map.prot, map.flags, fd, map.offset); And addr would be used to invoke the generated JIT code. 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 20C03C433DF for ; Sun, 2 Aug 2020 18:56:19 +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 EAB19206DA for ; Sun, 2 Aug 2020 18:56:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="ReKE9Ari"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="fHpnzFOJ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EAB19206DA 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=4Vp18BcVbRNKHFuyeXfaGAchUBAMjaj26Ww6/Pc9Oak=; b=ReKE9ArimBn6ZNK0+BCaTfqQw HmDWcOLuqVt9kIPKeyM89ZwtP20lcd3KYx87/oYfs+j0RDgzyEvXlVlPHeKOzVUiGBPrrRGVR7uz+ DJjLWGc3BQZy4KPW9cTPXmXOBP3X9jrXqpC9qXEmVGKLCJtoEIQETmFV9VzDexoqgvRGTYArajXaJ imqMFmCPfeonf98r0zFIglE0yjFTnpvNUj55EFFz2bQVqAbrjXLMhEHVlRij1b4GCjlu70XQEALRz H6pPNgzdIDgalHImlM7Z5BFwPgzXXeNy37ht9pzqE4iBGReI5QEwNNpsnE2Djui3WcbDO1r4yxRZV eq5iGFZjg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1k2J8A-0003Py-KD; Sun, 02 Aug 2020 18:54:46 +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 1k2J87-0003OY-JX for linux-arm-kernel@lists.infradead.org; Sun, 02 Aug 2020 18:54:44 +0000 Received: from [192.168.254.32] (unknown [47.187.206.220]) by linux.microsoft.com (Postfix) with ESMTPSA id 8B20620B4908; Sun, 2 Aug 2020 11:54:36 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 8B20620B4908 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1596394477; bh=Bi0Avm087nVKLtlYIbtSWKURIDHCpmDKtLVQ5vuWflc=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=fHpnzFOJOlzwXKwSY8zPf6k+L+PvjjAKdLTYmh86GcRZ1GlLSdgkG9g2/aH5jJhcq rLnj76Yu6QdnUO6KTpkXFwOCQ9jicshEkSNSDxcUKT9TPhmvEepbEQ05Wq5VephZTP PadVn+hOSExc6VqPzwe7hlZHes7rqpGKqv+UP3nE= Subject: Re: [PATCH v1 0/4] [RFC] Implement Trampoline File Descriptor To: Andy Lutomirski References: <20200728131050.24443-1-madvenka@linux.microsoft.com> From: "Madhavan T. Venkataraman" Message-ID: <3b916198-3a98-bd19-9a1c-f2d8d44febe8@linux.microsoft.com> Date: Sun, 2 Aug 2020 13:54:35 -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_145443_768844_8E323FE1 X-CRM114-Status: GOOD ( 34.19 ) 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 TW9yZSByZXNwb25zZXMgaW5saW5lLi4KCk9uIDcvMjgvMjAgMTI6MzEgUE0sIEFuZHkgTHV0b21p cnNraSB3cm90ZToKPj4gT24gSnVsIDI4LCAyMDIwLCBhdCA2OjExIEFNLCBtYWR2ZW5rYUBsaW51 eC5taWNyb3NvZnQuY29tIHdyb3RlOgo+Pgo+PiDvu79Gcm9tOiAiTWFkaGF2YW4gVC4gVmVua2F0 YXJhbWFuIiA8bWFkdmVua2FAbGludXgubWljcm9zb2Z0LmNvbT4KPj4KPgo+IDIuIFVzZSBleGlz dGluZyBrZXJuZWwgZnVuY3Rpb25hbGl0eS4gIFJhaXNlIGEgc2lnbmFsLCBtb2RpZnkgdGhlCj4g c3RhdGUsIGFuZCByZXR1cm4gZnJvbSB0aGUgc2lnbmFsLiAgVGhpcyBpcyB2ZXJ5IGZsZXhpYmxl IGFuZCBtYXkgbm90Cj4gYmUgYWxsIHRoYXQgbXVjaCBzbG93ZXIgdGhhbiB0cmFtcGZkLgoKTGV0 IG1lIHVuZGVyc3RhbmQgdGhpcy4gWW91IGFyZSBzYXlpbmcgdGhhdCB0aGUgdHJhbXBvbGluZSBj b2RlCndvdWxkIHJhaXNlIGEgc2lnbmFsIGFuZCwgaW4gdGhlIHNpZ25hbCBoYW5kbGVyLCBzZXQg dXAgdGhlIGNvbnRleHQKc28gdGhhdCB3aGVuIHRoZSBzaWduYWwgaGFuZGxlciByZXR1cm5zLCB3 ZSBlbmQgdXAgaW4gdGhlIHRhcmdldApmdW5jdGlvbiB3aXRoIHRoZSBjb250ZXh0IGNvcnJlY3Rs eSBzZXQgdXAuIEFuZCwgdGhpcyB0cmFtcG9saW5lIGNvZGUKY2FuIGJlIGdlbmVyYXRlZCBzdGF0 aWNhbGx5IGF0IGJ1aWxkIHRpbWUgc28gdGhhdCB0aGVyZSBhcmUgbm8Kc2VjdXJpdHkgaXNzdWVz IHVzaW5nIGl0LgoKSGF2ZSBJIHVuZGVyc3Rvb2QgeW91ciBzdWdnZXN0aW9uIGNvcnJlY3RseT8K ClNvLCBteSBhcmd1bWVudCB3b3VsZCBiZSB0aGF0IHRoaXMgd291bGQgYWx3YXlzIGluY3VyIHRo ZSBvdmVyaGVhZApvZiBhIHRyaXAgdG8gdGhlIGtlcm5lbC4gSSB0aGluayB0d2ljZSB0aGUgb3Zl cmhlYWQgaWYgSSBhbSBub3QgbWlzdGFrZW4uCldpdGggdHJhbXBmZCwgd2UgY2FuIGhhdmUgdGhl IGtlcm5lbCBnZW5lcmF0ZSB0aGUgY29kZSBzbyB0aGF0IHRoZXJlCmlzIG5vIHBlcmZvcm1hbmNl IHBlbmFsdHkgYXQgYWxsLgoKU2lnbmFscyBoYXZlIG1hbnkgcHJvYmxlbXMuIFdoaWNoIHNpZ25h bCBudW1iZXIgc2hvdWxkIHdlIHVzZSBmb3IgdGhpcwpwdXJwb3NlPyBJZiB3ZSB1c2UgYW4gZXhp c3Rpbmcgb25lLCB0aGF0IG1pZ2h0IGNvbmZsaWN0IHdpdGggd2hhdCB0aGUgYXBwbGljYXRpb24K aXMgYWxyZWFkeSBoYW5kbGluZy4gR2V0dGluZyBhIG5ldyBzaWduYWwgbnVtYmVyIGZvciB0aGlz IGNvdWxkIG1lZXQKd2l0aCByZXNpc3RhbmNlIGZyb20gdGhlIGNvbW11bml0eS4KCkFsc28sIHNp Z25hbHMgYXJlIGFzeW5jaHJvbm91cy4gU28sIHRoZXkgYXJlIHZ1bG5lcmFibGUgdG8gcmFjZSBj b25kaXRpb25zLgpUbyBwcmV2ZW50IG90aGVyIHNpZ25hbHMgZnJvbSBjb21pbmcgaW4gd2hpbGUg aGFuZGxpbmcgdGhlIHJhaXNlZCBzaWduYWwsCndlIHdvdWxkIG5lZWQgdG8gYmxvY2sgYW5kIHVu YmxvY2sgc2lnbmFscy4gVGhpcyB3aWxsIGNhdXNlIG1vcmUKb3ZlcmhlYWQuCgo+IDMuIFVzZSBh IHN5c2NhbGwuICBJbnN0ZWFkIG9mIGhhdmluZyB0aGUga2VybmVsIGhhbmRsZSBwYWdlIGZhdWx0 cywKPiBoYXZlIHRoZSB0cmFtcG9saW5lIGNvZGUgcHVzaCB0aGUgc3lzY2FsbCBuciByZWdpc3Rl ciwgbG9hZCBhIHNwZWNpYWwKPiBuZXcgc3lzY2FsbCBuciBpbnRvIHRoZSBzeXNjYWxsIG5yIHJl Z2lzdGVyLCBhbmQgZG8gYSBzeXNjYWxsLiBPbgo+IHg4Nl82NCwgdGhpcyB3b3VsZCBiZToKPgo+ IHB1c2hxICVyYXgKPiBtb3ZxIF9fTlJfbWFnaWNfdHJhbXBvbGluZSwgJXJheAo+IHN5c2NhbGwK Pgo+IHdpdGggc29tZSBhZGp1c3RtZW50IGlmIHRoZSBzdGFjayBzbG90IHlvdSdyZSBjbG9iYmVy aW5nIGlzIGltcG9ydGFudC4KCkhvdyBpcyB0aGlzIGJldHRlciB0aGFuIHRoZSBrZXJuZWwgaGFu ZGxpbmcgYW4gYWRkcmVzcyBmYXVsdD8KVGhlIHN5c3RlbSBjYWxsIHN0aWxsIG5lZWRzIHRvIGRv IHRoZSBzYW1lIHdvcmsgYXMgdGhlIGZhdWx0IGhhbmRsZXIuCldlIGRvIG5lZWQgdG8gc3BlY2lm eSB0aGUgcmVnaXN0ZXIgYW5kIHN0YWNrIGNvbnRleHRzIGJlZm9yZSBoYW5kCnNvIHRoZSBzeXN0 ZW0gY2FsbCBjYW4gZG8gaXRzIGpvYi4KCkFsc28sIHRoaXMgYWx3YXlzIGluY3VycyBhIHRyaXAg dG8gdGhlIGtlcm5lbC4gV2l0aCB0cmFtcGZkLCB0aGUga2VybmVsCmNvdWxkIGdlbmVyYXRlIHRo ZSBjb2RlIHRvIGF2b2lkIHRoZSBwZXJmb3JtYW5jZSBwZW5hbHR5LgoKCj4KPiBBbHNvLCB3aWxs IHVzaW5nIHRyYW1wZmQgY2F1c2UgaXNzdWVzIHdpdGggdmFyaW91cyB1bndpbmRlcnM/ICBJIGNh bgo+IGVhc2lseSBpbWFnaW5lIHVud2luZGVycyBleHBlY3RpbmcgY29kZSB0byBiZSByZWFkYWJs ZSwgYWx0aG91Z2ggdGhpcwo+IGlzIHNsb3dseSBnb2luZyBhd2F5IGZvciBvdGhlciByZWFzb25z LgoKSSBuZWVkIHRvIHN0dWR5IHVud2luZGVycyBhIGxpdHRsZSBiZWZvcmUgSSByZXNwb25kIHRv IHRoaXMgcXVlc3Rpb24uClNvLCBiZWFyIHdpdGggbWUuCgo+IEFsbCB0aGlzIGJlaW5nIHNhaWQs IEkgdGhpbmsgdGhhdCB0aGUga2VybmVsIHNob3VsZCBhYnNvbHV0ZWx5IGFkZCBhCj4gc2Vuc2li bGUgaW50ZXJmYWNlIGZvciBKSVRzIHRvIHVzZSB0byBtYXRlcmlhbGl6ZSB0aGVpciBjb2RlLiAg VGhpcwo+IHdvdWxkIGludGVncmF0ZSBzYW5lbHkgd2l0aCBMU01zIGFuZCB3b3VsZG4ndCByZXF1 aXJlIGhhY2tzIGxpa2UgdXNpbmcKPiBmaWxlcywgZXRjLiAgQSBjbGV2ZXJseSBkZXNpZ25lZCBK SVQgaW50ZXJmYWNlIGNvdWxkIGZ1bmN0aW9uIHdpdGhvdXQKPiBzZXJpYWlsaXphdGlvbiBJUElz LCBhbmQgZXZlbiBsYW1lIGFyY2hpdGVjdHVyZXMgbGlrZSB4ODYgY291bGQKPiBwb3RlbnRpYWxs eSBhdm9pZCBzaG9vdGRvd24gSVBJcyBpZiB0aGUgaW50ZXJmYWNlIGNvcGllZCBjb2RlIGluc3Rl YWQKPiBvZiBwbGF5aW5nIHZpcnR1YWwgbWVtb3J5IGdhbWVzLiAgQXQgaXRzIHZlcnkgc2ltcGxl c3QsIHRoaXMgY291bGQgYmU6Cj4KPiB2b2lkICpqaXRfY3JlYXRlX2NvZGUoY29uc3Qgdm9pZCAq c291cmNlLCBzaXplX3QgbGVuKTsKPgo+IGFuZCB0aGUgcmVzdWx0IHdvdWxkIGJlIGEgbmV3IGFu b255bW91cyBtYXBwaW5nIHRoYXQgY29udGFpbnMgZXhhY3RseQo+IHRoZSBjb2RlIHJlcXVlc3Rl ZC4gIFRoZXJlIGNvdWxkIGFsc28gYmU6Cj4KPiBpbnQgaml0dGZkX2NyZWF0ZSguLi4pOwo+Cj4g dGhhdCBkb2VzIHNvbWV0aGluZyBzaW1pbGFyIGJ1dCBjcmVhdGVzIGEgbWVtZmQuICBBIG5pY2Vy Cj4gaW1wbGVtZW50YXRpb24gZm9yIHNob3J0IEpJVCBzZXF1ZW5jZXMgd291bGQgYWxsb3cgYXBw ZW5kaW5nIG1vcmUgY29kZQo+IHRvIGFuIGV4aXN0aW5nIEpJVCByZWdpb24uICBPbiB4ODYsIGFu IGFwcGVuZGFibGUgSklUIHJlZ2lvbiB3b3VsZAo+IHN0YXJ0IGZpbGxlZCB3aXRoIDB4Q0MsIGFu ZCBJIGJldCB0aGVyZSdzIGEgd2F5IHRvIG1hdGVyaWFsaXplIG5ldwo+IGNvZGUgaW50byBhIHBy ZXZpb3VzbHkgMHhjYy1maWxsZWQgdmlydHVhbCBwYWdlIHd0aG91dCBhbnkKPiBzeW5jaHJvbml6 YXRpb24uICBPbmUgYXBwcm9hY2ggd291bGQgYmUgdG8gc3RhcnQgd2l0aDoKPgo+IDxzb21lIGNv ZGU+Cj4gMHhjYwo+IDB4Y2MKPiAuLi4KPiAweGNjCj4KPiBhbmQgdG8gY3JlYXRlIGEgd2hvbGUg bmV3IHBhZ2UgbGlrZToKPgo+IDxzb21lIGNvZGU+Cj4gPHNvbWUgbW9yZSBjb2RlPgo+IDB4Y2MK PiAuLi4KPiAweGNjCj4KPiBzbyB0aGF0IHRoZSBvbmx5IGRpZmZlcmVuY2UgaXMgdGhhdCBzb21l IGNvZGUgY2hhbmdlZCB0byBzb21lIG1vcmUKPiBjb2RlLiAgVGhlbiByZXBsYWNlIHRoZSBQVEUg dG8gc3dhcCBmcm9tIHRoZSBvbGQgcGFnZSB0byB0aGUgbmV3IHBhZ2UsCj4gYW5kIGFycmFuZ2Ug dG8gYXZvaWQgZnJlZWluZyB0aGUgb2xkIHBhZ2UgdW50aWwgd2UncmUgc3VyZSBpdCdzIGdvbmUK PiBmcm9tIGFsbCBUTEJzLiAgVGhpcyBtYXkgbm90IHdvcmsgaWYgPHNvbWUgbW9yZSBjb2RlPiBz cGFucyBhIHBhZ2UKPiBib3VuZGFyeS4gIFRoZSAjQlAgZml4dXAgd291bGQgemFwIHRoZSBUTEIg YW5kIHJldHJ5LiAgRXZlbiBqdXN0Cj4gZGlyZWN0bHkgY29weWluZyBjb2RlIG92ZXIgc29tZSAw eGNjIGJ5dGVzIGFsbW9zdCB3b3JrcywgYnV0IHRoZXJlJ3MgYQo+IG5hc3R5IGNvcm5lciBjYXNl IGludm9sdmluZyBpbnN0cnVjdGlvbnMgdGhhdCBmZXRjaCBJJCBmZXRjaAo+IGJvdW5kYXJpZXMu ICBJJ20gbm90IHN1cmUgdG8gd2hhdCBleHRlbnQgSSQgc25vb3BpbmcgaGVscHMuCgpJIGFtIHRo aW5raW5nIHRoYXQgdGhlIHRyYW1wZmQgQVBJIGNhbiBiZSB1c2VkIGZvciBhZGRyZXNzaW5nIEpJ VApjb2RlIGFzIHdlbGwuIEkgaGF2ZSBub3QgeWV0IHN0YXJ0ZWQgdGhpbmtpbmcgYWJvdXQgdGhl IGRldGFpbHMuIEJ1dCBJCnRoaW5rIHRoZSBBUEkgaXMgc3VmZmljaWVudC4gRS5nLiwKCsKgwqDC oCBzdHJ1Y3QgdHJhbXBmZF9qaXQgewrCoMKgwqAgwqDCoMKgIHZvaWTCoMKgwqAgKnNvdXJjZTsK wqDCoMKgIMKgwqDCoCBzaXplX3TCoMKgwqAgbGVuOwrCoMKgwqAgfTsKCsKgwqDCoCBzdHJ1Y3Qg dHJhbXBmZF9qaXTCoMKgwqAgaml0OwrCoMKgwqAgc3RydWN0IHRyYW1wZmRfbWFwwqDCoMKgIG1h cDsKwqDCoMKgIHZvaWTCoMKgwqAgKmFkZHI7CgrCoMKgwqAgaml0LnNvdXJjZSA9IGJsYWg7CsKg wqDCoCBqaXQuc2l6ZSA9IGJsYWg7CgrCoMKgwqAgZmQgPSBzeXNjYWxsKDQ0MCwgVFJBTVBGRF9K SVQsICZqaXQsIGZsYWdzKTsKwqDCoMKgIHByZWFkKGZkLCAmbWFwLCBzaXplb2YobWFwKSwgVFJB TVBGRF9NQVBfT0ZGU0VUKTsKwqDCoMKgIGFkZHIgPSBtbWFwKE5VTEwsIG1hcC5zaXplLCBtYXAu cHJvdCwgbWFwLmZsYWdzLCBmZCwgbWFwLm9mZnNldCk7CgpBbmQgYWRkciB3b3VsZCBiZSB1c2Vk IHRvIGludm9rZSB0aGUgZ2VuZXJhdGVkIEpJVCBjb2RlLgoKTWFkaGF2YW4KCgpfX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1hcm0ta2VybmVsIG1h aWxpbmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xp c3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVsCg==