From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jeff Layton Subject: Re: [PATCH v23 06/22] richacl: In-memory representation and helper functions Date: Tue, 05 Jul 2016 07:34:08 -0400 Message-ID: <1467718448.3800.16.camel@redhat.com> References: <1467294433-3222-1-git-send-email-agruenba@redhat.com> <1467294433-3222-7-git-send-email-agruenba@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Return-path: In-Reply-To: <1467294433-3222-7-git-send-email-agruenba@redhat.com> Sender: linux-fsdevel-owner@vger.kernel.org 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 List-Id: linux-api@vger.kernel.org On Thu, 2016-06-30 at 15:46 +0200, Andreas Gruenbacher wrote: > A richacl consists of an NFSv4 acl and an owner, group, and other mas= k. > These three masks correspond to the owner, group, and other file > permission bits, but they contain NFSv4 permissions instead of POSIX > permissions. >=20 > Each entry in the NFSv4 acl applies to the file owner (OWNER@), the > owning group (GROUP@), everyone (EVERYONE@), or to a specific uid or > gid. >=20 > As in the standard POSIX file permission model, each process is the > owner, group, or other file class.=C2=A0=C2=A0A richacl grants a requ= ested access > only if the NFSv4 acl in the richacl grants the access (according to = the > NFSv4 permission check algorithm), and the file mask that applies to = the > process includes the requested permissions. >=20 > Signed-off-by: Andreas Gruenbacher > Reviewed-by: J. Bruce Fields > --- > =C2=A0fs/Makefile=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0|=C2=A0=C2=A0=C2=A0= 1 + > =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=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0|=C2=A0=C2=A065 ++++= ++++++++++++ > =C2=A0include/linux/richacl.h=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0| 17= 9 +++++++++++++++++++++++++++++++++++++++++++ > =C2=A0include/uapi/linux/Kbuild=C2=A0=C2=A0=C2=A0=C2=A0|=C2=A0=C2=A0=C2= =A01 + > =C2=A0include/uapi/linux/richacl.h |=C2=A0=C2=A099 ++++++++++++++++++= ++++++ > =C2=A05 files changed, 345 insertions(+) > =C2=A0create mode 100644 fs/richacl.c > =C2=A0create mode 100644 include/linux/richacl.h > =C2=A0create mode 100644 include/uapi/linux/richacl.h >=20 > diff --git a/fs/Makefile b/fs/Makefile > index 85b6e13..2b3e6f1 100644 > --- a/fs/Makefile > +++ b/fs/Makefile > @@ -49,6 +49,7 @@ obj-$(CONFIG_COREDUMP) +=3D coredump.o > =C2=A0obj-$(CONFIG_SYSCTL) +=3D drop_caches.o > =C2=A0 > =C2=A0obj-$(CONFIG_FHANDLE) +=3D fhandle.o > +obj-$(CONFIG_FS_RICHACL) +=3D richacl.o > =C2=A0 > =C2=A0obj-y +=3D quota/ > =C2=A0 > diff --git a/fs/richacl.c b/fs/richacl.c > new file mode 100644 > index 0000000..bcc6591 > --- /dev/null > +++ b/fs/richacl.c > @@ -0,0 +1,65 @@ > +/* > + * Copyright (C) 2006, 2010=C2=A0=C2=A0Novell, Inc. > + * Copyright (C) 2015=C2=A0=C2=A0Red Hat, Inc. > + * Written by Andreas Gruenbacher > + * > + * This program is free software; you can redistribute it and/or mod= ify it > + * under the terms of the GNU General Public License as published by= the > + * Free Software Foundation; either version 2, or (at your option) a= ny > + * later version. > + * > + * This program is distributed in the hope that it will be useful, b= ut > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.=C2=A0=C2=A0S= ee the GNU > + * General Public License for more details. > + */ > + > +#include=20 > +#include=20 > +#include=20 > +#include=20 > +#include=20 > + > +/** > + * richacl_alloc=C2=A0=C2=A0-=C2=A0=C2=A0allocate a richacl > + * @count: number of entries > + */ > +struct richacl * > +richacl_alloc(int count, gfp_t gfp) > +{ > + size_t size =3D sizeof(struct richacl) + count * sizeof(struct rich= ace); > + struct richacl *acl =3D kzalloc(size, gfp); > + > + if (acl) { > + atomic_set(&acl->a_refcount, 1); > + acl->a_count =3D count; > + } > + return acl; > +} > +EXPORT_SYMBOL_GPL(richacl_alloc); > + I imagine we could have a lot of these at any given time. It might be nice to consider how to do this with dedicated slabcaches for better packing, but I think that would add to the complexity, unfortunately. > +/** > + * richacl_clone=C2=A0=C2=A0-=C2=A0=C2=A0create a copy of a richacl > + */ > +struct richacl * > +richacl_clone(const struct richacl *acl, gfp_t gfp) > +{ > + int count =3D acl->a_count; > + size_t size =3D sizeof(struct richacl) + count * sizeof(struct rich= ace); > + struct richacl *dup =3D kmalloc(size, gfp); > + > + if (dup) { > + memcpy(dup, acl, size); > + atomic_set(&dup->a_refcount, 1); > + } > + return dup; > +} > + > +/** > + * richace_copy=C2=A0=C2=A0-=C2=A0=C2=A0copy an acl entry > + */ > +void > +richace_copy(struct richace *to, const struct richace *from) > +{ > + memcpy(to, from, sizeof(struct richace)); > +} > diff --git a/include/linux/richacl.h b/include/linux/richacl.h > new file mode 100644 > index 0000000..edb8480 > --- /dev/null > +++ b/include/linux/richacl.h > @@ -0,0 +1,179 @@ > +/* > + * Copyright (C) 2006, 2010=C2=A0=C2=A0Novell, Inc. > + * Copyright (C) 2015=C2=A0=C2=A0Red Hat, Inc. > + * Written by Andreas Gruenbacher > + * > + * This program is free software; you can redistribute it and/or mod= ify it > + * under the terms of the GNU General Public License as published by= the > + * Free Software Foundation; either version 2, or (at your option) a= ny > + * later version. > + * > + * This program is distributed in the hope that it will be useful, b= ut > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.=C2=A0=C2=A0S= ee the GNU > + * General Public License for more details. > + */ > + > +#ifndef __RICHACL_H > +#define __RICHACL_H > + > +#include=20 > + > +struct richace { > + unsigned short e_type; > + unsigned short e_flags; > + unsigned int e_mask; > + union { > + kuid_t uid; > + kgid_t gid; > + unsigned int special; > + } e_id; > +}; > + > +struct richacl { > + atomic_t a_refcount; > + unsigned int a_owner_mask; > + unsigned int a_group_mask; > + unsigned int a_other_mask; > + unsigned short a_count; > + unsigned short a_flags; > + struct richace a_entries[0]; > +}; > + > +#define richacl_for_each_entry(_ace, _acl) \ > + for (_ace =3D (_acl)->a_entries; \ > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0_ace !=3D (_acl)->a_entries + (_acl)-= >a_count; \ > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0_ace++) > + > +#define richacl_for_each_entry_reverse(_ace, _acl) \ > + for (_ace =3D (_acl)->a_entries + (_acl)->a_count - 1; \ > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0_ace !=3D (_acl)->a_entries - 1; \ > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0_ace--) > + > +/** > + * richacl_get=C2=A0=C2=A0-=C2=A0=C2=A0grab another reference to a r= ichacl handle > + */ > +static inline struct richacl * > +richacl_get(struct richacl *acl) > +{ > + if (acl) > + atomic_inc(&acl->a_refcount); > + return acl; > +} > + > +/** > + * richacl_put=C2=A0=C2=A0-=C2=A0=C2=A0free a richacl handle > + */ > +static inline void > +richacl_put(struct richacl *acl) > +{ > + if (acl && atomic_dec_and_test(&acl->a_refcount)) > + kfree(acl); > +} > + > +/** > + * richace_is_owner=C2=A0=C2=A0-=C2=A0=C2=A0check if @ace is an OWNE= R@ entry > + */ > +static inline bool > +richace_is_owner(const struct richace *ace) > +{ > + return (ace->e_flags & RICHACE_SPECIAL_WHO) && > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0ace->e_id.special =3D=3D = RICHACE_OWNER_SPECIAL_ID; > +} > + > +/** > + * richace_is_group=C2=A0=C2=A0-=C2=A0=C2=A0check if @ace is a GROUP= @ entry > + */ > +static inline bool > +richace_is_group(const struct richace *ace) > +{ > + return (ace->e_flags & RICHACE_SPECIAL_WHO) && > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0ace->e_id.special =3D=3D = RICHACE_GROUP_SPECIAL_ID; > +} > + > +/** > + * richace_is_everyone=C2=A0=C2=A0-=C2=A0=C2=A0check if @ace is an E= VERYONE@ entry > + */ > +static inline bool > +richace_is_everyone(const struct richace *ace) > +{ > + return (ace->e_flags & RICHACE_SPECIAL_WHO) && > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0ace->e_id.special =3D=3D = RICHACE_EVERYONE_SPECIAL_ID; > +} > + > +/** > + * richace_is_unix_user=C2=A0=C2=A0-=C2=A0=C2=A0check if @ace applie= s to a specific user > + */ > +static inline bool > +richace_is_unix_user(const struct richace *ace) > +{ > + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0!(ace->e_flags & RICHACE_= IDENTIFIER_GROUP); > +} > + > +/** > + * richace_is_unix_group=C2=A0=C2=A0-=C2=A0=C2=A0check if @ace appli= es to a specific group > + */ > +static inline bool > +richace_is_unix_group(const struct richace *ace) > +{ > + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(ace->e_flags & RICHACE_I= DENTIFIER_GROUP); > +} > + > +/** > + * richace_is_inherit_only=C2=A0=C2=A0-=C2=A0=C2=A0check if @ace is = for inheritance only > + * > + * ACEs with the %RICHACE_INHERIT_ONLY_ACE flag set have no effect d= uring > + * permission checking. > + */ > +static inline bool > +richace_is_inherit_only(const struct richace *ace) > +{ > + return ace->e_flags & RICHACE_INHERIT_ONLY_ACE; > +} > + > +/** > + * richace_is_inheritable=C2=A0=C2=A0-=C2=A0=C2=A0check if @ace is i= nheritable > + */ > +static inline bool > +richace_is_inheritable(const struct richace *ace) > +{ > + return ace->e_flags & (RICHACE_FILE_INHERIT_ACE | > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0RICHACE_DIRECTORY_INHER= IT_ACE); > +} > + > +/** > + * richace_is_allow=C2=A0=C2=A0-=C2=A0=C2=A0check if @ace is an %ALL= OW type entry > + */ > +static inline bool > +richace_is_allow(const struct richace *ace) > +{ > + return ace->e_type =3D=3D RICHACE_ACCESS_ALLOWED_ACE_TYPE; > +} > + > +/** > + * richace_is_deny=C2=A0=C2=A0-=C2=A0=C2=A0check if @ace is a %DENY = type entry > + */ > +static inline bool > +richace_is_deny(const struct richace *ace) > +{ > + return ace->e_type =3D=3D RICHACE_ACCESS_DENIED_ACE_TYPE; > +} > + > +/** > + * richace_is_same_identifier=C2=A0=C2=A0-=C2=A0=C2=A0are both ident= ifiers the same? > + */ > +static inline bool > +richace_is_same_identifier(const struct richace *a, const struct ric= hace *b) > +{ > + return !((a->e_flags ^ b->e_flags) & > + =C2=A0(RICHACE_SPECIAL_WHO | RICHACE_IDENTIFIER_GROUP)) && > + =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0!memcmp(&a->e_id, &b->e_i= d, sizeof(a->e_id)); > +} > + > +extern struct richacl *richacl_alloc(int, gfp_t); > +extern struct richacl *richacl_clone(const struct richacl *, gfp_t); > +extern void richace_copy(struct richace *, const struct richace *); > + > +#endif /* __RICHACL_H */ > diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild > index 8bdae34..abeaa98 100644 > --- a/include/uapi/linux/Kbuild > +++ b/include/uapi/linux/Kbuild > @@ -355,6 +355,7 @@ header-y +=3D reboot.h > =C2=A0header-y +=3D reiserfs_fs.h > =C2=A0header-y +=3D reiserfs_xattr.h > =C2=A0header-y +=3D resource.h > +header-y +=3D richacl.h > =C2=A0header-y +=3D rfkill.h > =C2=A0header-y +=3D rio_mport_cdev.h > =C2=A0header-y +=3D romfs_fs.h > diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richac= l.h > new file mode 100644 > index 0000000..08856f8 > --- /dev/null > +++ b/include/uapi/linux/richacl.h > @@ -0,0 +1,99 @@ > +/* > + * Copyright (C) 2006, 2010=C2=A0=C2=A0Novell, Inc. > + * Copyright (C) 2015=C2=A0=C2=A0Red Hat, Inc. > + * Written by Andreas Gruenbacher > + * > + * This file is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version= =2E > + * > + * This file is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.=C2=A0=C2=A0S= ee the GNU > + * Lesser General Public License for more details. > + */ > + > +#ifndef __UAPI_RICHACL_H > +#define __UAPI_RICHACL_H > + > +/* a_flags values */ > +#define RICHACL_WRITE_THROUGH 0x40 > +#define RICHACL_MASKED 0x80 > + > +/* e_type values */ > +#define RICHACE_ACCESS_ALLOWED_ACE_TYPE 0x0000 > +#define RICHACE_ACCESS_DENIED_ACE_TYPE 0x0001 > + > +/* e_flags bitflags */ > +#define RICHACE_FILE_INHERIT_ACE 0x0001 > +#define RICHACE_DIRECTORY_INHERIT_ACE 0x0002 > +#define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 > +#define RICHACE_INHERIT_ONLY_ACE 0x0008 > +#define RICHACE_IDENTIFIER_GROUP 0x0040 > +#define RICHACE_SPECIAL_WHO 0x4000 > + > +/* e_mask bitflags */ > +#define RICHACE_READ_DATA 0x00000001 > +#define RICHACE_LIST_DIRECTORY 0x00000001 > +#define RICHACE_WRITE_DATA 0x00000002 > +#define RICHACE_ADD_FILE 0x00000002 > +#define RICHACE_APPEND_DATA 0x00000004 > +#define RICHACE_ADD_SUBDIRECTORY 0x00000004 > +#define RICHACE_READ_NAMED_ATTRS 0x00000008 > +#define RICHACE_WRITE_NAMED_ATTRS 0x00000010 > +#define RICHACE_EXECUTE 0x00000020 > +#define RICHACE_DELETE_CHILD 0x00000040 > +#define RICHACE_READ_ATTRIBUTES 0x00000080 > +#define RICHACE_WRITE_ATTRIBUTES 0x00000100 > +#define RICHACE_WRITE_RETENTION 0x00000200 > +#define RICHACE_WRITE_RETENTION_HOLD 0x00000400 > +#define RICHACE_DELETE 0x00010000 > +#define RICHACE_READ_ACL 0x00020000 > +#define RICHACE_WRITE_ACL 0x00040000 > +#define RICHACE_WRITE_OWNER 0x00080000 > +#define RICHACE_SYNCHRONIZE 0x00100000 > + > +/* e_id values */ > +#define RICHACE_OWNER_SPECIAL_ID 0 > +#define RICHACE_GROUP_SPECIAL_ID 1 > +#define RICHACE_EVERYONE_SPECIAL_ID 2 > + > +#define RICHACL_VALID_FLAGS ( \ > + RICHACL_WRITE_THROUGH | \ > + RICHACL_MASKED ) > + > +#define RICHACE_VALID_FLAGS ( \ > + RICHACE_FILE_INHERIT_ACE | \ > + RICHACE_DIRECTORY_INHERIT_ACE | \ > + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ > + RICHACE_INHERIT_ONLY_ACE | \ > + RICHACE_IDENTIFIER_GROUP | \ > + RICHACE_SPECIAL_WHO ) > + > +#define RICHACE_INHERITANCE_FLAGS ( \ > + RICHACE_FILE_INHERIT_ACE | \ > + RICHACE_DIRECTORY_INHERIT_ACE | \ > + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ > + RICHACE_INHERIT_ONLY_ACE ) > + > +/* Valid RICHACE_* flags for directories and non-directories */ > +#define RICHACE_VALID_MASK ( \ > + RICHACE_READ_DATA | RICHACE_LIST_DIRECTORY | \ > + RICHACE_WRITE_DATA | RICHACE_ADD_FILE | \ > + RICHACE_APPEND_DATA | RICHACE_ADD_SUBDIRECTORY | \ > + RICHACE_READ_NAMED_ATTRS | \ > + RICHACE_WRITE_NAMED_ATTRS | \ > + RICHACE_EXECUTE | \ > + RICHACE_DELETE_CHILD | \ > + RICHACE_READ_ATTRIBUTES | \ > + RICHACE_WRITE_ATTRIBUTES | \ > + RICHACE_WRITE_RETENTION | \ > + RICHACE_WRITE_RETENTION_HOLD | \ > + RICHACE_DELETE | \ > + RICHACE_READ_ACL | \ > + RICHACE_WRITE_ACL | \ > + RICHACE_WRITE_OWNER | \ > + RICHACE_SYNCHRONIZE ) > + > +#endif /* __UAPI_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: from mail-qt0-f172.google.com ([209.85.216.172]:33895 "EHLO mail-qt0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932753AbcGELeM (ORCPT ); Tue, 5 Jul 2016 07:34:12 -0400 Received: by mail-qt0-f172.google.com with SMTP id m2so99197482qtd.1 for ; Tue, 05 Jul 2016 04:34:11 -0700 (PDT) Message-ID: <1467718448.3800.16.camel@redhat.com> Subject: Re: [PATCH v23 06/22] richacl: In-memory representation and helper functions 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, 05 Jul 2016 07:34:08 -0400 In-Reply-To: <1467294433-3222-7-git-send-email-agruenba@redhat.com> References: <1467294433-3222-1-git-send-email-agruenba@redhat.com> <1467294433-3222-7-git-send-email-agruenba@redhat.com> Content-Type: text/plain; charset="UTF-8" Mime-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org List-ID: On Thu, 2016-06-30 at 15:46 +0200, Andreas Gruenbacher wrote: > A richacl consists of an NFSv4 acl and an owner, group, and other mask. > These three masks correspond to the owner, group, and other file > permission bits, but they contain NFSv4 permissions instead of POSIX > permissions. > > Each entry in the NFSv4 acl applies to the file owner (OWNER@), the > owning group (GROUP@), everyone (EVERYONE@), or to a specific uid or > gid. > > As in the standard POSIX file permission model, each process is the > owner, group, or other file class.  A richacl grants a requested access > only if the NFSv4 acl in the richacl grants the access (according to the > NFSv4 permission check algorithm), and the file mask that applies to the > process includes the requested permissions. > > Signed-off-by: Andreas Gruenbacher > Reviewed-by: J. Bruce Fields > --- >  fs/Makefile                  |   1 + >  fs/richacl.c                 |  65 ++++++++++++++++ >  include/linux/richacl.h      | 179 +++++++++++++++++++++++++++++++++++++++++++ >  include/uapi/linux/Kbuild    |   1 + >  include/uapi/linux/richacl.h |  99 ++++++++++++++++++++++++ >  5 files changed, 345 insertions(+) >  create mode 100644 fs/richacl.c >  create mode 100644 include/linux/richacl.h >  create mode 100644 include/uapi/linux/richacl.h > > diff --git a/fs/Makefile b/fs/Makefile > index 85b6e13..2b3e6f1 100644 > --- a/fs/Makefile > +++ b/fs/Makefile > @@ -49,6 +49,7 @@ obj-$(CONFIG_COREDUMP) += coredump.o >  obj-$(CONFIG_SYSCTL) += drop_caches.o >   >  obj-$(CONFIG_FHANDLE) += fhandle.o > +obj-$(CONFIG_FS_RICHACL) += richacl.o >   >  obj-y += quota/ >   > diff --git a/fs/richacl.c b/fs/richacl.c > new file mode 100644 > index 0000000..bcc6591 > --- /dev/null > +++ b/fs/richacl.c > @@ -0,0 +1,65 @@ > +/* > + * Copyright (C) 2006, 2010  Novell, Inc. > + * Copyright (C) 2015  Red Hat, Inc. > + * Written by Andreas Gruenbacher > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License as published by the > + * Free Software Foundation; either version 2, or (at your option) any > + * later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU > + * General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +/** > + * richacl_alloc  -  allocate a richacl > + * @count: number of entries > + */ > +struct richacl * > +richacl_alloc(int count, gfp_t gfp) > +{ > + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); > + struct richacl *acl = kzalloc(size, gfp); > + > + if (acl) { > + atomic_set(&acl->a_refcount, 1); > + acl->a_count = count; > + } > + return acl; > +} > +EXPORT_SYMBOL_GPL(richacl_alloc); > + I imagine we could have a lot of these at any given time. It might be nice to consider how to do this with dedicated slabcaches for better packing, but I think that would add to the complexity, unfortunately. > +/** > + * richacl_clone  -  create a copy of a richacl > + */ > +struct richacl * > +richacl_clone(const struct richacl *acl, gfp_t gfp) > +{ > + int count = acl->a_count; > + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); > + struct richacl *dup = kmalloc(size, gfp); > + > + if (dup) { > + memcpy(dup, acl, size); > + atomic_set(&dup->a_refcount, 1); > + } > + return dup; > +} > + > +/** > + * richace_copy  -  copy an acl entry > + */ > +void > +richace_copy(struct richace *to, const struct richace *from) > +{ > + memcpy(to, from, sizeof(struct richace)); > +} > diff --git a/include/linux/richacl.h b/include/linux/richacl.h > new file mode 100644 > index 0000000..edb8480 > --- /dev/null > +++ b/include/linux/richacl.h > @@ -0,0 +1,179 @@ > +/* > + * Copyright (C) 2006, 2010  Novell, Inc. > + * Copyright (C) 2015  Red Hat, Inc. > + * Written by Andreas Gruenbacher > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License as published by the > + * Free Software Foundation; either version 2, or (at your option) any > + * later version. > + * > + * This program is distributed in the hope that it will be useful, but > + * WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU > + * General Public License for more details. > + */ > + > +#ifndef __RICHACL_H > +#define __RICHACL_H > + > +#include > + > +struct richace { > + unsigned short e_type; > + unsigned short e_flags; > + unsigned int e_mask; > + union { > + kuid_t uid; > + kgid_t gid; > + unsigned int special; > + } e_id; > +}; > + > +struct richacl { > + atomic_t a_refcount; > + unsigned int a_owner_mask; > + unsigned int a_group_mask; > + unsigned int a_other_mask; > + unsigned short a_count; > + unsigned short a_flags; > + struct richace a_entries[0]; > +}; > + > +#define richacl_for_each_entry(_ace, _acl) \ > + for (_ace = (_acl)->a_entries; \ > +      _ace != (_acl)->a_entries + (_acl)->a_count; \ > +      _ace++) > + > +#define richacl_for_each_entry_reverse(_ace, _acl) \ > + for (_ace = (_acl)->a_entries + (_acl)->a_count - 1; \ > +      _ace != (_acl)->a_entries - 1; \ > +      _ace--) > + > +/** > + * richacl_get  -  grab another reference to a richacl handle > + */ > +static inline struct richacl * > +richacl_get(struct richacl *acl) > +{ > + if (acl) > + atomic_inc(&acl->a_refcount); > + return acl; > +} > + > +/** > + * richacl_put  -  free a richacl handle > + */ > +static inline void > +richacl_put(struct richacl *acl) > +{ > + if (acl && atomic_dec_and_test(&acl->a_refcount)) > + kfree(acl); > +} > + > +/** > + * richace_is_owner  -  check if @ace is an OWNER@ entry > + */ > +static inline bool > +richace_is_owner(const struct richace *ace) > +{ > + return (ace->e_flags & RICHACE_SPECIAL_WHO) && > +        ace->e_id.special == RICHACE_OWNER_SPECIAL_ID; > +} > + > +/** > + * richace_is_group  -  check if @ace is a GROUP@ entry > + */ > +static inline bool > +richace_is_group(const struct richace *ace) > +{ > + return (ace->e_flags & RICHACE_SPECIAL_WHO) && > +        ace->e_id.special == RICHACE_GROUP_SPECIAL_ID; > +} > + > +/** > + * richace_is_everyone  -  check if @ace is an EVERYONE@ entry > + */ > +static inline bool > +richace_is_everyone(const struct richace *ace) > +{ > + return (ace->e_flags & RICHACE_SPECIAL_WHO) && > +        ace->e_id.special == RICHACE_EVERYONE_SPECIAL_ID; > +} > + > +/** > + * richace_is_unix_user  -  check if @ace applies to a specific user > + */ > +static inline bool > +richace_is_unix_user(const struct richace *ace) > +{ > + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && > +        !(ace->e_flags & RICHACE_IDENTIFIER_GROUP); > +} > + > +/** > + * richace_is_unix_group  -  check if @ace applies to a specific group > + */ > +static inline bool > +richace_is_unix_group(const struct richace *ace) > +{ > + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && > +        (ace->e_flags & RICHACE_IDENTIFIER_GROUP); > +} > + > +/** > + * richace_is_inherit_only  -  check if @ace is for inheritance only > + * > + * ACEs with the %RICHACE_INHERIT_ONLY_ACE flag set have no effect during > + * permission checking. > + */ > +static inline bool > +richace_is_inherit_only(const struct richace *ace) > +{ > + return ace->e_flags & RICHACE_INHERIT_ONLY_ACE; > +} > + > +/** > + * richace_is_inheritable  -  check if @ace is inheritable > + */ > +static inline bool > +richace_is_inheritable(const struct richace *ace) > +{ > + return ace->e_flags & (RICHACE_FILE_INHERIT_ACE | > +        RICHACE_DIRECTORY_INHERIT_ACE); > +} > + > +/** > + * richace_is_allow  -  check if @ace is an %ALLOW type entry > + */ > +static inline bool > +richace_is_allow(const struct richace *ace) > +{ > + return ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE; > +} > + > +/** > + * richace_is_deny  -  check if @ace is a %DENY type entry > + */ > +static inline bool > +richace_is_deny(const struct richace *ace) > +{ > + return ace->e_type == RICHACE_ACCESS_DENIED_ACE_TYPE; > +} > + > +/** > + * richace_is_same_identifier  -  are both identifiers the same? > + */ > +static inline bool > +richace_is_same_identifier(const struct richace *a, const struct richace *b) > +{ > + return !((a->e_flags ^ b->e_flags) & > +  (RICHACE_SPECIAL_WHO | RICHACE_IDENTIFIER_GROUP)) && > +        !memcmp(&a->e_id, &b->e_id, sizeof(a->e_id)); > +} > + > +extern struct richacl *richacl_alloc(int, gfp_t); > +extern struct richacl *richacl_clone(const struct richacl *, gfp_t); > +extern void richace_copy(struct richace *, const struct richace *); > + > +#endif /* __RICHACL_H */ > diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild > index 8bdae34..abeaa98 100644 > --- a/include/uapi/linux/Kbuild > +++ b/include/uapi/linux/Kbuild > @@ -355,6 +355,7 @@ header-y += reboot.h >  header-y += reiserfs_fs.h >  header-y += reiserfs_xattr.h >  header-y += resource.h > +header-y += richacl.h >  header-y += rfkill.h >  header-y += rio_mport_cdev.h >  header-y += romfs_fs.h > diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h > new file mode 100644 > index 0000000..08856f8 > --- /dev/null > +++ b/include/uapi/linux/richacl.h > @@ -0,0 +1,99 @@ > +/* > + * Copyright (C) 2006, 2010  Novell, Inc. > + * Copyright (C) 2015  Red Hat, Inc. > + * Written by Andreas Gruenbacher > + * > + * This file is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This file is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU > + * Lesser General Public License for more details. > + */ > + > +#ifndef __UAPI_RICHACL_H > +#define __UAPI_RICHACL_H > + > +/* a_flags values */ > +#define RICHACL_WRITE_THROUGH 0x40 > +#define RICHACL_MASKED 0x80 > + > +/* e_type values */ > +#define RICHACE_ACCESS_ALLOWED_ACE_TYPE 0x0000 > +#define RICHACE_ACCESS_DENIED_ACE_TYPE 0x0001 > + > +/* e_flags bitflags */ > +#define RICHACE_FILE_INHERIT_ACE 0x0001 > +#define RICHACE_DIRECTORY_INHERIT_ACE 0x0002 > +#define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 > +#define RICHACE_INHERIT_ONLY_ACE 0x0008 > +#define RICHACE_IDENTIFIER_GROUP 0x0040 > +#define RICHACE_SPECIAL_WHO 0x4000 > + > +/* e_mask bitflags */ > +#define RICHACE_READ_DATA 0x00000001 > +#define RICHACE_LIST_DIRECTORY 0x00000001 > +#define RICHACE_WRITE_DATA 0x00000002 > +#define RICHACE_ADD_FILE 0x00000002 > +#define RICHACE_APPEND_DATA 0x00000004 > +#define RICHACE_ADD_SUBDIRECTORY 0x00000004 > +#define RICHACE_READ_NAMED_ATTRS 0x00000008 > +#define RICHACE_WRITE_NAMED_ATTRS 0x00000010 > +#define RICHACE_EXECUTE 0x00000020 > +#define RICHACE_DELETE_CHILD 0x00000040 > +#define RICHACE_READ_ATTRIBUTES 0x00000080 > +#define RICHACE_WRITE_ATTRIBUTES 0x00000100 > +#define RICHACE_WRITE_RETENTION 0x00000200 > +#define RICHACE_WRITE_RETENTION_HOLD 0x00000400 > +#define RICHACE_DELETE 0x00010000 > +#define RICHACE_READ_ACL 0x00020000 > +#define RICHACE_WRITE_ACL 0x00040000 > +#define RICHACE_WRITE_OWNER 0x00080000 > +#define RICHACE_SYNCHRONIZE 0x00100000 > + > +/* e_id values */ > +#define RICHACE_OWNER_SPECIAL_ID 0 > +#define RICHACE_GROUP_SPECIAL_ID 1 > +#define RICHACE_EVERYONE_SPECIAL_ID 2 > + > +#define RICHACL_VALID_FLAGS ( \ > + RICHACL_WRITE_THROUGH | \ > + RICHACL_MASKED ) > + > +#define RICHACE_VALID_FLAGS ( \ > + RICHACE_FILE_INHERIT_ACE | \ > + RICHACE_DIRECTORY_INHERIT_ACE | \ > + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ > + RICHACE_INHERIT_ONLY_ACE | \ > + RICHACE_IDENTIFIER_GROUP | \ > + RICHACE_SPECIAL_WHO ) > + > +#define RICHACE_INHERITANCE_FLAGS ( \ > + RICHACE_FILE_INHERIT_ACE | \ > + RICHACE_DIRECTORY_INHERIT_ACE | \ > + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ > + RICHACE_INHERIT_ONLY_ACE ) > + > +/* Valid RICHACE_* flags for directories and non-directories */ > +#define RICHACE_VALID_MASK ( \ > + RICHACE_READ_DATA | RICHACE_LIST_DIRECTORY | \ > + RICHACE_WRITE_DATA | RICHACE_ADD_FILE | \ > + RICHACE_APPEND_DATA | RICHACE_ADD_SUBDIRECTORY | \ > + RICHACE_READ_NAMED_ATTRS | \ > + RICHACE_WRITE_NAMED_ATTRS | \ > + RICHACE_EXECUTE | \ > + RICHACE_DELETE_CHILD | \ > + RICHACE_READ_ATTRIBUTES | \ > + RICHACE_WRITE_ATTRIBUTES | \ > + RICHACE_WRITE_RETENTION | \ > + RICHACE_WRITE_RETENTION_HOLD | \ > + RICHACE_DELETE | \ > + RICHACE_READ_ACL | \ > + RICHACE_WRITE_ACL | \ > + RICHACE_WRITE_OWNER | \ > + RICHACE_SYNCHRONIZE ) > + > +#endif /* __UAPI_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 159FA7CCF for ; Tue, 5 Jul 2016 06:34:15 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id DC7D930404E for ; Tue, 5 Jul 2016 04:34:14 -0700 (PDT) Received: from mail-qt0-f173.google.com (mail-qt0-f173.google.com [209.85.216.173]) by cuda.sgi.com with ESMTP id 1H86Q6YuCTT4GHIi (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 05 Jul 2016 04:34:12 -0700 (PDT) Received: by mail-qt0-f173.google.com with SMTP id c34so99051843qte.0 for ; Tue, 05 Jul 2016 04:34:12 -0700 (PDT) Message-ID: <1467718448.3800.16.camel@redhat.com> Subject: Re: [PATCH v23 06/22] richacl: In-memory representation and helper functions From: Jeff Layton Date: Tue, 05 Jul 2016 07:34:08 -0400 In-Reply-To: <1467294433-3222-7-git-send-email-agruenba@redhat.com> References: <1467294433-3222-1-git-send-email-agruenba@redhat.com> <1467294433-3222-7-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 T24gVGh1LCAyMDE2LTA2LTMwIGF0IDE1OjQ2ICswMjAwLCBBbmRyZWFzIEdydWVuYmFjaGVyIHdy b3RlOgo+IEEgcmljaGFjbCBjb25zaXN0cyBvZiBhbiBORlN2NCBhY2wgYW5kIGFuIG93bmVyLCBn cm91cCwgYW5kIG90aGVyIG1hc2suCj4gVGhlc2UgdGhyZWUgbWFza3MgY29ycmVzcG9uZCB0byB0 aGUgb3duZXIsIGdyb3VwLCBhbmQgb3RoZXIgZmlsZQo+IHBlcm1pc3Npb24gYml0cywgYnV0IHRo ZXkgY29udGFpbiBORlN2NCBwZXJtaXNzaW9ucyBpbnN0ZWFkIG9mIFBPU0lYCj4gcGVybWlzc2lv bnMuCj4gCj4gRWFjaCBlbnRyeSBpbiB0aGUgTkZTdjQgYWNsIGFwcGxpZXMgdG8gdGhlIGZpbGUg b3duZXIgKE9XTkVSQCksIHRoZQo+IG93bmluZyBncm91cCAoR1JPVVBAKSwgZXZlcnlvbmUgKEVW RVJZT05FQCksIG9yIHRvIGEgc3BlY2lmaWMgdWlkIG9yCj4gZ2lkLgo+IAo+IEFzIGluIHRoZSBz dGFuZGFyZCBQT1NJWCBmaWxlIHBlcm1pc3Npb24gbW9kZWwsIGVhY2ggcHJvY2VzcyBpcyB0aGUK PiBvd25lciwgZ3JvdXAsIG9yIG90aGVyIGZpbGUgY2xhc3MuwqDCoEEgcmljaGFjbCBncmFudHMg YSByZXF1ZXN0ZWQgYWNjZXNzCj4gb25seSBpZiB0aGUgTkZTdjQgYWNsIGluIHRoZSByaWNoYWNs IGdyYW50cyB0aGUgYWNjZXNzIChhY2NvcmRpbmcgdG8gdGhlCj4gTkZTdjQgcGVybWlzc2lvbiBj aGVjayBhbGdvcml0aG0pLCBhbmQgdGhlIGZpbGUgbWFzayB0aGF0IGFwcGxpZXMgdG8gdGhlCj4g cHJvY2VzcyBpbmNsdWRlcyB0aGUgcmVxdWVzdGVkIHBlcm1pc3Npb25zLgo+IAo+IFNpZ25lZC1v ZmYtYnk6IEFuZHJlYXMgR3J1ZW5iYWNoZXIgPGFncnVlbmJhQHJlZGhhdC5jb20+Cj4gUmV2aWV3 ZWQtYnk6IEouIEJydWNlIEZpZWxkcyA8YmZpZWxkc0ByZWRoYXQuY29tPgo+IC0tLQo+IMKgZnMv TWFrZWZpbGXCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgMSArCj4g wqBmcy9yaWNoYWNsLmPCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqA2NSAr KysrKysrKysrKysrKysrCj4gwqBpbmNsdWRlL2xpbnV4L3JpY2hhY2wuaMKgwqDCoMKgwqDCoHwg MTc5ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKPiDCoGluY2x1 ZGUvdWFwaS9saW51eC9LYnVpbGTCoMKgwqDCoHzCoMKgwqAxICsKPiDCoGluY2x1ZGUvdWFwaS9s aW51eC9yaWNoYWNsLmggfMKgwqA5OSArKysrKysrKysrKysrKysrKysrKysrKysKPiDCoDUgZmls ZXMgY2hhbmdlZCwgMzQ1IGluc2VydGlvbnMoKykKPiDCoGNyZWF0ZSBtb2RlIDEwMDY0NCBmcy9y aWNoYWNsLmMKPiDCoGNyZWF0ZSBtb2RlIDEwMDY0NCBpbmNsdWRlL2xpbnV4L3JpY2hhY2wuaAo+ IMKgY3JlYXRlIG1vZGUgMTAwNjQ0IGluY2x1ZGUvdWFwaS9saW51eC9yaWNoYWNsLmgKPiAKPiBk aWZmIC0tZ2l0IGEvZnMvTWFrZWZpbGUgYi9mcy9NYWtlZmlsZQo+IGluZGV4IDg1YjZlMTMuLjJi M2U2ZjEgMTAwNjQ0Cj4gLS0tIGEvZnMvTWFrZWZpbGUKPiArKysgYi9mcy9NYWtlZmlsZQo+IEBA IC00OSw2ICs0OSw3IEBAIG9iai0kKENPTkZJR19DT1JFRFVNUCkJCSs9IGNvcmVkdW1wLm8KPiDC oG9iai0kKENPTkZJR19TWVNDVEwpCQkrPSBkcm9wX2NhY2hlcy5vCj4gwqAKPiDCoG9iai0kKENP TkZJR19GSEFORExFKQkJKz0gZmhhbmRsZS5vCj4gK29iai0kKENPTkZJR19GU19SSUNIQUNMKQkr PSByaWNoYWNsLm8KPiDCoAo+IMKgb2JqLXkJCQkJKz0gcXVvdGEvCj4gwqAKPiBkaWZmIC0tZ2l0 IGEvZnMvcmljaGFjbC5jIGIvZnMvcmljaGFjbC5jCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBp bmRleCAwMDAwMDAwLi5iY2M2NTkxCj4gLS0tIC9kZXYvbnVsbAo+ICsrKyBiL2ZzL3JpY2hhY2wu Ywo+IEBAIC0wLDAgKzEsNjUgQEAKPiArLyoKPiArICogQ29weXJpZ2h0IChDKSAyMDA2LCAyMDEw wqDCoE5vdmVsbCwgSW5jLgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTXCoMKgUmVkIEhhdCwgSW5j Lgo+ICsgKiBXcml0dGVuIGJ5IEFuZHJlYXMgR3J1ZW5iYWNoZXIgPGFncnVlbmJhQHJlZGhhdC5j b20+Cj4gKyAqCj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJl ZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Cj4gKyAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0 aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZQo+ICsgKiBG cmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIsIG9yIChhdCB5b3VyIG9w dGlvbikgYW55Cj4gKyAqIGxhdGVyIHZlcnNpb24uCj4gKyAqCj4gKyAqIFRoaXMgcHJvZ3JhbSBp cyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQKPiAr ICogV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50 eSBvZgo+ICsgKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBV UlBPU0UuwqDCoFNlZSB0aGUgR05VCj4gKyAqIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1v cmUgZGV0YWlscy4KPiArICovCj4gKwo+ICsjaW5jbHVkZSAKPiArI2luY2x1ZGUgCj4gKyNpbmNs dWRlIAo+ICsjaW5jbHVkZSAKPiArI2luY2x1ZGUgCj4gKwo+ICsvKioKPiArICogcmljaGFjbF9h bGxvY8KgwqAtwqDCoGFsbG9jYXRlIGEgcmljaGFjbAo+ICsgKiBAY291bnQ6CW51bWJlciBvZiBl bnRyaWVzCj4gKyAqLwo+ICtzdHJ1Y3QgcmljaGFjbCAqCj4gK3JpY2hhY2xfYWxsb2MoaW50IGNv dW50LCBnZnBfdCBnZnApCj4gK3sKPiArCXNpemVfdCBzaXplID0gc2l6ZW9mKHN0cnVjdCByaWNo YWNsKSArIGNvdW50ICogc2l6ZW9mKHN0cnVjdCByaWNoYWNlKTsKPiArCXN0cnVjdCByaWNoYWNs ICphY2wgPSBremFsbG9jKHNpemUsIGdmcCk7Cj4gKwo+ICsJaWYgKGFjbCkgewo+ICsJCWF0b21p Y19zZXQoJmFjbC0+YV9yZWZjb3VudCwgMSk7Cj4gKwkJYWNsLT5hX2NvdW50ID0gY291bnQ7Cj4g Kwl9Cj4gKwlyZXR1cm4gYWNsOwo+ICt9Cj4gK0VYUE9SVF9TWU1CT0xfR1BMKHJpY2hhY2xfYWxs b2MpOwo+ICsKCkkgaW1hZ2luZSB3ZSBjb3VsZCBoYXZlIGEgbG90IG9mIHRoZXNlIGF0IGFueSBn aXZlbiB0aW1lLiBJdCBtaWdodCBiZQpuaWNlIHRvIGNvbnNpZGVyIGhvdyB0byBkbyB0aGlzIHdp dGggZGVkaWNhdGVkIHNsYWJjYWNoZXMgZm9yIGJldHRlcgpwYWNraW5nLCBidXQgSSB0aGluayB0 aGF0IHdvdWxkIGFkZCB0byB0aGUgY29tcGxleGl0eSwgdW5mb3J0dW5hdGVseS4KCj4gKy8qKgo+ ICsgKiByaWNoYWNsX2Nsb25lwqDCoC3CoMKgY3JlYXRlIGEgY29weSBvZiBhIHJpY2hhY2wKPiAr ICovCj4gK3N0cnVjdCByaWNoYWNsICoKPiArcmljaGFjbF9jbG9uZShjb25zdCBzdHJ1Y3Qgcmlj aGFjbCAqYWNsLCBnZnBfdCBnZnApCj4gK3sKPiArCWludCBjb3VudCA9IGFjbC0+YV9jb3VudDsK PiArCXNpemVfdCBzaXplID0gc2l6ZW9mKHN0cnVjdCByaWNoYWNsKSArIGNvdW50ICogc2l6ZW9m KHN0cnVjdCByaWNoYWNlKTsKPiArCXN0cnVjdCByaWNoYWNsICpkdXAgPSBrbWFsbG9jKHNpemUs IGdmcCk7Cj4gKwo+ICsJaWYgKGR1cCkgewo+ICsJCW1lbWNweShkdXAsIGFjbCwgc2l6ZSk7Cj4g KwkJYXRvbWljX3NldCgmZHVwLT5hX3JlZmNvdW50LCAxKTsKPiArCX0KPiArCXJldHVybiBkdXA7 Cj4gK30KPiArCj4gKy8qKgo+ICsgKiByaWNoYWNlX2NvcHnCoMKgLcKgwqBjb3B5IGFuIGFjbCBl bnRyeQo+ICsgKi8KPiArdm9pZAo+ICtyaWNoYWNlX2NvcHkoc3RydWN0IHJpY2hhY2UgKnRvLCBj b25zdCBzdHJ1Y3QgcmljaGFjZSAqZnJvbSkKPiArewo+ICsJbWVtY3B5KHRvLCBmcm9tLCBzaXpl b2Yoc3RydWN0IHJpY2hhY2UpKTsKPiArfQo+IGRpZmYgLS1naXQgYS9pbmNsdWRlL2xpbnV4L3Jp Y2hhY2wuaCBiL2luY2x1ZGUvbGludXgvcmljaGFjbC5oCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQK PiBpbmRleCAwMDAwMDAwLi5lZGI4NDgwCj4gLS0tIC9kZXYvbnVsbAo+ICsrKyBiL2luY2x1ZGUv bGludXgvcmljaGFjbC5oCj4gQEAgLTAsMCArMSwxNzkgQEAKPiArLyoKPiArICogQ29weXJpZ2h0 IChDKSAyMDA2LCAyMDEwwqDCoE5vdmVsbCwgSW5jLgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTXC oMKgUmVkIEhhdCwgSW5jLgo+ICsgKiBXcml0dGVuIGJ5IEFuZHJlYXMgR3J1ZW5iYWNoZXIgPGFn cnVlbmJhQHJlZGhhdC5jb20+Cj4gKyAqCj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3 YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0Cj4gKyAqIHVuZGVy IHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVk IGJ5IHRoZQo+ICsgKiBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIs IG9yIChhdCB5b3VyIG9wdGlvbikgYW55Cj4gKyAqIGxhdGVyIHZlcnNpb24uCj4gKyAqCj4gKyAq IFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUg dXNlZnVsLCBidXQKPiArICogV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUg aW1wbGllZCB3YXJyYW50eSBvZgo+ICsgKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1Ig QSBQQVJUSUNVTEFSIFBVUlBPU0UuwqDCoFNlZSB0aGUgR05VCj4gKyAqIEdlbmVyYWwgUHVibGlj IExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KPiArICovCj4gKwo+ICsjaWZuZGVmIF9fUklDSEFD TF9ICj4gKyNkZWZpbmUgX19SSUNIQUNMX0gKPiArCj4gKyNpbmNsdWRlIAo+ICsKPiArc3RydWN0 IHJpY2hhY2Ugewo+ICsJdW5zaWduZWQgc2hvcnQJZV90eXBlOwo+ICsJdW5zaWduZWQgc2hvcnQJ ZV9mbGFnczsKPiArCXVuc2lnbmVkIGludAllX21hc2s7Cj4gKwl1bmlvbiB7Cj4gKwkJa3VpZF90 CQl1aWQ7Cj4gKwkJa2dpZF90CQlnaWQ7Cj4gKwkJdW5zaWduZWQgaW50CXNwZWNpYWw7Cj4gKwl9 IGVfaWQ7Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgcmljaGFjbCB7Cj4gKwlhdG9taWNfdAlhX3JlZmNv dW50Owo+ICsJdW5zaWduZWQgaW50CWFfb3duZXJfbWFzazsKPiArCXVuc2lnbmVkIGludAlhX2dy b3VwX21hc2s7Cj4gKwl1bnNpZ25lZCBpbnQJYV9vdGhlcl9tYXNrOwo+ICsJdW5zaWduZWQgc2hv cnQJYV9jb3VudDsKPiArCXVuc2lnbmVkIHNob3J0CWFfZmxhZ3M7Cj4gKwlzdHJ1Y3QgcmljaGFj ZQlhX2VudHJpZXNbMF07Cj4gK307Cj4gKwo+ICsjZGVmaW5lIHJpY2hhY2xfZm9yX2VhY2hfZW50 cnkoX2FjZSwgX2FjbCkJCQlcCj4gKwlmb3IgKF9hY2UgPSAoX2FjbCktPmFfZW50cmllczsJCQkJ XAo+ICsJwqDCoMKgwqDCoF9hY2UgIT0gKF9hY2wpLT5hX2VudHJpZXMgKyAoX2FjbCktPmFfY291 bnQ7CVwKPiArCcKgwqDCoMKgwqBfYWNlKyspCj4gKwo+ICsjZGVmaW5lIHJpY2hhY2xfZm9yX2Vh Y2hfZW50cnlfcmV2ZXJzZShfYWNlLCBfYWNsKQkJXAo+ICsJZm9yIChfYWNlID0gKF9hY2wpLT5h X2VudHJpZXMgKyAoX2FjbCktPmFfY291bnQgLSAxOwlcCj4gKwnCoMKgwqDCoMKgX2FjZSAhPSAo X2FjbCktPmFfZW50cmllcyAtIDE7CQkJXAo+ICsJwqDCoMKgwqDCoF9hY2UtLSkKPiArCj4gKy8q Kgo+ICsgKiByaWNoYWNsX2dldMKgwqAtwqDCoGdyYWIgYW5vdGhlciByZWZlcmVuY2UgdG8gYSBy aWNoYWNsIGhhbmRsZQo+ICsgKi8KPiArc3RhdGljIGlubGluZSBzdHJ1Y3QgcmljaGFjbCAqCj4g K3JpY2hhY2xfZ2V0KHN0cnVjdCByaWNoYWNsICphY2wpCj4gK3sKPiArCWlmIChhY2wpCj4gKwkJ YXRvbWljX2luYygmYWNsLT5hX3JlZmNvdW50KTsKPiArCXJldHVybiBhY2w7Cj4gK30KPiArCj4g Ky8qKgo+ICsgKiByaWNoYWNsX3B1dMKgwqAtwqDCoGZyZWUgYSByaWNoYWNsIGhhbmRsZQo+ICsg Ki8KPiArc3RhdGljIGlubGluZSB2b2lkCj4gK3JpY2hhY2xfcHV0KHN0cnVjdCByaWNoYWNsICph Y2wpCj4gK3sKPiArCWlmIChhY2wgJiYgYXRvbWljX2RlY19hbmRfdGVzdCgmYWNsLT5hX3JlZmNv dW50KSkKPiArCQlrZnJlZShhY2wpOwo+ICt9Cj4gKwo+ICsvKioKPiArICogcmljaGFjZV9pc19v d25lcsKgwqAtwqDCoGNoZWNrIGlmIEBhY2UgaXMgYW4gT1dORVJAIGVudHJ5Cj4gKyAqLwo+ICtz dGF0aWMgaW5saW5lIGJvb2wKPiArcmljaGFjZV9pc19vd25lcihjb25zdCBzdHJ1Y3QgcmljaGFj ZSAqYWNlKQo+ICt7Cj4gKwlyZXR1cm4gKGFjZS0+ZV9mbGFncyAmIFJJQ0hBQ0VfU1BFQ0lBTF9X SE8pICYmCj4gKwnCoMKgwqDCoMKgwqDCoGFjZS0+ZV9pZC5zcGVjaWFsID09IFJJQ0hBQ0VfT1dO RVJfU1BFQ0lBTF9JRDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIHJpY2hhY2VfaXNfZ3JvdXDCoMKg LcKgwqBjaGVjayBpZiBAYWNlIGlzIGEgR1JPVVBAIGVudHJ5Cj4gKyAqLwo+ICtzdGF0aWMgaW5s aW5lIGJvb2wKPiArcmljaGFjZV9pc19ncm91cChjb25zdCBzdHJ1Y3QgcmljaGFjZSAqYWNlKQo+ ICt7Cj4gKwlyZXR1cm4gKGFjZS0+ZV9mbGFncyAmIFJJQ0hBQ0VfU1BFQ0lBTF9XSE8pICYmCj4g KwnCoMKgwqDCoMKgwqDCoGFjZS0+ZV9pZC5zcGVjaWFsID09IFJJQ0hBQ0VfR1JPVVBfU1BFQ0lB TF9JRDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIHJpY2hhY2VfaXNfZXZlcnlvbmXCoMKgLcKgwqBj aGVjayBpZiBAYWNlIGlzIGFuIEVWRVJZT05FQCBlbnRyeQo+ICsgKi8KPiArc3RhdGljIGlubGlu ZSBib29sCj4gK3JpY2hhY2VfaXNfZXZlcnlvbmUoY29uc3Qgc3RydWN0IHJpY2hhY2UgKmFjZSkK PiArewo+ICsJcmV0dXJuIChhY2UtPmVfZmxhZ3MgJiBSSUNIQUNFX1NQRUNJQUxfV0hPKSAmJgo+ ICsJwqDCoMKgwqDCoMKgwqBhY2UtPmVfaWQuc3BlY2lhbCA9PSBSSUNIQUNFX0VWRVJZT05FX1NQ RUNJQUxfSUQ7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiByaWNoYWNlX2lzX3VuaXhfdXNlcsKgwqAt wqDCoGNoZWNrIGlmIEBhY2UgYXBwbGllcyB0byBhIHNwZWNpZmljIHVzZXIKPiArICovCj4gK3N0 YXRpYyBpbmxpbmUgYm9vbAo+ICtyaWNoYWNlX2lzX3VuaXhfdXNlcihjb25zdCBzdHJ1Y3Qgcmlj aGFjZSAqYWNlKQo+ICt7Cj4gKwlyZXR1cm4gIShhY2UtPmVfZmxhZ3MgJiBSSUNIQUNFX1NQRUNJ QUxfV0hPKSAmJgo+ICsJwqDCoMKgwqDCoMKgwqAhKGFjZS0+ZV9mbGFncyAmIFJJQ0hBQ0VfSURF TlRJRklFUl9HUk9VUCk7Cj4gK30KPiArCj4gKy8qKgo+ICsgKiByaWNoYWNlX2lzX3VuaXhfZ3Jv dXDCoMKgLcKgwqBjaGVjayBpZiBAYWNlIGFwcGxpZXMgdG8gYSBzcGVjaWZpYyBncm91cAo+ICsg Ki8KPiArc3RhdGljIGlubGluZSBib29sCj4gK3JpY2hhY2VfaXNfdW5peF9ncm91cChjb25zdCBz dHJ1Y3QgcmljaGFjZSAqYWNlKQo+ICt7Cj4gKwlyZXR1cm4gIShhY2UtPmVfZmxhZ3MgJiBSSUNI QUNFX1NQRUNJQUxfV0hPKSAmJgo+ICsJwqDCoMKgwqDCoMKgwqAoYWNlLT5lX2ZsYWdzICYgUklD SEFDRV9JREVOVElGSUVSX0dST1VQKTsKPiArfQo+ICsKPiArLyoqCj4gKyAqIHJpY2hhY2VfaXNf aW5oZXJpdF9vbmx5wqDCoC3CoMKgY2hlY2sgaWYgQGFjZSBpcyBmb3IgaW5oZXJpdGFuY2Ugb25s eQo+ICsgKgo+ICsgKiBBQ0VzIHdpdGggdGhlICVSSUNIQUNFX0lOSEVSSVRfT05MWV9BQ0UgZmxh ZyBzZXQgaGF2ZSBubyBlZmZlY3QgZHVyaW5nCj4gKyAqIHBlcm1pc3Npb24gY2hlY2tpbmcuCj4g KyAqLwo+ICtzdGF0aWMgaW5saW5lIGJvb2wKPiArcmljaGFjZV9pc19pbmhlcml0X29ubHkoY29u c3Qgc3RydWN0IHJpY2hhY2UgKmFjZSkKPiArewo+ICsJcmV0dXJuIGFjZS0+ZV9mbGFncyAmIFJJ Q0hBQ0VfSU5IRVJJVF9PTkxZX0FDRTsKPiArfQo+ICsKPiArLyoqCj4gKyAqIHJpY2hhY2VfaXNf aW5oZXJpdGFibGXCoMKgLcKgwqBjaGVjayBpZiBAYWNlIGlzIGluaGVyaXRhYmxlCj4gKyAqLwo+ ICtzdGF0aWMgaW5saW5lIGJvb2wKPiArcmljaGFjZV9pc19pbmhlcml0YWJsZShjb25zdCBzdHJ1 Y3QgcmljaGFjZSAqYWNlKQo+ICt7Cj4gKwlyZXR1cm4gYWNlLT5lX2ZsYWdzICYgKFJJQ0hBQ0Vf RklMRV9JTkhFUklUX0FDRSB8Cj4gKwkJCcKgwqDCoMKgwqDCoMKgUklDSEFDRV9ESVJFQ1RPUllf SU5IRVJJVF9BQ0UpOwo+ICt9Cj4gKwo+ICsvKioKPiArICogcmljaGFjZV9pc19hbGxvd8KgwqAt wqDCoGNoZWNrIGlmIEBhY2UgaXMgYW4gJUFMTE9XIHR5cGUgZW50cnkKPiArICovCj4gK3N0YXRp YyBpbmxpbmUgYm9vbAo+ICtyaWNoYWNlX2lzX2FsbG93KGNvbnN0IHN0cnVjdCByaWNoYWNlICph Y2UpCj4gK3sKPiArCXJldHVybiBhY2UtPmVfdHlwZSA9PSBSSUNIQUNFX0FDQ0VTU19BTExPV0VE X0FDRV9UWVBFOwo+ICt9Cj4gKwo+ICsvKioKPiArICogcmljaGFjZV9pc19kZW55wqDCoC3CoMKg Y2hlY2sgaWYgQGFjZSBpcyBhICVERU5ZIHR5cGUgZW50cnkKPiArICovCj4gK3N0YXRpYyBpbmxp bmUgYm9vbAo+ICtyaWNoYWNlX2lzX2RlbnkoY29uc3Qgc3RydWN0IHJpY2hhY2UgKmFjZSkKPiAr ewo+ICsJcmV0dXJuIGFjZS0+ZV90eXBlID09IFJJQ0hBQ0VfQUNDRVNTX0RFTklFRF9BQ0VfVFlQ RTsKPiArfQo+ICsKPiArLyoqCj4gKyAqIHJpY2hhY2VfaXNfc2FtZV9pZGVudGlmaWVywqDCoC3C oMKgYXJlIGJvdGggaWRlbnRpZmllcnMgdGhlIHNhbWU/Cj4gKyAqLwo+ICtzdGF0aWMgaW5saW5l IGJvb2wKPiArcmljaGFjZV9pc19zYW1lX2lkZW50aWZpZXIoY29uc3Qgc3RydWN0IHJpY2hhY2Ug KmEsIGNvbnN0IHN0cnVjdCByaWNoYWNlICpiKQo+ICt7Cj4gKwlyZXR1cm4gISgoYS0+ZV9mbGFn cyBeIGItPmVfZmxhZ3MpICYKPiArCQnCoChSSUNIQUNFX1NQRUNJQUxfV0hPIHwgUklDSEFDRV9J REVOVElGSUVSX0dST1VQKSkgJiYKPiArCcKgwqDCoMKgwqDCoMKgIW1lbWNtcCgmYS0+ZV9pZCwg JmItPmVfaWQsIHNpemVvZihhLT5lX2lkKSk7Cj4gK30KPiArCj4gK2V4dGVybiBzdHJ1Y3Qgcmlj aGFjbCAqcmljaGFjbF9hbGxvYyhpbnQsIGdmcF90KTsKPiArZXh0ZXJuIHN0cnVjdCByaWNoYWNs ICpyaWNoYWNsX2Nsb25lKGNvbnN0IHN0cnVjdCByaWNoYWNsICosIGdmcF90KTsKPiArZXh0ZXJu IHZvaWQgcmljaGFjZV9jb3B5KHN0cnVjdCByaWNoYWNlICosIGNvbnN0IHN0cnVjdCByaWNoYWNl ICopOwo+ICsKPiArI2VuZGlmIC8qIF9fUklDSEFDTF9IICovCj4gZGlmZiAtLWdpdCBhL2luY2x1 ZGUvdWFwaS9saW51eC9LYnVpbGQgYi9pbmNsdWRlL3VhcGkvbGludXgvS2J1aWxkCj4gaW5kZXgg OGJkYWUzNC4uYWJlYWE5OCAxMDA2NDQKPiAtLS0gYS9pbmNsdWRlL3VhcGkvbGludXgvS2J1aWxk Cj4gKysrIGIvaW5jbHVkZS91YXBpL2xpbnV4L0tidWlsZAo+IEBAIC0zNTUsNiArMzU1LDcgQEAg aGVhZGVyLXkgKz0gcmVib290LmgKPiDCoGhlYWRlci15ICs9IHJlaXNlcmZzX2ZzLmgKPiDCoGhl YWRlci15ICs9IHJlaXNlcmZzX3hhdHRyLmgKPiDCoGhlYWRlci15ICs9IHJlc291cmNlLmgKPiAr aGVhZGVyLXkgKz0gcmljaGFjbC5oCj4gwqBoZWFkZXIteSArPSByZmtpbGwuaAo+IMKgaGVhZGVy LXkgKz0gcmlvX21wb3J0X2NkZXYuaAo+IMKgaGVhZGVyLXkgKz0gcm9tZnNfZnMuaAo+IGRpZmYg LS1naXQgYS9pbmNsdWRlL3VhcGkvbGludXgvcmljaGFjbC5oIGIvaW5jbHVkZS91YXBpL2xpbnV4 L3JpY2hhY2wuaAo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMC4uMDg4NTZm OAo+IC0tLSAvZGV2L251bGwKPiArKysgYi9pbmNsdWRlL3VhcGkvbGludXgvcmljaGFjbC5oCj4g QEAgLTAsMCArMSw5OSBAQAo+ICsvKgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMDYsIDIwMTDCoMKg Tm92ZWxsLCBJbmMuCj4gKyAqIENvcHlyaWdodCAoQykgMjAxNcKgwqBSZWQgSGF0LCBJbmMuCj4g KyAqIFdyaXR0ZW4gYnkgQW5kcmVhcyBHcnVlbmJhY2hlciA8YWdydWVuYmFAcmVkaGF0LmNvbT4K PiArICoKPiArICogVGhpcyBmaWxlIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmli dXRlIGl0IGFuZC9vcgo+ICsgKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUg TGVzc2VyIEdlbmVyYWwgUHVibGljCj4gKyAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBG cmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgo+ICsgKiB2ZXJzaW9uIDIuMSBvZiB0aGUg TGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KPiArICoKPiAr ICogVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1 c2VmdWwsCj4gKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBp bXBsaWVkIHdhcnJhbnR5IG9mCj4gKyAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBB IFBBUlRJQ1VMQVIgUFVSUE9TRS7CoMKgU2VlIHRoZSBHTlUKPiArICogTGVzc2VyIEdlbmVyYWwg UHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KPiArICovCj4gKwo+ICsjaWZuZGVmIF9f VUFQSV9SSUNIQUNMX0gKPiArI2RlZmluZSBfX1VBUElfUklDSEFDTF9ICj4gKwo+ICsvKiBhX2Zs YWdzIHZhbHVlcyAqLwo+ICsjZGVmaW5lIFJJQ0hBQ0xfV1JJVEVfVEhST1VHSAkJCTB4NDAKPiAr I2RlZmluZSBSSUNIQUNMX01BU0tFRAkJCQkweDgwCj4gKwo+ICsvKiBlX3R5cGUgdmFsdWVzICov Cj4gKyNkZWZpbmUgUklDSEFDRV9BQ0NFU1NfQUxMT1dFRF9BQ0VfVFlQRQkJMHgwMDAwCj4gKyNk ZWZpbmUgUklDSEFDRV9BQ0NFU1NfREVOSUVEX0FDRV9UWVBFCQkweDAwMDEKPiArCj4gKy8qIGVf ZmxhZ3MgYml0ZmxhZ3MgKi8KPiArI2RlZmluZSBSSUNIQUNFX0ZJTEVfSU5IRVJJVF9BQ0UJCTB4 MDAwMQo+ICsjZGVmaW5lIFJJQ0hBQ0VfRElSRUNUT1JZX0lOSEVSSVRfQUNFCQkweDAwMDIKPiAr I2RlZmluZSBSSUNIQUNFX05PX1BST1BBR0FURV9JTkhFUklUX0FDRQkweDAwMDQKPiArI2RlZmlu ZSBSSUNIQUNFX0lOSEVSSVRfT05MWV9BQ0UJCTB4MDAwOAo+ICsjZGVmaW5lIFJJQ0hBQ0VfSURF TlRJRklFUl9HUk9VUAkJMHgwMDQwCj4gKyNkZWZpbmUgUklDSEFDRV9TUEVDSUFMX1dITwkJCTB4 NDAwMAo+ICsKPiArLyogZV9tYXNrIGJpdGZsYWdzICovCj4gKyNkZWZpbmUgUklDSEFDRV9SRUFE X0RBVEEJCQkweDAwMDAwMDAxCj4gKyNkZWZpbmUgUklDSEFDRV9MSVNUX0RJUkVDVE9SWQkJCTB4 MDAwMDAwMDEKPiArI2RlZmluZSBSSUNIQUNFX1dSSVRFX0RBVEEJCQkweDAwMDAwMDAyCj4gKyNk ZWZpbmUgUklDSEFDRV9BRERfRklMRQkJCTB4MDAwMDAwMDIKPiArI2RlZmluZSBSSUNIQUNFX0FQ UEVORF9EQVRBCQkJMHgwMDAwMDAwNAo+ICsjZGVmaW5lIFJJQ0hBQ0VfQUREX1NVQkRJUkVDVE9S WQkJMHgwMDAwMDAwNAo+ICsjZGVmaW5lIFJJQ0hBQ0VfUkVBRF9OQU1FRF9BVFRSUwkJMHgwMDAw MDAwOAo+ICsjZGVmaW5lIFJJQ0hBQ0VfV1JJVEVfTkFNRURfQVRUUlMJCTB4MDAwMDAwMTAKPiAr I2RlZmluZSBSSUNIQUNFX0VYRUNVVEUJCQkJMHgwMDAwMDAyMAo+ICsjZGVmaW5lIFJJQ0hBQ0Vf REVMRVRFX0NISUxECQkJMHgwMDAwMDA0MAo+ICsjZGVmaW5lIFJJQ0hBQ0VfUkVBRF9BVFRSSUJV VEVTCQkJMHgwMDAwMDA4MAo+ICsjZGVmaW5lIFJJQ0hBQ0VfV1JJVEVfQVRUUklCVVRFUwkJMHgw MDAwMDEwMAo+ICsjZGVmaW5lIFJJQ0hBQ0VfV1JJVEVfUkVURU5USU9OCQkJMHgwMDAwMDIwMAo+ ICsjZGVmaW5lIFJJQ0hBQ0VfV1JJVEVfUkVURU5USU9OX0hPTEQJCTB4MDAwMDA0MDAKPiArI2Rl ZmluZSBSSUNIQUNFX0RFTEVURQkJCQkweDAwMDEwMDAwCj4gKyNkZWZpbmUgUklDSEFDRV9SRUFE X0FDTAkJCTB4MDAwMjAwMDAKPiArI2RlZmluZSBSSUNIQUNFX1dSSVRFX0FDTAkJCTB4MDAwNDAw MDAKPiArI2RlZmluZSBSSUNIQUNFX1dSSVRFX09XTkVSCQkJMHgwMDA4MDAwMAo+ICsjZGVmaW5l IFJJQ0hBQ0VfU1lOQ0hST05JWkUJCQkweDAwMTAwMDAwCj4gKwo+ICsvKiBlX2lkIHZhbHVlcyAq Lwo+ICsjZGVmaW5lIFJJQ0hBQ0VfT1dORVJfU1BFQ0lBTF9JRAkJMAo+ICsjZGVmaW5lIFJJQ0hB Q0VfR1JPVVBfU1BFQ0lBTF9JRAkJMQo+ICsjZGVmaW5lIFJJQ0hBQ0VfRVZFUllPTkVfU1BFQ0lB TF9JRAkJMgo+ICsKPiArI2RlZmluZSBSSUNIQUNMX1ZBTElEX0ZMQUdTICgJCQkJCVwKPiArCVJJ Q0hBQ0xfV1JJVEVfVEhST1VHSCB8CQkJCQlcCj4gKwlSSUNIQUNMX01BU0tFRCApCj4gKwo+ICsj ZGVmaW5lIFJJQ0hBQ0VfVkFMSURfRkxBR1MgKAkJCQkJXAo+ICsJUklDSEFDRV9GSUxFX0lOSEVS SVRfQUNFIHwJCQkJXAo+ICsJUklDSEFDRV9ESVJFQ1RPUllfSU5IRVJJVF9BQ0UgfAkJCQlcCj4g KwlSSUNIQUNFX05PX1BST1BBR0FURV9JTkhFUklUX0FDRSB8CQkJXAo+ICsJUklDSEFDRV9JTkhF UklUX09OTFlfQUNFIHwJCQkJXAo+ICsJUklDSEFDRV9JREVOVElGSUVSX0dST1VQIHwJCQkJXAo+ ICsJUklDSEFDRV9TUEVDSUFMX1dITyApCj4gKwo+ICsjZGVmaW5lIFJJQ0hBQ0VfSU5IRVJJVEFO Q0VfRkxBR1MgKAkJCQlcCj4gKwlSSUNIQUNFX0ZJTEVfSU5IRVJJVF9BQ0UgfAkJCQlcCj4gKwlS SUNIQUNFX0RJUkVDVE9SWV9JTkhFUklUX0FDRSB8CQkJCVwKPiArCVJJQ0hBQ0VfTk9fUFJPUEFH QVRFX0lOSEVSSVRfQUNFIHwJCQlcCj4gKwlSSUNIQUNFX0lOSEVSSVRfT05MWV9BQ0UgKQo+ICsK PiArLyogVmFsaWQgUklDSEFDRV8qIGZsYWdzIGZvciBkaXJlY3RvcmllcyBhbmQgbm9uLWRpcmVj dG9yaWVzICovCj4gKyNkZWZpbmUgUklDSEFDRV9WQUxJRF9NQVNLICgJCQkJCVwKPiArCVJJQ0hB Q0VfUkVBRF9EQVRBIHwgUklDSEFDRV9MSVNUX0RJUkVDVE9SWSB8CQlcCj4gKwlSSUNIQUNFX1dS SVRFX0RBVEEgfCBSSUNIQUNFX0FERF9GSUxFIHwJCQlcCj4gKwlSSUNIQUNFX0FQUEVORF9EQVRB IHwgUklDSEFDRV9BRERfU1VCRElSRUNUT1JZIHwJXAo+ICsJUklDSEFDRV9SRUFEX05BTUVEX0FU VFJTIHwJCQkJXAo+ICsJUklDSEFDRV9XUklURV9OQU1FRF9BVFRSUyB8CQkJCVwKPiArCVJJQ0hB Q0VfRVhFQ1VURSB8CQkJCQlcCj4gKwlSSUNIQUNFX0RFTEVURV9DSElMRCB8CQkJCQlcCj4gKwlS SUNIQUNFX1JFQURfQVRUUklCVVRFUyB8CQkJCVwKPiArCVJJQ0hBQ0VfV1JJVEVfQVRUUklCVVRF UyB8CQkJCVwKPiArCVJJQ0hBQ0VfV1JJVEVfUkVURU5USU9OIHwJCQkJXAo+ICsJUklDSEFDRV9X UklURV9SRVRFTlRJT05fSE9MRCB8CQkJCVwKPiArCVJJQ0hBQ0VfREVMRVRFIHwJCQkJCVwKPiAr CVJJQ0hBQ0VfUkVBRF9BQ0wgfAkJCQkJXAo+ICsJUklDSEFDRV9XUklURV9BQ0wgfAkJCQkJXAo+ ICsJUklDSEFDRV9XUklURV9PV05FUiB8CQkJCQlcCj4gKwlSSUNIQUNFX1NZTkNIUk9OSVpFICkK PiArCj4gKyNlbmRpZiAvKiBfX1VBUElfUklDSEFDTF9IICovCgpSZXZpZXdlZC1ieTogSmVmZiBM YXl0b24gPGpsYXl0b25AcmVkaGF0LmNvbT4KCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fCnhmcyBtYWlsaW5nIGxpc3QKeGZzQG9zcy5zZ2kuY29tCmh0dHA6 Ly9vc3Muc2dpLmNvbS9tYWlsbWFuL2xpc3RpbmZvL3hmcwo=