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 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 603B1C46CD2 for ; Wed, 24 Jan 2024 06:58:12 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id CE63F6B0072; Wed, 24 Jan 2024 01:58:11 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id C94BC6B0075; Wed, 24 Jan 2024 01:58:11 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B840F6B007D; Wed, 24 Jan 2024 01:58:11 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id A47786B0072 for ; Wed, 24 Jan 2024 01:58:11 -0500 (EST) Received: from smtpin01.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 2D035A1C5B for ; Wed, 24 Jan 2024 06:58:11 +0000 (UTC) X-FDA: 81713300382.01.DE59FB4 Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) by imf21.hostedemail.com (Postfix) with ESMTP id 55AD21C000B for ; Wed, 24 Jan 2024 06:58:09 +0000 (UTC) Authentication-Results: imf21.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=T7VbsHPL; spf=pass (imf21.hostedemail.com: domain of yosryahmed@google.com designates 209.85.167.54 as permitted sender) smtp.mailfrom=yosryahmed@google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1706079489; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=/HUNAWl4C+LajTE63kyebzHQxUP0MAIa9ujNkriZ7FM=; b=Wnr/WxTlaSjP2f6Ll3df1nZgg7jFopkbiWvQTnixwzPrjBTaW61E9s6mQg62oi2xAVq96d 5/CY4DXb+XWZ/S+/GC8wG6+aXWjKF8HIF+7nuHFMi3a36eJcDp0aWLUzPYSfBvFDA18zlO XukcYSJ+raoEDpF6sr8O38Alh/82twM= ARC-Authentication-Results: i=1; imf21.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=T7VbsHPL; spf=pass (imf21.hostedemail.com: domain of yosryahmed@google.com designates 209.85.167.54 as permitted sender) smtp.mailfrom=yosryahmed@google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1706079489; a=rsa-sha256; cv=none; b=uQF/L57+i+T5ZbKtQWsSgj64PalhDRQfHmQQP5CM9iGTkdPdDqmgYvz1TLMrowkJCld52/ JNhI48aEtBvB6/YToNLdIPtGOZI7VVi7wlVp3zq3jwX/KmgYUTdJVtLD0HbxeGwYlq2Rgx x3MRbv0+LkzBcXjFvTvdz8DZI3pmyZ8= Received: by mail-lf1-f54.google.com with SMTP id 2adb3069b0e04-51008c86ecbso1650699e87.2 for ; Tue, 23 Jan 2024 22:58:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1706079487; x=1706684287; darn=kvack.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=/HUNAWl4C+LajTE63kyebzHQxUP0MAIa9ujNkriZ7FM=; b=T7VbsHPLxybYD53gH46YaIrAeDRgsUKbCp0wPzMoc6iuRdl93bsGYIFaeV4ZuldsLa oa68ac2CG3Kl0f6crQk7fWYmdXeS4MTgFe66kGSInCZzAsp/hJlzGIF/XJRxwC6vzU4Z mkDrkVi7fHAPyYI0sN/Q1l7aIhFTGmGG8qI/QhWw0rNVGMK6Ikru3ZVwlHUeFbC9mv4v nxUB7M/1HCy3uyh/lCVmUPEaqQWgLGcq1l9+eIUJN1OPH0ZAe6Izvj6EDKj6+NFfnu1K KYsInQIgdARmtuISAKjcPJjxR9UYAK0ONmrp9GBGfpEO7i71H8JKwQkq9XUaFCPWsGGQ afag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706079487; x=1706684287; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=/HUNAWl4C+LajTE63kyebzHQxUP0MAIa9ujNkriZ7FM=; b=JuMHRpwS2xYAcE3g5MzPJcfODkiQhOsB3cy01aOBmwopBNMfGaqERtpu/ZoDnMXKSV q7FFVMfG1pT7uU2iKFMS6QFr/dYfajiUp7mWpPCRVWIjjFFix1Hz4qzPdh8JaQdbFNxl Un5YdYxBiwt5HQhPJrAhhE/rmbNNlRdy8fhgzK7B+RZ70HPWh4Ny87t6CAaBG6shPeJ7 eXxt+2mGMZ6bcQkwFQpyQK/664Z+LVxl8LlJh7+4BXtrPSi0wO1WJjfwXIge7xTS08VX uNzWTZAIg5CmDfK8Mp5mWPl1mXskGKf1TAS5l1H4i6jIa873E13gov9mSwZQoFMnYP9l cOjw== X-Gm-Message-State: AOJu0YxR5QQQW6lOuLkX6ye2FaPj8xbwcchqqlQJLKUK+DNGcJHj3Tdh prhF5pXkDc/8//39ZJtt26zLTdmDocnUqifI91nNaoU65WEZpenjxf/mA7MtxcXyvrR+RA7HX11 KgTu95Od8m4jTUPdorQX5hEgCsT3lj+ijB3dm X-Google-Smtp-Source: AGHT+IEJEsLHmf36UzMWexlGozGTA3oncay9+EIOYknKAP+eAjKjeJ3MHNltDTaFjlQPJAUKixYdmXAstWPNY7P/2RQ= X-Received: by 2002:a05:6512:10c3:b0:50f:152b:4430 with SMTP id k3-20020a05651210c300b0050f152b4430mr4342142lfg.8.1706079487182; Tue, 23 Jan 2024 22:58:07 -0800 (PST) MIME-Version: 1.0 References: <20240120024007.2850671-1-yosryahmed@google.com> <20240120024007.2850671-3-yosryahmed@google.com> <20240122201906.GA1567330@cmpxchg.org> <20240123153851.GA1745986@cmpxchg.org> <20240123201234.GC1745986@cmpxchg.org> In-Reply-To: From: Yosry Ahmed Date: Tue, 23 Jan 2024 22:57:30 -0800 Message-ID: Subject: Re: [PATCH 2/2] mm: zswap: remove unnecessary tree cleanups in zswap_swapoff() To: Johannes Weiner Cc: Andrew Morton , Nhat Pham , Chris Li , Chengming Zhou , Huang Ying , linux-mm@kvack.org, linux-kernel@vger.kernel.org Content-Type: multipart/mixed; boundary="000000000000cc0d87060fab951c" X-Rspamd-Queue-Id: 55AD21C000B X-Rspam-User: X-Stat-Signature: peytxswxes686xps4ro7apy3xmssdtwh X-Rspamd-Server: rspam01 X-HE-Tag: 1706079489-694557 X-HE-Meta: U2FsdGVkX19vblQEQZdUug1OVzOtzb+s8agLTgtXYL0R2+T/hbX0mIBNseualGNkNzVPorPkDqUM67Prbt4a/7u+10xxHV1h96xlR4r7Ne5WVe8BXE9bpuiCE9WUMfPA1jjlC0jWNY2AVNbVkKwwb1+9ikkuEXsBSpOdP6D1o4l0mB88ehxg7Tx9B2r2AgauW6tX6K9YXNt7U24Ee9CqTMu3MjGME6fh5W6JSCE+kI2dM7PKox98vORPCaKRR2o37DnWOGsxds6JgXwFh1VLMng5qal7+j6xVDvdeDDTpPk/RcLHpXUnUau+sFddJ92Hx14JirSJg9rX1/w5Gb83FOPqeGUXctFZaUqhRhjslSnkPV0zf3tzhNPvzP7PiGiepKqHdqUjgJWiA1Y79jItt3bze2U2TZ5mVn7tfIJ6/lzsjU/MDnRh0OMPHL2jNtVHFtaDFTsg58QhayijRJLUikl1xW8umI5LDwcJStt7an2dUxH9O2YRNcj+RZLf6C7bc+EaUaOdQZKXAWp3gwUzTOEkTKf9XOLBGYhmh+OgQ/5vSb/33L5IUFSWMJex+BI3nk5c+x0FXeiQ0A87woFnpMPROyg0dPiD4FtiUmgPgNoYbrOa18iOvumMNAJ9IJvl5+/or5ylO4omxwR4xw1tQJ/l6BzkwaaJ1PS/q1pdDaldxDLmcl33WmV5P/xeelyZffud/HUVj/ahTx+j8zbzIdYRfNmV8ABH9EM98kkzy0QiMQVCexPB5o7XnAzlpyEf9VuI6FLAe6XnbbQxaKt9BZH+PzYJqomM1UK1xoNvUOzC+Ph/zS8r1+ZF3t088mSwKJBCCDcF6fAm7KCA1RURlzLKkgOMydHY+nCVnv9xOWBGInpP5xSI9YlW8ou6trzCNyrRzJQkECqCeJ0lqmQr3qTErobnEra6S/mV4BdoZkIqjgpe3FIyI6ij2cHafSAcmFS/okNfGbGVetSe9k3 LY4EsGXM 9O1bxi3U04shf1fdJlK+KP+TDKmt3YNb0rjSD3b0Y8xoyHeZakkugjtEJUH+nDbWoLf7NBs7qn0XjAYcOG2izBwUJ7N07zjfSwCcl1ajUb/utxoHRib2RbVdn7XQjEuVzbqLA9+e+g5Uy/ScOYCbyEXyVmVuFzh2/qYTPDNEcmFSf2c7T84K3wA0EICpAKbRpLn9coby4JUjf9oqBSo1Qn3Lxa66DV5F8YC5ilIGqxGpLkXZYejdwKJYW4qVX7Rk5plokj4yIQQn4jxWnhQeaR++mn4zK/K0FgGoW23wpuqUNkRsYrCzZME3gAYJOrXvtc2vhlcoGGt0KrEdKiig1znRtSpdcopFITwdvfpRAsPljAD6P3ued82qBCiFY/+1RZwZoBnzKPAqFTFu1ForrWn0qdUV6Bcq2H0/C3JunkPi7pkjMFz9jSNBVKM3YHVrHwZzjq/Q5gEn4pVX/FmM+FVsn03EMmGOSeuexTZicaTS4JnGhKdAniF6xOSchHdqlddcbMYViVXO/CAwjZnB92rajUz68nbjVCAKTubfTgguu1IoV+ChSlTiLXIehbLHoE5+1wCukAe8483x/HqIIUd+hLw== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: --000000000000cc0d87060fab951c Content-Type: text/plain; charset="UTF-8" > > > > > However, while I have your attention on the swapoff path, there's a > > > > > slightly irrelevant problem that I think might be there, but I am not > > > > > sure. > > > > > > > > > > It looks to me like swapoff can race with writeback, and there may be > > > > > a chance of UAF for the zswap tree. For example, if zswap_swapoff() > > > > > races with shrink_memcg_cb(), I feel like we may free the tree as it > > > > > is being used. For example if zswap_swapoff()->kfree(tree) happen > > > > > right before shrink_memcg_cb()->list_lru_isolate(l, item). > > > > > > > > > > Please tell me that I am being paranoid and that there is some > > > > > protection against zswap writeback racing with swapoff. It feels like > > > > > we are very careful with zswap entries refcounting, but not with the > > > > > zswap tree itself. > > > > > > > > Hm, I don't see how. > > > > > > > > Writeback operates on entries from the LRU. By the time > > > > zswap_swapoff() is called, try_to_unuse() -> zswap_invalidate() should > > > > will have emptied out the LRU and tree. > > > > > > > > Writeback could have gotten a refcount to the entry and dropped the > > > > tree->lock. But then it does __read_swap_cache_async(), and while > > > > holding the page lock checks the tree under lock once more; if that > > > > finds the entry valid, it means try_to_unuse() hasn't started on this > > > > page yet, and would be held up by the page lock/writeback state. > > > > > > Consider the following race: > > > > > > CPU 1 CPU 2 > > > # In shrink_memcg_cb() # In swap_off > > > list_lru_isolate() > > > zswap_invalidate() > > > .. > > > zswap_swapoff() -> kfree(tree) > > > spin_lock(&tree->lock); > > > > > > Isn't this a UAF or am I missing something here? > > > > Oof. You're right, it looks like there is a bug. Digging through the > > history, I think this is actually quite old: the original backend > > shrinkers would pluck something off their LRU, drop all locks, then > > try to acquire tree->lock. There is no protection against swapoff. > > > > The lock that is supposed to protect this is the LRU lock. That's > > where reclaim and invalidation should synchronize. But it's not right: > > > > 1. We drop the LRU lock before acquiring the tree lock. We should > > instead trylock the tree while still holding the LRU lock to make > > sure the tree is safe against swapoff. > > > > 2. zswap_invalidate() acquires the LRU lock when refcount hits 0. But > > it must always cycle the LRU lock before freeing the tree for that > > synchronization to work. > > > > Once we're holding a refcount to the entry, it's safe to drop all > > locks for the next step because we'll then work against the swapcache > > and entry: __read_swap_cache_async() will try to pin and lock whatever > > swap entry is at that type+offset. This also pins the type's current > > tree. HOWEVER, if swapoff + swapon raced, this could be a different > > tree than what we had in @tree, so > > > > 3. we shouldn't pass @tree to zswap_writeback_entry(). It needs to > > look up zswap_trees[] again after __read_swap_cache_async() > > succeeded to validate the entry. > > > > Once it succeeded, we can validate the entry. The entry is valid due > > to our refcount. The zswap_trees[type] is valid due to the cache pin. > > > > However, if validation failed and we have a non-zero writeback_result, > > there is one last bug: > > > > 4. the original entry's tree is no longer valid for the entry put. > > > > The current scheme handles invalidation fine (which is good because > > that's quite common). But it's fundamentally unsynchronized against > > swapoff (which has probably gone undetected because that's rare). > > > > I can't think of an immediate solution to this, but I wanted to put my > > analysis out for comments. > > > Thanks for the great analysis, I missed the swapoff/swapon race myself :) > > The first solution that came to mind for me was refcounting the zswap > tree with RCU with percpu-refcount, similar to how cgroup refs are > handled (init in zswap_swapon() and kill in zswap_swapoff()). I think > the percpu-refcount may be an overkill in terms of memory usage > though. I think we can still do our own refcounting with RCU, but it > may be more complicated. FWIW, I was able to reproduce the problem in a vm with the following kernel diff: diff --git a/mm/zswap.c b/mm/zswap.c index 78df16d307aa8..6580a4be52a18 100644 --- a/mm/zswap.c +++ b/mm/zswap.c @@ -880,6 +880,9 @@ static enum lru_status shrink_memcg_cb(struct list_head *item, struct list_lru_o */ spin_unlock(lock); + pr_info("Sleeping in shrink_memcg_cb() before spin_lock(&tree->lock)\n"); + schedule_timeout_uninterruptible(msecs_to_jiffies(10 * 1000)); + /* Check for invalidate() race */ spin_lock(&tree->lock); if (entry != zswap_rb_search(&tree->rbroot, swpoffset)) This basically expands the race window to 10 seconds. I have a reproducer script attached that utilizes the zswap shrinker (which makes this much easier to reproduce btw). The steps are as follows: - Compile the kernel with the above diff, and both ZRAM & KASAN enabled. - In one terminal, run zswap_wb_swapoff_race.sh. - In a different terminal, once the "Sleeping in shrink_memcg_cb()" message is logged, run "swapoff /dev/zram0". - In the first terminal, once the 10 seconds elapse, I get a UAF BUG from KASAN (log attached as well). --000000000000cc0d87060fab951c Content-Type: text/x-sh; charset="US-ASCII"; name="zswap_wb_swapoff_race.sh" Content-Disposition: attachment; filename="zswap_wb_swapoff_race.sh" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_lrrfmazh1 IyEvYmluL2Jhc2gKClRPVEFMX01CPTEwMApUT1RBTF9CWVRFUz0kKChUT1RBTF9NQiA8PCAyMCkp ClJPT1RfQ0c9L3N5cy9mcy9jZ3JvdXAKWlJBTV9ERVY9L2Rldi96cmFtMApUTVBGUz0uL3RtcGZz CkFfQVNDSUk9JChwcmludGYgJyVkJyAiJ0EiKQoKZnVuY3Rpb24gY2xlYW51cCgpIHsKICBybSAt cmYgJFRNUEZTLyoKICB1bW91bnQgJFRNUEZTCiAgcm1kaXIgJFRNUEZTCgogIGlmIHN3YXBvbiAt cyB8IGdyZXAgLXEgJFpSQU1fREVWOyB0aGVuCiAgICBzd2Fwb2ZmICRaUkFNX0RFVgogIGZpCiAg ZWNobyAxID4gL3N5cy9ibG9jay96cmFtMC9yZXNldAoKICBybWRpciAkUk9PVF9DRy90ZXN0Cn0K dHJhcCBjbGVhbnVwIEVYSVQKCmVjaG8gMSA+IC9zeXMvbW9kdWxlL3pzd2FwL3BhcmFtZXRlcnMv c2hyaW5rZXJfZW5hYmxlZAoKIyBJbml0aWFsaXplIHRtcGZzCm1rZGlyICRUTVBGUwptb3VudCAt dCB0bXBmcyBub25lICRUTVBGUwoKIyBJbml0aWFsaXplIHpyYW0KZWNobyAkKChUT1RBTF9NQioy KSltID4gL3N5cy9ibG9jay96cmFtMC9kaXNrc2l6ZQpta3N3YXAgLUwgenJhbTAgJFpSQU1fREVW CnN3YXBvbiAkWlJBTV9ERVYKCiMgSW5pdGlhbGl6ZSBjZ3JvdXAKZWNobyAiK21lbW9yeSIgPiAk Uk9PVF9DRy9jZ3JvdXAuc3VidHJlZV9jb250cm9sCm1rZGlyICRST09UX0NHL3Rlc3QKCiMgQ3Jl YXRlIGEgdGVzdCB0bXBmcyBmaWxlIGNvbnRhaW5pbmcgdGhlIGFscGhhYmV0IG9uIHJlcGVhdAoo CiAgZWNobyAwID4gJFJPT1RfQ0cvdGVzdC9jZ3JvdXAucHJvY3MKICBzPSQocHJpbnRmICclcycg e0EuLlp9KQogIHllcyAkcyB8IGRkIGlmbGFnPWZ1bGxibG9jayBvZj0kVE1QRlMvdGVzdCBicz0x TSBjb3VudD0kVE9UQUxfTUIgc3RhdHVzPW5vbmUKKQoKIyBSZWNsYWltIGV2ZXJ5dGhpbmcgKGlu dm9raW5nIHRoZSB6c3dhcCBzaHJpbmtlcikKZWNobyAkVE9UQUxfQllURVMgPiAkUk9PVF9DRy90 ZXN0L21lbW9yeS5yZWNsYWltCg== --000000000000cc0d87060fab951c Content-Type: application/octet-stream; name=uaf_log Content-Disposition: attachment; filename=uaf_log Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_lrrfmaze0 WyAgIDMwLjI1MTExNF0genN3YXA6IFNsZWVwaW5nIGluIHNocmlua19tZW1jZ19jYigpIGJlZm9y ZSBzcGluX2xvY2soJnRyZWUtPmxvY2spClsgICA0MC40MDg0MzFdID09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpbICAgNDAu NDEzMDYyXSBCVUc6IEtBU0FOOiBzbGFiLXVzZS1hZnRlci1mcmVlIGluIF9yYXdfc3Bpbl9sb2Nr KzB4NTkvMHgxMTAKWyAgIDQwLjQxNzI0N10gV3JpdGUgb2Ygc2l6ZSA0IGF0IGFkZHIgZmZmZjg4 ODEwMjUyZGM5OCBieSB0YXNrIHpzd2FwX3diX3N3YXBvZi8zODMKWyAgIDQwLjQyMTYwOV0KWyAg IDQwLjQyMjY0OF0gQ1BVOiAwIFBJRDogMzgzIENvbW06IHpzd2FwX3diX3N3YXBvZiBOb3QgdGFp bnRlZCA2LjcuMCsgIzE5ClsgICA0MC40MjY2NjNdIEhhcmR3YXJlIG5hbWU6IFFFTVUgU3RhbmRh cmQgUEMgKFEzNSArIElDSDksIDIwMDkpLCBCSU9TIDEuMTYuMy1kZWJpYW4tMS4xNi4zLTIgMDQv MDEvMjAxNApbICAgNDAuNDMyMTUxXSBDYWxsIFRyYWNlOgpbICAgNDAuNDMzNzE3XSAgPFRBU0s+ ClsgICA0MC40MzUxMjVdICBkdW1wX3N0YWNrX2x2bCsweDk4LzB4ZDAKWyAgIDQwLjQzNzM4OV0g IHByaW50X2FkZHJlc3NfZGVzY3JpcHRpb24rMHg3Zi8weDNhMApbICAgNDAuNDQwMjcyXSAgcHJp bnRfcmVwb3J0KzB4MTE5LzB4MjIwClsgICA0MC40NDI1NDBdICA/IF9yYXdfc3Bpbl9sb2NrKzB4 NTkvMHgxMTAKWyAgIDQwLjQ0NDk3MV0gID8ga2FzYW5fY29tcGxldGVfbW9kZV9yZXBvcnRfaW5m bysweDY2LzB4ODAKWyAgIDQwLjQ0ODE3MF0gID8gX3Jhd19zcGluX2xvY2srMHg1OS8weDExMApb ICAgNDAuNDUwNTcxXSAga2FzYW5fcmVwb3J0KzB4ZDcvMHgxMTAKWyAgIDQwLjQ1Mjc2Ml0gID8g X3Jhd19zcGluX2xvY2srMHg1OS8weDExMApbICAgNDAuNDU1MjgxXSAga2FzYW5fY2hlY2tfcmFu Z2UrMHgyNTAvMHgyZjAKWyAgIDQwLjQ1Nzc4Ml0gID8gX3Jhd19zcGluX2xvY2srMHg1OS8weDEx MApbICAgNDAuNDYwMTYxXSAgX19rYXNhbl9jaGVja193cml0ZSsweDE4LzB4MjAKWyAgIDQwLjQ2 MjYzOF0gIF9yYXdfc3Bpbl9sb2NrKzB4NTkvMHgxMTAKWyAgIDQwLjQ2NDkzM10gIHNocmlua19t ZW1jZ19jYisweDExYy8weDcwMApbICAgNDAuNDY3MzYwXSAgPyB4YV9sb2FkKzB4Y2QvMHgxNDAK WyAgIDQwLjQ2OTQyOV0gIF9fbGlzdF9scnVfd2Fsa19vbmUrMHgyMzYvMHg1YzAKWyAgIDQwLjQ3 MjA4MF0gID8genN3YXBfc2hyaW5rZXJfY291bnQrMHgzMzAvMHgzMzAKWyAgIDQwLjQ3NDg0MV0g ID8genN3YXBfc2hyaW5rZXJfY291bnQrMHgzMzAvMHgzMzAKWyAgIDQwLjQ3NzU4Nl0gIGxpc3Rf bHJ1X3dhbGtfb25lKzB4YTMvMHgxMDAKWyAgIDQwLjQ4MDAyM10gIHpzd2FwX3Nocmlua2VyX3Nj YW4rMHgyYzcvMHg0NTAKWyAgIDQwLjQ4MjY0OV0gIGRvX3Nocmlua19zbGFiKzB4M2E2LzB4OGYw ClsgICA0MC40ODUwMDVdICBzaHJpbmtfc2xhYl9tZW1jZysweDNmZS8weDdjMApbICAgNDAuNDg3 NDk5XSAgc2hyaW5rX3NsYWIrMHg3Yy8weDNhMApbICAgNDAuNDg5NjU4XSAgPyBtZW1fY2dyb3Vw X2l0ZXIrMHgyYWUvMHg3ODAKWyAgIDQwLjQ5MjEzN10gIHNocmlua19ub2RlX21lbWNncysweDM5 Ny8weDY3MApbICAgNDAuNDk0NjcxXSAgc2hyaW5rX25vZGUrMHgyNWYvMHhjZTAKWyAgIDQwLjQ5 Njg3N10gIHNocmlua196b25lcysweDUzMS8weDllMApbICAgNDAuNDk5MTYwXSAgZG9fdHJ5X3Rv X2ZyZWVfcGFnZXMrMHgxZjQvMHhiMTAKWyAgIDQwLjUwMTgzOF0gIHRyeV90b19mcmVlX21lbV9j Z3JvdXBfcGFnZXMrMHgzN2QvMHg3YzAKWyAgIDQwLjUwNDg5M10gIG1lbW9yeV9yZWNsYWltKzB4 MzAxLzB4MzcwClsgICA0MC41MDcyNDldICA/IF9jb3B5X2Zyb21faXRlcisweDE2Mi8weDExZTAK WyAgIDQwLjUwOTg1MV0gID8gY2hlY2tfaGVhcF9vYmplY3QrMHgxNjAvMHg0MTAKWyAgIDQwLjUx MjQ2M10gIGNncm91cF9maWxlX3dyaXRlKzB4MWUzLzB4M2QwClsgICA0MC41MTQ5NjBdICA/IGNn cm91cF9zZXFmaWxlX3N0b3ArMHhiMC8weGIwClsgICA0MC41MTc2MDFdICBrZXJuZnNfZm9wX3dy aXRlX2l0ZXIrMHgyOGUvMHgzOTAKWyAgIDQwLjUyMDM0OV0gIHZmc193cml0ZSsweDdkMi8weGIx MApbICAgNDAuNTIyNDc4XSAga3N5c193cml0ZSsweGRlLzB4MWEwClsgICA0MC41MjQ1NzRdICBf X3g2NF9zeXNfd3JpdGUrMHg3Zi8weDkwClsgICA0MC41MjY4OTFdICBkb19zeXNjYWxsXzY0KzB4 NmMvMHgxNTAKWyAgIDQwLjUyOTE0MF0gIGVudHJ5X1NZU0NBTExfNjRfYWZ0ZXJfaHdmcmFtZSsw eDYzLzB4NmIKWyAgIDQwLjUzMjE4OV0gUklQOiAwMDMzOjB4N2Y3MThhOTgyYjAwClsgICA0MC41 MzQ0MTFdIENvZGU6IDQwIDAwIDQ4IDhiIDE1IDE5IGIzIDBkIDAwIGY3IGQ4IDY0IDg5IDAyIDQ4 IGM3IGMwIGZmIGZmIGZmIGZmIGViIGI3IDBmIDFmIDAwIDgwIDNkIGUxIDNhIDBlIDAwIDAwIDc0 IDE3IGI4IDAxIDAwIDAwIDAwIDA5ClsgICA0MC41NDUzMzhdIFJTUDogMDAyYjowMDAwN2ZmZmY1 ZmI1YzY4IEVGTEFHUzogMDAwMDAyMDIgT1JJR19SQVg6IDAwMDAwMDAwMDAwMDAwMDEKWyAgIDQw LjU0OTg0Nl0gUkFYOiBmZmZmZmZmZmZmZmZmZmRhIFJCWDogMDAwMDAwMDAwMDAwMDAwYSBSQ1g6 IDAwMDA3ZjcxOGE5ODJiMDAKWyAgIDQwLjU1NDEwNl0gUkRYOiAwMDAwMDAwMDAwMDAwMDBhIFJT STogMDAwMDU1NjRmYjFkNTg4MCBSREk6IDAwMDAwMDAwMDAwMDAwMDEKWyAgIDQwLjU1ODM0Ml0g UkJQOiAwMDAwNTU2NGZiMWQ1ODgwIFIwODogMDAwMDAwMDAwMDAwMDA3MyBSMDk6IDAwMDAwMDAw MDAwMDAwMDEKWyAgIDQwLjU2MjU4Nl0gUjEwOiAwMDAwMDAwMDAwMDAwMDAwIFIxMTogMDAwMDAw MDAwMDAwMDIwMiBSMTI6IDAwMDAwMDAwMDAwMDAwMGEKWyAgIDQwLjU2Njg1OV0gUjEzOiAwMDAw N2Y3MThhYTVmNzgwIFIxNDogMDAwMDAwMDAwMDAwMDAwYSBSMTU6IDAwMDA3ZjcxOGFhNWFkMDAK WyAgIDQwLjU3MTEwM10gIDwvVEFTSz4KWyAgIDQwLjU3MjQ4OV0KWyAgIDQwLjU3MzUxMl0gQWxs b2NhdGVkIGJ5IHRhc2sgMzg4OgpbICAgNDAuNTc1NjUwXSAga2FzYW5fc2F2ZV90cmFjaysweDMw LzB4NjAKWyAgIDQwLjU3Nzk4Nl0gIGthc2FuX3NhdmVfYWxsb2NfaW5mbysweDY5LzB4NzAKWyAg IDQwLjU4MDU3Ml0gIF9fa2FzYW5fa21hbGxvYysweGEyLzB4YjAKWyAgIDQwLjU4Mjg3OV0gIF9f a21hbGxvY19ub2RlKzB4MWVlLzB4NDIwClsgICA0MC41ODUyMzVdICBrdm1hbGxvY19ub2RlKzB4 NTQvMHgxYTAKWyAgIDQwLjU4NzQ1MV0gIHpzd2FwX3N3YXBvbisweDRhLzB4MjYwClsgICA0MC41 ODk2NTBdICBfX2RvX3N5c19zd2Fwb24rMHgxMmFkLzB4MWZjMApbICAgNDAuNTkyMTA5XSAgX194 NjRfc3lzX3N3YXBvbisweDVlLzB4NzAKWyAgIDQwLjU5NDQzNF0gIGRvX3N5c2NhbGxfNjQrMHg2 Yy8weDE1MApbICAgNDAuNTk2NjUyXSAgZW50cnlfU1lTQ0FMTF82NF9hZnRlcl9od2ZyYW1lKzB4 NjMvMHg2YgpbICAgNDAuNTk5Njg1XQpbICAgNDAuNjAwNjg4XSBGcmVlZCBieSB0YXNrIDQwMDoK WyAgIDQwLjYwMjYxMF0gIGthc2FuX3NhdmVfdHJhY2srMHgzMC8weDYwClsgICA0MC42MDQ5NDNd ICBrYXNhbl9zYXZlX2ZyZWVfaW5mbysweDUyLzB4NjAKWyAgIDQwLjYwNzQ3Nl0gIHBvaXNvbl9z bGFiX29iamVjdCsweDExYS8weDE5MApbICAgNDAuNjEwMDA2XSAgX19rYXNhbl9zbGFiX2ZyZWUr MHgzOS8weDcwClsgICA0MC42MTIzNzVdICBrZnJlZSsweGYzLzB4MjgwClsgICA0MC42MTQyOTRd ICBrdmZyZWUrMHgyOS8weDMwClsgICA0MC42MTYxMzZdICB6c3dhcF9zd2Fwb2ZmKzB4MTAzLzB4 MWEwClsgICA0MC42MTg0NTRdICBfX3NlX3N5c19zd2Fwb2ZmKzB4MTlkOC8weDIxZDAKWyAgIDQw LjYyMDk5MF0gIF9feDY0X3N5c19zd2Fwb2ZmKzB4M2MvMHg0MApbICAgNDAuNjIzMzYxXSAgZG9f c3lzY2FsbF82NCsweDZjLzB4MTUwClsgICA0MC42MjU2MDVdICBlbnRyeV9TWVNDQUxMXzY0X2Fm dGVyX2h3ZnJhbWUrMHg2My8weDZiClsgICA0MC42Mjg2MjBdClsgICA0MC42Mjk2NDRdIFRoZSBi dWdneSBhZGRyZXNzIGJlbG9uZ3MgdG8gdGhlIG9iamVjdCBhdCBmZmZmODg4MTAyNTJkYzgwClsg ICA0MC42Mjk2NDRdICB3aGljaCBiZWxvbmdzIHRvIHRoZSBjYWNoZSBrbWFsbG9jLTY0IG9mIHNp emUgNjQKWyAgIDQwLjYzNjgxM10gVGhlIGJ1Z2d5IGFkZHJlc3MgaXMgbG9jYXRlZCAyNCBieXRl cyBpbnNpZGUgb2YKWyAgIDQwLjYzNjgxM10gIGZyZWVkIDY0LWJ5dGUgcmVnaW9uIFtmZmZmODg4 MTAyNTJkYzgwLCBmZmZmODg4MTAyNTJkY2MwKQpbICAgNDAuNjQzODU0XQpbICAgNDAuNjQ0ODcx XSBUaGUgYnVnZ3kgYWRkcmVzcyBiZWxvbmdzIHRvIHRoZSBwaHlzaWNhbCBwYWdlOgpbICAgNDAu NjQ4MTg3XSBwYWdlOjAwMDAwMDAwOTg1OTAzYjYgcmVmY291bnQ6MSBtYXBjb3VudDowIG1hcHBp bmc6MDAwMDAwMDAwMDAwMDAwMCBpbmRleDoweDAgcGZuOjB4MTAyNTJkClsgICA0MC42NTM3MTNd IGZsYWdzOiAweDQwMDAwMDAwMDAwMDgwMChzbGFifG5vZGU9MHx6b25lPTEpClsgICA0MC42NTY4 ODBdIHBhZ2VfdHlwZTogMHhmZmZmZmZmZigpClsgICA0MC42NTkwMzFdIHJhdzogMDQwMDAwMDAw MDAwMDgwMCBmZmZmODg4MTAwMDQyNjQwIGRlYWQwMDAwMDAwMDAxMDAgZGVhZDAwMDAwMDAwMDEy MgpbICAgNDAuNjYzNjM1XSByYXc6IDAwMDAwMDAwMDAwMDAwMDAgMDAwMDAwMDAwMDIwMDAyMCAw MDAwMDAwMWZmZmZmZmZmIDAwMDAwMDAwMDAwMDAwMDAKWyAgIDQwLjY2ODIzNV0gcGFnZSBkdW1w ZWQgYmVjYXVzZToga2FzYW46IGJhZCBhY2Nlc3MgZGV0ZWN0ZWQKWyAgIDQwLjY3MTU2NF0KWyAg IDQwLjY3MjU2OV0gTWVtb3J5IHN0YXRlIGFyb3VuZCB0aGUgYnVnZ3kgYWRkcmVzczoKWyAgIDQw LjY3NTQ2M10gIGZmZmY4ODgxMDI1MmRiODA6IDAwIDAwIDAwIDAwIDAwIDAwIDAwIGZjIGZjIGZj IGZjIGZjIGZjIGZjIGZjIGZjClsgICA0MC42Nzk3NjZdICBmZmZmODg4MTAyNTJkYzAwOiAwMCAw MCAwMCAwMCAwMCAwMCAwMCBmYyBmYyBmYyBmYyBmYyBmYyBmYyBmYyBmYwpbICAgNDAuNjg0MTIw XSA+ZmZmZjg4ODEwMjUyZGM4MDogZmEgZmIgZmIgZmIgZmIgZmIgZmIgZmIgZmMgZmMgZmMgZmMg ZmMgZmMgZmMgZmMKWyAgIDQwLjY4ODQyM10gICAgICAgICAgICAgICAgICAgICAgICAgICAgIF4K WyAgIDQwLjY5MDg2MF0gIGZmZmY4ODgxMDI1MmRkMDA6IDAwIDAwIDAwIDAwIDAwIDAwIDAwIGZj IGZjIGZjIGZjIGZjIGZjIGZjIGZjIGZjClsgICA0MC42OTUxMzZdICBmZmZmODg4MTAyNTJkZDgw OiAwMCAwMCAwMCAwMCAwMCAwMCBmYyBmYyBmYyBmYyBmYyBmYyBmYyBmYyBmYyBmYwpbICAgNDAu Njk5NDU1XSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT0KWyAgIDQwLjcwNDI1OF0gRGlzYWJsaW5nIGxvY2sgZGVidWdnaW5n IGR1ZSB0byBrZXJuZWwgdGFpbnQK --000000000000cc0d87060fab951c--