From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 58BC71DEFE2 for ; Tue, 8 Oct 2024 06:27:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.41 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728368876; cv=none; b=dhduZLHZYgsVdc+r9ViSEBIunrTB69NdyDwc9E88AlfCB5TMeikFzEKI4U36ah1BkkVdW6XS4iI33ynQDsReAEStXizmz6NfGTmnz/cEH0Z59NpYx3oTckKswfAjYrah8JIfPrXK0O0L+wgJWkjUTX7s+ey03fZh+SqlRSqc8sk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728368876; c=relaxed/simple; bh=sRrs971ywU2XBHAio/v+KH3KPEi6b2tpjaOK3Y8GDYY=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=jTB2bMsHOw9xdJ/7w8XsteP3mgYDQGaE9e1OFyFbvLbBYBOgdHDILOQ4p4PA9s7pO1CJfA3LSSAfqGWdxr3+50KPNcurOvq/mBeELL76rOJ8D5xhTOnJA7kMirzdKhVvJl+2ecZBrv2MR1c99GuDp6dzz6ftS+1RHR/1epqCgj8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com; spf=pass smtp.mailfrom=rivosinc.com; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b=XTIHt7n8; arc=none smtp.client-ip=209.85.216.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b="XTIHt7n8" Received: by mail-pj1-f41.google.com with SMTP id 98e67ed59e1d1-2e082bf1c7fso3593491a91.3 for ; Mon, 07 Oct 2024 23:27:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1728368873; x=1728973673; darn=vger.kernel.org; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:from:to :cc:subject:date:message-id:reply-to; bh=yD1uY1GFMUYlwE1Gpa3bWH24Ki4C8p8PksybGuIxKXE=; b=XTIHt7n8eFdZ98U/iFWue/AxK+I9gGtVd1ksnkBACkNE4Ir/TPvhqYx+tkzy8Sl5J5 Swmen6YabiMoYR83mUXPFuus/OrvInPq/eOgEJjayw11BERkTFwsaDqhqR8TEnNdadX2 HSjfp0VtceYiCRaLbHfQ1dlUm01Y+B+4/hIvll01ntHwoKENIJ5+LxiF9Ek2G2TaLjJI kyQOrkZSTZ1/WGp6V+i5slBo/mqB39+TwKTPE9YGXfyY2ffObMucn5Q6jg3XMnjAHtjA Q+34YskpP/mU99fti72DpH+Ol4kOXEWdvmkEy1ffzlCW4BcziiNvJrrIUm2NZgiGUvsJ hdVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728368873; x=1728973673; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=yD1uY1GFMUYlwE1Gpa3bWH24Ki4C8p8PksybGuIxKXE=; b=gRkHfuTIV4EosnNs/LRR6Yqmv06mIfeXE2tNyl61afkLzIx+IcIx8ytmx9iP7URd9J JSYAOaLrzjMdZWgw05Wyks8m29OfKk2fp/nKUiTPlIdT4sVvDV0Gg6RBMxjvODd7ONln sU6NOjA8jGjc76ldYOSoINAEEcEmpcI4ytiWAruwVQ2y9PKxyLwjYvZsfdJ63eeaRZXW 9WP/aNOk7n0Z1W3skZO2c1ZXJJvu+i756lFdb0xGzFBl9Dn9uffGfvL29O4xCZZI8t20 9MNsNcf6AQ/TNwWKwNg7z9IpRQi5YQbFjvCch7wDtOPF3SBO3rJI+hGbvCv5qssyhUaX oXpw== X-Forwarded-Encrypted: i=1; AJvYcCWyOrtD/Y6QHDUPOXiuVoMY2zC+f0g1Q1ySYVgLeWli/DWbN1BlVLMeLKbtx1nd+O/RZcEvzno48cIV@vger.kernel.org X-Gm-Message-State: AOJu0YwDgGINfAgi3ACx4JRotUoRrfdX19gWC7TpMtMqutjldf8/V2x6 QBahoOjyqCtOOMXJGuEkSBdHtKDwzGE9uPnlFR/0kP2vYO8xCYwjRLYy/BbYTCk= X-Google-Smtp-Source: AGHT+IF/ZQHlU6tp9Sg21rBMwoL6ZDWlzQEcykMAFPhKfSpu/YJnzOfJudFoJo575FCLm+0FY5JUkg== X-Received: by 2002:a17:90b:1b05:b0:2d3:cd5c:15bb with SMTP id 98e67ed59e1d1-2e1e63698a6mr17009604a91.25.1728368873537; Mon, 07 Oct 2024 23:27:53 -0700 (PDT) Received: from debug.ba.rivosinc.com ([64.71.180.162]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2e28b773a77sm464805a91.11.2024.10.07.23.27.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Oct 2024 23:27:53 -0700 (PDT) Date: Mon, 7 Oct 2024 23:27:49 -0700 From: Deepak Gupta To: Zong Li Cc: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Andrew Morton , "Liam R. Howlett" , Vlastimil Babka , Lorenzo Stoakes , Paul Walmsley , Palmer Dabbelt , Albert Ou , Conor Dooley , Rob Herring , Krzysztof Kozlowski , Arnd Bergmann , Christian Brauner , Peter Zijlstra , Oleg Nesterov , Eric Biederman , Kees Cook , Jonathan Corbet , Shuah Khan , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, alistair.francis@wdc.com, richard.henderson@linaro.org, jim.shu@sifive.com, andybnac@gmail.com, kito.cheng@sifive.com, charlie@rivosinc.com, atishp@rivosinc.com, evan@rivosinc.com, cleger@rivosinc.com, alexghiti@rivosinc.com, samitolvanen@google.com, broonie@kernel.org, rick.p.edgecombe@intel.com Subject: Re: [PATCH 16/33] riscv/shstk: If needed allocate a new shadow stack on clone Message-ID: References: <20241001-v5_user_cfi_series-v1-0-3ba65b6e550f@rivosinc.com> <20241001-v5_user_cfi_series-v1-16-3ba65b6e550f@rivosinc.com> Precedence: bulk X-Mailing-List: linux-arch@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: On Tue, Oct 08, 2024 at 02:18:58PM +0800, Zong Li wrote: >On Tue, Oct 8, 2024 at 1:31 PM Deepak Gupta wrote: >> >> On Tue, Oct 08, 2024 at 01:16:17PM +0800, Zong Li wrote: >> >On Tue, Oct 8, 2024 at 7:30 AM Deepak Gupta wrote: >> >> >> >> On Mon, Oct 07, 2024 at 04:17:47PM +0800, Zong Li wrote: >> >> >On Wed, Oct 2, 2024 at 12:20 AM Deepak Gupta wrote: >> >> >> >> >> >> Userspace specifies CLONE_VM to share address space and spawn new thread. >> >> >> `clone` allow userspace to specify a new stack for new thread. However >> >> >> there is no way to specify new shadow stack base address without changing >> >> >> API. This patch allocates a new shadow stack whenever CLONE_VM is given. >> >> >> >> >> >> In case of CLONE_VFORK, parent is suspended until child finishes and thus >> >> >> can child use parent shadow stack. In case of !CLONE_VM, COW kicks in >> >> >> because entire address space is copied from parent to child. >> >> >> >> >> >> `clone3` is extensible and can provide mechanisms using which shadow stack >> >> >> as an input parameter can be provided. This is not settled yet and being >> >> >> extensively discussed on mailing list. Once that's settled, this commit >> >> >> will adapt to that. >> >> >> >> >> >> Signed-off-by: Deepak Gupta >> >> >> --- >> >> >> arch/riscv/include/asm/usercfi.h | 25 ++++++++ >> >> >> >> ... snipped... >> >> >> >> >> + >> >> >> +/* >> >> >> + * This gets called during clone/clone3/fork. And is needed to allocate a shadow stack for >> >> >> + * cases where CLONE_VM is specified and thus a different stack is specified by user. We >> >> >> + * thus need a separate shadow stack too. How does separate shadow stack is specified by >> >> >> + * user is still being debated. Once that's settled, remove this part of the comment. >> >> >> + * This function simply returns 0 if shadow stack are not supported or if separate shadow >> >> >> + * stack allocation is not needed (like in case of !CLONE_VM) >> >> >> + */ >> >> >> +unsigned long shstk_alloc_thread_stack(struct task_struct *tsk, >> >> >> + const struct kernel_clone_args *args) >> >> >> +{ >> >> >> + unsigned long addr, size; >> >> >> + >> >> >> + /* If shadow stack is not supported, return 0 */ >> >> >> + if (!cpu_supports_shadow_stack()) >> >> >> + return 0; >> >> >> + >> >> >> + /* >> >> >> + * If shadow stack is not enabled on the new thread, skip any >> >> >> + * switch to a new shadow stack. >> >> >> + */ >> >> >> + if (is_shstk_enabled(tsk)) >> >> > >> >> >Hi Deepak, >> >> >Should it be '!' is_shstk_enabled(tsk)? >> >> >> >> Yes it is a bug. It seems like fork without CLONE_VM or with CLONE_VFORK, it was returning >> >> 0 anyways. And in the case of CLONE_VM (used by pthread), it was not doing the right thing. >> > >> >Hi Deepak, >> >I'd like to know if I understand correctly. Could I know whether there >> >might also be a risk when the user program doesn't enable the CFI and >> >the kernel doesn't activate CFI. Because this flow will still try to >> >allocate the shadow stack and execute the ssamowap command. Thanks >> >> `shstk_alloc_thread_stack` is only called from `copy_thread` and allocates and >> returns non-zero (positive value) for ssp only if `CLONE_VM` is specified. >> `CLONE_VM` means that address space is shared and userspace has allocated >> separate stack. This flow is ensuring that newly created thread with separate >> data stack gets a separate shadow stack as well. >> >> Retruning zero value from `shstk_alloc_thread_stack` means that, no need to >> allocate a shadow stack. If you look at `copy_thread` function, it simply sets >> the returned ssp in newly created task's task_struct (if it was non-zero). >> If returned ssp was zero, `copy_thread` doesn't do anything. Thus whatever is >> current task settings are that will be copied over to new forked/cloned task. >> If current task had shadow stack enabled, new task will also get it enabled at >> same address (to be COWed later). >> >> Any task get shadow stack enabled for first time using new prctls (see prctl >> patches). >> >> So only time `ssamoswap` will be exercised will be are >> - User issues enabling `prctl` (it'll be issued from loader) >> - fork/clone happens >> >> In both cases, it is guarded against checks of whether cpu supports it and task >> has shadow stack enabled. >> >> Let me know if you think I missed any flow. > >Thanks a lot for the detail, it is very helpful for me. But sorry for >the confusion, my question is actually on the situation with this bug >(i.e., before the fix) Yeah with the bug (i.e. before the fix), this function would still return 0 for `fork` or `clone` with `!CLONE_VM`. And if existing (current) thread had shadow stack enabled, that will become shadow stack for new thread (COWed later) The bug would surface only when `clone` is called with `CLONE_VM` and in that case instead of allocating a new shadow stack, it would be re-using same shadow stack for both `pthreads`. In anycase, thanks again for noticing and bringing it up. > >> >> > >> >> Most of the testing has been with busybox build (independent binaries0 driven via buildroot >> >> setup. Wondering why it wasn't caught. >> >> >> >> Anyways, will fix it. Thanks for catching it. >> >> >> >> > >> >> >> + return 0; >> >> >> + >> >> >> + /* 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4D66ECED270 for ; Tue, 8 Oct 2024 06:34:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References:Message-ID: Subject:Cc: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=LKiqPCqRChTZ2Gh3U/ROXDvAEAWVGpBowGgHnWQ21jM=; b=p+eoatocegM90mJ5jiJbQdALEn DsWA6DrkDn9E/X5WVIssKpcNPLd0S6la6JBN+MtnKcAPZv4PH2ow9V2V51TVp0eqtIeUEPpVTr40m ge/47ukLSGGUFonpGa9GfRVmvhdU0/UsXvMK3Xo83ktB/mOsw1GQ9VaZIshvzxrt525epYNf2o5Dc p/Wc+Jz41/kNSs4LFSHbRqcWQWV7MDcoKufrk404sWCU3JH5nhimmayP3Wa0YySr7MP2fYF+V0Y1m YKVC1Z32mwTI0ymQP8d2bXMg7Rz+9sDEuswF9OwmLSFBFRAcmfhF46nc4wI9wpaynzUsUtcoOqC7m mpwvihJw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1sy3nI-00000004fWd-3JDm; Tue, 08 Oct 2024 06:34:04 +0000 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1sy3hK-00000004ejT-2eeH for linux-riscv@lists.infradead.org; Tue, 08 Oct 2024 06:27:56 +0000 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-2e28bd0bd13so106216a91.1 for ; Mon, 07 Oct 2024 23:27:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1728368873; x=1728973673; darn=lists.infradead.org; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:from:to :cc:subject:date:message-id:reply-to; bh=yD1uY1GFMUYlwE1Gpa3bWH24Ki4C8p8PksybGuIxKXE=; b=yEotS0kEtHgVtgmacnsXLbWzT8hwiMICvHJcyJ+ZwW6314rDBEpE/JauaZiyfVJnw8 +8dDXQlZ6mXtAkdN9VFKNPYRlt64DDjsRXzpDygS+XnV/rYFt7NpbF0y9hYmlNdHa4mR SbO//Byd/lre+3vcrxSF+YB5rwnNqHqTNE844kr1jj0bPgPrRtFxkh4wKdkfD/k8OolN IG3jvl2otIJ/wdDdrW3QQo9lPyPxTHxYphJG9EZULVI/A3AGrXs10AzpfmdrNZL205HH oylANcKmth1V0DAjWw8ykijxzavL2l6lnf/MwvOx9LRvHwILyFIL443nXOErJeTxwGRl DcoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728368873; x=1728973673; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=yD1uY1GFMUYlwE1Gpa3bWH24Ki4C8p8PksybGuIxKXE=; b=LIx2XmTBMK0ak3iKsTFm91kFaQUVXbnOu1m1AerQf0RJAePCKzosd7ot0fm+MwO7zY a8PFsYyvp5JIG/Wa+DNWQOxQS9L4DSkq4NIm1Lzo1BvDirj3/q/ZvLkWT9uEnOQ9alCw Jl6ZlkJPhK+Qbqnt3iyOXFD5NgRFpzXPIvpigy2GFDRLt8B3MfQv38UEn22BJmp8o8oh jf3ANQZbnkBcQSA+yNDeXeQEKFsfBsn0E0akre7VYzWYAA61RPQZOAStPKzhc4pTXMY/ atjs9UmHyofPzG5MlJZcDbNxa2KZGL5TXOCokgPshajpp9X1fynQ5IJShGO/OhdsTzrs aKkg== X-Forwarded-Encrypted: i=1; AJvYcCXJ9kZBB7gJLTZtDvNuUq7pjCjD7gOM1BGuBJZJnz/BhDuNC79F8woQVpDM81ABrqIsm/wpnbwVW4HlhA==@lists.infradead.org X-Gm-Message-State: AOJu0YzfgvI+Rt+XGcZvURIZwrw/g7+G+YYFWW0vbbleW4b8SOnK/Chn AmGUJhnGa1M7TfaHfoVSJaN/OCMoLm0CeMX67VapidX7PzmCcD71PSIIkvcR8AU= X-Google-Smtp-Source: AGHT+IF/ZQHlU6tp9Sg21rBMwoL6ZDWlzQEcykMAFPhKfSpu/YJnzOfJudFoJo575FCLm+0FY5JUkg== X-Received: by 2002:a17:90b:1b05:b0:2d3:cd5c:15bb with SMTP id 98e67ed59e1d1-2e1e63698a6mr17009604a91.25.1728368873537; Mon, 07 Oct 2024 23:27:53 -0700 (PDT) Received: from debug.ba.rivosinc.com ([64.71.180.162]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2e28b773a77sm464805a91.11.2024.10.07.23.27.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Oct 2024 23:27:53 -0700 (PDT) Date: Mon, 7 Oct 2024 23:27:49 -0700 From: Deepak Gupta To: Zong Li Cc: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" , Andrew Morton , "Liam R. Howlett" , Vlastimil Babka , Lorenzo Stoakes , Paul Walmsley , Palmer Dabbelt , Albert Ou , Conor Dooley , Rob Herring , Krzysztof Kozlowski , Arnd Bergmann , Christian Brauner , Peter Zijlstra , Oleg Nesterov , Eric Biederman , Kees Cook , Jonathan Corbet , Shuah Khan , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, alistair.francis@wdc.com, richard.henderson@linaro.org, jim.shu@sifive.com, andybnac@gmail.com, kito.cheng@sifive.com, charlie@rivosinc.com, atishp@rivosinc.com, evan@rivosinc.com, cleger@rivosinc.com, alexghiti@rivosinc.com, samitolvanen@google.com, broonie@kernel.org, rick.p.edgecombe@intel.com Subject: Re: [PATCH 16/33] riscv/shstk: If needed allocate a new shadow stack on clone Message-ID: References: <20241001-v5_user_cfi_series-v1-0-3ba65b6e550f@rivosinc.com> <20241001-v5_user_cfi_series-v1-16-3ba65b6e550f@rivosinc.com> 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-20241007_232754_713458_2883222E X-CRM114-Status: GOOD ( 35.79 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org T24gVHVlLCBPY3QgMDgsIDIwMjQgYXQgMDI6MTg6NThQTSArMDgwMCwgWm9uZyBMaSB3cm90ZToK Pk9uIFR1ZSwgT2N0IDgsIDIwMjQgYXQgMTozMeKAr1BNIERlZXBhayBHdXB0YSA8ZGVidWdAcml2 b3NpbmMuY29tPiB3cm90ZToKPj4KPj4gT24gVHVlLCBPY3QgMDgsIDIwMjQgYXQgMDE6MTY6MTdQ TSArMDgwMCwgWm9uZyBMaSB3cm90ZToKPj4gPk9uIFR1ZSwgT2N0IDgsIDIwMjQgYXQgNzozMOKA r0FNIERlZXBhayBHdXB0YSA8ZGVidWdAcml2b3NpbmMuY29tPiB3cm90ZToKPj4gPj4KPj4gPj4g T24gTW9uLCBPY3QgMDcsIDIwMjQgYXQgMDQ6MTc6NDdQTSArMDgwMCwgWm9uZyBMaSB3cm90ZToK Pj4gPj4gPk9uIFdlZCwgT2N0IDIsIDIwMjQgYXQgMTI6MjDigK9BTSBEZWVwYWsgR3VwdGEgPGRl YnVnQHJpdm9zaW5jLmNvbT4gd3JvdGU6Cj4+ID4+ID4+Cj4+ID4+ID4+IFVzZXJzcGFjZSBzcGVj aWZpZXMgQ0xPTkVfVk0gdG8gc2hhcmUgYWRkcmVzcyBzcGFjZSBhbmQgc3Bhd24gbmV3IHRocmVh ZC4KPj4gPj4gPj4gYGNsb25lYCBhbGxvdyB1c2Vyc3BhY2UgdG8gc3BlY2lmeSBhIG5ldyBzdGFj ayBmb3IgbmV3IHRocmVhZC4gSG93ZXZlcgo+PiA+PiA+PiB0aGVyZSBpcyBubyB3YXkgdG8gc3Bl Y2lmeSBuZXcgc2hhZG93IHN0YWNrIGJhc2UgYWRkcmVzcyB3aXRob3V0IGNoYW5naW5nCj4+ID4+ ID4+IEFQSS4gVGhpcyBwYXRjaCBhbGxvY2F0ZXMgYSBuZXcgc2hhZG93IHN0YWNrIHdoZW5ldmVy IENMT05FX1ZNIGlzIGdpdmVuLgo+PiA+PiA+Pgo+PiA+PiA+PiBJbiBjYXNlIG9mIENMT05FX1ZG T1JLLCBwYXJlbnQgaXMgc3VzcGVuZGVkIHVudGlsIGNoaWxkIGZpbmlzaGVzIGFuZCB0aHVzCj4+ ID4+ID4+IGNhbiBjaGlsZCB1c2UgcGFyZW50IHNoYWRvdyBzdGFjay4gSW4gY2FzZSBvZiAhQ0xP TkVfVk0sIENPVyBraWNrcyBpbgo+PiA+PiA+PiBiZWNhdXNlIGVudGlyZSBhZGRyZXNzIHNwYWNl IGlzIGNvcGllZCBmcm9tIHBhcmVudCB0byBjaGlsZC4KPj4gPj4gPj4KPj4gPj4gPj4gYGNsb25l M2AgaXMgZXh0ZW5zaWJsZSBhbmQgY2FuIHByb3ZpZGUgbWVjaGFuaXNtcyB1c2luZyB3aGljaCBz aGFkb3cgc3RhY2sKPj4gPj4gPj4gYXMgYW4gaW5wdXQgcGFyYW1ldGVyIGNhbiBiZSBwcm92aWRl ZC4gVGhpcyBpcyBub3Qgc2V0dGxlZCB5ZXQgYW5kIGJlaW5nCj4+ID4+ID4+IGV4dGVuc2l2ZWx5 IGRpc2N1c3NlZCBvbiBtYWlsaW5nIGxpc3QuIE9uY2UgdGhhdCdzIHNldHRsZWQsIHRoaXMgY29t bWl0Cj4+ID4+ID4+IHdpbGwgYWRhcHQgdG8gdGhhdC4KPj4gPj4gPj4KPj4gPj4gPj4gU2lnbmVk LW9mZi1ieTogRGVlcGFrIEd1cHRhIDxkZWJ1Z0ByaXZvc2luYy5jb20+Cj4+ID4+ID4+IC0tLQo+ PiA+PiA+PiAgYXJjaC9yaXNjdi9pbmNsdWRlL2FzbS91c2VyY2ZpLmggfCAgMjUgKysrKysrKysK Pj4gPj4KPj4gPj4gLi4uIHNuaXBwZWQuLi4KPj4gPj4KPj4gPj4gPj4gKwo+PiA+PiA+PiArLyoK Pj4gPj4gPj4gKyAqIFRoaXMgZ2V0cyBjYWxsZWQgZHVyaW5nIGNsb25lL2Nsb25lMy9mb3JrLiBB bmQgaXMgbmVlZGVkIHRvIGFsbG9jYXRlIGEgc2hhZG93IHN0YWNrIGZvcgo+PiA+PiA+PiArICog Y2FzZXMgd2hlcmUgQ0xPTkVfVk0gaXMgc3BlY2lmaWVkIGFuZCB0aHVzIGEgZGlmZmVyZW50IHN0 YWNrIGlzIHNwZWNpZmllZCBieSB1c2VyLiBXZQo+PiA+PiA+PiArICogdGh1cyBuZWVkIGEgc2Vw YXJhdGUgc2hhZG93IHN0YWNrIHRvby4gSG93IGRvZXMgc2VwYXJhdGUgc2hhZG93IHN0YWNrIGlz IHNwZWNpZmllZCBieQo+PiA+PiA+PiArICogdXNlciBpcyBzdGlsbCBiZWluZyBkZWJhdGVkLiBP bmNlIHRoYXQncyBzZXR0bGVkLCByZW1vdmUgdGhpcyBwYXJ0IG9mIHRoZSBjb21tZW50Lgo+PiA+ PiA+PiArICogVGhpcyBmdW5jdGlvbiBzaW1wbHkgcmV0dXJucyAwIGlmIHNoYWRvdyBzdGFjayBh cmUgbm90IHN1cHBvcnRlZCBvciBpZiBzZXBhcmF0ZSBzaGFkb3cKPj4gPj4gPj4gKyAqIHN0YWNr IGFsbG9jYXRpb24gaXMgbm90IG5lZWRlZCAobGlrZSBpbiBjYXNlIG9mICFDTE9ORV9WTSkKPj4g Pj4gPj4gKyAqLwo+PiA+PiA+PiArdW5zaWduZWQgbG9uZyBzaHN0a19hbGxvY190aHJlYWRfc3Rh Y2soc3RydWN0IHRhc2tfc3RydWN0ICp0c2ssCj4+ID4+ID4+ICsgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJ1Y3Qga2VybmVsX2Nsb25lX2FyZ3MgKmFy Z3MpCj4+ID4+ID4+ICt7Cj4+ID4+ID4+ICsgICAgICAgdW5zaWduZWQgbG9uZyBhZGRyLCBzaXpl Owo+PiA+PiA+PiArCj4+ID4+ID4+ICsgICAgICAgLyogSWYgc2hhZG93IHN0YWNrIGlzIG5vdCBz dXBwb3J0ZWQsIHJldHVybiAwICovCj4+ID4+ID4+ICsgICAgICAgaWYgKCFjcHVfc3VwcG9ydHNf c2hhZG93X3N0YWNrKCkpCj4+ID4+ID4+ICsgICAgICAgICAgICAgICByZXR1cm4gMDsKPj4gPj4g Pj4gKwo+PiA+PiA+PiArICAgICAgIC8qCj4+ID4+ID4+ICsgICAgICAgICogSWYgc2hhZG93IHN0 YWNrIGlzIG5vdCBlbmFibGVkIG9uIHRoZSBuZXcgdGhyZWFkLCBza2lwIGFueQo+PiA+PiA+PiAr ICAgICAgICAqIHN3aXRjaCB0byBhIG5ldyBzaGFkb3cgc3RhY2suCj4+ID4+ID4+ICsgICAgICAg ICovCj4+ID4+ID4+ICsgICAgICAgaWYgKGlzX3Noc3RrX2VuYWJsZWQodHNrKSkKPj4gPj4gPgo+ PiA+PiA+SGkgRGVlcGFrLAo+PiA+PiA+U2hvdWxkIGl0IGJlICchJyBpc19zaHN0a19lbmFibGVk KHRzayk/Cj4+ID4+Cj4+ID4+IFllcyBpdCBpcyBhIGJ1Zy4gSXQgc2VlbXMgbGlrZSBmb3JrIHdp dGhvdXQgQ0xPTkVfVk0gb3Igd2l0aCBDTE9ORV9WRk9SSywgaXQgd2FzIHJldHVybmluZwo+PiA+ PiAwIGFueXdheXMuIEFuZCBpbiB0aGUgY2FzZSBvZiBDTE9ORV9WTSAodXNlZCBieSBwdGhyZWFk KSwgaXQgd2FzIG5vdCBkb2luZyB0aGUgcmlnaHQgdGhpbmcuCj4+ID4KPj4gPkhpIERlZXBhaywK Pj4gPkknZCBsaWtlIHRvIGtub3cgaWYgSSB1bmRlcnN0YW5kIGNvcnJlY3RseS4gQ291bGQgSSBr bm93IHdoZXRoZXIgdGhlcmUKPj4gPm1pZ2h0IGFsc28gYmUgYSByaXNrIHdoZW4gdGhlIHVzZXIg cHJvZ3JhbSBkb2Vzbid0IGVuYWJsZSB0aGUgQ0ZJIGFuZAo+PiA+dGhlIGtlcm5lbCBkb2Vzbid0 IGFjdGl2YXRlIENGSS4gQmVjYXVzZSB0aGlzIGZsb3cgd2lsbCBzdGlsbCB0cnkgdG8KPj4gPmFs bG9jYXRlIHRoZSBzaGFkb3cgc3RhY2sgYW5kIGV4ZWN1dGUgdGhlIHNzYW1vd2FwIGNvbW1hbmQu IFRoYW5rcwo+Pgo+PiBgc2hzdGtfYWxsb2NfdGhyZWFkX3N0YWNrYCBpcyBvbmx5IGNhbGxlZCBm cm9tIGBjb3B5X3RocmVhZGAgYW5kICBhbGxvY2F0ZXMgYW5kCj4+IHJldHVybnMgbm9uLXplcm8g KHBvc2l0aXZlIHZhbHVlKSBmb3Igc3NwIG9ubHkgaWYgYENMT05FX1ZNYCBpcyBzcGVjaWZpZWQu Cj4+IGBDTE9ORV9WTWAgbWVhbnMgdGhhdCBhZGRyZXNzIHNwYWNlIGlzIHNoYXJlZCBhbmQgdXNl cnNwYWNlIGhhcyBhbGxvY2F0ZWQKPj4gc2VwYXJhdGUgc3RhY2suIFRoaXMgZmxvdyBpcyBlbnN1 cmluZyB0aGF0IG5ld2x5IGNyZWF0ZWQgdGhyZWFkIHdpdGggc2VwYXJhdGUKPj4gZGF0YSBzdGFj ayBnZXRzIGEgc2VwYXJhdGUgc2hhZG93IHN0YWNrIGFzIHdlbGwuCj4+Cj4+IFJldHJ1bmluZyB6 ZXJvIHZhbHVlIGZyb20gYHNoc3RrX2FsbG9jX3RocmVhZF9zdGFja2AgbWVhbnMgdGhhdCwgbm8g bmVlZCB0bwo+PiBhbGxvY2F0ZSBhIHNoYWRvdyBzdGFjay4gSWYgeW91IGxvb2sgYXQgYGNvcHlf dGhyZWFkYCBmdW5jdGlvbiwgaXQgc2ltcGx5IHNldHMKPj4gdGhlIHJldHVybmVkIHNzcCBpbiBu ZXdseSBjcmVhdGVkIHRhc2sncyB0YXNrX3N0cnVjdCAoaWYgaXQgd2FzIG5vbi16ZXJvKS4KPj4g SWYgcmV0dXJuZWQgc3NwIHdhcyB6ZXJvLCBgY29weV90aHJlYWRgIGRvZXNuJ3QgZG8gYW55dGhp bmcuIFRodXMgd2hhdGV2ZXIgaXMKPj4gY3VycmVudCB0YXNrIHNldHRpbmdzIGFyZSB0aGF0IHdp bGwgYmUgY29waWVkIG92ZXIgdG8gbmV3IGZvcmtlZC9jbG9uZWQgdGFzay4KPj4gSWYgY3VycmVu dCB0YXNrIGhhZCBzaGFkb3cgc3RhY2sgZW5hYmxlZCwgbmV3IHRhc2sgd2lsbCBhbHNvIGdldCBp dCBlbmFibGVkIGF0Cj4+IHNhbWUgYWRkcmVzcyAodG8gYmUgQ09XZWQgbGF0ZXIpLgo+Pgo+PiBB bnkgdGFzayBnZXQgc2hhZG93IHN0YWNrIGVuYWJsZWQgZm9yIGZpcnN0IHRpbWUgdXNpbmcgbmV3 IHByY3RscyAoc2VlIHByY3RsCj4+IHBhdGNoZXMpLgo+Pgo+PiBTbyBvbmx5IHRpbWUgYHNzYW1v c3dhcGAgd2lsbCBiZSBleGVyY2lzZWQgd2lsbCBiZSBhcmUKPj4gLSBVc2VyIGlzc3VlcyBlbmFi bGluZyBgcHJjdGxgIChpdCdsbCBiZSBpc3N1ZWQgZnJvbSBsb2FkZXIpCj4+IC0gZm9yay9jbG9u ZSBoYXBwZW5zCj4+Cj4+IEluIGJvdGggY2FzZXMsIGl0IGlzIGd1YXJkZWQgYWdhaW5zdCBjaGVj a3Mgb2Ygd2hldGhlciBjcHUgc3VwcG9ydHMgaXQgYW5kIHRhc2sKPj4gaGFzIHNoYWRvdyBzdGFj ayBlbmFibGVkLgo+Pgo+PiBMZXQgbWUga25vdyBpZiB5b3UgdGhpbmsgSSBtaXNzZWQgYW55IGZs b3cuCj4KPlRoYW5rcyBhIGxvdCBmb3IgdGhlIGRldGFpbCwgaXQgaXMgdmVyeSBoZWxwZnVsIGZv ciBtZS4gQnV0IHNvcnJ5IGZvcgo+dGhlIGNvbmZ1c2lvbiwgbXkgcXVlc3Rpb24gaXMgYWN0dWFs bHkgb24gdGhlIHNpdHVhdGlvbiB3aXRoIHRoaXMgYnVnCj4oaS5lLiwgYmVmb3JlIHRoZSBmaXgp CgoKWWVhaCB3aXRoIHRoZSBidWcgKGkuZS4gYmVmb3JlIHRoZSBmaXgpLCB0aGlzIGZ1bmN0aW9u IHdvdWxkIHN0aWxsIHJldHVybiAwCmZvciBgZm9ya2Agb3IgYGNsb25lYCB3aXRoIGAhQ0xPTkVf Vk1gLiBBbmQgaWYgZXhpc3RpbmcgKGN1cnJlbnQpIHRocmVhZCBoYWQKc2hhZG93IHN0YWNrIGVu YWJsZWQsIHRoYXQgd2lsbCBiZWNvbWUgc2hhZG93IHN0YWNrIGZvciBuZXcgdGhyZWFkIChDT1dl ZCBsYXRlcikKClRoZSBidWcgd291bGQgc3VyZmFjZSBvbmx5IHdoZW4gYGNsb25lYCBpcyBjYWxs ZWQgd2l0aCBgQ0xPTkVfVk1gIGFuZCBpbiB0aGF0IGNhc2UKaW5zdGVhZCBvZiBhbGxvY2F0aW5n IGEgbmV3IHNoYWRvdyBzdGFjaywgaXQgd291bGQgYmUgcmUtdXNpbmcgc2FtZSBzaGFkb3cgc3Rh Y2sKZm9yIGJvdGggYHB0aHJlYWRzYC4KCkluIGFueWNhc2UsIHRoYW5rcyBhZ2FpbiBmb3Igbm90 aWNpbmcgYW5kIGJyaW5naW5nIGl0IHVwLgoKPgo+Pgo+PiA+Cj4+ID4+IE1vc3Qgb2YgdGhlIHRl c3RpbmcgaGFzIGJlZW4gd2l0aCBidXN5Ym94IGJ1aWxkIChpbmRlcGVuZGVudCBiaW5hcmllczAg ZHJpdmVuIHZpYSBidWlsZHJvb3QKPj4gPj4gc2V0dXAuIFdvbmRlcmluZyB3aHkgaXQgd2Fzbid0 IGNhdWdodC4KPj4gPj4KPj4gPj4gQW55d2F5cywgd2lsbCBmaXggaXQuIFRoYW5rcyBmb3IgY2F0 Y2hpbmcgaXQuCj4+ID4+Cj4+ID4+ID4KPj4gPj4gPj4gKyAgICAgICAgICAgICAgIHJldHVybiAw Owo+PiA+PiA+PiArCj4+ID4+ID4+ICsgICAgICAgLyoKCl9fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LXJpc2N2IG1haWxpbmcgbGlzdApsaW51eC1y aXNjdkBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxt YW4vbGlzdGluZm8vbGludXgtcmlzY3YK