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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A4A57C433EF for ; Thu, 25 Nov 2021 12:10:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347054AbhKYMNe (ORCPT ); Thu, 25 Nov 2021 07:13:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55842 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238867AbhKYMLd (ORCPT ); Thu, 25 Nov 2021 07:11:33 -0500 Received: from mail-lf1-x136.google.com (mail-lf1-x136.google.com [IPv6:2a00:1450:4864:20::136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 902E6C06173E for ; Thu, 25 Nov 2021 04:08:21 -0800 (PST) Received: by mail-lf1-x136.google.com with SMTP id u3so15804254lfl.2 for ; Thu, 25 Nov 2021 04:08:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kempniu.pl; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to; bh=JkdfzLF/ZT0meZ9K3RxhDerHR55SIfBpOC9iC8N3REw=; b=nYhMa9VvgqD/5tVDNKrf4lpGM7pqt5eSQ2pd6ceCRaViy3NCDW7y1CWyM2o6vJ7jUf zyfAk/XjuFrwoLax7Pmr27ORHWHQeBw6FthLStjqxAx7Zo5ywVjlrW/9m4+LjYAWCsjl NW1cSb6VGZJa6SrPF5alELHs+laa9gVrrlR7s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to; bh=JkdfzLF/ZT0meZ9K3RxhDerHR55SIfBpOC9iC8N3REw=; b=ciI7yLzwHPFoVRNoNAKZ0ecH96vY562wwLvdZ6YnEUvMNL6WVewFH/VjC5z1gabnWY 2y4bLBO/+gVpwIy3oeHVEvA89qgSo8ctyhPdURJGcbqhQrD5v4HcaHIfHz6KrJi9vk/z SRtyp8IGSmbkYArGhE8aRzu6+UCa4V43ODkO1enW+Vsf0n9g9w/YHlhEofZ0I4qn2LAU DTyzlSdgv/wWPjuE3N4S39ceP6ezxVWY8qL7XOCkEO2S+GQ+996Mp32DJsHeioC/l2p0 fuFR9Zq7VrVwhoM4/pc6Z5tk2A1x/ZbM83aN6XlzhDM56uJ/fECGSZtaxLdmq56tRqjN QGBA== X-Gm-Message-State: AOAM530Uq6rr9m0nhL2KKwesVqMnm+PYKtRdbZK2d5m+YS6Xj4mBhi40 UMd9OaHmqvrcpW08z6KoalnLlg== X-Google-Smtp-Source: ABdhPJzgBgorf4UQPr3rAtMPS9jzAmnikYL22lGssV3hmusbtzqqdthpC9nMfVtuEr70Vcu1VTUphg== X-Received: by 2002:a05:6512:1296:: with SMTP id u22mr23122317lfs.296.1637842099803; Thu, 25 Nov 2021 04:08:19 -0800 (PST) Received: from larwa.hq.kempniu.pl ([2001:470:64df:111::e02]) by smtp.gmail.com with ESMTPSA id t7sm287475lfl.260.2021.11.25.04.08.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Nov 2021 04:08:19 -0800 (PST) Date: Thu, 25 Nov 2021 13:08:16 +0100 From: =?utf-8?B?TWljaGHFgiBLxJlwaWXFhA==?= To: Miquel Raynal Cc: Richard Weinberger , Vignesh Raghavendra , Boris Brezillon , linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH] mtdchar: prevent unbounded allocation in MEMWRITE ioctl Message-ID: References: <20211025082104.8017-1-kernel@kempniu.pl> <20211122103122.424326a1@xps13> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20211122103122.424326a1@xps13> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Miquèl, TL;DR: thanks, your comment made me look closer and I found what seems to be a feasible workaround that I will apply in v2 (along other fixes). > > Despite my efforts, the patch does _not_ retain absolute backward > > compatibility and I do not know whether this is acceptable. > > Specifically, multi-eraseblock-sized writes (requiring multiple loop > > iterations to be processed) which succeeded with the original code _may_ > > now return errors and/or write different contents to the device than the > > original code, depending on the MTD mode of operation requested and on > > whether the start offset is page-aligned. The documentation for struct > > mtd_oob_ops warns about even multi-page write requests, but... > > > > Example: > > > > MTD device parameters: > > > > - mtd->writesize = 2048 > > - mtd->erasesize = 131072 > > - 64 bytes of raw OOB space per page > > > > struct mtd_write_req req = { > > .start = 2048, > > .len = 262144, > > .ooblen = 64, > > .usr_data = ..., > > .usr_oob = ..., > > .mode = MTD_OPS_RAW, > > }; > > > > (This is a 128-page write with OOB data supplied for just one page.) > > > > Current mtdchar_write_ioctl() returns 0 for this request and writes > > 128 pages of data and 1 page's worth of OOB data (64 bytes) to the > > MTD device. > > > > Patched mtdchar_write_ioctl() may return an error because the > > original request gets split into two chunks (): > > > > <131072, 64> > > <131072, 0> > > > > and the second chunk with zero OOB data length may make the MTD > > driver unhappy in raw mode (resulting in only the first 64 pages of > > data and 1 page's worth of OOB data getting written to the MTD > > device). > > Isn't this a driver issue instead? I mean, writing an eraseblock > without providing any OOB data is completely fine, if the driver > accepts 2 blocks + 1 page OOB but refuses 1 block + 1 page OOB and then > 1 block, it's broken, no? Have you experienced such a situation in your > testing? I may not have expressed myself clearly here, sorry - the example was already getting a bit lengthy at that point... :) I tested the patch with nandsim, but I do not think it is that specific driver that is broken. The catch is that when mtd_write_oob() is called, nand_do_write_ops() splits multi-page requests into single-page requests and what it passes to nand_write_page() depends on whether the struct mtd_oob_ops it was invoked with has the oobbuf field set to NULL or not. This is okay in itself, but when another request-splitting "layer" is introduced by my patch, the ioctl may start returning different result codes than it used to. Here is what happens with the unpatched code for the example above: 1. mtdchar_write_ioctl() gets called with the following request: struct mtd_write_req req = { .start = 2048, .len = 262144, .ooblen = 64, .usr_data = 0x10000000, .usr_oob = 0x20000000, .mode = MTD_OPS_RAW, }; 2. The above request is passed through to mtd_write_oob() verbatim: struct mtd_oob_ops ops = { .mode = MTD_OPS_RAW, .len = 262144, .ooblen = 64, .datbuf = 0x10000000, .oobbuf = 0x20000000, }; 3. nand_do_write_ops() splits this request up into page-sized requests. a) For the first page, the initial 2048 bytes of data + 64 bytes of OOB data are passed to nand_write_page(). b) For each subsequent page, a 2048-byte chunk of data + 64 bytes of 0xff bytes are passed to nand_write_page(). Since the oobbuf field in the struct mtd_oob_ops passed is not NULL, oob_required is set to 1 for all nand_write_page() calls. 4. The above causes the driver to receive 2112 bytes of data for each page write, which results in the ioctl being successful. Here is what happens with the patched code: 1. mtdchar_write_ioctl() gets called with the same request as above. 2. The original request gets split into two eraseblock-sized mtd_write_oob() calls: a) struct mtd_oob_ops ops = { .mode = MTD_OPS_RAW, .len = 131072, .ooblen = 64, .datbuf = 0x10000000, .oobbuf = 0x20000000, }; b) struct mtd_oob_ops ops = { .mode = MTD_OPS_RAW, .len = 131072, .ooblen = 0, .datbuf = 0x10020000, .oobbuf = NULL, }; (My code sets oobbuf to NULL if ooblen is 0.) 3. nand_do_write_ops() splits the first request up into page-sized requests the same way as for the original code. It returns successfully, so mtdchar_write_ioctl() proceeds with the next eraseblock-sized request. 4. nand_do_write_ops() splits the second request up into page-sized requests. The first page write contains 2048 bytes of data and no OOB data; since the oobbuf field in the struct mtd_oob_ops passed is NULL, oob_required is set to 0. 5. The above causes the driver to receive 2048 bytes of data for a page write in raw mode, which results in an error that propagates all the way up to mtdchar_write_ioctl(). The nandsim driver returns the same error if you pass the following request to the MEMWRITE ioctl: struct mtd_write_req req = { .start = 2048, .len = 2048, .ooblen = 0, .usr_data = 0x10000000, .usr_oob = NULL, .mode = MTD_OPS_RAW, }; so it is not the driver that is broken or insane, it is the splitting process that may cause the MEMWRITE ioctl to return different error codes than before. I played with the code a bit more and I found a fix which addresses this issue without breaking other scenarios: setting oobbuf to the same pointer for every loop iteration (if ooblen is 0, no OOB data will be written anyway). I also tackled the problem of mishandling large non-page-aligned writes in v1 and I managed to fix it by trimming the first mtd_write_oob() call so that it ends on an eraseblock boundary. This implicitly makes subsequent writes page-aligned and seems to fix the problem. Finally, I reworked the OOB length adjustment code to address other cases of mishandling non-page-aligned writes. I could not find any other cases in which the revised code behaves differently than the original one. I will send v2 soon. -- Best regards, Michał Kępień 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 DC77DC433F5 for ; Thu, 25 Nov 2021 12:09:26 +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-Transfer-Encoding:Content-Type: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=TUCuBDW9lfLTvYRBnlXT2cnzocppggUsbhurP89rduY=; b=igciuB8ITYxqL9 ZnikgY44xqfzhstF5adsahenk/COwcBynp7s9+cvL1LbpuWWwR3olM3XaoVbCfeUhpNsiIz8TLv4+ Um6tH/P/mZzSGUdC1w1N3RXAGuwPcFHRAymHc/GC+xL5QzTiQyINNPGYTxuyqs8GQicJ94gsN5zNr GSWkNrI70JYUUqbx/Qh6i6A60phIwP0AhwaNHJAI8hZju+AIDHqU5OM6doqh8iHqP+2qPiZqzkr8H mMRi2GMhoi4fA8kMm2wMKVcijYkQDSJlItuQXftdJHt0TuFvkpNJ3gYI6rLnSZ9SQ6cnle8vCDKKC UXaVd3bm3NXiSXbyY7jw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mqDYB-007L3B-3H; Thu, 25 Nov 2021 12:08:27 +0000 Received: from mail-lf1-x134.google.com ([2a00:1450:4864:20::134]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mqDY6-007L25-MQ for linux-mtd@lists.infradead.org; Thu, 25 Nov 2021 12:08:25 +0000 Received: by mail-lf1-x134.google.com with SMTP id r26so15779616lfn.8 for ; Thu, 25 Nov 2021 04:08:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kempniu.pl; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to; bh=JkdfzLF/ZT0meZ9K3RxhDerHR55SIfBpOC9iC8N3REw=; b=nYhMa9VvgqD/5tVDNKrf4lpGM7pqt5eSQ2pd6ceCRaViy3NCDW7y1CWyM2o6vJ7jUf zyfAk/XjuFrwoLax7Pmr27ORHWHQeBw6FthLStjqxAx7Zo5ywVjlrW/9m4+LjYAWCsjl NW1cSb6VGZJa6SrPF5alELHs+laa9gVrrlR7s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to; bh=JkdfzLF/ZT0meZ9K3RxhDerHR55SIfBpOC9iC8N3REw=; b=TZMgM+GrCQacuqZkn3Mm6M4FtYrfcsm5pZa+zIhjnrhO9cndbYi8aNFC24Xbdh5mGG j7mkD9avIs2uO4mKgHBt5CmBOoj/BcWhqjiPPxPfdxDCZw7ZXWVnsOcAMa8JdUI8EgHp ln8NZY+1VYDoWi6ZgSjde9YAj0u88RxzNAE2JBOQ98aoTZQW/pJcaZespYwyXh9PAlC7 Pk63nAzwpuiQ+7WIEcOcYG9hrFPIfnqmVzhqxA+/biVMQxQzZuQG+S0LQf5ZHmE0y/Sk izMzv9eCcOvk//yq6EGWA8S8wvRWn2O+CzEXCoN+RwgMuSiKbFjdQY0OAImSky+3i9u2 cypg== X-Gm-Message-State: AOAM532N8d91e8UQx5GR/QavdBpOGunaL6wcNduc8dG7AnUkytVNdXKl h8UDaKF8RA2hYDbmFeMLdUwrRg== X-Google-Smtp-Source: ABdhPJzgBgorf4UQPr3rAtMPS9jzAmnikYL22lGssV3hmusbtzqqdthpC9nMfVtuEr70Vcu1VTUphg== X-Received: by 2002:a05:6512:1296:: with SMTP id u22mr23122317lfs.296.1637842099803; Thu, 25 Nov 2021 04:08:19 -0800 (PST) Received: from larwa.hq.kempniu.pl ([2001:470:64df:111::e02]) by smtp.gmail.com with ESMTPSA id t7sm287475lfl.260.2021.11.25.04.08.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Nov 2021 04:08:19 -0800 (PST) Date: Thu, 25 Nov 2021 13:08:16 +0100 From: =?utf-8?B?TWljaGHFgiBLxJlwaWXFhA==?= To: Miquel Raynal Cc: Richard Weinberger , Vignesh Raghavendra , Boris Brezillon , linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH] mtdchar: prevent unbounded allocation in MEMWRITE ioctl Message-ID: References: <20211025082104.8017-1-kernel@kempniu.pl> <20211122103122.424326a1@xps13> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20211122103122.424326a1@xps13> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211125_040822_839618_FD4EA3A2 X-CRM114-Status: GOOD ( 35.13 ) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org SGkgTWlxdcOobCwKClRMO0RSOiB0aGFua3MsIHlvdXIgY29tbWVudCBtYWRlIG1lIGxvb2sgY2xv c2VyIGFuZCBJIGZvdW5kIHdoYXQgc2VlbXMKdG8gYmUgYSBmZWFzaWJsZSB3b3JrYXJvdW5kIHRo YXQgSSB3aWxsIGFwcGx5IGluIHYyIChhbG9uZyBvdGhlciBmaXhlcykuCgo+ID4gRGVzcGl0ZSBt eSBlZmZvcnRzLCB0aGUgcGF0Y2ggZG9lcyBfbm90XyByZXRhaW4gYWJzb2x1dGUgYmFja3dhcmQK PiA+IGNvbXBhdGliaWxpdHkgYW5kIEkgZG8gbm90IGtub3cgd2hldGhlciB0aGlzIGlzIGFjY2Vw dGFibGUuCj4gPiBTcGVjaWZpY2FsbHksIG11bHRpLWVyYXNlYmxvY2stc2l6ZWQgd3JpdGVzIChy ZXF1aXJpbmcgbXVsdGlwbGUgbG9vcAo+ID4gaXRlcmF0aW9ucyB0byBiZSBwcm9jZXNzZWQpIHdo aWNoIHN1Y2NlZWRlZCB3aXRoIHRoZSBvcmlnaW5hbCBjb2RlIF9tYXlfCj4gPiBub3cgcmV0dXJu IGVycm9ycyBhbmQvb3Igd3JpdGUgZGlmZmVyZW50IGNvbnRlbnRzIHRvIHRoZSBkZXZpY2UgdGhh biB0aGUKPiA+IG9yaWdpbmFsIGNvZGUsIGRlcGVuZGluZyBvbiB0aGUgTVREIG1vZGUgb2Ygb3Bl cmF0aW9uIHJlcXVlc3RlZCBhbmQgb24KPiA+IHdoZXRoZXIgdGhlIHN0YXJ0IG9mZnNldCBpcyBw YWdlLWFsaWduZWQuICBUaGUgZG9jdW1lbnRhdGlvbiBmb3Igc3RydWN0Cj4gPiBtdGRfb29iX29w cyB3YXJucyBhYm91dCBldmVuIG11bHRpLXBhZ2Ugd3JpdGUgcmVxdWVzdHMsIGJ1dC4uLgo+ID4g Cj4gPiBFeGFtcGxlOgo+ID4gCj4gPiAgICAgTVREIGRldmljZSBwYXJhbWV0ZXJzOgo+ID4gCj4g PiAgICAgICAtIG10ZC0+d3JpdGVzaXplID0gMjA0OAo+ID4gICAgICAgLSBtdGQtPmVyYXNlc2l6 ZSA9IDEzMTA3Mgo+ID4gICAgICAgLSA2NCBieXRlcyBvZiByYXcgT09CIHNwYWNlIHBlciBwYWdl Cj4gPiAKPiA+ICAgICBzdHJ1Y3QgbXRkX3dyaXRlX3JlcSByZXEgPSB7Cj4gPiAgICAgICAgIC5z dGFydCA9IDIwNDgsCj4gPiAgICAgICAgIC5sZW4gPSAyNjIxNDQsCj4gPiAgICAgICAgIC5vb2Js ZW4gPSA2NCwKPiA+ICAgICAgICAgLnVzcl9kYXRhID0gLi4uLAo+ID4gICAgICAgICAudXNyX29v YiA9IC4uLiwKPiA+ICAgICAgICAgLm1vZGUgPSBNVERfT1BTX1JBVywKPiA+ICAgICB9Owo+ID4g Cj4gPiAgICAgKFRoaXMgaXMgYSAxMjgtcGFnZSB3cml0ZSB3aXRoIE9PQiBkYXRhIHN1cHBsaWVk IGZvciBqdXN0IG9uZSBwYWdlLikKPiA+IAo+ID4gICAgIEN1cnJlbnQgbXRkY2hhcl93cml0ZV9p b2N0bCgpIHJldHVybnMgMCBmb3IgdGhpcyByZXF1ZXN0IGFuZCB3cml0ZXMKPiA+ICAgICAxMjgg cGFnZXMgb2YgZGF0YSBhbmQgMSBwYWdlJ3Mgd29ydGggb2YgT09CIGRhdGEgKDY0IGJ5dGVzKSB0 byB0aGUKPiA+ICAgICBNVEQgZGV2aWNlLgo+ID4gCj4gPiAgICAgUGF0Y2hlZCBtdGRjaGFyX3dy aXRlX2lvY3RsKCkgbWF5IHJldHVybiBhbiBlcnJvciBiZWNhdXNlIHRoZQo+ID4gICAgIG9yaWdp bmFsIHJlcXVlc3QgZ2V0cyBzcGxpdCBpbnRvIHR3byBjaHVua3MgKDxkYXRhX2xlbiwgb29iX2xl bj4pOgo+ID4gCj4gPiAgICAgICAgIDwxMzEwNzIsIDY0Pgo+ID4gICAgICAgICA8MTMxMDcyLCAw Pgo+ID4gCj4gPiAgICAgYW5kIHRoZSBzZWNvbmQgY2h1bmsgd2l0aCB6ZXJvIE9PQiBkYXRhIGxl bmd0aCBtYXkgbWFrZSB0aGUgTVRECj4gPiAgICAgZHJpdmVyIHVuaGFwcHkgaW4gcmF3IG1vZGUg KHJlc3VsdGluZyBpbiBvbmx5IHRoZSBmaXJzdCA2NCBwYWdlcyBvZgo+ID4gICAgIGRhdGEgYW5k IDEgcGFnZSdzIHdvcnRoIG9mIE9PQiBkYXRhIGdldHRpbmcgd3JpdHRlbiB0byB0aGUgTVRECj4g PiAgICAgZGV2aWNlKS4KPiAKPiBJc24ndCB0aGlzIGEgZHJpdmVyIGlzc3VlIGluc3RlYWQ/IEkg bWVhbiwgd3JpdGluZyBhbiBlcmFzZWJsb2NrCj4gd2l0aG91dCBwcm92aWRpbmcgYW55IE9PQiBk YXRhIGlzIGNvbXBsZXRlbHkgZmluZSwgaWYgdGhlIGRyaXZlcgo+IGFjY2VwdHMgMiBibG9ja3Mg KyAxIHBhZ2UgT09CIGJ1dCByZWZ1c2VzIDEgYmxvY2sgKyAxIHBhZ2UgT09CIGFuZCB0aGVuCj4g MSBibG9jaywgaXQncyBicm9rZW4sIG5vPyBIYXZlIHlvdSBleHBlcmllbmNlZCBzdWNoIGEgc2l0 dWF0aW9uIGluIHlvdXIKPiB0ZXN0aW5nPwoKSSBtYXkgbm90IGhhdmUgZXhwcmVzc2VkIG15c2Vs ZiBjbGVhcmx5IGhlcmUsIHNvcnJ5IC0gdGhlIGV4YW1wbGUgd2FzCmFscmVhZHkgZ2V0dGluZyBh IGJpdCBsZW5ndGh5IGF0IHRoYXQgcG9pbnQuLi4gOikKCkkgdGVzdGVkIHRoZSBwYXRjaCB3aXRo IG5hbmRzaW0sIGJ1dCBJIGRvIG5vdCB0aGluayBpdCBpcyB0aGF0IHNwZWNpZmljCmRyaXZlciB0 aGF0IGlzIGJyb2tlbi4gIFRoZSBjYXRjaCBpcyB0aGF0IHdoZW4gbXRkX3dyaXRlX29vYigpIGlz CmNhbGxlZCwgbmFuZF9kb193cml0ZV9vcHMoKSBzcGxpdHMgbXVsdGktcGFnZSByZXF1ZXN0cyBp bnRvIHNpbmdsZS1wYWdlCnJlcXVlc3RzIGFuZCB3aGF0IGl0IHBhc3NlcyB0byBuYW5kX3dyaXRl X3BhZ2UoKSBkZXBlbmRzIG9uIHdoZXRoZXIgdGhlCnN0cnVjdCBtdGRfb29iX29wcyBpdCB3YXMg aW52b2tlZCB3aXRoIGhhcyB0aGUgb29iYnVmIGZpZWxkIHNldCB0byBOVUxMCm9yIG5vdC4gIFRo aXMgaXMgb2theSBpbiBpdHNlbGYsIGJ1dCB3aGVuIGFub3RoZXIgcmVxdWVzdC1zcGxpdHRpbmcK ImxheWVyIiBpcyBpbnRyb2R1Y2VkIGJ5IG15IHBhdGNoLCB0aGUgaW9jdGwgbWF5IHN0YXJ0IHJl dHVybmluZwpkaWZmZXJlbnQgcmVzdWx0IGNvZGVzIHRoYW4gaXQgdXNlZCB0by4KCkhlcmUgaXMg d2hhdCBoYXBwZW5zIHdpdGggdGhlIHVucGF0Y2hlZCBjb2RlIGZvciB0aGUgZXhhbXBsZSBhYm92 ZToKCiAxLiBtdGRjaGFyX3dyaXRlX2lvY3RsKCkgZ2V0cyBjYWxsZWQgd2l0aCB0aGUgZm9sbG93 aW5nIHJlcXVlc3Q6CgogICAgc3RydWN0IG10ZF93cml0ZV9yZXEgcmVxID0gewogICAgICAgIC5z dGFydCA9IDIwNDgsCiAgICAgICAgLmxlbiA9IDI2MjE0NCwKICAgICAgICAub29ibGVuID0gNjQs CiAgICAgICAgLnVzcl9kYXRhID0gMHgxMDAwMDAwMCwKICAgICAgICAudXNyX29vYiA9IDB4MjAw MDAwMDAsCiAgICAgICAgLm1vZGUgPSBNVERfT1BTX1JBVywKICAgIH07CgogMi4gVGhlIGFib3Zl IHJlcXVlc3QgaXMgcGFzc2VkIHRocm91Z2ggdG8gbXRkX3dyaXRlX29vYigpIHZlcmJhdGltOgoK ICAgIHN0cnVjdCBtdGRfb29iX29wcyBvcHMgPSB7CiAgICAgICAgLm1vZGUgPSBNVERfT1BTX1JB VywKCS5sZW4gPSAyNjIxNDQsCgkub29ibGVuID0gNjQsCiAgICAgICAgLmRhdGJ1ZiA9IDB4MTAw MDAwMDAsCiAgICAgICAgLm9vYmJ1ZiA9IDB4MjAwMDAwMDAsCiAgICB9OwoKIDMuIG5hbmRfZG9f d3JpdGVfb3BzKCkgc3BsaXRzIHRoaXMgcmVxdWVzdCB1cCBpbnRvIHBhZ2Utc2l6ZWQgcmVxdWVz dHMuCgogICAgIGEpIEZvciB0aGUgZmlyc3QgcGFnZSwgdGhlIGluaXRpYWwgMjA0OCBieXRlcyBv ZiBkYXRhICsgNjQgYnl0ZXMgb2YKICAgICAgICBPT0IgZGF0YSBhcmUgcGFzc2VkIHRvIG5hbmRf d3JpdGVfcGFnZSgpLgoKICAgICBiKSBGb3IgZWFjaCBzdWJzZXF1ZW50IHBhZ2UsIGEgMjA0OC1i eXRlIGNodW5rIG9mIGRhdGEgKyA2NCBieXRlcwogICAgICAgIG9mIDB4ZmYgYnl0ZXMgYXJlIHBh c3NlZCB0byBuYW5kX3dyaXRlX3BhZ2UoKS4KCiAgICBTaW5jZSB0aGUgb29iYnVmIGZpZWxkIGlu IHRoZSBzdHJ1Y3QgbXRkX29vYl9vcHMgcGFzc2VkIGlzIG5vdCBOVUxMLAogICAgb29iX3JlcXVp cmVkIGlzIHNldCB0byAxIGZvciBhbGwgbmFuZF93cml0ZV9wYWdlKCkgY2FsbHMuCgogNC4gVGhl IGFib3ZlIGNhdXNlcyB0aGUgZHJpdmVyIHRvIHJlY2VpdmUgMjExMiBieXRlcyBvZiBkYXRhIGZv ciBlYWNoCiAgICBwYWdlIHdyaXRlLCB3aGljaCByZXN1bHRzIGluIHRoZSBpb2N0bCBiZWluZyBz dWNjZXNzZnVsLgoKSGVyZSBpcyB3aGF0IGhhcHBlbnMgd2l0aCB0aGUgcGF0Y2hlZCBjb2RlOgoK IDEuIG10ZGNoYXJfd3JpdGVfaW9jdGwoKSBnZXRzIGNhbGxlZCB3aXRoIHRoZSBzYW1lIHJlcXVl c3QgYXMgYWJvdmUuCgogMi4gVGhlIG9yaWdpbmFsIHJlcXVlc3QgZ2V0cyBzcGxpdCBpbnRvIHR3 byBlcmFzZWJsb2NrLXNpemVkCiAgICBtdGRfd3JpdGVfb29iKCkgY2FsbHM6CgogICAgIGEpIHN0 cnVjdCBtdGRfb29iX29wcyBvcHMgPSB7CiAgICAgICAgICAgIC5tb2RlID0gTVREX09QU19SQVcs CiAgICAgICAgICAgIC5sZW4gPSAxMzEwNzIsCiAgICAgICAgICAgIC5vb2JsZW4gPSA2NCwKICAg ICAgICAgICAgLmRhdGJ1ZiA9IDB4MTAwMDAwMDAsCiAgICAgICAgICAgIC5vb2JidWYgPSAweDIw MDAwMDAwLAogICAgICAgIH07CgogICAgIGIpIHN0cnVjdCBtdGRfb29iX29wcyBvcHMgPSB7CiAg ICAgICAgICAgIC5tb2RlID0gTVREX09QU19SQVcsCiAgICAgICAgICAgIC5sZW4gPSAxMzEwNzIs CiAgICAgICAgICAgIC5vb2JsZW4gPSAwLAogICAgICAgICAgICAuZGF0YnVmID0gMHgxMDAyMDAw MCwKICAgICAgICAgICAgLm9vYmJ1ZiA9IE5VTEwsCiAgICAgICAgfTsKCiAgICAoTXkgY29kZSBz ZXRzIG9vYmJ1ZiB0byBOVUxMIGlmIG9vYmxlbiBpcyAwLikKCiAzLiBuYW5kX2RvX3dyaXRlX29w cygpIHNwbGl0cyB0aGUgZmlyc3QgcmVxdWVzdCB1cCBpbnRvIHBhZ2Utc2l6ZWQKICAgIHJlcXVl c3RzIHRoZSBzYW1lIHdheSBhcyBmb3IgdGhlIG9yaWdpbmFsIGNvZGUuICBJdCByZXR1cm5zCiAg ICBzdWNjZXNzZnVsbHksIHNvIG10ZGNoYXJfd3JpdGVfaW9jdGwoKSBwcm9jZWVkcyB3aXRoIHRo ZSBuZXh0CiAgICBlcmFzZWJsb2NrLXNpemVkIHJlcXVlc3QuCgogNC4gbmFuZF9kb193cml0ZV9v cHMoKSBzcGxpdHMgdGhlIHNlY29uZCByZXF1ZXN0IHVwIGludG8gcGFnZS1zaXplZAogICAgcmVx dWVzdHMuICBUaGUgZmlyc3QgcGFnZSB3cml0ZSBjb250YWlucyAyMDQ4IGJ5dGVzIG9mIGRhdGEg YW5kIG5vCiAgICBPT0IgZGF0YTsgc2luY2UgdGhlIG9vYmJ1ZiBmaWVsZCBpbiB0aGUgc3RydWN0 IG10ZF9vb2Jfb3BzIHBhc3NlZCBpcwogICAgTlVMTCwgb29iX3JlcXVpcmVkIGlzIHNldCB0byAw LgoKIDUuIFRoZSBhYm92ZSBjYXVzZXMgdGhlIGRyaXZlciB0byByZWNlaXZlIDIwNDggYnl0ZXMg b2YgZGF0YSBmb3IgYSBwYWdlCiAgICB3cml0ZSBpbiByYXcgbW9kZSwgd2hpY2ggcmVzdWx0cyBp biBhbiBlcnJvciB0aGF0IHByb3BhZ2F0ZXMgYWxsIHRoZQogICAgd2F5IHVwIHRvIG10ZGNoYXJf d3JpdGVfaW9jdGwoKS4KClRoZSBuYW5kc2ltIGRyaXZlciByZXR1cm5zIHRoZSBzYW1lIGVycm9y IGlmIHlvdSBwYXNzIHRoZSBmb2xsb3dpbmcKcmVxdWVzdCB0byB0aGUgTUVNV1JJVEUgaW9jdGw6 CgogICAgc3RydWN0IG10ZF93cml0ZV9yZXEgcmVxID0gewogICAgICAgIC5zdGFydCA9IDIwNDgs CiAgICAgICAgLmxlbiA9IDIwNDgsCiAgICAgICAgLm9vYmxlbiA9IDAsCiAgICAgICAgLnVzcl9k YXRhID0gMHgxMDAwMDAwMCwKICAgICAgICAudXNyX29vYiA9IE5VTEwsCiAgICAgICAgLm1vZGUg PSBNVERfT1BTX1JBVywKICAgIH07CgpzbyBpdCBpcyBub3QgdGhlIGRyaXZlciB0aGF0IGlzIGJy b2tlbiBvciBpbnNhbmUsIGl0IGlzIHRoZSBzcGxpdHRpbmcKcHJvY2VzcyB0aGF0IG1heSBjYXVz ZSB0aGUgTUVNV1JJVEUgaW9jdGwgdG8gcmV0dXJuIGRpZmZlcmVudCBlcnJvcgpjb2RlcyB0aGFu IGJlZm9yZS4KCkkgcGxheWVkIHdpdGggdGhlIGNvZGUgYSBiaXQgbW9yZSBhbmQgSSBmb3VuZCBh IGZpeCB3aGljaCBhZGRyZXNzZXMgdGhpcwppc3N1ZSB3aXRob3V0IGJyZWFraW5nIG90aGVyIHNj ZW5hcmlvczogc2V0dGluZyBvb2JidWYgdG8gdGhlIHNhbWUKcG9pbnRlciBmb3IgZXZlcnkgbG9v cCBpdGVyYXRpb24gKGlmIG9vYmxlbiBpcyAwLCBubyBPT0IgZGF0YSB3aWxsIGJlCndyaXR0ZW4g YW55d2F5KS4KCkkgYWxzbyB0YWNrbGVkIHRoZSBwcm9ibGVtIG9mIG1pc2hhbmRsaW5nIGxhcmdl IG5vbi1wYWdlLWFsaWduZWQgd3JpdGVzCmluIHYxIGFuZCBJIG1hbmFnZWQgdG8gZml4IGl0IGJ5 IHRyaW1taW5nIHRoZSBmaXJzdCBtdGRfd3JpdGVfb29iKCkgY2FsbApzbyB0aGF0IGl0IGVuZHMg b24gYW4gZXJhc2VibG9jayBib3VuZGFyeS4gIFRoaXMgaW1wbGljaXRseSBtYWtlcwpzdWJzZXF1 ZW50IHdyaXRlcyBwYWdlLWFsaWduZWQgYW5kIHNlZW1zIHRvIGZpeCB0aGUgcHJvYmxlbS4KCkZp bmFsbHksIEkgcmV3b3JrZWQgdGhlIE9PQiBsZW5ndGggYWRqdXN0bWVudCBjb2RlIHRvIGFkZHJl c3Mgb3RoZXIKY2FzZXMgb2YgbWlzaGFuZGxpbmcgbm9uLXBhZ2UtYWxpZ25lZCB3cml0ZXMuCgpJ IGNvdWxkIG5vdCBmaW5kIGFueSBvdGhlciBjYXNlcyBpbiB3aGljaCB0aGUgcmV2aXNlZCBjb2Rl IGJlaGF2ZXMKZGlmZmVyZW50bHkgdGhhbiB0aGUgb3JpZ2luYWwgb25lLiAgSSB3aWxsIHNlbmQg djIgc29vbi4KCi0tIApCZXN0IHJlZ2FyZHMsCk1pY2hhxYIgS8SZcGllxYQKCl9fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpMaW51eCBNVEQgZGlz Y3Vzc2lvbiBtYWlsaW5nIGxpc3QKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9s aXN0aW5mby9saW51eC1tdGQvCg==