From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jeff Layton Subject: Re: [PATCH v23 15/22] richacl: Check if an acl is equivalent to a file mode Date: Tue, 12 Jul 2016 07:39:34 -0400 Message-ID: <1468323574.7798.8.camel@redhat.com> References: <1467294433-3222-1-git-send-email-agruenba@redhat.com> <1467294433-3222-16-git-send-email-agruenba@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: Christoph Hellwig , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org To: Andreas Gruenbacher , Alexander Viro Return-path: In-Reply-To: <1467294433-3222-16-git-send-email-agruenba@redhat.com> Sender: linux-fsdevel-owner@vger.kernel.org List-Id: linux-cifs.vger.kernel.org On Thu, 2016-06-30 at 15:47 +0200, Andreas Gruenbacher wrote: > ACLs are considered equivalent to file modes if they only consist of > owner@, group@, and everyone@ entries, the owner@ permissions do not > depend on whether the owner is a member in the owning group, and no > inheritance flags are set.=C2=A0=C2=A0This test is used to avoid stor= ing richacls > if the acl can be computed from the file permission bits. >=20 > Signed-off-by: Andreas Gruenbacher > Reviewed-by: J. Bruce Fields > --- > =C2=A0fs/richacl.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0| 104 ++++++++++++++++++++++++++++++++++++++++++++= ++++ > =C2=A0include/linux/richacl.h |=C2=A0=C2=A0=C2=A01 + > =C2=A02 files changed, 105 insertions(+) >=20 > diff --git a/fs/richacl.c b/fs/richacl.c > index ba110a6..e8a383b 100644 > --- a/fs/richacl.c > +++ b/fs/richacl.c > @@ -618,3 +618,107 @@ richacl_chmod(struct inode *inode, umode_t mode= ) > =C2=A0 return retval; > =C2=A0} > =C2=A0EXPORT_SYMBOL(richacl_chmod); > + > +/** > + * richacl_equiv_mode=C2=A0=C2=A0-=C2=A0=C2=A0compute the mode equiv= alent of @acl > + * > + * An acl is considered equivalent to a file mode if it only consist= s of > + * owner@, group@, and everyone@ entries and the owner@ permissions = do not > + * depend on whether the owner is a member in the owning group. > + */ > +int > +richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) > +{ > + umode_t mode =3D *mode_p; > + > + /* > + =C2=A0* The RICHACE_DELETE_CHILD flag is meaningless for non-direct= ories, so > + =C2=A0* we ignore it. > + =C2=A0*/ > + unsigned int x =3D S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; > + struct { > + unsigned int allowed; > + unsigned int defined;=C2=A0=C2=A0/* allowed or denied */ > + } owner =3D { > + .defined =3D RICHACE_POSIX_ALWAYS_ALLOWED | > + =C2=A0=C2=A0=C2=A0RICHACE_POSIX_OWNER_ALLOWED=C2=A0=C2=A0| x, > + }, group =3D { > + .defined =3D RICHACE_POSIX_ALWAYS_ALLOWED | x, > + }, everyone =3D { > + .defined =3D RICHACE_POSIX_ALWAYS_ALLOWED | x, > + }; > + const struct richace *ace; > + > + if (acl->a_flags & ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED)) > + return -1; > + > + richacl_for_each_entry(ace, acl) { > + if (ace->e_flags & ~RICHACE_SPECIAL_WHO) > + return -1; > + > + if (richace_is_owner(ace) || richace_is_everyone(ace)) { > + x =3D ace->e_mask & ~owner.defined; > + if (richace_is_allow(ace)) { > + unsigned int group_denied =3D > + group.defined & ~group.allowed; > + > + if (x & group_denied) > + return -1; > + owner.allowed |=3D x; > + } else /* if (richace_is_deny(ace)) */ { > + if (x & group.allowed) > + return -1; > + } > + owner.defined |=3D x; > + > + if (richace_is_everyone(ace)) { > + x =3D ace->e_mask; > + if (richace_is_allow(ace)) { > + group.allowed |=3D > + x & ~group.defined; > + everyone.allowed |=3D > + x & ~everyone.defined; > + } > + group.defined |=3D x; > + everyone.defined |=3D x; > + } > + } else if (richace_is_group(ace)) { > + x =3D ace->e_mask & ~group.defined; > + if (richace_is_allow(ace)) > + group.allowed |=3D x; > + group.defined |=3D x; > + } else > + return -1; > + } > + > + if (group.allowed & ~owner.defined) > + return -1; > + > + if (acl->a_flags & RICHACL_MASKED) { > + if (acl->a_flags & RICHACL_WRITE_THROUGH) { > + owner.allowed =3D acl->a_owner_mask; > + everyone.allowed =3D acl->a_other_mask; > + } else { > + owner.allowed &=3D acl->a_owner_mask; > + everyone.allowed &=3D acl->a_other_mask; > + } > + group.allowed &=3D acl->a_group_mask; > + } > + > + mode =3D (mode & ~S_IRWXUGO) | > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(richacl_mask_to_mode(own= er.allowed) << 6) | > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(richacl_mask_to_mode(gro= up.allowed) << 3) | > + richacl_mask_to_mode(everyone.allowed); > + > + /* Mask flags we can ignore */ > + x =3D S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; > + > + if (((richacl_mode_to_mask(mode >> 6) ^ owner.allowed)=C2=A0=C2=A0=C2= =A0=C2=A0& ~x) || > + =C2=A0=C2=A0=C2=A0=C2=A0((richacl_mode_to_mask(mode >> 3) ^ group.a= llowed)=C2=A0=C2=A0=C2=A0=C2=A0& ~x) || > + =C2=A0=C2=A0=C2=A0=C2=A0((richacl_mode_to_mask(mode)=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0^ everyone.allowed) & ~x)) > + return -1; > + > + *mode_p =3D mode; > + return 0; > +} > +EXPORT_SYMBOL_GPL(richacl_equiv_mode); > diff --git a/include/linux/richacl.h b/include/linux/richacl.h > index db82fab..9212edb 100644 > --- a/include/linux/richacl.h > +++ b/include/linux/richacl.h > @@ -191,5 +191,6 @@ extern unsigned int richacl_want_to_mask(unsigned= int); > =C2=A0extern void richacl_compute_max_masks(struct richacl *); > =C2=A0extern int richacl_permission(struct inode *, const struct rich= acl *, int); > =C2=A0extern int richacl_chmod(struct inode *, umode_t); > +extern int richacl_equiv_mode(const struct richacl *, umode_t *); > =C2=A0 > =C2=A0#endif /* __RICHACL_H */ Reviewed-by: Jeff Layton -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel= " in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932983AbcGLLjm (ORCPT ); Tue, 12 Jul 2016 07:39:42 -0400 Received: from mail-qt0-f176.google.com ([209.85.216.176]:33519 "EHLO mail-qt0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753379AbcGLLjj (ORCPT ); Tue, 12 Jul 2016 07:39:39 -0400 Message-ID: <1468323574.7798.8.camel@redhat.com> Subject: Re: [PATCH v23 15/22] richacl: Check if an acl is equivalent to a file mode From: Jeff Layton To: Andreas Gruenbacher , Alexander Viro Cc: Christoph Hellwig , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Date: Tue, 12 Jul 2016 07:39:34 -0400 In-Reply-To: <1467294433-3222-16-git-send-email-agruenba@redhat.com> References: <1467294433-3222-1-git-send-email-agruenba@redhat.com> <1467294433-3222-16-git-send-email-agruenba@redhat.com> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.20.3 (3.20.3-1.fc24) Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 2016-06-30 at 15:47 +0200, Andreas Gruenbacher wrote: > ACLs are considered equivalent to file modes if they only consist of > owner@, group@, and everyone@ entries, the owner@ permissions do not > depend on whether the owner is a member in the owning group, and no > inheritance flags are set.  This test is used to avoid storing richacls > if the acl can be computed from the file permission bits. > > Signed-off-by: Andreas Gruenbacher > Reviewed-by: J. Bruce Fields > --- >  fs/richacl.c            | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ >  include/linux/richacl.h |   1 + >  2 files changed, 105 insertions(+) > > diff --git a/fs/richacl.c b/fs/richacl.c > index ba110a6..e8a383b 100644 > --- a/fs/richacl.c > +++ b/fs/richacl.c > @@ -618,3 +618,107 @@ richacl_chmod(struct inode *inode, umode_t mode) >   return retval; >  } >  EXPORT_SYMBOL(richacl_chmod); > + > +/** > + * richacl_equiv_mode  -  compute the mode equivalent of @acl > + * > + * An acl is considered equivalent to a file mode if it only consists of > + * owner@, group@, and everyone@ entries and the owner@ permissions do not > + * depend on whether the owner is a member in the owning group. > + */ > +int > +richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) > +{ > + umode_t mode = *mode_p; > + > + /* > +  * The RICHACE_DELETE_CHILD flag is meaningless for non-directories, so > +  * we ignore it. > +  */ > + unsigned int x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; > + struct { > + unsigned int allowed; > + unsigned int defined;  /* allowed or denied */ > + } owner = { > + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | > +    RICHACE_POSIX_OWNER_ALLOWED  | x, > + }, group = { > + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, > + }, everyone = { > + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, > + }; > + const struct richace *ace; > + > + if (acl->a_flags & ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED)) > + return -1; > + > + richacl_for_each_entry(ace, acl) { > + if (ace->e_flags & ~RICHACE_SPECIAL_WHO) > + return -1; > + > + if (richace_is_owner(ace) || richace_is_everyone(ace)) { > + x = ace->e_mask & ~owner.defined; > + if (richace_is_allow(ace)) { > + unsigned int group_denied = > + group.defined & ~group.allowed; > + > + if (x & group_denied) > + return -1; > + owner.allowed |= x; > + } else /* if (richace_is_deny(ace)) */ { > + if (x & group.allowed) > + return -1; > + } > + owner.defined |= x; > + > + if (richace_is_everyone(ace)) { > + x = ace->e_mask; > + if (richace_is_allow(ace)) { > + group.allowed |= > + x & ~group.defined; > + everyone.allowed |= > + x & ~everyone.defined; > + } > + group.defined |= x; > + everyone.defined |= x; > + } > + } else if (richace_is_group(ace)) { > + x = ace->e_mask & ~group.defined; > + if (richace_is_allow(ace)) > + group.allowed |= x; > + group.defined |= x; > + } else > + return -1; > + } > + > + if (group.allowed & ~owner.defined) > + return -1; > + > + if (acl->a_flags & RICHACL_MASKED) { > + if (acl->a_flags & RICHACL_WRITE_THROUGH) { > + owner.allowed = acl->a_owner_mask; > + everyone.allowed = acl->a_other_mask; > + } else { > + owner.allowed &= acl->a_owner_mask; > + everyone.allowed &= acl->a_other_mask; > + } > + group.allowed &= acl->a_group_mask; > + } > + > + mode = (mode & ~S_IRWXUGO) | > +        (richacl_mask_to_mode(owner.allowed) << 6) | > +        (richacl_mask_to_mode(group.allowed) << 3) | > + richacl_mask_to_mode(everyone.allowed); > + > + /* Mask flags we can ignore */ > + x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; > + > + if (((richacl_mode_to_mask(mode >> 6) ^ owner.allowed)    & ~x) || > +     ((richacl_mode_to_mask(mode >> 3) ^ group.allowed)    & ~x) || > +     ((richacl_mode_to_mask(mode)      ^ everyone.allowed) & ~x)) > + return -1; > + > + *mode_p = mode; > + return 0; > +} > +EXPORT_SYMBOL_GPL(richacl_equiv_mode); > diff --git a/include/linux/richacl.h b/include/linux/richacl.h > index db82fab..9212edb 100644 > --- a/include/linux/richacl.h > +++ b/include/linux/richacl.h > @@ -191,5 +191,6 @@ extern unsigned int richacl_want_to_mask(unsigned int); >  extern void richacl_compute_max_masks(struct richacl *); >  extern int richacl_permission(struct inode *, const struct richacl *, int); >  extern int richacl_chmod(struct inode *, umode_t); > +extern int richacl_equiv_mode(const struct richacl *, umode_t *); >   >  #endif /* __RICHACL_H */ Reviewed-by: Jeff Layton From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id CC7E67CA1 for ; Tue, 12 Jul 2016 06:39:41 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7CE34304043 for ; Tue, 12 Jul 2016 04:39:41 -0700 (PDT) Received: from mail-qt0-f171.google.com (mail-qt0-f171.google.com [209.85.216.171]) by cuda.sgi.com with ESMTP id NdKw1e7EdCcBSzPc (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 12 Jul 2016 04:39:38 -0700 (PDT) Received: by mail-qt0-f171.google.com with SMTP id w38so6258006qtb.0 for ; Tue, 12 Jul 2016 04:39:38 -0700 (PDT) Message-ID: <1468323574.7798.8.camel@redhat.com> Subject: Re: [PATCH v23 15/22] richacl: Check if an acl is equivalent to a file mode From: Jeff Layton Date: Tue, 12 Jul 2016 07:39:34 -0400 In-Reply-To: <1467294433-3222-16-git-send-email-agruenba@redhat.com> References: <1467294433-3222-1-git-send-email-agruenba@redhat.com> <1467294433-3222-16-git-send-email-agruenba@redhat.com> Mime-Version: 1.0 List-Id: XFS Filesystem from SGI List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: xfs-bounces@oss.sgi.com Sender: xfs-bounces@oss.sgi.com To: Andreas Gruenbacher , Alexander Viro Cc: "J. Bruce Fields" , linux-nfs@vger.kernel.org, Theodore Ts'o , linux-cifs@vger.kernel.org, linux-api@vger.kernel.org, Trond Myklebust , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Christoph Hellwig , Andreas Dilger , linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, Anna Schumaker T24gVGh1LCAyMDE2LTA2LTMwIGF0IDE1OjQ3ICswMjAwLCBBbmRyZWFzIEdydWVuYmFjaGVyIHdy b3RlOgo+IEFDTHMgYXJlIGNvbnNpZGVyZWQgZXF1aXZhbGVudCB0byBmaWxlIG1vZGVzIGlmIHRo ZXkgb25seSBjb25zaXN0IG9mCj4gb3duZXJALCBncm91cEAsIGFuZCBldmVyeW9uZUAgZW50cmll cywgdGhlIG93bmVyQCBwZXJtaXNzaW9ucyBkbyBub3QKPiBkZXBlbmQgb24gd2hldGhlciB0aGUg b3duZXIgaXMgYSBtZW1iZXIgaW4gdGhlIG93bmluZyBncm91cCwgYW5kIG5vCj4gaW5oZXJpdGFu Y2UgZmxhZ3MgYXJlIHNldC7CoMKgVGhpcyB0ZXN0IGlzIHVzZWQgdG8gYXZvaWQgc3RvcmluZyBy aWNoYWNscwo+IGlmIHRoZSBhY2wgY2FuIGJlIGNvbXB1dGVkIGZyb20gdGhlIGZpbGUgcGVybWlz c2lvbiBiaXRzLgo+IAo+IFNpZ25lZC1vZmYtYnk6IEFuZHJlYXMgR3J1ZW5iYWNoZXIgPGFncnVl bmJhQHJlZGhhdC5jb20+Cj4gUmV2aWV3ZWQtYnk6IEouIEJydWNlIEZpZWxkcyA8YmZpZWxkc0By ZWRoYXQuY29tPgo+IC0tLQo+IMKgZnMvcmljaGFjbC5jwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg fCAxMDQgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCj4g wqBpbmNsdWRlL2xpbnV4L3JpY2hhY2wuaCB8wqDCoMKgMSArCj4gwqAyIGZpbGVzIGNoYW5nZWQs IDEwNSBpbnNlcnRpb25zKCspCj4gCj4gZGlmZiAtLWdpdCBhL2ZzL3JpY2hhY2wuYyBiL2ZzL3Jp Y2hhY2wuYwo+IGluZGV4IGJhMTEwYTYuLmU4YTM4M2IgMTAwNjQ0Cj4gLS0tIGEvZnMvcmljaGFj bC5jCj4gKysrIGIvZnMvcmljaGFjbC5jCj4gQEAgLTYxOCwzICs2MTgsMTA3IEBAIHJpY2hhY2xf Y2htb2Qoc3RydWN0IGlub2RlICppbm9kZSwgdW1vZGVfdCBtb2RlKQo+IMKgCXJldHVybiByZXR2 YWw7Cj4gwqB9Cj4gwqBFWFBPUlRfU1lNQk9MKHJpY2hhY2xfY2htb2QpOwo+ICsKPiArLyoqCj4g KyAqIHJpY2hhY2xfZXF1aXZfbW9kZcKgwqAtwqDCoGNvbXB1dGUgdGhlIG1vZGUgZXF1aXZhbGVu dCBvZiBAYWNsCj4gKyAqCj4gKyAqIEFuIGFjbCBpcyBjb25zaWRlcmVkIGVxdWl2YWxlbnQgdG8g YSBmaWxlIG1vZGUgaWYgaXQgb25seSBjb25zaXN0cyBvZgo+ICsgKiBvd25lckAsIGdyb3VwQCwg YW5kIGV2ZXJ5b25lQCBlbnRyaWVzIGFuZCB0aGUgb3duZXJAIHBlcm1pc3Npb25zIGRvIG5vdAo+ ICsgKiBkZXBlbmQgb24gd2hldGhlciB0aGUgb3duZXIgaXMgYSBtZW1iZXIgaW4gdGhlIG93bmlu ZyBncm91cC4KPiArICovCj4gK2ludAo+ICtyaWNoYWNsX2VxdWl2X21vZGUoY29uc3Qgc3RydWN0 IHJpY2hhY2wgKmFjbCwgdW1vZGVfdCAqbW9kZV9wKQo+ICt7Cj4gKwl1bW9kZV90IG1vZGUgPSAq bW9kZV9wOwo+ICsKPiArCS8qCj4gKwnCoCogVGhlIFJJQ0hBQ0VfREVMRVRFX0NISUxEIGZsYWcg aXMgbWVhbmluZ2xlc3MgZm9yIG5vbi1kaXJlY3Rvcmllcywgc28KPiArCcKgKiB3ZSBpZ25vcmUg aXQuCj4gKwnCoCovCj4gKwl1bnNpZ25lZCBpbnQgeCA9IFNfSVNESVIobW9kZSkgPyAwIDogUklD SEFDRV9ERUxFVEVfQ0hJTEQ7Cj4gKwlzdHJ1Y3Qgewo+ICsJCXVuc2lnbmVkIGludCBhbGxvd2Vk Owo+ICsJCXVuc2lnbmVkIGludCBkZWZpbmVkO8KgwqAvKiBhbGxvd2VkIG9yIGRlbmllZCAqLwo+ ICsJfSBvd25lciA9IHsKPiArCQkuZGVmaW5lZCA9IFJJQ0hBQ0VfUE9TSVhfQUxXQVlTX0FMTE9X RUQgfAo+ICsJCQnCoMKgwqBSSUNIQUNFX1BPU0lYX09XTkVSX0FMTE9XRUTCoMKgfCB4LAo+ICsJ fSwgZ3JvdXAgPSB7Cj4gKwkJLmRlZmluZWQgPSBSSUNIQUNFX1BPU0lYX0FMV0FZU19BTExPV0VE IHwgeCwKPiArCX0sIGV2ZXJ5b25lID0gewo+ICsJCS5kZWZpbmVkID0gUklDSEFDRV9QT1NJWF9B TFdBWVNfQUxMT1dFRCB8IHgsCj4gKwl9Owo+ICsJY29uc3Qgc3RydWN0IHJpY2hhY2UgKmFjZTsK PiArCj4gKwlpZiAoYWNsLT5hX2ZsYWdzICYgfihSSUNIQUNMX1dSSVRFX1RIUk9VR0ggfCBSSUNI QUNMX01BU0tFRCkpCj4gKwkJcmV0dXJuIC0xOwo+ICsKPiArCXJpY2hhY2xfZm9yX2VhY2hfZW50 cnkoYWNlLCBhY2wpIHsKPiArCQlpZiAoYWNlLT5lX2ZsYWdzICYgflJJQ0hBQ0VfU1BFQ0lBTF9X SE8pCj4gKwkJCXJldHVybiAtMTsKPiArCj4gKwkJaWYgKHJpY2hhY2VfaXNfb3duZXIoYWNlKSB8 fCByaWNoYWNlX2lzX2V2ZXJ5b25lKGFjZSkpIHsKPiArCQkJeCA9IGFjZS0+ZV9tYXNrICYgfm93 bmVyLmRlZmluZWQ7Cj4gKwkJCWlmIChyaWNoYWNlX2lzX2FsbG93KGFjZSkpIHsKPiArCQkJCXVu c2lnbmVkIGludCBncm91cF9kZW5pZWQgPQo+ICsJCQkJCWdyb3VwLmRlZmluZWQgJiB+Z3JvdXAu YWxsb3dlZDsKPiArCj4gKwkJCQlpZiAoeCAmIGdyb3VwX2RlbmllZCkKPiArCQkJCQlyZXR1cm4g LTE7Cj4gKwkJCQlvd25lci5hbGxvd2VkIHw9IHg7Cj4gKwkJCX0gZWxzZSAvKiBpZiAocmljaGFj ZV9pc19kZW55KGFjZSkpICovIHsKPiArCQkJCWlmICh4ICYgZ3JvdXAuYWxsb3dlZCkKPiArCQkJ CQlyZXR1cm4gLTE7Cj4gKwkJCX0KPiArCQkJb3duZXIuZGVmaW5lZCB8PSB4Owo+ICsKPiArCQkJ aWYgKHJpY2hhY2VfaXNfZXZlcnlvbmUoYWNlKSkgewo+ICsJCQkJeCA9IGFjZS0+ZV9tYXNrOwo+ ICsJCQkJaWYgKHJpY2hhY2VfaXNfYWxsb3coYWNlKSkgewo+ICsJCQkJCWdyb3VwLmFsbG93ZWQg fD0KPiArCQkJCQkJeCAmIH5ncm91cC5kZWZpbmVkOwo+ICsJCQkJCWV2ZXJ5b25lLmFsbG93ZWQg fD0KPiArCQkJCQkJeCAmIH5ldmVyeW9uZS5kZWZpbmVkOwo+ICsJCQkJfQo+ICsJCQkJZ3JvdXAu ZGVmaW5lZCB8PSB4Owo+ICsJCQkJZXZlcnlvbmUuZGVmaW5lZCB8PSB4Owo+ICsJCQl9Cj4gKwkJ fSBlbHNlIGlmIChyaWNoYWNlX2lzX2dyb3VwKGFjZSkpIHsKPiArCQkJeCA9IGFjZS0+ZV9tYXNr ICYgfmdyb3VwLmRlZmluZWQ7Cj4gKwkJCWlmIChyaWNoYWNlX2lzX2FsbG93KGFjZSkpCj4gKwkJ CQlncm91cC5hbGxvd2VkIHw9IHg7Cj4gKwkJCWdyb3VwLmRlZmluZWQgfD0geDsKPiArCQl9IGVs c2UKPiArCQkJcmV0dXJuIC0xOwo+ICsJfQo+ICsKPiArCWlmIChncm91cC5hbGxvd2VkICYgfm93 bmVyLmRlZmluZWQpCj4gKwkJcmV0dXJuIC0xOwo+ICsKPiArCWlmIChhY2wtPmFfZmxhZ3MgJiBS SUNIQUNMX01BU0tFRCkgewo+ICsJCWlmIChhY2wtPmFfZmxhZ3MgJiBSSUNIQUNMX1dSSVRFX1RI Uk9VR0gpIHsKPiArCQkJb3duZXIuYWxsb3dlZCA9IGFjbC0+YV9vd25lcl9tYXNrOwo+ICsJCQll dmVyeW9uZS5hbGxvd2VkID0gYWNsLT5hX290aGVyX21hc2s7Cj4gKwkJfSBlbHNlIHsKPiArCQkJ b3duZXIuYWxsb3dlZCAmPSBhY2wtPmFfb3duZXJfbWFzazsKPiArCQkJZXZlcnlvbmUuYWxsb3dl ZCAmPSBhY2wtPmFfb3RoZXJfbWFzazsKPiArCQl9Cj4gKwkJZ3JvdXAuYWxsb3dlZCAmPSBhY2wt PmFfZ3JvdXBfbWFzazsKPiArCX0KPiArCj4gKwltb2RlID0gKG1vZGUgJiB+U19JUldYVUdPKSB8 Cj4gKwnCoMKgwqDCoMKgwqDCoChyaWNoYWNsX21hc2tfdG9fbW9kZShvd25lci5hbGxvd2VkKSA8 PCA2KSB8Cj4gKwnCoMKgwqDCoMKgwqDCoChyaWNoYWNsX21hc2tfdG9fbW9kZShncm91cC5hbGxv d2VkKSA8PCAzKSB8Cj4gKwkJcmljaGFjbF9tYXNrX3RvX21vZGUoZXZlcnlvbmUuYWxsb3dlZCk7 Cj4gKwo+ICsJLyogTWFzayBmbGFncyB3ZSBjYW4gaWdub3JlICovCj4gKwl4ID0gU19JU0RJUiht b2RlKSA/IDAgOiBSSUNIQUNFX0RFTEVURV9DSElMRDsKPiArCj4gKwlpZiAoKChyaWNoYWNsX21v ZGVfdG9fbWFzayhtb2RlID4+IDYpIF4gb3duZXIuYWxsb3dlZCnCoMKgwqDCoCYgfngpIHx8Cj4g KwnCoMKgwqDCoCgocmljaGFjbF9tb2RlX3RvX21hc2sobW9kZSA+PiAzKSBeIGdyb3VwLmFsbG93 ZWQpwqDCoMKgwqAmIH54KSB8fAo+ICsJwqDCoMKgwqAoKHJpY2hhY2xfbW9kZV90b19tYXNrKG1v ZGUpwqDCoMKgwqDCoMKgXiBldmVyeW9uZS5hbGxvd2VkKSAmIH54KSkKPiArCQlyZXR1cm4gLTE7 Cj4gKwo+ICsJKm1vZGVfcCA9IG1vZGU7Cj4gKwlyZXR1cm4gMDsKPiArfQo+ICtFWFBPUlRfU1lN Qk9MX0dQTChyaWNoYWNsX2VxdWl2X21vZGUpOwo+IGRpZmYgLS1naXQgYS9pbmNsdWRlL2xpbnV4 L3JpY2hhY2wuaCBiL2luY2x1ZGUvbGludXgvcmljaGFjbC5oCj4gaW5kZXggZGI4MmZhYi4uOTIx MmVkYiAxMDA2NDQKPiAtLS0gYS9pbmNsdWRlL2xpbnV4L3JpY2hhY2wuaAo+ICsrKyBiL2luY2x1 ZGUvbGludXgvcmljaGFjbC5oCj4gQEAgLTE5MSw1ICsxOTEsNiBAQCBleHRlcm4gdW5zaWduZWQg aW50IHJpY2hhY2xfd2FudF90b19tYXNrKHVuc2lnbmVkIGludCk7Cj4gwqBleHRlcm4gdm9pZCBy aWNoYWNsX2NvbXB1dGVfbWF4X21hc2tzKHN0cnVjdCByaWNoYWNsICopOwo+IMKgZXh0ZXJuIGlu dCByaWNoYWNsX3Blcm1pc3Npb24oc3RydWN0IGlub2RlICosIGNvbnN0IHN0cnVjdCByaWNoYWNs ICosIGludCk7Cj4gwqBleHRlcm4gaW50IHJpY2hhY2xfY2htb2Qoc3RydWN0IGlub2RlICosIHVt b2RlX3QpOwo+ICtleHRlcm4gaW50IHJpY2hhY2xfZXF1aXZfbW9kZShjb25zdCBzdHJ1Y3Qgcmlj aGFjbCAqLCB1bW9kZV90ICopOwo+IMKgCj4gwqAjZW5kaWYgLyogX19SSUNIQUNMX0ggKi8KClJl dmlld2VkLWJ5OiBKZWZmIExheXRvbiA8amxheXRvbkByZWRoYXQuY29tPgoKX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KeGZzIG1haWxpbmcgbGlzdAp4ZnNA b3NzLnNnaS5jb20KaHR0cDovL29zcy5zZ2kuY29tL21haWxtYW4vbGlzdGluZm8veGZzCg==