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 0960FC433EF for ; Mon, 22 Nov 2021 09:31:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239059AbhKVJee convert rfc822-to-8bit (ORCPT ); Mon, 22 Nov 2021 04:34:34 -0500 Received: from relay3-d.mail.gandi.net ([217.70.183.195]:47643 "EHLO relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238838AbhKVJec (ORCPT ); Mon, 22 Nov 2021 04:34:32 -0500 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 0D4C360014; Mon, 22 Nov 2021 09:31:22 +0000 (UTC) Date: Mon, 22 Nov 2021 10:31:22 +0100 From: Miquel Raynal To: =?UTF-8?B?TWljaGHFgiBLxJlwaWXFhA==?= 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: <20211122103122.424326a1@xps13> In-Reply-To: <20211025082104.8017-1-kernel@kempniu.pl> References: <20211025082104.8017-1-kernel@kempniu.pl> Organization: Bootlin X-Mailer: Claws Mail 3.17.7 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8BIT Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Michał, kernel@kempniu.pl wrote on Mon, 25 Oct 2021 10:21:04 +0200: > In the mtdchar_write_ioctl() function, memdup_user() is called with its > 'len' parameter set to verbatim values provided by user space via a > struct mtd_write_req. Both the 'len' and 'ooblen' fields of that > structure are 64-bit unsigned integers, which means the MEMWRITE ioctl > can trigger unbounded kernel memory allocation requests. > > Fix by iterating over the buffers provided by user space in a loop, > processing at most mtd->erasesize bytes in each iteration. Adopt some > checks from mtd_check_oob_ops() to retain backward user space > compatibility. > Thank you very much for this proposal! > Suggested-by: Boris Brezillon > Signed-off-by: Michał Kępień > --- > Fixing this problem was suggested last month, during a discussion about > a new MEMREAD ioctl. [1] [2] > > My primary objective was to not break user space, i.e. to not change > externally visible behavior compared to the current code. The main > problem I faced was that splitting the input data into chunks makes the > MEMWRITE ioctl a _wrapper_ for mtd_write_oob() rather than a direct > _interface_ to it and yet from the user space perspective it still needs > to behave as if nothing changed. > > 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? > > Is an ioctl like this considered a "degenerate" one and therefore > acceptable to break or not? I don't think so :) > > At any rate, the revised code feels brittle to me and I would not be > particularly surprised if I missed more cases in which it produces > different results than the original code. > > I keep on wondering whether the benefits of this change are worth the > extra code complexity, but fortunately it is not my call to make :) > Perhaps I am missing something and my proposal can be simplified? Or > maybe the way I approached this is completely wrong? Any thoughts on > this are welcome. > > As the outcome of the discussion around this patch will have a > significant influence on the shape of the v2 of the MEMREAD ioctl, I > decided to submit this one first as a standalone patch. > > [1] https://lists.infradead.org/pipermail/linux-mtd/2021-September/088485.html > [2] https://lists.infradead.org/pipermail/linux-mtd/2021-September/088544.html > > drivers/mtd/mtdchar.c | 93 ++++++++++++++++++++++++++++++++----------- > 1 file changed, 70 insertions(+), 23 deletions(-) > > diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c > index 155e991d9d75..a3afc390e254 100644 > --- a/drivers/mtd/mtdchar.c > +++ b/drivers/mtd/mtdchar.c > @@ -578,9 +578,10 @@ static int mtdchar_write_ioctl(struct mtd_info *mtd, > { > struct mtd_info *master = mtd_get_master(mtd); > struct mtd_write_req req; > - struct mtd_oob_ops ops = {}; > const void __user *usr_data, *usr_oob; > - int ret; > + uint8_t *datbuf = NULL, *oobbuf = NULL; > + size_t datbuf_len, oobbuf_len; > + int ret = 0; > > if (copy_from_user(&req, argp, sizeof(req))) > return -EFAULT; > @@ -590,33 +591,79 @@ static int mtdchar_write_ioctl(struct mtd_info *mtd, > > if (!master->_write_oob) > return -EOPNOTSUPP; > - ops.mode = req.mode; > - ops.len = (size_t)req.len; > - ops.ooblen = (size_t)req.ooblen; > - ops.ooboffs = 0; > - > - if (usr_data) { > - ops.datbuf = memdup_user(usr_data, ops.len); > - if (IS_ERR(ops.datbuf)) > - return PTR_ERR(ops.datbuf); > - } else { > - ops.datbuf = NULL; > + > + if (!usr_data) > + req.len = 0; > + > + if (!usr_oob) > + req.ooblen = 0; > + > + if (req.start + req.len > mtd->size) > + return -EINVAL; > + > + datbuf_len = min_t(size_t, req.len, mtd->erasesize); > + if (datbuf_len > 0) { > + datbuf = kmalloc(datbuf_len, GFP_KERNEL); > + if (!datbuf) > + return -ENOMEM; > } > > - if (usr_oob) { > - ops.oobbuf = memdup_user(usr_oob, ops.ooblen); > - if (IS_ERR(ops.oobbuf)) { > - kfree(ops.datbuf); > - return PTR_ERR(ops.oobbuf); > + oobbuf_len = min_t(size_t, req.ooblen, mtd->erasesize); > + if (oobbuf_len > 0) { > + oobbuf = kmalloc(oobbuf_len, GFP_KERNEL); > + if (!oobbuf) { > + kfree(datbuf); > + return -ENOMEM; > } > - } else { > - ops.oobbuf = NULL; > } > > - ret = mtd_write_oob(mtd, (loff_t)req.start, &ops); > + while (req.len > 0 || (!usr_data && req.ooblen > 0)) { > + struct mtd_oob_ops ops = { > + .mode = req.mode, > + .len = min_t(size_t, req.len, datbuf_len), > + .ooblen = min_t(size_t, req.ooblen, oobbuf_len), > + .datbuf = req.len ? datbuf : NULL, > + .oobbuf = req.ooblen ? oobbuf : NULL, > + }; > > - kfree(ops.datbuf); > - kfree(ops.oobbuf); > + /* > + * For writes which are not OOB-only, adjust the amount of OOB > + * data written according to the number of data pages written. > + * This is necessary to prevent OOB data from being skipped > + * over in data+OOB writes requiring multiple mtd_write_oob() > + * calls to be completed. > + */ > + if (ops.len > 0 && ops.ooblen > 0) { > + u32 oob_per_page = mtd_oobavail(mtd, &ops); > + uint32_t pages_to_write = mtd_div_by_ws(ops.len, mtd); > + > + if (mtd_mod_by_ws(req.start + ops.len, mtd)) > + pages_to_write++; > + > + ops.ooblen = min_t(size_t, ops.ooblen, > + pages_to_write * oob_per_page); > + } > + > + if (copy_from_user(datbuf, usr_data, ops.len) || > + copy_from_user(oobbuf, usr_oob, ops.ooblen)) { > + ret = -EFAULT; > + break; > + } > + > + ret = mtd_write_oob(mtd, req.start, &ops); > + if (ret) > + break; > + > + req.start += ops.retlen; > + req.len -= ops.retlen; > + usr_data += ops.retlen; > + > + req.ooblen -= ops.oobretlen; > + usr_oob += ops.oobretlen; > + } > + > + kfree(datbuf); > + kfree(oobbuf); > > return ret; > } Thanks, Miquèl 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 DF40EC433F5 for ; Mon, 22 Nov 2021 09:59:16 +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:MIME-Version:References:In-Reply-To: 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=aVpQ1Ak//gop/JqnxmoCjrJ+b+OpbQ9UvOmTEK5S/pc=; b=eAyKB/4/8hmH+w mPT1udkbHBoeGI6pbtY/vFFphwg6R4VT/a0AemIrLoLTY+lzE4r6Dugzkf1fCfxGBkDvr1K+ZAhSM yrhfhQw5Ott3VlMhtWHe0TdgQCx03vK5eJN9tGVWNOHkYJ0BHBPOK8E+x0+PwdOWCfIKidCXhAl4P +zLqAkmhe20Dl9WWJXhatRE9tNFTvDdPAcSwyGbetL6DKSsb5H8t8ewHihvUJOMh4UURfO4KDDYO0 82hhCLBYeRDbb9g9tSdpup/mZ/gqFHc6q0sYQ6FBIJowT2nB1hM2LvuS7s7UZTz08rEGpKMYcyLqw NYjvhjWyBf+18pgL49EQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mp65k-00Fj90-Jc; Mon, 22 Nov 2021 09:58:28 +0000 Received: from relay3-d.mail.gandi.net ([217.70.183.195]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mp5fb-00FbGC-Fu for linux-mtd@lists.infradead.org; Mon, 22 Nov 2021 09:31:32 +0000 Received: (Authenticated sender: miquel.raynal@bootlin.com) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 0D4C360014; Mon, 22 Nov 2021 09:31:22 +0000 (UTC) Date: Mon, 22 Nov 2021 10:31:22 +0100 From: Miquel Raynal To: =?UTF-8?B?TWljaGHFgiBLxJlwaWXFhA==?= 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: <20211122103122.424326a1@xps13> In-Reply-To: <20211025082104.8017-1-kernel@kempniu.pl> References: <20211025082104.8017-1-kernel@kempniu.pl> Organization: Bootlin X-Mailer: Claws Mail 3.17.7 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211122_013127_862778_12965713 X-CRM114-Status: GOOD ( 47.43 ) 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 SGkgTWljaGHFgiwKCmtlcm5lbEBrZW1wbml1LnBsIHdyb3RlIG9uIE1vbiwgMjUgT2N0IDIwMjEg MTA6MjE6MDQgKzAyMDA6Cgo+IEluIHRoZSBtdGRjaGFyX3dyaXRlX2lvY3RsKCkgZnVuY3Rpb24s IG1lbWR1cF91c2VyKCkgaXMgY2FsbGVkIHdpdGggaXRzCj4gJ2xlbicgcGFyYW1ldGVyIHNldCB0 byB2ZXJiYXRpbSB2YWx1ZXMgcHJvdmlkZWQgYnkgdXNlciBzcGFjZSB2aWEgYQo+IHN0cnVjdCBt dGRfd3JpdGVfcmVxLiAgQm90aCB0aGUgJ2xlbicgYW5kICdvb2JsZW4nIGZpZWxkcyBvZiB0aGF0 Cj4gc3RydWN0dXJlIGFyZSA2NC1iaXQgdW5zaWduZWQgaW50ZWdlcnMsIHdoaWNoIG1lYW5zIHRo ZSBNRU1XUklURSBpb2N0bAo+IGNhbiB0cmlnZ2VyIHVuYm91bmRlZCBrZXJuZWwgbWVtb3J5IGFs bG9jYXRpb24gcmVxdWVzdHMuCj4gCj4gRml4IGJ5IGl0ZXJhdGluZyBvdmVyIHRoZSBidWZmZXJz IHByb3ZpZGVkIGJ5IHVzZXIgc3BhY2UgaW4gYSBsb29wLAo+IHByb2Nlc3NpbmcgYXQgbW9zdCBt dGQtPmVyYXNlc2l6ZSBieXRlcyBpbiBlYWNoIGl0ZXJhdGlvbi4gIEFkb3B0IHNvbWUKPiBjaGVj a3MgZnJvbSBtdGRfY2hlY2tfb29iX29wcygpIHRvIHJldGFpbiBiYWNrd2FyZCB1c2VyIHNwYWNl Cj4gY29tcGF0aWJpbGl0eS4KPiAKClRoYW5rIHlvdSB2ZXJ5IG11Y2ggZm9yIHRoaXMgcHJvcG9z YWwhCgo+IFN1Z2dlc3RlZC1ieTogQm9yaXMgQnJlemlsbG9uIDxib3Jpcy5icmV6aWxsb25AY29s bGFib3JhLmNvbT4KPiBTaWduZWQtb2ZmLWJ5OiBNaWNoYcWCIEvEmXBpZcWEIDxrZXJuZWxAa2Vt cG5pdS5wbD4KPiAtLS0KPiBGaXhpbmcgdGhpcyBwcm9ibGVtIHdhcyBzdWdnZXN0ZWQgbGFzdCBt b250aCwgZHVyaW5nIGEgZGlzY3Vzc2lvbiBhYm91dAo+IGEgbmV3IE1FTVJFQUQgaW9jdGwuIFsx XSBbMl0KPiAKPiBNeSBwcmltYXJ5IG9iamVjdGl2ZSB3YXMgdG8gbm90IGJyZWFrIHVzZXIgc3Bh Y2UsIGkuZS4gdG8gbm90IGNoYW5nZQo+IGV4dGVybmFsbHkgdmlzaWJsZSBiZWhhdmlvciBjb21w YXJlZCB0byB0aGUgY3VycmVudCBjb2RlLiAgVGhlIG1haW4KPiBwcm9ibGVtIEkgZmFjZWQgd2Fz IHRoYXQgc3BsaXR0aW5nIHRoZSBpbnB1dCBkYXRhIGludG8gY2h1bmtzIG1ha2VzIHRoZQo+IE1F TVdSSVRFIGlvY3RsIGEgX3dyYXBwZXJfIGZvciBtdGRfd3JpdGVfb29iKCkgcmF0aGVyIHRoYW4g YSBkaXJlY3QKPiBfaW50ZXJmYWNlXyB0byBpdCBhbmQgeWV0IGZyb20gdGhlIHVzZXIgc3BhY2Ug cGVyc3BlY3RpdmUgaXQgc3RpbGwgbmVlZHMKPiB0byBiZWhhdmUgYXMgaWYgbm90aGluZyBjaGFu Z2VkLgo+IAo+IERlc3BpdGUgbXkgZWZmb3J0cywgdGhlIHBhdGNoIGRvZXMgX25vdF8gcmV0YWlu IGFic29sdXRlIGJhY2t3YXJkCj4gY29tcGF0aWJpbGl0eSBhbmQgSSBkbyBub3Qga25vdyB3aGV0 aGVyIHRoaXMgaXMgYWNjZXB0YWJsZS4KPiBTcGVjaWZpY2FsbHksIG11bHRpLWVyYXNlYmxvY2st c2l6ZWQgd3JpdGVzIChyZXF1aXJpbmcgbXVsdGlwbGUgbG9vcAo+IGl0ZXJhdGlvbnMgdG8gYmUg cHJvY2Vzc2VkKSB3aGljaCBzdWNjZWVkZWQgd2l0aCB0aGUgb3JpZ2luYWwgY29kZSBfbWF5Xwo+ IG5vdyByZXR1cm4gZXJyb3JzIGFuZC9vciB3cml0ZSBkaWZmZXJlbnQgY29udGVudHMgdG8gdGhl IGRldmljZSB0aGFuIHRoZQo+IG9yaWdpbmFsIGNvZGUsIGRlcGVuZGluZyBvbiB0aGUgTVREIG1v ZGUgb2Ygb3BlcmF0aW9uIHJlcXVlc3RlZCBhbmQgb24KPiB3aGV0aGVyIHRoZSBzdGFydCBvZmZz ZXQgaXMgcGFnZS1hbGlnbmVkLiAgVGhlIGRvY3VtZW50YXRpb24gZm9yIHN0cnVjdAo+IG10ZF9v b2Jfb3BzIHdhcm5zIGFib3V0IGV2ZW4gbXVsdGktcGFnZSB3cml0ZSByZXF1ZXN0cywgYnV0Li4u Cj4gCj4gRXhhbXBsZToKPiAKPiAgICAgTVREIGRldmljZSBwYXJhbWV0ZXJzOgo+IAo+ICAgICAg IC0gbXRkLT53cml0ZXNpemUgPSAyMDQ4Cj4gICAgICAgLSBtdGQtPmVyYXNlc2l6ZSA9IDEzMTA3 Mgo+ICAgICAgIC0gNjQgYnl0ZXMgb2YgcmF3IE9PQiBzcGFjZSBwZXIgcGFnZQo+IAo+ICAgICBz dHJ1Y3QgbXRkX3dyaXRlX3JlcSByZXEgPSB7Cj4gICAgICAgICAuc3RhcnQgPSAyMDQ4LAo+ICAg ICAgICAgLmxlbiA9IDI2MjE0NCwKPiAgICAgICAgIC5vb2JsZW4gPSA2NCwKPiAgICAgICAgIC51 c3JfZGF0YSA9IC4uLiwKPiAgICAgICAgIC51c3Jfb29iID0gLi4uLAo+ICAgICAgICAgLm1vZGUg PSBNVERfT1BTX1JBVywKPiAgICAgfTsKPiAKPiAgICAgKFRoaXMgaXMgYSAxMjgtcGFnZSB3cml0 ZSB3aXRoIE9PQiBkYXRhIHN1cHBsaWVkIGZvciBqdXN0IG9uZSBwYWdlLikKPiAKPiAgICAgQ3Vy cmVudCBtdGRjaGFyX3dyaXRlX2lvY3RsKCkgcmV0dXJucyAwIGZvciB0aGlzIHJlcXVlc3QgYW5k IHdyaXRlcwo+ICAgICAxMjggcGFnZXMgb2YgZGF0YSBhbmQgMSBwYWdlJ3Mgd29ydGggb2YgT09C IGRhdGEgKDY0IGJ5dGVzKSB0byB0aGUKPiAgICAgTVREIGRldmljZS4KPiAKPiAgICAgUGF0Y2hl ZCBtdGRjaGFyX3dyaXRlX2lvY3RsKCkgbWF5IHJldHVybiBhbiBlcnJvciBiZWNhdXNlIHRoZQo+ ICAgICBvcmlnaW5hbCByZXF1ZXN0IGdldHMgc3BsaXQgaW50byB0d28gY2h1bmtzICg8ZGF0YV9s ZW4sIG9vYl9sZW4+KToKPiAKPiAgICAgICAgIDwxMzEwNzIsIDY0Pgo+ICAgICAgICAgPDEzMTA3 MiwgMD4KPiAKPiAgICAgYW5kIHRoZSBzZWNvbmQgY2h1bmsgd2l0aCB6ZXJvIE9PQiBkYXRhIGxl bmd0aCBtYXkgbWFrZSB0aGUgTVRECj4gICAgIGRyaXZlciB1bmhhcHB5IGluIHJhdyBtb2RlIChy ZXN1bHRpbmcgaW4gb25seSB0aGUgZmlyc3QgNjQgcGFnZXMgb2YKPiAgICAgZGF0YSBhbmQgMSBw YWdlJ3Mgd29ydGggb2YgT09CIGRhdGEgZ2V0dGluZyB3cml0dGVuIHRvIHRoZSBNVEQKPiAgICAg ZGV2aWNlKS4KCklzbid0IHRoaXMgYSBkcml2ZXIgaXNzdWUgaW5zdGVhZD8gSSBtZWFuLCB3cml0 aW5nIGFuIGVyYXNlYmxvY2sKd2l0aG91dCBwcm92aWRpbmcgYW55IE9PQiBkYXRhIGlzIGNvbXBs ZXRlbHkgZmluZSwgaWYgdGhlIGRyaXZlcgphY2NlcHRzIDIgYmxvY2tzICsgMSBwYWdlIE9PQiBi dXQgcmVmdXNlcyAxIGJsb2NrICsgMSBwYWdlIE9PQiBhbmQgdGhlbgoxIGJsb2NrLCBpdCdzIGJy b2tlbiwgbm8/IEhhdmUgeW91IGV4cGVyaWVuY2VkIHN1Y2ggYSBzaXR1YXRpb24gaW4geW91cgp0 ZXN0aW5nPwoKPiAKPiAgICAgSXMgYW4gaW9jdGwgbGlrZSB0aGlzIGNvbnNpZGVyZWQgYSAiZGVn ZW5lcmF0ZSIgb25lIGFuZCB0aGVyZWZvcmUKPiAgICAgYWNjZXB0YWJsZSB0byBicmVhayBvciBu b3Q/CgpJIGRvbid0IHRoaW5rIHNvIDopCgo+IAo+IEF0IGFueSByYXRlLCB0aGUgcmV2aXNlZCBj b2RlIGZlZWxzIGJyaXR0bGUgdG8gbWUgYW5kIEkgd291bGQgbm90IGJlCj4gcGFydGljdWxhcmx5 IHN1cnByaXNlZCBpZiBJIG1pc3NlZCBtb3JlIGNhc2VzIGluIHdoaWNoIGl0IHByb2R1Y2VzCj4g ZGlmZmVyZW50IHJlc3VsdHMgdGhhbiB0aGUgb3JpZ2luYWwgY29kZS4KPiAKPiBJIGtlZXAgb24g d29uZGVyaW5nIHdoZXRoZXIgdGhlIGJlbmVmaXRzIG9mIHRoaXMgY2hhbmdlIGFyZSB3b3J0aCB0 aGUKPiBleHRyYSBjb2RlIGNvbXBsZXhpdHksIGJ1dCBmb3J0dW5hdGVseSBpdCBpcyBub3QgbXkg Y2FsbCB0byBtYWtlIDopCj4gUGVyaGFwcyBJIGFtIG1pc3Npbmcgc29tZXRoaW5nIGFuZCBteSBw cm9wb3NhbCBjYW4gYmUgc2ltcGxpZmllZD8gIE9yCj4gbWF5YmUgdGhlIHdheSBJIGFwcHJvYWNo ZWQgdGhpcyBpcyBjb21wbGV0ZWx5IHdyb25nPyAgQW55IHRob3VnaHRzIG9uCj4gdGhpcyBhcmUg d2VsY29tZS4KPiAKPiBBcyB0aGUgb3V0Y29tZSBvZiB0aGUgZGlzY3Vzc2lvbiBhcm91bmQgdGhp cyBwYXRjaCB3aWxsIGhhdmUgYQo+IHNpZ25pZmljYW50IGluZmx1ZW5jZSBvbiB0aGUgc2hhcGUg b2YgdGhlIHYyIG9mIHRoZSBNRU1SRUFEIGlvY3RsLCBJCj4gZGVjaWRlZCB0byBzdWJtaXQgdGhp cyBvbmUgZmlyc3QgYXMgYSBzdGFuZGFsb25lIHBhdGNoLgo+IAo+IFsxXSBodHRwczovL2xpc3Rz LmluZnJhZGVhZC5vcmcvcGlwZXJtYWlsL2xpbnV4LW10ZC8yMDIxLVNlcHRlbWJlci8wODg0ODUu aHRtbAo+IFsyXSBodHRwczovL2xpc3RzLmluZnJhZGVhZC5vcmcvcGlwZXJtYWlsL2xpbnV4LW10 ZC8yMDIxLVNlcHRlbWJlci8wODg1NDQuaHRtbAo+IAo+ICBkcml2ZXJzL210ZC9tdGRjaGFyLmMg fCA5MyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0tLS0tLS0tLS0tCj4gIDEgZmls ZSBjaGFuZ2VkLCA3MCBpbnNlcnRpb25zKCspLCAyMyBkZWxldGlvbnMoLSkKPiAKPiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9tdGQvbXRkY2hhci5jIGIvZHJpdmVycy9tdGQvbXRkY2hhci5jCj4gaW5k ZXggMTU1ZTk5MWQ5ZDc1Li5hM2FmYzM5MGUyNTQgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9tdGQv bXRkY2hhci5jCj4gKysrIGIvZHJpdmVycy9tdGQvbXRkY2hhci5jCj4gQEAgLTU3OCw5ICs1Nzgs MTAgQEAgc3RhdGljIGludCBtdGRjaGFyX3dyaXRlX2lvY3RsKHN0cnVjdCBtdGRfaW5mbyAqbXRk LAo+ICB7Cj4gIAlzdHJ1Y3QgbXRkX2luZm8gKm1hc3RlciA9IG10ZF9nZXRfbWFzdGVyKG10ZCk7 Cj4gIAlzdHJ1Y3QgbXRkX3dyaXRlX3JlcSByZXE7Cj4gLQlzdHJ1Y3QgbXRkX29vYl9vcHMgb3Bz ID0ge307Cj4gIAljb25zdCB2b2lkIF9fdXNlciAqdXNyX2RhdGEsICp1c3Jfb29iOwo+IC0JaW50 IHJldDsKPiArCXVpbnQ4X3QgKmRhdGJ1ZiA9IE5VTEwsICpvb2JidWYgPSBOVUxMOwo+ICsJc2l6 ZV90IGRhdGJ1Zl9sZW4sIG9vYmJ1Zl9sZW47Cj4gKwlpbnQgcmV0ID0gMDsKPiAgCj4gIAlpZiAo Y29weV9mcm9tX3VzZXIoJnJlcSwgYXJncCwgc2l6ZW9mKHJlcSkpKQo+ICAJCXJldHVybiAtRUZB VUxUOwo+IEBAIC01OTAsMzMgKzU5MSw3OSBAQCBzdGF0aWMgaW50IG10ZGNoYXJfd3JpdGVfaW9j dGwoc3RydWN0IG10ZF9pbmZvICptdGQsCj4gIAo+ICAJaWYgKCFtYXN0ZXItPl93cml0ZV9vb2Ip Cj4gIAkJcmV0dXJuIC1FT1BOT1RTVVBQOwo+IC0Jb3BzLm1vZGUgPSByZXEubW9kZTsKPiAtCW9w cy5sZW4gPSAoc2l6ZV90KXJlcS5sZW47Cj4gLQlvcHMub29ibGVuID0gKHNpemVfdClyZXEub29i bGVuOwo+IC0Jb3BzLm9vYm9mZnMgPSAwOwo+IC0KPiAtCWlmICh1c3JfZGF0YSkgewo+IC0JCW9w cy5kYXRidWYgPSBtZW1kdXBfdXNlcih1c3JfZGF0YSwgb3BzLmxlbik7Cj4gLQkJaWYgKElTX0VS UihvcHMuZGF0YnVmKSkKPiAtCQkJcmV0dXJuIFBUUl9FUlIob3BzLmRhdGJ1Zik7Cj4gLQl9IGVs c2Ugewo+IC0JCW9wcy5kYXRidWYgPSBOVUxMOwo+ICsKPiArCWlmICghdXNyX2RhdGEpCj4gKwkJ cmVxLmxlbiA9IDA7Cj4gKwo+ICsJaWYgKCF1c3Jfb29iKQo+ICsJCXJlcS5vb2JsZW4gPSAwOwo+ ICsKPiArCWlmIChyZXEuc3RhcnQgKyByZXEubGVuID4gbXRkLT5zaXplKQo+ICsJCXJldHVybiAt RUlOVkFMOwo+ICsKPiArCWRhdGJ1Zl9sZW4gPSBtaW5fdChzaXplX3QsIHJlcS5sZW4sIG10ZC0+ ZXJhc2VzaXplKTsKPiArCWlmIChkYXRidWZfbGVuID4gMCkgewo+ICsJCWRhdGJ1ZiA9IGttYWxs b2MoZGF0YnVmX2xlbiwgR0ZQX0tFUk5FTCk7Cj4gKwkJaWYgKCFkYXRidWYpCj4gKwkJCXJldHVy biAtRU5PTUVNOwo+ICAJfQo+ICAKPiAtCWlmICh1c3Jfb29iKSB7Cj4gLQkJb3BzLm9vYmJ1ZiA9 IG1lbWR1cF91c2VyKHVzcl9vb2IsIG9wcy5vb2JsZW4pOwo+IC0JCWlmIChJU19FUlIob3BzLm9v YmJ1ZikpIHsKPiAtCQkJa2ZyZWUob3BzLmRhdGJ1Zik7Cj4gLQkJCXJldHVybiBQVFJfRVJSKG9w cy5vb2JidWYpOwo+ICsJb29iYnVmX2xlbiA9IG1pbl90KHNpemVfdCwgcmVxLm9vYmxlbiwgbXRk LT5lcmFzZXNpemUpOwo+ICsJaWYgKG9vYmJ1Zl9sZW4gPiAwKSB7Cj4gKwkJb29iYnVmID0ga21h bGxvYyhvb2JidWZfbGVuLCBHRlBfS0VSTkVMKTsKPiArCQlpZiAoIW9vYmJ1Zikgewo+ICsJCQlr ZnJlZShkYXRidWYpOwo+ICsJCQlyZXR1cm4gLUVOT01FTTsKPiAgCQl9Cj4gLQl9IGVsc2Ugewo+ IC0JCW9wcy5vb2JidWYgPSBOVUxMOwo+ICAJfQo+ICAKPiAtCXJldCA9IG10ZF93cml0ZV9vb2Io bXRkLCAobG9mZl90KXJlcS5zdGFydCwgJm9wcyk7Cj4gKwl3aGlsZSAocmVxLmxlbiA+IDAgfHwg KCF1c3JfZGF0YSAmJiByZXEub29ibGVuID4gMCkpIHsKPiArCQlzdHJ1Y3QgbXRkX29vYl9vcHMg b3BzID0gewo+ICsJCQkubW9kZSA9IHJlcS5tb2RlLAo+ICsJCQkubGVuID0gbWluX3Qoc2l6ZV90 LCByZXEubGVuLCBkYXRidWZfbGVuKSwKPiArCQkJLm9vYmxlbiA9IG1pbl90KHNpemVfdCwgcmVx Lm9vYmxlbiwgb29iYnVmX2xlbiksCj4gKwkJCS5kYXRidWYgPSByZXEubGVuID8gZGF0YnVmIDog TlVMTCwKPiArCQkJLm9vYmJ1ZiA9IHJlcS5vb2JsZW4gPyBvb2JidWYgOiBOVUxMLAo+ICsJCX07 Cj4gIAo+IC0Ja2ZyZWUob3BzLmRhdGJ1Zik7Cj4gLQlrZnJlZShvcHMub29iYnVmKTsKPiArCQkv Kgo+ICsJCSAqIEZvciB3cml0ZXMgd2hpY2ggYXJlIG5vdCBPT0Itb25seSwgYWRqdXN0IHRoZSBh bW91bnQgb2YgT09CCj4gKwkJICogZGF0YSB3cml0dGVuIGFjY29yZGluZyB0byB0aGUgbnVtYmVy IG9mIGRhdGEgcGFnZXMgd3JpdHRlbi4KPiArCQkgKiBUaGlzIGlzIG5lY2Vzc2FyeSB0byBwcmV2 ZW50IE9PQiBkYXRhIGZyb20gYmVpbmcgc2tpcHBlZAo+ICsJCSAqIG92ZXIgaW4gZGF0YStPT0Ig d3JpdGVzIHJlcXVpcmluZyBtdWx0aXBsZSBtdGRfd3JpdGVfb29iKCkKPiArCQkgKiBjYWxscyB0 byBiZSBjb21wbGV0ZWQuCj4gKwkJICovCj4gKwkJaWYgKG9wcy5sZW4gPiAwICYmIG9wcy5vb2Js ZW4gPiAwKSB7Cj4gKwkJCXUzMiBvb2JfcGVyX3BhZ2UgPSBtdGRfb29iYXZhaWwobXRkLCAmb3Bz KTsKPiArCQkJdWludDMyX3QgcGFnZXNfdG9fd3JpdGUgPSBtdGRfZGl2X2J5X3dzKG9wcy5sZW4s IG10ZCk7Cj4gKwo+ICsJCQlpZiAobXRkX21vZF9ieV93cyhyZXEuc3RhcnQgKyBvcHMubGVuLCBt dGQpKQo+ICsJCQkJcGFnZXNfdG9fd3JpdGUrKzsKPiArCj4gKwkJCW9wcy5vb2JsZW4gPSBtaW5f dChzaXplX3QsIG9wcy5vb2JsZW4sCj4gKwkJCQkJICAgcGFnZXNfdG9fd3JpdGUgKiBvb2JfcGVy X3BhZ2UpOwo+ICsJCX0KPiArCj4gKwkJaWYgKGNvcHlfZnJvbV91c2VyKGRhdGJ1ZiwgdXNyX2Rh dGEsIG9wcy5sZW4pIHx8Cj4gKwkJICAgIGNvcHlfZnJvbV91c2VyKG9vYmJ1ZiwgdXNyX29vYiwg b3BzLm9vYmxlbikpIHsKPiArCQkJcmV0ID0gLUVGQVVMVDsKPiArCQkJYnJlYWs7Cj4gKwkJfQo+ ICsKPiArCQlyZXQgPSBtdGRfd3JpdGVfb29iKG10ZCwgcmVxLnN0YXJ0LCAmb3BzKTsKPiArCQlp ZiAocmV0KQo+ICsJCQlicmVhazsKPiArCj4gKwkJcmVxLnN0YXJ0ICs9IG9wcy5yZXRsZW47Cj4g KwkJcmVxLmxlbiAtPSBvcHMucmV0bGVuOwo+ICsJCXVzcl9kYXRhICs9IG9wcy5yZXRsZW47Cj4g Kwo+ICsJCXJlcS5vb2JsZW4gLT0gb3BzLm9vYnJldGxlbjsKPiArCQl1c3Jfb29iICs9IG9wcy5v b2JyZXRsZW47Cj4gKwl9Cj4gKwo+ICsJa2ZyZWUoZGF0YnVmKTsKPiArCWtmcmVlKG9vYmJ1Zik7 Cj4gIAo+ICAJcmV0dXJuIHJldDsKPiAgfQoKClRoYW5rcywKTWlxdcOobAoKX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCkxpbnV4IE1URCBkaXNj dXNzaW9uIG1haWxpbmcgbGlzdApodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xp c3RpbmZvL2xpbnV4LW10ZC8K