From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from smtps.newmedia-net.de ([185.84.6.167]:54937 "EHLO webmail.newmedia-net.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752640AbdJTTnn (ORCPT ); Fri, 20 Oct 2017 15:43:43 -0400 Subject: Re: [PATCH] ath10k: rebuild crypto header in RX data frames To: Kalle Valo , ath10k@lists.infradead.org Cc: linux-wireless@vger.kernel.org References: <150851690590.5158.11970481736247725763.stgit@potku.adurom.net> From: Sebastian Gottschall Message-ID: <5ccfddbf-5b23-8750-17a4-cf96284dbde0@dd-wrt.com> (sfid-20171020_214347_744938_E3D26E1D) Date: Fri, 20 Oct 2017 21:43:35 +0200 MIME-Version: 1.0 In-Reply-To: <150851690590.5158.11970481736247725763.stgit@potku.adurom.net> Content-Type: text/plain; charset=utf-8; format=flowed Sender: linux-wireless-owner@vger.kernel.org List-ID: maybe this small patch hint here should help to make this patch better --- rx_desc.h   (revision 3655) +++ rx_desc.h   (working copy) @@ -239,6 +239,9 @@         HTT_RX_MPDU_ENCRYPT_WAPI             = 5,         HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2     = 6,         HTT_RX_MPDU_ENCRYPT_NONE             = 7, +       HTT_RX_MPDU_ENCRYPT_AES_CCMP_256     = 8, +       HTT_RX_MPDU_ENCRYPT_AES_GCMP_128     = 9, +       HTT_RX_MPDU_ENCRYPT_AES_GCMP_256     = 10, Am 20.10.2017 um 18:28 schrieb Kalle Valo: > From: Vasanthakumar Thiagarajan > > RX data frames notified through HTT_T2H_MSG_TYPE_RX_IND and > HTT_T2H_MSG_TYPE_RX_FRAG_IND expect PN/TSC check to be done > on host (mac80211) rather than firmware. Rebuild cipher header > in every received data frames (that are notified through those > HTT interfaces) from the PN/TSC and key_id information available > from rx descriptor of the first msdu of each mpdu. Skip setting > RX_FLAG_IV_STRIPPED flag for the packets which requires mac80211 > PN/TSC check support and set appropriate RX_FLAG for stripped > crypto tail. QCA988X, QCA9887, QCA99X0, QCA9984, QCA9888 and > QCA4019 currently need the rebuilding of cipher header to perform > PN/TSC check for replay attack. > > Signed-off-by: Vasanthakumar Thiagarajan > Signed-off-by: Kalle Valo > --- > drivers/net/wireless/ath/ath10k/htt_rx.c | 120 ++++++++++++++++++++++++++---- > 1 file changed, 104 insertions(+), 16 deletions(-) > > diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c > index a3f5dc78353f..9a070ad05179 100644 > --- a/drivers/net/wireless/ath/ath10k/htt_rx.c > +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c > @@ -995,8 +995,55 @@ static int ath10k_htt_rx_nwifi_hdrlen(struct ath10k *ar, > return len; > } > > +static void ath10k_htt_rx_build_crypto_hdr(struct ath10k *ar, > + struct sk_buff *msdu, > + struct htt_rx_desc *rxd, > + struct ieee80211_rx_status *status, > + enum htt_rx_mpdu_encrypt_type type) > +{ > + u8 *hdr; > + > + if (!(status->flag & RX_FLAG_DECRYPTED) || > + status->flag & RX_FLAG_IV_STRIPPED) > + return; > + > + switch (type) { > + case HTT_RX_MPDU_ENCRYPT_NONE: > + return; > + case HTT_RX_MPDU_ENCRYPT_WEP40: > + case HTT_RX_MPDU_ENCRYPT_WEP104: > + hdr = skb_push(msdu, IEEE80211_WEP_IV_LEN); > + memcpy(hdr, rxd->mpdu_start.pn, IEEE80211_WEP_IV_LEN - 1); > + hdr[3] = rxd->msdu_end.common.key_id_octet; > + return; > + case HTT_RX_MPDU_ENCRYPT_TKIP_WITHOUT_MIC: > + case HTT_RX_MPDU_ENCRYPT_TKIP_WPA: > + hdr = skb_push(msdu, IEEE80211_TKIP_IV_LEN); > + hdr[0] = rxd->mpdu_start.pn[1]; > + hdr[1] = 0; > + hdr[2] = rxd->mpdu_start.pn[0]; > + hdr[3] = 0x20 | (rxd->msdu_end.common.key_id_octet << 6); > + memcpy(hdr + 4, rxd->mpdu_start.pn + 2, 4); > + return; > + case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2: > + hdr = skb_push(msdu, IEEE80211_CCMP_HDR_LEN); > + memcpy(hdr, rxd->mpdu_start.pn, 2); > + hdr[2] = 0; > + hdr[3] = 0x20 | (rxd->msdu_end.common.key_id_octet << 6); > + memcpy(hdr + 4, rxd->mpdu_start.pn + 2, 4); > + return; > + case HTT_RX_MPDU_ENCRYPT_WEP128: > + case HTT_RX_MPDU_ENCRYPT_WAPI: > + return; > + default: > + ath10k_warn(ar, "unsupported encryption type %d\n", type); > + return; > + } > +} > + > static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar, > struct sk_buff *msdu, > + struct htt_rx_desc *first_rxd, > struct ieee80211_rx_status *status, > enum htt_rx_mpdu_encrypt_type enctype, > bool is_decrypted) > @@ -1050,8 +1097,14 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar, > > hdr = (void *)msdu->data; > > - /* Tail */ > - if (status->flag & RX_FLAG_IV_STRIPPED) > + /* MIC */ > + if ((status->flag & RX_FLAG_MIC_STRIPPED) && > + enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2) > + skb_trim(msdu, msdu->len - 8); > + > + /* ICV */ > + if (status->flag & RX_FLAG_ICV_STRIPPED && > + enctype != HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2) > skb_trim(msdu, msdu->len - > ath10k_htt_rx_crypto_tail_len(ar, enctype)); > > @@ -1075,7 +1128,9 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar, > static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar, > struct sk_buff *msdu, > struct ieee80211_rx_status *status, > - const u8 first_hdr[64]) > + struct htt_rx_desc *first_rxd, > + const u8 first_hdr[64], > + enum htt_rx_mpdu_encrypt_type enctype) > { > struct ieee80211_hdr *hdr; > struct htt_rx_desc *rxd; > @@ -1108,6 +1163,8 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar, > ether_addr_copy(sa, ieee80211_get_SA(hdr)); > skb_pull(msdu, hdr_len); > > + ath10k_htt_rx_build_crypto_hdr(ar, msdu, first_rxd, status, enctype); > + > /* push original 802.11 header */ > hdr = (struct ieee80211_hdr *)first_hdr; > hdr_len = ieee80211_hdrlen(hdr->frame_control); > @@ -1160,6 +1217,7 @@ static void *ath10k_htt_rx_h_find_rfc1042(struct ath10k *ar, > static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar, > struct sk_buff *msdu, > struct ieee80211_rx_status *status, > + struct htt_rx_desc *first_rxd, > const u8 first_hdr[64], > enum htt_rx_mpdu_encrypt_type enctype) > { > @@ -1196,6 +1254,8 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar, > memcpy(skb_push(msdu, sizeof(struct rfc1042_hdr)), rfc1042, > sizeof(struct rfc1042_hdr)); > > + ath10k_htt_rx_build_crypto_hdr(ar, msdu, first_rxd, status, enctype); > + > /* push original 802.11 header */ > hdr = (struct ieee80211_hdr *)first_hdr; > hdr_len = ieee80211_hdrlen(hdr->frame_control); > @@ -1212,7 +1272,9 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar, > static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar, > struct sk_buff *msdu, > struct ieee80211_rx_status *status, > - const u8 first_hdr[64]) > + struct htt_rx_desc *first_rxd, > + const u8 first_hdr[64], > + enum htt_rx_mpdu_encrypt_type enctype) > { > struct ieee80211_hdr *hdr; > size_t hdr_len; > @@ -1231,6 +1293,8 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar, > skb_put(msdu, l3_pad_bytes); > skb_pull(msdu, sizeof(struct amsdu_subframe_hdr) + l3_pad_bytes); > > + ath10k_htt_rx_build_crypto_hdr(ar, msdu, first_rxd, status, enctype); > + > hdr = (struct ieee80211_hdr *)first_hdr; > hdr_len = ieee80211_hdrlen(hdr->frame_control); > memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); > @@ -1240,6 +1304,7 @@ static void ath10k_htt_rx_h_undecap(struct ath10k *ar, > struct sk_buff *msdu, > struct ieee80211_rx_status *status, > u8 first_hdr[64], > + struct htt_rx_desc *first_rxd, > enum htt_rx_mpdu_encrypt_type enctype, > bool is_decrypted) > { > @@ -1263,17 +1328,20 @@ static void ath10k_htt_rx_h_undecap(struct ath10k *ar, > > switch (decap) { > case RX_MSDU_DECAP_RAW: > - ath10k_htt_rx_h_undecap_raw(ar, msdu, status, enctype, > - is_decrypted); > + ath10k_htt_rx_h_undecap_raw(ar, msdu, first_rxd, status, > + enctype, is_decrypted); > break; > case RX_MSDU_DECAP_NATIVE_WIFI: > - ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr); > + ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_rxd, > + first_hdr, enctype); > break; > case RX_MSDU_DECAP_ETHERNET2_DIX: > - ath10k_htt_rx_h_undecap_eth(ar, msdu, status, first_hdr, enctype); > + ath10k_htt_rx_h_undecap_eth(ar, msdu, status, first_rxd, > + first_hdr, enctype); > break; > case RX_MSDU_DECAP_8023_SNAP_LLC: > - ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr); > + ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_rxd, > + first_hdr, enctype); > break; > } > } > @@ -1316,7 +1384,8 @@ static void ath10k_htt_rx_h_csum_offload(struct sk_buff *msdu) > > static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, > struct sk_buff_head *amsdu, > - struct ieee80211_rx_status *status) > + struct ieee80211_rx_status *status, > + bool fill_crypt_header) > { > struct sk_buff *first; > struct sk_buff *last; > @@ -1406,14 +1475,20 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, > status->flag |= RX_FLAG_DECRYPTED; > > if (likely(!is_mgmt)) > - status->flag |= RX_FLAG_IV_STRIPPED | > - RX_FLAG_MMIC_STRIPPED; > + status->flag |= RX_FLAG_MMIC_STRIPPED; > + > + if (fill_crypt_header) > + status->flag |= RX_FLAG_MIC_STRIPPED | > + RX_FLAG_ICV_STRIPPED; > + else > + status->flag |= RX_FLAG_IV_STRIPPED; > } > > skb_queue_walk(amsdu, msdu) { > ath10k_htt_rx_h_csum_offload(msdu); > - ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype, > - is_decrypted); > + ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, > + (void *)first->data - sizeof(*rxd), > + enctype, is_decrypted); > > /* Undecapping involves copying the original 802.11 header back > * to sk_buff. If frame is protected and hardware has decrypted > @@ -1424,6 +1499,9 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, > if (is_mgmt) > continue; > > + if (fill_crypt_header) > + continue; > + > hdr = (void *)msdu->data; > hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); > } > @@ -1434,6 +1512,9 @@ static void ath10k_htt_rx_h_deliver(struct ath10k *ar, > struct ieee80211_rx_status *status) > { > struct sk_buff *msdu; > + struct sk_buff *first_subframe; > + > + first_subframe = skb_peek(amsdu); > > while ((msdu = __skb_dequeue(amsdu))) { > /* Setup per-MSDU flags */ > @@ -1442,6 +1523,13 @@ static void ath10k_htt_rx_h_deliver(struct ath10k *ar, > else > status->flag |= RX_FLAG_AMSDU_MORE; > > + if (msdu == first_subframe) { > + first_subframe = NULL; > + status->flag &= ~RX_FLAG_ALLOW_SAME_PN; > + } else { > + status->flag |= RX_FLAG_ALLOW_SAME_PN; > + } > + > ath10k_process_rx(ar, status, msdu); > } > } > @@ -1584,7 +1672,7 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) > ath10k_htt_rx_h_unchain(ar, &amsdu); > > ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); > - ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); > + ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true); > ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); > > return num_msdus; > @@ -1923,7 +2011,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb, > budget_left -= skb_queue_len(&amsdu); > ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id); > ath10k_htt_rx_h_filter(ar, &amsdu, status); > - ath10k_htt_rx_h_mpdu(ar, &amsdu, status); > + ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false); > ath10k_htt_rx_h_deliver(ar, &amsdu, status); > break; > case -EAGAIN: > > -- Mit freundlichen Grüssen / Regards Sebastian Gottschall / CTO NewMedia-NET GmbH - DD-WRT Firmensitz: Stubenwaldallee 21a, 64625 Bensheim Registergericht: Amtsgericht Darmstadt, HRB 25473 Geschäftsführer: Peter Steinhäuser, Christian Scheele http://www.dd-wrt.com email: s.gottschall@dd-wrt.com Tel.: +496251-582650 / Fax: +496251-5826565 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from smtps.newmedia-net.de ([2a05:a1c0:0:de::167] helo=webmail.newmedia-net.de) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1e5dDE-00078t-CB for ath10k@lists.infradead.org; Fri, 20 Oct 2017 19:44:12 +0000 Subject: Re: [PATCH] ath10k: rebuild crypto header in RX data frames References: <150851690590.5158.11970481736247725763.stgit@potku.adurom.net> From: Sebastian Gottschall Message-ID: <5ccfddbf-5b23-8750-17a4-cf96284dbde0@dd-wrt.com> Date: Fri, 20 Oct 2017 21:43:35 +0200 MIME-Version: 1.0 In-Reply-To: <150851690590.5158.11970481736247725763.stgit@potku.adurom.net> 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: "ath10k" Errors-To: ath10k-bounces+kvalo=adurom.com@lists.infradead.org To: Kalle Valo , ath10k@lists.infradead.org Cc: linux-wireless@vger.kernel.org bWF5YmUgdGhpcyBzbWFsbCBwYXRjaCBoaW50IGhlcmUgc2hvdWxkIGhlbHAgdG8gbWFrZSB0aGlz IHBhdGNoIGJldHRlcgoKLS0tIHJ4X2Rlc2MuaMKgwqAgKHJldmlzaW9uIDM2NTUpCisrKyByeF9k ZXNjLmjCoMKgICh3b3JraW5nIGNvcHkpCkBAIC0yMzksNiArMjM5LDkgQEAKIMKgwqDCoMKgwqDC oMKgIEhUVF9SWF9NUERVX0VOQ1JZUFRfV0FQScKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCA9IDUs CiDCoMKgwqDCoMKgwqDCoCBIVFRfUlhfTVBEVV9FTkNSWVBUX0FFU19DQ01fV1BBMsKgwqDCoMKg ID0gNiwKIMKgwqDCoMKgwqDCoMKgIEhUVF9SWF9NUERVX0VOQ1JZUFRfTk9ORcKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoCA9IDcsCivCoMKgwqDCoMKgwqAgSFRUX1JYX01QRFVfRU5DUllQVF9BRVNf Q0NNUF8yNTbCoMKgwqDCoCA9IDgsCivCoMKgwqDCoMKgwqAgSFRUX1JYX01QRFVfRU5DUllQVF9B RVNfR0NNUF8xMjjCoMKgwqDCoCA9IDksCivCoMKgwqDCoMKgwqAgSFRUX1JYX01QRFVfRU5DUllQ VF9BRVNfR0NNUF8yNTbCoMKgwqDCoCA9IDEwLAoKQW0gMjAuMTAuMjAxNyB1bSAxODoyOCBzY2hy aWViIEthbGxlIFZhbG86Cj4gRnJvbTogVmFzYW50aGFrdW1hciBUaGlhZ2FyYWphbiA8dnRoaWFn YXJAcXRpLnF1YWxjb21tLmNvbT4KPgo+IFJYIGRhdGEgZnJhbWVzIG5vdGlmaWVkIHRocm91Z2gg SFRUX1QySF9NU0dfVFlQRV9SWF9JTkQgYW5kCj4gSFRUX1QySF9NU0dfVFlQRV9SWF9GUkFHX0lO RCBleHBlY3QgUE4vVFNDIGNoZWNrIHRvIGJlIGRvbmUKPiBvbiBob3N0IChtYWM4MDIxMSkgcmF0 aGVyIHRoYW4gZmlybXdhcmUuIFJlYnVpbGQgY2lwaGVyIGhlYWRlcgo+IGluIGV2ZXJ5IHJlY2Vp dmVkIGRhdGEgZnJhbWVzICh0aGF0IGFyZSBub3RpZmllZCB0aHJvdWdoIHRob3NlCj4gSFRUIGlu dGVyZmFjZXMpIGZyb20gdGhlIFBOL1RTQyBhbmQga2V5X2lkIGluZm9ybWF0aW9uIGF2YWlsYWJs ZQo+IGZyb20gcnggZGVzY3JpcHRvciBvZiB0aGUgZmlyc3QgbXNkdSBvZiBlYWNoIG1wZHUuIFNr aXAgc2V0dGluZwo+IFJYX0ZMQUdfSVZfU1RSSVBQRUQgZmxhZyBmb3IgdGhlIHBhY2tldHMgd2hp Y2ggcmVxdWlyZXMgbWFjODAyMTEKPiBQTi9UU0MgY2hlY2sgc3VwcG9ydCBhbmQgc2V0IGFwcHJv cHJpYXRlIFJYX0ZMQUcgZm9yIHN0cmlwcGVkCj4gY3J5cHRvIHRhaWwuIFFDQTk4OFgsIFFDQTk4 ODcsIFFDQTk5WDAsIFFDQTk5ODQsIFFDQTk4ODggYW5kCj4gUUNBNDAxOSBjdXJyZW50bHkgbmVl ZCB0aGUgcmVidWlsZGluZyBvZiBjaXBoZXIgaGVhZGVyIHRvIHBlcmZvcm0KPiBQTi9UU0MgY2hl Y2sgZm9yIHJlcGxheSBhdHRhY2suCj4KPiBTaWduZWQtb2ZmLWJ5OiBWYXNhbnRoYWt1bWFyIFRo aWFnYXJhamFuIDx2dGhpYWdhckBxdGkucXVhbGNvbW0uY29tPgo+IFNpZ25lZC1vZmYtYnk6IEth bGxlIFZhbG8gPGt2YWxvQHFjYS5xdWFsY29tbS5jb20+Cj4gLS0tCj4gICBkcml2ZXJzL25ldC93 aXJlbGVzcy9hdGgvYXRoMTBrL2h0dF9yeC5jIHwgIDEyMCArKysrKysrKysrKysrKysrKysrKysr KysrKy0tLS0KPiAgIDEgZmlsZSBjaGFuZ2VkLCAxMDQgaW5zZXJ0aW9ucygrKSwgMTYgZGVsZXRp b25zKC0pCj4KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvd2lyZWxlc3MvYXRoL2F0aDEway9o dHRfcnguYyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2F0aC9hdGgxMGsvaHR0X3J4LmMKPiBpbmRl eCBhM2Y1ZGM3ODM1M2YuLjlhMDcwYWQwNTE3OSAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL25ldC93 aXJlbGVzcy9hdGgvYXRoMTBrL2h0dF9yeC5jCj4gKysrIGIvZHJpdmVycy9uZXQvd2lyZWxlc3Mv YXRoL2F0aDEway9odHRfcnguYwo+IEBAIC05OTUsOCArOTk1LDU1IEBAIHN0YXRpYyBpbnQgYXRo MTBrX2h0dF9yeF9ud2lmaV9oZHJsZW4oc3RydWN0IGF0aDEwayAqYXIsCj4gICAJcmV0dXJuIGxl bjsKPiAgIH0KPiAgIAo+ICtzdGF0aWMgdm9pZCBhdGgxMGtfaHR0X3J4X2J1aWxkX2NyeXB0b19o ZHIoc3RydWN0IGF0aDEwayAqYXIsCj4gKwkJCQkJICAgc3RydWN0IHNrX2J1ZmYgKm1zZHUsCj4g KwkJCQkJICAgc3RydWN0IGh0dF9yeF9kZXNjICpyeGQsCj4gKwkJCQkJICAgc3RydWN0IGllZWU4 MDIxMV9yeF9zdGF0dXMgKnN0YXR1cywKPiArCQkJCQkgICBlbnVtIGh0dF9yeF9tcGR1X2VuY3J5 cHRfdHlwZSB0eXBlKQo+ICt7Cj4gKwl1OCAqaGRyOwo+ICsKPiArCWlmICghKHN0YXR1cy0+Zmxh ZyAmIFJYX0ZMQUdfREVDUllQVEVEKSB8fAo+ICsJICAgIHN0YXR1cy0+ZmxhZyAmIFJYX0ZMQUdf SVZfU1RSSVBQRUQpCj4gKwkJcmV0dXJuOwo+ICsKPiArCXN3aXRjaCAodHlwZSkgewo+ICsJY2Fz ZSBIVFRfUlhfTVBEVV9FTkNSWVBUX05PTkU6Cj4gKwkJcmV0dXJuOwo+ICsJY2FzZSBIVFRfUlhf TVBEVV9FTkNSWVBUX1dFUDQwOgo+ICsJY2FzZSBIVFRfUlhfTVBEVV9FTkNSWVBUX1dFUDEwNDoK PiArCQloZHIgPSBza2JfcHVzaChtc2R1LCBJRUVFODAyMTFfV0VQX0lWX0xFTik7Cj4gKwkJbWVt Y3B5KGhkciwgcnhkLT5tcGR1X3N0YXJ0LnBuLCBJRUVFODAyMTFfV0VQX0lWX0xFTiAtIDEpOwo+ ICsJCWhkclszXSA9IHJ4ZC0+bXNkdV9lbmQuY29tbW9uLmtleV9pZF9vY3RldDsKPiArCQlyZXR1 cm47Cj4gKwljYXNlIEhUVF9SWF9NUERVX0VOQ1JZUFRfVEtJUF9XSVRIT1VUX01JQzoKPiArCWNh c2UgSFRUX1JYX01QRFVfRU5DUllQVF9US0lQX1dQQToKPiArCQloZHIgPSBza2JfcHVzaChtc2R1 LCBJRUVFODAyMTFfVEtJUF9JVl9MRU4pOwo+ICsJCWhkclswXSA9IHJ4ZC0+bXBkdV9zdGFydC5w blsxXTsKPiArCQloZHJbMV0gPSAwOwo+ICsJCWhkclsyXSA9IHJ4ZC0+bXBkdV9zdGFydC5wblsw XTsKPiArCQloZHJbM10gPSAweDIwIHwgKHJ4ZC0+bXNkdV9lbmQuY29tbW9uLmtleV9pZF9vY3Rl dCA8PCA2KTsKPiArCQltZW1jcHkoaGRyICsgNCwgcnhkLT5tcGR1X3N0YXJ0LnBuICsgMiwgNCk7 Cj4gKwkJcmV0dXJuOwo+ICsJY2FzZSBIVFRfUlhfTVBEVV9FTkNSWVBUX0FFU19DQ01fV1BBMjoK PiArCQloZHIgPSBza2JfcHVzaChtc2R1LCBJRUVFODAyMTFfQ0NNUF9IRFJfTEVOKTsKPiArCQlt ZW1jcHkoaGRyLCByeGQtPm1wZHVfc3RhcnQucG4sIDIpOwo+ICsJCWhkclsyXSA9IDA7Cj4gKwkJ aGRyWzNdID0gMHgyMCB8IChyeGQtPm1zZHVfZW5kLmNvbW1vbi5rZXlfaWRfb2N0ZXQgPDwgNik7 Cj4gKwkJbWVtY3B5KGhkciArIDQsIHJ4ZC0+bXBkdV9zdGFydC5wbiArIDIsIDQpOwo+ICsJCXJl dHVybjsKPiArCWNhc2UgSFRUX1JYX01QRFVfRU5DUllQVF9XRVAxMjg6Cj4gKwljYXNlIEhUVF9S WF9NUERVX0VOQ1JZUFRfV0FQSToKPiArCQlyZXR1cm47Cj4gKwlkZWZhdWx0Ogo+ICsJCWF0aDEw a193YXJuKGFyLCAidW5zdXBwb3J0ZWQgZW5jcnlwdGlvbiB0eXBlICVkXG4iLCB0eXBlKTsKPiAr CQlyZXR1cm47Cj4gKwl9Cj4gK30KPiArCj4gICBzdGF0aWMgdm9pZCBhdGgxMGtfaHR0X3J4X2hf dW5kZWNhcF9yYXcoc3RydWN0IGF0aDEwayAqYXIsCj4gICAJCQkJCXN0cnVjdCBza19idWZmICpt c2R1LAo+ICsJCQkJCXN0cnVjdCBodHRfcnhfZGVzYyAqZmlyc3RfcnhkLAo+ICAgCQkJCQlzdHJ1 Y3QgaWVlZTgwMjExX3J4X3N0YXR1cyAqc3RhdHVzLAo+ICAgCQkJCQllbnVtIGh0dF9yeF9tcGR1 X2VuY3J5cHRfdHlwZSBlbmN0eXBlLAo+ICAgCQkJCQlib29sIGlzX2RlY3J5cHRlZCkKPiBAQCAt MTA1MCw4ICsxMDk3LDE0IEBAIHN0YXRpYyB2b2lkIGF0aDEwa19odHRfcnhfaF91bmRlY2FwX3Jh dyhzdHJ1Y3QgYXRoMTBrICphciwKPiAgIAo+ICAgCWhkciA9ICh2b2lkICopbXNkdS0+ZGF0YTsK PiAgIAo+IC0JLyogVGFpbCAqLwo+IC0JaWYgKHN0YXR1cy0+ZmxhZyAmIFJYX0ZMQUdfSVZfU1RS SVBQRUQpCj4gKwkvKiBNSUMgKi8KPiArCWlmICgoc3RhdHVzLT5mbGFnICYgUlhfRkxBR19NSUNf U1RSSVBQRUQpICYmCj4gKwkgICAgZW5jdHlwZSA9PSBIVFRfUlhfTVBEVV9FTkNSWVBUX0FFU19D Q01fV1BBMikKPiArCQlza2JfdHJpbShtc2R1LCBtc2R1LT5sZW4gLSA4KTsKPiArCj4gKwkvKiBJ Q1YgKi8KPiArCWlmIChzdGF0dXMtPmZsYWcgJiBSWF9GTEFHX0lDVl9TVFJJUFBFRCAmJgo+ICsJ ICAgIGVuY3R5cGUgIT0gSFRUX1JYX01QRFVfRU5DUllQVF9BRVNfQ0NNX1dQQTIpCj4gICAJCXNr Yl90cmltKG1zZHUsIG1zZHUtPmxlbiAtCj4gICAJCQkgYXRoMTBrX2h0dF9yeF9jcnlwdG9fdGFp bF9sZW4oYXIsIGVuY3R5cGUpKTsKPiAgIAo+IEBAIC0xMDc1LDcgKzExMjgsOSBAQCBzdGF0aWMg dm9pZCBhdGgxMGtfaHR0X3J4X2hfdW5kZWNhcF9yYXcoc3RydWN0IGF0aDEwayAqYXIsCj4gICBz dGF0aWMgdm9pZCBhdGgxMGtfaHR0X3J4X2hfdW5kZWNhcF9ud2lmaShzdHJ1Y3QgYXRoMTBrICph ciwKPiAgIAkJCQkJICBzdHJ1Y3Qgc2tfYnVmZiAqbXNkdSwKPiAgIAkJCQkJICBzdHJ1Y3QgaWVl ZTgwMjExX3J4X3N0YXR1cyAqc3RhdHVzLAo+IC0JCQkJCSAgY29uc3QgdTggZmlyc3RfaGRyWzY0 XSkKPiArCQkJCQkgIHN0cnVjdCBodHRfcnhfZGVzYyAqZmlyc3RfcnhkLAo+ICsJCQkJCSAgY29u c3QgdTggZmlyc3RfaGRyWzY0XSwKPiArCQkJCQkgIGVudW0gaHR0X3J4X21wZHVfZW5jcnlwdF90 eXBlIGVuY3R5cGUpCj4gICB7Cj4gICAJc3RydWN0IGllZWU4MDIxMV9oZHIgKmhkcjsKPiAgIAlz dHJ1Y3QgaHR0X3J4X2Rlc2MgKnJ4ZDsKPiBAQCAtMTEwOCw2ICsxMTYzLDggQEAgc3RhdGljIHZv aWQgYXRoMTBrX2h0dF9yeF9oX3VuZGVjYXBfbndpZmkoc3RydWN0IGF0aDEwayAqYXIsCj4gICAJ ZXRoZXJfYWRkcl9jb3B5KHNhLCBpZWVlODAyMTFfZ2V0X1NBKGhkcikpOwo+ICAgCXNrYl9wdWxs KG1zZHUsIGhkcl9sZW4pOwo+ICAgCj4gKwlhdGgxMGtfaHR0X3J4X2J1aWxkX2NyeXB0b19oZHIo YXIsIG1zZHUsIGZpcnN0X3J4ZCwgc3RhdHVzLCBlbmN0eXBlKTsKPiArCj4gICAJLyogcHVzaCBv cmlnaW5hbCA4MDIuMTEgaGVhZGVyICovCj4gICAJaGRyID0gKHN0cnVjdCBpZWVlODAyMTFfaGRy ICopZmlyc3RfaGRyOwo+ICAgCWhkcl9sZW4gPSBpZWVlODAyMTFfaGRybGVuKGhkci0+ZnJhbWVf Y29udHJvbCk7Cj4gQEAgLTExNjAsNiArMTIxNyw3IEBAIHN0YXRpYyB2b2lkICphdGgxMGtfaHR0 X3J4X2hfZmluZF9yZmMxMDQyKHN0cnVjdCBhdGgxMGsgKmFyLAo+ICAgc3RhdGljIHZvaWQgYXRo MTBrX2h0dF9yeF9oX3VuZGVjYXBfZXRoKHN0cnVjdCBhdGgxMGsgKmFyLAo+ICAgCQkJCQlzdHJ1 Y3Qgc2tfYnVmZiAqbXNkdSwKPiAgIAkJCQkJc3RydWN0IGllZWU4MDIxMV9yeF9zdGF0dXMgKnN0 YXR1cywKPiArCQkJCQlzdHJ1Y3QgaHR0X3J4X2Rlc2MgKmZpcnN0X3J4ZCwKPiAgIAkJCQkJY29u c3QgdTggZmlyc3RfaGRyWzY0XSwKPiAgIAkJCQkJZW51bSBodHRfcnhfbXBkdV9lbmNyeXB0X3R5 cGUgZW5jdHlwZSkKPiAgIHsKPiBAQCAtMTE5Niw2ICsxMjU0LDggQEAgc3RhdGljIHZvaWQgYXRo MTBrX2h0dF9yeF9oX3VuZGVjYXBfZXRoKHN0cnVjdCBhdGgxMGsgKmFyLAo+ICAgCW1lbWNweShz a2JfcHVzaChtc2R1LCBzaXplb2Yoc3RydWN0IHJmYzEwNDJfaGRyKSksIHJmYzEwNDIsCj4gICAJ ICAgICAgIHNpemVvZihzdHJ1Y3QgcmZjMTA0Ml9oZHIpKTsKPiAgIAo+ICsJYXRoMTBrX2h0dF9y eF9idWlsZF9jcnlwdG9faGRyKGFyLCBtc2R1LCBmaXJzdF9yeGQsIHN0YXR1cywgZW5jdHlwZSk7 Cj4gKwo+ICAgCS8qIHB1c2ggb3JpZ2luYWwgODAyLjExIGhlYWRlciAqLwo+ICAgCWhkciA9IChz dHJ1Y3QgaWVlZTgwMjExX2hkciAqKWZpcnN0X2hkcjsKPiAgIAloZHJfbGVuID0gaWVlZTgwMjEx X2hkcmxlbihoZHItPmZyYW1lX2NvbnRyb2wpOwo+IEBAIC0xMjEyLDcgKzEyNzIsOSBAQCBzdGF0 aWMgdm9pZCBhdGgxMGtfaHR0X3J4X2hfdW5kZWNhcF9ldGgoc3RydWN0IGF0aDEwayAqYXIsCj4g ICBzdGF0aWMgdm9pZCBhdGgxMGtfaHR0X3J4X2hfdW5kZWNhcF9zbmFwKHN0cnVjdCBhdGgxMGsg KmFyLAo+ICAgCQkJCQkgc3RydWN0IHNrX2J1ZmYgKm1zZHUsCj4gICAJCQkJCSBzdHJ1Y3QgaWVl ZTgwMjExX3J4X3N0YXR1cyAqc3RhdHVzLAo+IC0JCQkJCSBjb25zdCB1OCBmaXJzdF9oZHJbNjRd KQo+ICsJCQkJCSBzdHJ1Y3QgaHR0X3J4X2Rlc2MgKmZpcnN0X3J4ZCwKPiArCQkJCQkgY29uc3Qg dTggZmlyc3RfaGRyWzY0XSwKPiArCQkJCQkgZW51bSBodHRfcnhfbXBkdV9lbmNyeXB0X3R5cGUg ZW5jdHlwZSkKPiAgIHsKPiAgIAlzdHJ1Y3QgaWVlZTgwMjExX2hkciAqaGRyOwo+ICAgCXNpemVf dCBoZHJfbGVuOwo+IEBAIC0xMjMxLDYgKzEyOTMsOCBAQCBzdGF0aWMgdm9pZCBhdGgxMGtfaHR0 X3J4X2hfdW5kZWNhcF9zbmFwKHN0cnVjdCBhdGgxMGsgKmFyLAo+ICAgCXNrYl9wdXQobXNkdSwg bDNfcGFkX2J5dGVzKTsKPiAgIAlza2JfcHVsbChtc2R1LCBzaXplb2Yoc3RydWN0IGFtc2R1X3N1 YmZyYW1lX2hkcikgKyBsM19wYWRfYnl0ZXMpOwo+ICAgCj4gKwlhdGgxMGtfaHR0X3J4X2J1aWxk X2NyeXB0b19oZHIoYXIsIG1zZHUsIGZpcnN0X3J4ZCwgc3RhdHVzLCBlbmN0eXBlKTsKPiArCj4g ICAJaGRyID0gKHN0cnVjdCBpZWVlODAyMTFfaGRyICopZmlyc3RfaGRyOwo+ICAgCWhkcl9sZW4g PSBpZWVlODAyMTFfaGRybGVuKGhkci0+ZnJhbWVfY29udHJvbCk7Cj4gICAJbWVtY3B5KHNrYl9w dXNoKG1zZHUsIGhkcl9sZW4pLCBoZHIsIGhkcl9sZW4pOwo+IEBAIC0xMjQwLDYgKzEzMDQsNyBA QCBzdGF0aWMgdm9pZCBhdGgxMGtfaHR0X3J4X2hfdW5kZWNhcChzdHJ1Y3QgYXRoMTBrICphciwK PiAgIAkJCQkgICAgc3RydWN0IHNrX2J1ZmYgKm1zZHUsCj4gICAJCQkJICAgIHN0cnVjdCBpZWVl ODAyMTFfcnhfc3RhdHVzICpzdGF0dXMsCj4gICAJCQkJICAgIHU4IGZpcnN0X2hkcls2NF0sCj4g KwkJCQkgICAgc3RydWN0IGh0dF9yeF9kZXNjICpmaXJzdF9yeGQsCj4gICAJCQkJICAgIGVudW0g aHR0X3J4X21wZHVfZW5jcnlwdF90eXBlIGVuY3R5cGUsCj4gICAJCQkJICAgIGJvb2wgaXNfZGVj cnlwdGVkKQo+ICAgewo+IEBAIC0xMjYzLDE3ICsxMzI4LDIwIEBAIHN0YXRpYyB2b2lkIGF0aDEw a19odHRfcnhfaF91bmRlY2FwKHN0cnVjdCBhdGgxMGsgKmFyLAo+ICAgCj4gICAJc3dpdGNoIChk ZWNhcCkgewo+ICAgCWNhc2UgUlhfTVNEVV9ERUNBUF9SQVc6Cj4gLQkJYXRoMTBrX2h0dF9yeF9o X3VuZGVjYXBfcmF3KGFyLCBtc2R1LCBzdGF0dXMsIGVuY3R5cGUsCj4gLQkJCQkJICAgIGlzX2Rl Y3J5cHRlZCk7Cj4gKwkJYXRoMTBrX2h0dF9yeF9oX3VuZGVjYXBfcmF3KGFyLCBtc2R1LCBmaXJz dF9yeGQsIHN0YXR1cywKPiArCQkJCQkgICAgZW5jdHlwZSwgaXNfZGVjcnlwdGVkKTsKPiAgIAkJ YnJlYWs7Cj4gICAJY2FzZSBSWF9NU0RVX0RFQ0FQX05BVElWRV9XSUZJOgo+IC0JCWF0aDEwa19o dHRfcnhfaF91bmRlY2FwX253aWZpKGFyLCBtc2R1LCBzdGF0dXMsIGZpcnN0X2hkcik7Cj4gKwkJ YXRoMTBrX2h0dF9yeF9oX3VuZGVjYXBfbndpZmkoYXIsIG1zZHUsIHN0YXR1cywgZmlyc3Rfcnhk LAo+ICsJCQkJCSAgICAgIGZpcnN0X2hkciwgZW5jdHlwZSk7Cj4gICAJCWJyZWFrOwo+ICAgCWNh c2UgUlhfTVNEVV9ERUNBUF9FVEhFUk5FVDJfRElYOgo+IC0JCWF0aDEwa19odHRfcnhfaF91bmRl Y2FwX2V0aChhciwgbXNkdSwgc3RhdHVzLCBmaXJzdF9oZHIsIGVuY3R5cGUpOwo+ICsJCWF0aDEw a19odHRfcnhfaF91bmRlY2FwX2V0aChhciwgbXNkdSwgc3RhdHVzLCBmaXJzdF9yeGQsCj4gKwkJ CQkJICAgIGZpcnN0X2hkciwgZW5jdHlwZSk7Cj4gICAJCWJyZWFrOwo+ICAgCWNhc2UgUlhfTVNE VV9ERUNBUF84MDIzX1NOQVBfTExDOgo+IC0JCWF0aDEwa19odHRfcnhfaF91bmRlY2FwX3NuYXAo YXIsIG1zZHUsIHN0YXR1cywgZmlyc3RfaGRyKTsKPiArCQlhdGgxMGtfaHR0X3J4X2hfdW5kZWNh cF9zbmFwKGFyLCBtc2R1LCBzdGF0dXMsIGZpcnN0X3J4ZCwKPiArCQkJCQkgICAgIGZpcnN0X2hk ciwgZW5jdHlwZSk7Cj4gICAJCWJyZWFrOwo+ICAgCX0KPiAgIH0KPiBAQCAtMTMxNiw3ICsxMzg0 LDggQEAgc3RhdGljIHZvaWQgYXRoMTBrX2h0dF9yeF9oX2NzdW1fb2ZmbG9hZChzdHJ1Y3Qgc2tf YnVmZiAqbXNkdSkKPiAgIAo+ICAgc3RhdGljIHZvaWQgYXRoMTBrX2h0dF9yeF9oX21wZHUoc3Ry dWN0IGF0aDEwayAqYXIsCj4gICAJCQkJIHN0cnVjdCBza19idWZmX2hlYWQgKmFtc2R1LAo+IC0J CQkJIHN0cnVjdCBpZWVlODAyMTFfcnhfc3RhdHVzICpzdGF0dXMpCj4gKwkJCQkgc3RydWN0IGll ZWU4MDIxMV9yeF9zdGF0dXMgKnN0YXR1cywKPiArCQkJCSBib29sIGZpbGxfY3J5cHRfaGVhZGVy KQo+ICAgewo+ICAgCXN0cnVjdCBza19idWZmICpmaXJzdDsKPiAgIAlzdHJ1Y3Qgc2tfYnVmZiAq bGFzdDsKPiBAQCAtMTQwNiwxNCArMTQ3NSwyMCBAQCBzdGF0aWMgdm9pZCBhdGgxMGtfaHR0X3J4 X2hfbXBkdShzdHJ1Y3QgYXRoMTBrICphciwKPiAgIAkJc3RhdHVzLT5mbGFnIHw9IFJYX0ZMQUdf REVDUllQVEVEOwo+ICAgCj4gICAJCWlmIChsaWtlbHkoIWlzX21nbXQpKQo+IC0JCQlzdGF0dXMt PmZsYWcgfD0gUlhfRkxBR19JVl9TVFJJUFBFRCB8Cj4gLQkJCQkJUlhfRkxBR19NTUlDX1NUUklQ UEVEOwo+ICsJCQlzdGF0dXMtPmZsYWcgfD0gUlhfRkxBR19NTUlDX1NUUklQUEVEOwo+ICsKPiAr CQlpZiAoZmlsbF9jcnlwdF9oZWFkZXIpCj4gKwkJCXN0YXR1cy0+ZmxhZyB8PSBSWF9GTEFHX01J Q19TVFJJUFBFRCB8Cj4gKwkJCQkJUlhfRkxBR19JQ1ZfU1RSSVBQRUQ7Cj4gKwkJZWxzZQo+ICsJ CQlzdGF0dXMtPmZsYWcgfD0gUlhfRkxBR19JVl9TVFJJUFBFRDsKPiAgIH0KPiAgIAo+ICAgCXNr Yl9xdWV1ZV93YWxrKGFtc2R1LCBtc2R1KSB7Cj4gICAJCWF0aDEwa19odHRfcnhfaF9jc3VtX29m ZmxvYWQobXNkdSk7Cj4gLQkJYXRoMTBrX2h0dF9yeF9oX3VuZGVjYXAoYXIsIG1zZHUsIHN0YXR1 cywgZmlyc3RfaGRyLCBlbmN0eXBlLAo+IC0JCQkJCWlzX2RlY3J5cHRlZCk7Cj4gKwkJYXRoMTBr X2h0dF9yeF9oX3VuZGVjYXAoYXIsIG1zZHUsIHN0YXR1cywgZmlyc3RfaGRyLAo+ICsJCQkJCSh2 b2lkICopZmlyc3QtPmRhdGEgLSBzaXplb2YoKnJ4ZCksCj4gKwkJCQkJZW5jdHlwZSwgaXNfZGVj cnlwdGVkKTsKPiAgIAo+ICAgCQkvKiBVbmRlY2FwcGluZyBpbnZvbHZlcyBjb3B5aW5nIHRoZSBv cmlnaW5hbCA4MDIuMTEgaGVhZGVyIGJhY2sKPiAgIAkJICogdG8gc2tfYnVmZi4gSWYgZnJhbWUg aXMgcHJvdGVjdGVkIGFuZCBoYXJkd2FyZSBoYXMgZGVjcnlwdGVkCj4gQEAgLTE0MjQsNiArMTQ5 OSw5IEBAIHN0YXRpYyB2b2lkIGF0aDEwa19odHRfcnhfaF9tcGR1KHN0cnVjdCBhdGgxMGsgKmFy LAo+ICAgCQlpZiAoaXNfbWdtdCkKPiAgIAkJCWNvbnRpbnVlOwo+ICAgCj4gKwkJaWYgKGZpbGxf Y3J5cHRfaGVhZGVyKQo+ICsJCQljb250aW51ZTsKPiArCj4gICAJCWhkciA9ICh2b2lkICopbXNk dS0+ZGF0YTsKPiAgIAkJaGRyLT5mcmFtZV9jb250cm9sICY9IH5fX2NwdV90b19sZTE2KElFRUU4 MDIxMV9GQ1RMX1BST1RFQ1RFRCk7Cj4gICAJfQo+IEBAIC0xNDM0LDYgKzE1MTIsOSBAQCBzdGF0 aWMgdm9pZCBhdGgxMGtfaHR0X3J4X2hfZGVsaXZlcihzdHJ1Y3QgYXRoMTBrICphciwKPiAgIAkJ CQkgICAgc3RydWN0IGllZWU4MDIxMV9yeF9zdGF0dXMgKnN0YXR1cykKPiAgIHsKPiAgIAlzdHJ1 Y3Qgc2tfYnVmZiAqbXNkdTsKPiArCXN0cnVjdCBza19idWZmICpmaXJzdF9zdWJmcmFtZTsKPiAr Cj4gKwlmaXJzdF9zdWJmcmFtZSA9IHNrYl9wZWVrKGFtc2R1KTsKPiAgIAo+ICAgCXdoaWxlICgo bXNkdSA9IF9fc2tiX2RlcXVldWUoYW1zZHUpKSkgewo+ICAgCQkvKiBTZXR1cCBwZXItTVNEVSBm bGFncyAqLwo+IEBAIC0xNDQyLDYgKzE1MjMsMTMgQEAgc3RhdGljIHZvaWQgYXRoMTBrX2h0dF9y eF9oX2RlbGl2ZXIoc3RydWN0IGF0aDEwayAqYXIsCj4gICAJCWVsc2UKPiAgIAkJCXN0YXR1cy0+ ZmxhZyB8PSBSWF9GTEFHX0FNU0RVX01PUkU7Cj4gICAKPiArCQlpZiAobXNkdSA9PSBmaXJzdF9z dWJmcmFtZSkgewo+ICsJCQlmaXJzdF9zdWJmcmFtZSA9IE5VTEw7Cj4gKwkJCXN0YXR1cy0+Zmxh ZyAmPSB+UlhfRkxBR19BTExPV19TQU1FX1BOOwo+ICsJCX0gZWxzZSB7Cj4gKwkJCXN0YXR1cy0+ ZmxhZyB8PSBSWF9GTEFHX0FMTE9XX1NBTUVfUE47Cj4gKwkJfQo+ICsKPiAgIAkJYXRoMTBrX3By b2Nlc3NfcngoYXIsIHN0YXR1cywgbXNkdSk7Cj4gICAJfQo+ICAgfQo+IEBAIC0xNTg0LDcgKzE2 NzIsNyBAQCBzdGF0aWMgaW50IGF0aDEwa19odHRfcnhfaGFuZGxlX2Ftc2R1KHN0cnVjdCBhdGgx MGtfaHR0ICpodHQpCj4gICAJCWF0aDEwa19odHRfcnhfaF91bmNoYWluKGFyLCAmYW1zZHUpOwo+ ICAgCj4gICAJYXRoMTBrX2h0dF9yeF9oX2ZpbHRlcihhciwgJmFtc2R1LCByeF9zdGF0dXMpOwo+ IC0JYXRoMTBrX2h0dF9yeF9oX21wZHUoYXIsICZhbXNkdSwgcnhfc3RhdHVzKTsKPiArCWF0aDEw a19odHRfcnhfaF9tcGR1KGFyLCAmYW1zZHUsIHJ4X3N0YXR1cywgdHJ1ZSk7Cj4gICAJYXRoMTBr X2h0dF9yeF9oX2RlbGl2ZXIoYXIsICZhbXNkdSwgcnhfc3RhdHVzKTsKPiAgIAo+ICAgCXJldHVy biBudW1fbXNkdXM7Cj4gQEAgLTE5MjMsNyArMjAxMSw3IEBAIHN0YXRpYyBpbnQgYXRoMTBrX2h0 dF9yeF9pbl9vcmRfaW5kKHN0cnVjdCBhdGgxMGsgKmFyLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiLAo+ ICAgCQkJYnVkZ2V0X2xlZnQgLT0gc2tiX3F1ZXVlX2xlbigmYW1zZHUpOwo+ICAgCQkJYXRoMTBr X2h0dF9yeF9oX3BwZHUoYXIsICZhbXNkdSwgc3RhdHVzLCB2ZGV2X2lkKTsKPiAgIAkJCWF0aDEw a19odHRfcnhfaF9maWx0ZXIoYXIsICZhbXNkdSwgc3RhdHVzKTsKPiAtCQkJYXRoMTBrX2h0dF9y eF9oX21wZHUoYXIsICZhbXNkdSwgc3RhdHVzKTsKPiArCQkJYXRoMTBrX2h0dF9yeF9oX21wZHUo YXIsICZhbXNkdSwgc3RhdHVzLCBmYWxzZSk7Cj4gICAJCQlhdGgxMGtfaHR0X3J4X2hfZGVsaXZl cihhciwgJmFtc2R1LCBzdGF0dXMpOwo+ICAgCQkJYnJlYWs7Cj4gICAJCWNhc2UgLUVBR0FJTjoK Pgo+CgotLSAKTWl0IGZyZXVuZGxpY2hlbiBHcsO8c3NlbiAvIFJlZ2FyZHMKClNlYmFzdGlhbiBH b3R0c2NoYWxsIC8gQ1RPCgpOZXdNZWRpYS1ORVQgR21iSCAtIERELVdSVApGaXJtZW5zaXR6OiAg U3R1YmVud2FsZGFsbGVlIDIxYSwgNjQ2MjUgQmVuc2hlaW0KUmVnaXN0ZXJnZXJpY2h0OiBBbXRz Z2VyaWNodCBEYXJtc3RhZHQsIEhSQiAyNTQ3MwpHZXNjaMOkZnRzZsO8aHJlcjogUGV0ZXIgU3Rl aW5ow6R1c2VyLCBDaHJpc3RpYW4gU2NoZWVsZQpodHRwOi8vd3d3LmRkLXdydC5jb20KZW1haWw6 IHMuZ290dHNjaGFsbEBkZC13cnQuY29tClRlbC46ICs0OTYyNTEtNTgyNjUwIC8gRmF4OiArNDk2 MjUxLTU4MjY1NjUKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fXwphdGgxMGsgbWFpbGluZyBsaXN0CmF0aDEwa0BsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6 Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vYXRoMTBrCg==