Received: from malur.postgresql.org ([2a02:16a8:dc51::56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1fxHVp-0000qR-Ik for pgsql-hackers@arkaria.postgresql.org; Tue, 04 Sep 2018 20:01:21 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1fxHVo-000313-3D for pgsql-hackers@arkaria.postgresql.org; Tue, 04 Sep 2018 20:01:20 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1fxHVn-00030v-Pc for pgsql-hackers@lists.postgresql.org; Tue, 04 Sep 2018 20:01:19 +0000 Received: from smtp-fw-6001.amazon.com ([52.95.48.154]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1fxHVj-0006Dk-Uk for pgsql-hackers@postgresql.org; Tue, 04 Sep 2018 20:01:19 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1536091275; x=1567627275; h=from:to:subject:date:message-id:mime-version; bh=6uN+lN4CRIq8ThbBfulZIfrhT3F7qHzd+qhFtMmgnxI=; b=iEEbCSVkiDAUtfkTmHOjkPEHKVp6TtlT7SGBLrZ9uGeLZ1+j4vdOyh4b ffi4AQe8mdElrduZwPMhHIdWoI4I6Wz7XW2qns0Bf+p+NZz61vqhz0chz OYkJdjTBSSJz0hEGiKTi4Wsio7MMUVApXvzOihMFSzCy8lUMAYfHQfY5y g=; X-Amazon-filename: rewrite-ginRedoRecompress-scratch-space-processing-replay_v1.patch X-IronPort-AV: E=Sophos;i="5.53,330,1531785600"; d="scan'208,217,223";a="355372318" Received: from iad6-co-svc-p1-lb1-vlan3.amazon.com (HELO email-inbound-relay-2b-4e24fd92.us-west-2.amazon.com) ([10.124.125.6]) by smtp-border-fw-out-6001.iad6.amazon.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 04 Sep 2018 20:01:08 +0000 Received: from EX13MTAUWB001.ant.amazon.com (pdx1-ws-svc-p6-lb9-vlan3.pdx.amazon.com [10.236.137.198]) by email-inbound-relay-2b-4e24fd92.us-west-2.amazon.com (8.14.7/8.14.7) with ESMTP id w84JxCte076594 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=FAIL) for ; Tue, 4 Sep 2018 19:59:12 GMT Received: from EX13D08UWB004.ant.amazon.com (10.43.161.232) by EX13MTAUWB001.ant.amazon.com (10.43.161.207) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Tue, 4 Sep 2018 19:59:12 +0000 Received: from EX13D08UWB001.ant.amazon.com (10.43.161.104) by EX13D08UWB004.ant.amazon.com (10.43.161.232) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Tue, 4 Sep 2018 19:59:12 +0000 Received: from EX13D08UWB001.ant.amazon.com ([10.43.161.104]) by EX13D08UWB001.ant.amazon.com ([10.43.161.104]) with mapi id 15.00.1367.000; Tue, 4 Sep 2018 19:59:11 +0000 From: "R, Siva" To: pgsql-hackers Subject: Bug in ginRedoRecompress that causes opaque data on page to be overrun Thread-Topic: Bug in ginRedoRecompress that causes opaque data on page to be overrun Thread-Index: AQHURITWziSocye1S0ygUmXh1SVXsQ== Date: Tue, 4 Sep 2018 19:59:11 +0000 Message-ID: <1536091151804.6588@amazon.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: yes X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.43.160.81] Content-Type: multipart/mixed; boundary="_004_15360911518046588amazoncom_" MIME-Version: 1.0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --_004_15360911518046588amazoncom_ Content-Type: multipart/alternative; boundary="_000_15360911518046588amazoncom_" --_000_15360911518046588amazoncom_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Hi, We recently encountered an issue where the opaque data flags on a gin data = leaf page was corrupted while replaying a gin insert WAL record. Upon furth= er examination of the redo code, we found a bug in ginRedoRecompress code, = which extracts the WAL information and updates the page. Specifically, when a new segment is inserted in the middle of a page, a mem= move operation is performed [1] at the current point in the page to make ro= om for the new segment. If this segment insertion is followed by delete seg= ment actions that are yet to be processed and the total data size is very c= lose to GinDataPageMaxDataSize, then we may move the data portion beyond th= e boundary causing the opaque data to be corrupted. One way of solving this problem is to perform the replay work on a scratch = space, perform sanity check on the total size of the data portion before co= pying it back to the actual page. While it involves additional memory alloc= ation and memcpy operations, it is safer and similar to the 'do' code path = where we ensure to make a copy of all segment past the first modified segme= nt before placing them back on the page [2]. I have attached a patch for that approach here. Please let us know any comm= ents or feedback. Thanks! Best Siva References: [1] - https://git.postgresql.org/gitweb/?p=3Dpostgresql.git;a=3Dblob;f=3Dsr= c/backend/access/gin/ginxlog.c;h=3D7515f8bc167c2eafceced5d6ad5d74f7ec09e0a5= ;hb=3Drefs/heads/REL9_6_STABLE#l278 [2] - https://git.postgresql.org/gitweb/?p=3Dpostgresql.git;a=3Dblob;f=3Dsr= c/backend/access/gin/gindatapage.c;h=3Dcd3b9dfb784b084dd27a37146a4909fa1109= ee81;hb=3Drefs/heads/REL9_6_STABLE#l1726 --_000_15360911518046588amazoncom_ Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable

Hi,

We recently encountered an issue where the opaque data flags on a gin da= ta leaf page was corrupted while replaying a gin insert WAL record. Upon fu= rther examination of the redo code, we found a bug in ginRedoRecompress cod= e, which extracts the WAL information and updates the page.

Specifically, when a new segment is inserted in the middle of a page, a mem= move operation is performed [1] at the current point in the page to make ro= om for the new segment. If this segment insertion is followed by delete seg= ment actions that are yet to be processed and the total data size is very close to GinDataPageMaxDataSize,= then we may move the data portion beyond the boundary causing the opaque d= ata to be corrupted.

One way of solving this problem is to perform the replay work on a scratch = space, perform sanity check on the total size of the data portion before co= pying it back to the actual page. While it involves additional memory alloc= ation and memcpy operations, it is safer and similar to the 'do' code path where we ensure to make a copy = of all segment past the first modified segment before placing them back on = the page [2].

I have attached a patch for that approach here. Please let us know any comm= ents or feedback.
Thanks!

Best
Siva

References:
[1] - https://git.postgresql.org/gitweb/?p=3Dpostgresql.git;a=3Dblob;f=3Dsrc/back= end/access/gin/ginxlog.c;h=3D7515f8bc167c2eafceced5d6ad5d74f7ec09e0a5;hb=3D= refs/heads/REL9_6_STABLE#l278
[2] - https://git.postgresql.org/gitweb/?p=3Dpostgresql.git;a=3Dblob;f=3Dsrc/back= end/access/gin/gindatapage.c;h=3Dcd3b9dfb784b084dd27a37146a4909fa1109ee81;h= b=3Drefs/heads/REL9_6_STABLE#l1726

--_000_15360911518046588amazoncom_-- --_004_15360911518046588amazoncom_ Content-Type: application/octet-stream; name="rewrite-ginRedoRecompress-scratch-space-processing-replay_v1.patch" Content-Description: rewrite-ginRedoRecompress-scratch-space-processing-replay_v1.patch Content-Disposition: attachment; filename="rewrite-ginRedoRecompress-scratch-space-processing-replay_v1.patch"; size=7877; creation-date="Tue, 04 Sep 2018 19:24:02 GMT"; modification-date="Tue, 04 Sep 2018 19:24:02 GMT" Content-Transfer-Encoding: base64 RnJvbSA5Zjk3MWU3ODAyZDA0MTU3MzAyNGVlZGU3ZTAwNzIzNzJlZjFkNmU2IE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBTaXZhIFIgPHNpdmFzdWJyQGFtYXpvbi5jb20+CkRhdGU6IFR1 ZSwgNCBTZXAgMjAxOCAxOToxOToxNiArMDAwMApTdWJqZWN0OiBbUEFUQ0hdIFJld3JpdGUgZ2lu UmVkb1JlY29tcHJlc3MgdG8gdXNlIGEgc2NyYXRjaCBzcGFjZSBmb3IKIHByb2Nlc3NpbmcgcmVw bGF5IGFjdGlvbnMgaW5zdGVhZCBvZiBtb2RpZnlpbmcgY29udGVudHMgb24gdGhlIGFjdHVhbCBw YWdlIHRvCiBhdm9pZCBhY2NpZGVudGFsIG92ZXJ3cml0ZXMgb2Ygb3BhcXVlIGRhdGEuCgotLS0K IHNyYy9iYWNrZW5kL2FjY2Vzcy9naW4vZ2lueGxvZy5jIHwgMTgwICsrKysrKysrKysrKysrKysr KysrKy0tLS0tLS0tLS0tLS0tLS0tLQogMSBmaWxlIGNoYW5nZWQsIDk4IGluc2VydGlvbnMoKyks IDgyIGRlbGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL3NyYy9iYWNrZW5kL2FjY2Vzcy9naW4vZ2lu eGxvZy5jIGIvc3JjL2JhY2tlbmQvYWNjZXNzL2dpbi9naW54bG9nLmMKaW5kZXggNzUxNWY4Yi4u N2VhNzk4ZiAxMDA2NDQKLS0tIGEvc3JjL2JhY2tlbmQvYWNjZXNzL2dpbi9naW54bG9nLmMKKysr IGIvc3JjL2JhY2tlbmQvYWNjZXNzL2dpbi9naW54bG9nLmMKQEAgLTEzOCwxNyArMTM4LDIxIEBA IGdpblJlZG9SZWNvbXByZXNzKFBhZ2UgcGFnZSwgZ2lueGxvZ1JlY29tcHJlc3NEYXRhTGVhZiAq ZGF0YSkKIHsKIAlpbnQJCQlhY3Rpb25ubzsKIAlpbnQJCQlzZWdubzsKLQlHaW5Qb3N0aW5nTGlz dCAqb2xkc2VnOworCUdpblBvc3RpbmdMaXN0ICpzZWdpdGVyOworCVBvaW50ZXIJCXNlZ21lbnRj b3B5YmVnaW47CiAJUG9pbnRlcgkJc2VnbWVudGVuZDsKIAljaGFyCSAgICp3YWxidWY7CiAJaW50 CQkJdG90YWxzaXplOworCVBvaW50ZXIJCXNjcmF0Y2g7CisJUG9pbnRlcgkJc2NyYXRjaGJlZ2lu OworCWJvb2wJCW1vZGlmaWVkOwogCiAJLyoKIAkgKiBJZiB0aGUgcGFnZSBpcyBpbiBwcmUtOS40 IGZvcm1hdCwgY29udmVydCB0byBuZXcgZm9ybWF0IGZpcnN0LgogCSAqLwogCWlmICghR2luUGFn ZUlzQ29tcHJlc3NlZChwYWdlKSkKIAl7Ci0JCUl0ZW1Qb2ludGVyIHVuY29tcHJlc3NlZCA9IChJ dGVtUG9pbnRlcikgR2luRGF0YVBhZ2VHZXREYXRhKHBhZ2UpOworCQlJdGVtUG9pbnRlciB1bmNv bXByZXNzZWQgPSAoSXRlbVBvaW50ZXIpR2luRGF0YVBhZ2VHZXREYXRhKHBhZ2UpOwogCQlpbnQJ CQludW5jb21wcmVzc2VkID0gR2luUGFnZUdldE9wYXF1ZShwYWdlKS0+bWF4b2ZmOwogCQlpbnQJ CQlucGFja2VkOwogCkBAIC0xODAsNjMgKzE4NCw3NyBAQCBnaW5SZWRvUmVjb21wcmVzcyhQYWdl IHBhZ2UsIGdpbnhsb2dSZWNvbXByZXNzRGF0YUxlYWYgKmRhdGEpCiAJCUdpblBhZ2VHZXRPcGFx dWUocGFnZSktPm1heG9mZiA9IEludmFsaWRPZmZzZXROdW1iZXI7CiAJfQogCi0Jb2xkc2VnID0g R2luRGF0YUxlYWZQYWdlR2V0UG9zdGluZ0xpc3QocGFnZSk7Ci0Jc2VnbWVudGVuZCA9IChQb2lu dGVyKSBvbGRzZWcgKyBHaW5EYXRhTGVhZlBhZ2VHZXRQb3N0aW5nTGlzdFNpemUocGFnZSk7Ci0J c2Vnbm8gPSAwOworCXNjcmF0Y2ggPSBwYWxsb2MoR2luRGF0YVBhZ2VNYXhEYXRhU2l6ZSk7CisK KwlzZWdpdGVyID0gR2luRGF0YUxlYWZQYWdlR2V0UG9zdGluZ0xpc3QocGFnZSk7CisJc2VnbWVu dGVuZCA9IChQb2ludGVyKXNlZ2l0ZXIgKyBHaW5EYXRhTGVhZlBhZ2VHZXRQb3N0aW5nTGlzdFNp emUocGFnZSk7CisJc2VnbWVudGNvcHliZWdpbiA9IHNlZ21lbnRlbmQ7CiAKLQl3YWxidWYgPSAo KGNoYXIgKikgZGF0YSkgKyBzaXplb2YoZ2lueGxvZ1JlY29tcHJlc3NEYXRhTGVhZik7CisJc2Vn bm8gPSAwOworCW1vZGlmaWVkID0gZmFsc2U7CisJc2NyYXRjaGJlZ2luID0gc2NyYXRjaDsKKwl3 YWxidWYgPSAoKGNoYXIgKilkYXRhKSArIHNpemVvZihnaW54bG9nUmVjb21wcmVzc0RhdGFMZWFm KTsKIAlmb3IgKGFjdGlvbm5vID0gMDsgYWN0aW9ubm8gPCBkYXRhLT5uYWN0aW9uczsgYWN0aW9u bm8rKykKIAl7Ci0JCXVpbnQ4CQlhX3NlZ25vID0gKigodWludDggKikgKHdhbGJ1ZisrKSk7Ci0J CXVpbnQ4CQlhX2FjdGlvbiA9ICooKHVpbnQ4ICopICh3YWxidWYrKykpOworCQl1aW50OAkJYV9z ZWdubyA9ICooKHVpbnQ4ICopKHdhbGJ1ZisrKSk7CisJCXVpbnQ4CQlhX2FjdGlvbiA9ICooKHVp bnQ4ICopKHdhbGJ1ZisrKSk7CiAJCUdpblBvc3RpbmdMaXN0ICpuZXdzZWcgPSBOVUxMOwogCQlp bnQJCQluZXdzZWdzaXplID0gMDsKIAkJSXRlbVBvaW50ZXJEYXRhICppdGVtcyA9IE5VTEw7CiAJ CXVpbnQxNgkJbml0ZW1zID0gMDsKLQkJSXRlbVBvaW50ZXJEYXRhICpvbGRpdGVtczsKLQkJaW50 CQkJbm9sZGl0ZW1zOwotCQlJdGVtUG9pbnRlckRhdGEgKm5ld2l0ZW1zOwotCQlpbnQJCQlubmV3 aXRlbXM7Ci0JCWludAkJCXNlZ3NpemU7Ci0JCVBvaW50ZXIJCXNlZ3B0cjsKLQkJaW50CQkJc3ps ZWZ0OwotCi0JCS8qIEV4dHJhY3QgYWxsIHRoZSBpbmZvcm1hdGlvbiB3ZSBuZWVkIGZyb20gdGhl IFdBTCByZWNvcmQgKi8KLQkJaWYgKGFfYWN0aW9uID09IEdJTl9TRUdNRU5UX0lOU0VSVCB8fAot CQkJYV9hY3Rpb24gPT0gR0lOX1NFR01FTlRfUkVQTEFDRSkKLQkJewotCQkJbmV3c2VnID0gKEdp blBvc3RpbmdMaXN0ICopIHdhbGJ1ZjsKLQkJCW5ld3NlZ3NpemUgPSBTaXplT2ZHaW5Qb3N0aW5n TGlzdChuZXdzZWcpOwotCQkJd2FsYnVmICs9IFNIT1JUQUxJR04obmV3c2Vnc2l6ZSk7Ci0JCX0K LQotCQlpZiAoYV9hY3Rpb24gPT0gR0lOX1NFR01FTlRfQURESVRFTVMpCi0JCXsKLQkJCW1lbWNw eSgmbml0ZW1zLCB3YWxidWYsIHNpemVvZih1aW50MTYpKTsKLQkJCXdhbGJ1ZiArPSBzaXplb2Yo dWludDE2KTsKLQkJCWl0ZW1zID0gKEl0ZW1Qb2ludGVyRGF0YSAqKSB3YWxidWY7Ci0JCQl3YWxi dWYgKz0gbml0ZW1zICogc2l6ZW9mKEl0ZW1Qb2ludGVyRGF0YSk7Ci0JCX0KIAogCQkvKiBTa2lw IHRvIHRoZSBzZWdtZW50IHRoYXQgdGhpcyBhY3Rpb24gY29uY2VybnMgKi8KIAkJQXNzZXJ0KHNl Z25vIDw9IGFfc2Vnbm8pOwogCQl3aGlsZSAoc2Vnbm8gPCBhX3NlZ25vKQogCQl7Ci0JCQlvbGRz ZWcgPSBHaW5OZXh0UG9zdGluZ0xpc3RTZWdtZW50KG9sZHNlZyk7CisJCQlpZiAobW9kaWZpZWQp CisJCQl7CisJCQkJaW50CQkJY3Vyc2Vnc2l6ZTsKKworCQkJCS8qIENvcHkgb3V0IHRoZSBzZWdt ZW50IHRvIHNjcmF0Y2ggc3BhY2UgKi8KKwkJCQljdXJzZWdzaXplID0gU2l6ZU9mR2luUG9zdGlu Z0xpc3Qoc2VnaXRlcik7CisJCQkJQXNzZXJ0KHNjcmF0Y2ggKyBjdXJzZWdzaXplIC0gc2NyYXRj aGJlZ2luIDw9IEdpbkRhdGFQYWdlTWF4RGF0YVNpemUpOworCQkJCW1lbWNweShzY3JhdGNoLCBz ZWdpdGVyLCBjdXJzZWdzaXplKTsKKwkJCQlzY3JhdGNoICs9IGN1cnNlZ3NpemU7CisJCQl9CisK KwkJCS8qIE1vdmUgdG8gbmV4dCBzZWdtZW50IGluIHRoZSBwYWdlICovCisJCQlzZWdpdGVyID0g R2luTmV4dFBvc3RpbmdMaXN0U2VnbWVudChzZWdpdGVyKTsKIAkJCXNlZ25vKys7CiAJCX0KIAog CQkvKgotCQkgKiBBRERJVEVNUyBhY3Rpb24gaXMgaGFuZGxlZCBsaWtlIFJFUExBQ0UsIGJ1dCB0 aGUgbmV3IHNlZ21lbnQgdG8KLQkJICogcmVwbGFjZSB0aGUgb2xkIG9uZSBpcyByZWNvbnN0cnVj dGVkIHVzaW5nIHRoZSBvbGQgc2VnbWVudCBmcm9tCi0JCSAqIGRpc2sgYW5kIHRoZSBuZXcgaXRl bXMgZnJvbSB0aGUgV0FMIHJlY29yZC4KKwkJICogRW5jb3VudGVyZWQgZmlyc3Qgc2VnbWVudCB3 aXRoIGFuIGFjdGlvbi4gRXZlcnkgc3Vic2VxdWVudCBzZWdtZW50CisJCSAqIG5lZWRzIHRvIGJl IGluIHNjcmF0Y2ggc3BhY2UuCisJCSAqLworCQlpZiAoIW1vZGlmaWVkKQorCQl7CisJCQltb2Rp ZmllZCA9IHRydWU7CisJCQlzZWdtZW50Y29weWJlZ2luID0gKFBvaW50ZXIpc2VnaXRlcjsKKwkJ fQorCisJCS8qCisJCSAqIFBvc2l0aW9uZWQgYWZ0ZXIgdGhlIGxhc3QgZXhpc3Rpbmcgc2VnbWVu dC4gT25seSBJTlNFUlRzIGV4cGVjdGVkCisJCSAqIGhlcmUuCiAJCSAqLworCQlpZiAoKFBvaW50 ZXIpc2VnaXRlciA9PSBzZWdtZW50ZW5kKQorCQkJQXNzZXJ0KGFfYWN0aW9uID09IEdJTl9TRUdN RU5UX0lOU0VSVCk7CisKKwkJLyogUHJvY2VzcyB0aGUgYWN0aW9uIG9uIHRoZSBzZWdtZW50ICov CiAJCWlmIChhX2FjdGlvbiA9PSBHSU5fU0VHTUVOVF9BRERJVEVNUykKIAkJeworCQkJSXRlbVBv aW50ZXJEYXRhICpvbGRpdGVtczsKKwkJCWludAkJCW5vbGRpdGVtczsKKwkJCUl0ZW1Qb2ludGVy RGF0YSAqbmV3aXRlbXM7CisJCQlpbnQJCQlubmV3aXRlbXM7CiAJCQlpbnQJCQlucGFja2VkOwog Ci0JCQlvbGRpdGVtcyA9IGdpblBvc3RpbmdMaXN0RGVjb2RlKG9sZHNlZywgJm5vbGRpdGVtcyk7 CisJCQltZW1jcHkoJm5pdGVtcywgd2FsYnVmLCBzaXplb2YodWludDE2KSk7CisJCQl3YWxidWYg Kz0gc2l6ZW9mKHVpbnQxNik7CisJCQlpdGVtcyA9IChJdGVtUG9pbnRlckRhdGEgKil3YWxidWY7 CisJCQl3YWxidWYgKz0gbml0ZW1zICogc2l6ZW9mKEl0ZW1Qb2ludGVyRGF0YSk7CiAKKwkJCW9s ZGl0ZW1zID0gZ2luUG9zdGluZ0xpc3REZWNvZGUoc2VnaXRlciwgJm5vbGRpdGVtcyk7CiAJCQlu ZXdpdGVtcyA9IGdpbk1lcmdlSXRlbVBvaW50ZXJzKGl0ZW1zLCBuaXRlbXMsCiAJCQkJCQkJCQkJ CW9sZGl0ZW1zLCBub2xkaXRlbXMsCiAJCQkJCQkJCQkJCSZubmV3aXRlbXMpOwpAQCAtMjQ3LDYx ICsyNjUsNTkgQEAgZ2luUmVkb1JlY29tcHJlc3MoUGFnZSBwYWdlLCBnaW54bG9nUmVjb21wcmVz c0RhdGFMZWFmICpkYXRhKQogCQkJQXNzZXJ0KG5wYWNrZWQgPT0gbm5ld2l0ZW1zKTsKIAogCQkJ bmV3c2Vnc2l6ZSA9IFNpemVPZkdpblBvc3RpbmdMaXN0KG5ld3NlZyk7Ci0JCQlhX2FjdGlvbiA9 IEdJTl9TRUdNRU5UX1JFUExBQ0U7CisJCQltZW1jcHkoc2NyYXRjaCwgbmV3c2VnLCBuZXdzZWdz aXplKTsKKwkJCXNjcmF0Y2ggKz0gbmV3c2Vnc2l6ZTsKIAkJfQorCQllbHNlIGlmIChhX2FjdGlv biA9PSBHSU5fU0VHTUVOVF9JTlNFUlQgfHwKKwkJCQkgYV9hY3Rpb24gPT0gR0lOX1NFR01FTlRf UkVQTEFDRSkKKwkJeworCQkJbmV3c2VnID0gKEdpblBvc3RpbmdMaXN0ICopd2FsYnVmOworCQkJ bmV3c2Vnc2l6ZSA9IFNpemVPZkdpblBvc3RpbmdMaXN0KG5ld3NlZyk7CisJCQl3YWxidWYgKz0g U0hPUlRBTElHTihTaXplT2ZHaW5Qb3N0aW5nTGlzdChuZXdzZWcpKTsKIAotCQlzZWdwdHIgPSAo UG9pbnRlcikgb2xkc2VnOwotCQlpZiAoc2VncHRyICE9IHNlZ21lbnRlbmQpCi0JCQlzZWdzaXpl ID0gU2l6ZU9mR2luUG9zdGluZ0xpc3Qob2xkc2VnKTsKKwkJCS8qIENvcHkgdGhlIG5ldy9yZXBs YWNlZCBzZWdtZW50IGludG8gc2NyYXRjaCBzcGFjZSAqLworCQkJbWVtY3B5KHNjcmF0Y2gsIG5l d3NlZywgbmV3c2Vnc2l6ZSk7CisJCQlzY3JhdGNoICs9IG5ld3NlZ3NpemU7CisJCX0KKwkJZWxz ZSBpZiAoYV9hY3Rpb24gPT0gR0lOX1NFR01FTlRfREVMRVRFKQorCQl7CisJCQkvKiBObyBvcCAq LworCQl9CiAJCWVsc2UKIAkJewotCQkJLyoKLQkJCSAqIFBvc2l0aW9uZWQgYWZ0ZXIgdGhlIGxh c3QgZXhpc3Rpbmcgc2VnbWVudC4gT25seSBJTlNFUlRzCi0JCQkgKiBleHBlY3RlZCBoZXJlLgot CQkJICovCi0JCQlBc3NlcnQoYV9hY3Rpb24gPT0gR0lOX1NFR01FTlRfSU5TRVJUKTsKLQkJCXNl Z3NpemUgPSAwOworCQkJZWxvZyhFUlJPUiwgInVuZXhwZWN0ZWQgR0lOIGxlYWYgYWN0aW9uOiAl dSIsIGFfYWN0aW9uKTsKIAkJfQotCQlzemxlZnQgPSBzZWdtZW50ZW5kIC0gc2VncHRyOwogCi0J CXN3aXRjaCAoYV9hY3Rpb24pCisJCS8qCisJCSAqIEFkdmFuY2UgdG8gbmV4dCBzZWdtZW50IG9u IG9yaWdpbmFsIHBhZ2UgaWYgdGhlIGN1cnJlbnQgc2VnbWVudAorCQkgKiBhY3Rpb24gaXMgbm90 IGluc2VydC4KKwkJICovCisJCWlmIChhX2FjdGlvbiAhPSBHSU5fU0VHTUVOVF9JTlNFUlQpCiAJ CXsKLQkJCWNhc2UgR0lOX1NFR01FTlRfREVMRVRFOgotCQkJCW1lbW1vdmUoc2VncHRyLCBzZWdw dHIgKyBzZWdzaXplLCBzemxlZnQgLSBzZWdzaXplKTsKLQkJCQlzZWdtZW50ZW5kIC09IHNlZ3Np emU7Ci0KLQkJCQlzZWdubysrOwotCQkJCWJyZWFrOwotCi0JCQljYXNlIEdJTl9TRUdNRU5UX0lO U0VSVDoKLQkJCQkvKiBtYWtlIHJvb20gZm9yIHRoZSBuZXcgc2VnbWVudCAqLwotCQkJCW1lbW1v dmUoc2VncHRyICsgbmV3c2Vnc2l6ZSwgc2VncHRyLCBzemxlZnQpOwotCQkJCS8qIGNvcHkgdGhl IG5ldyBzZWdtZW50IGluIHBsYWNlICovCi0JCQkJbWVtY3B5KHNlZ3B0ciwgbmV3c2VnLCBuZXdz ZWdzaXplKTsKLQkJCQlzZWdtZW50ZW5kICs9IG5ld3NlZ3NpemU7Ci0JCQkJc2VncHRyICs9IG5l d3NlZ3NpemU7Ci0JCQkJYnJlYWs7Ci0KLQkJCWNhc2UgR0lOX1NFR01FTlRfUkVQTEFDRToKLQkJ CQkvKiBzaGlmdCB0aGUgc2VnbWVudHMgdGhhdCBmb2xsb3cgKi8KLQkJCQltZW1tb3ZlKHNlZ3B0 ciArIG5ld3NlZ3NpemUsCi0JCQkJCQlzZWdwdHIgKyBzZWdzaXplLAotCQkJCQkJc3psZWZ0IC0g c2Vnc2l6ZSk7Ci0JCQkJLyogY29weSB0aGUgcmVwbGFjZW1lbnQgc2VnbWVudCBpbiBwbGFjZSAq LwotCQkJCW1lbWNweShzZWdwdHIsIG5ld3NlZywgbmV3c2Vnc2l6ZSk7Ci0JCQkJc2VnbWVudGVu ZCAtPSBzZWdzaXplOwotCQkJCXNlZ21lbnRlbmQgKz0gbmV3c2Vnc2l6ZTsKLQkJCQlzZWdwdHIg Kz0gbmV3c2Vnc2l6ZTsKLQkJCQlzZWdubysrOwotCQkJCWJyZWFrOwotCi0JCQlkZWZhdWx0Ogot CQkJCWVsb2coRVJST1IsICJ1bmV4cGVjdGVkIEdJTiBsZWFmIGFjdGlvbjogJXUiLCBhX2FjdGlv bik7CisJCQlzZWdpdGVyID0gR2luTmV4dFBvc3RpbmdMaXN0U2VnbWVudChzZWdpdGVyKTsKKwkJ CXNlZ25vKys7CiAJCX0KLQkJb2xkc2VnID0gKEdpblBvc3RpbmdMaXN0ICopIHNlZ3B0cjsKIAl9 CiAKLQl0b3RhbHNpemUgPSBzZWdtZW50ZW5kIC0gKFBvaW50ZXIpIEdpbkRhdGFMZWFmUGFnZUdl dFBvc3RpbmdMaXN0KHBhZ2UpOworCS8qIEFzc2VydCB0aGF0IHRoZXJlIHdhcyBzb21lIG1vZGlm aWNhdGlvbiBwZXJmb3JtZWQgKi8KKwlBc3NlcnQobW9kaWZpZWQpOworCisJLyogQ29weSBvdXQg cmVtYWluZGVyIG9mIHRoZSBwYWdlIGludG8gc2NyYXRjaCAqLworCWlmICgoUG9pbnRlcilzZWdp dGVyIDwgc2VnbWVudGVuZCkKKwkJbWVtY3B5KHNjcmF0Y2gsIHNlZ2l0ZXIsIChzZWdtZW50ZW5k IC0gKChQb2ludGVyKXNlZ2l0ZXIpKSk7CisKKwkvKgorCSAqIENoZWNrIHRoYXQgdGhlIG5ldyB0 b3RhbCBzaXplIGlzIHdpdGhpbiB0aGUgbWF4IGRhdGEgcGFnZSBzaXplIGFsbG93ZWQuCisJICog TmV3IHRvdGFsIHNpemUgaXMgc3VtIG9mIHNjcmF0Y2ggc3BhY2Ugc2l6ZSBjb25zdW1lZCBhbmQg cG9ydGlvbiBvZgorCSAqIHBhZ2UgdGhhdCB3YXMgdW5tb2RpZmllZC4KKwkgKi8KKwl0b3RhbHNp emUgPSAoc2NyYXRjaCAtIHNjcmF0Y2hiZWdpbikgKyAoc2VnbWVudGNvcHliZWdpbiAtIChQb2lu dGVyKUdpbkRhdGFMZWFmUGFnZUdldFBvc3RpbmdMaXN0KHBhZ2UpKTsKKwlBc3NlcnQodG90YWxz aXplIDw9IEdpbkRhdGFQYWdlTWF4RGF0YVNpemUpOworCisJLyogQ29weSB0aGUgaXRlbXMgYmFj ayBvbnRvIHRoZSBwYWdlICovCisJbWVtY3B5KHNlZ21lbnRjb3B5YmVnaW4sIHNjcmF0Y2hiZWdp biwgKHNjcmF0Y2ggLSBzY3JhdGNoYmVnaW4pKTsKKworCS8qIFNldCBzaXplIG9uIHRoZSBwYWdl ICovCiAJR2luRGF0YVBhZ2VTZXREYXRhU2l6ZShwYWdlLCB0b3RhbHNpemUpOwogfQogCi0tIAoy LjcuMy5BTVpOCgo= --_004_15360911518046588amazoncom_--