diff mbox series

[v3] sstatesig: Add ACL and XATTR data to outhash

Message ID 20230818162909.1733262-1-JPEWhacker@gmail.com
State New
Headers show
Series [v3] sstatesig: Add ACL and XATTR data to outhash | expand

Commit Message

Joshua Watt Aug. 18, 2023, 4:29 p.m. UTC
Records the ACL and (some) extended attributes in the outhash

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
NOTE: This requires ACL and XATTR support from bitbake

V2: Filter ACLs to not duplicate the stat mode (since that also does
extra filtering)

V3: Fix missing .items() when iterating XATTRS

 meta/lib/oe/sstatesig.py | 42 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

Comments

Piotr Łobacz Aug. 21, 2023, 9:06 p.m. UTC | #1
W dniu 18.08.2023 o 18:29, Joshua Watt via lists.openembedded.org pisze:
> Records the ACL and (some) extended attributes in the outhash
>
Reviewed-by: Piotr Łobacz <p.lobacz@welotec.com>
Tested-by: Piotr Łobacz <p.lobacz@welotec.com>
> Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
> ---
> NOTE: This requires ACL and XATTR support from bitbake
>
> V2: Filter ACLs to not duplicate the stat mode (since that also does
> extra filtering)
>
> V3: Fix missing .items() when iterating XATTRS
>
>   meta/lib/oe/sstatesig.py | 42 ++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 42 insertions(+)
>
> diff --git a/meta/lib/oe/sstatesig.py b/meta/lib/oe/sstatesig.py
> index 633a0fd4502..fb39efa933e 100644
> --- a/meta/lib/oe/sstatesig.py
> +++ b/meta/lib/oe/sstatesig.py
> @@ -478,6 +478,8 @@ def OEOuthashBasic(path, sigfile, task, d):
>       import grp
>       import re
>       import fnmatch
> +    import bb.xattr
> +    import bb.acl
>   
>       def update_hash(s):
>           s = s.encode('utf-8')
> @@ -640,6 +642,46 @@ def OEOuthashBasic(path, sigfile, task, d):
>   
>                   update_hash("\n")
>   
> +                def filter_acl(entry):
> +                    # Skip owner user, owner group, and other tags. These are
> +                    # covered by the stat permissions above
> +                    if entry.tag in (bb.acl.ACL_USER_OBJ, bb.acl.ACL_GROUP_OBJ, bb.acl.ACL_OTHER):
> +                        return False
> +                    return True
> +
> +                def add_acl(path, typ, name):
> +                    acl = bb.acl.ACL.from_path(path, typ)
> +                    entries = [e for e in acl.entries() if filter_acl(e)]
> +                    if entries:
> +                        update_hash(name)
> +                        update_hash(":\n")
> +                        entries.sort(key=lambda x: (x.tag, x.qualifier, x.mode))
> +                        for e in entries:
> +                            update_hash(str(e))
> +                            update_hash("\n")
> +
> +                def filter_xattr(name):
> +                    # ACLs are handled above
> +                    if name == "system.posix_acl_access":
> +                        return False
> +                    if name == "system.posix_acl_default":
> +                        return False
> +                    return True
> +
> +                # libacl always follows symlinks, so skip them
> +                if not stat.S_ISLNK(s.st_mode):
> +                    add_acl(path, bb.acl.ACL_TYPE_ACCESS, "ACL")
> +                    if stat.S_ISDIR(s.st_mode):
> +                        add_acl(path, bb.acl.ACL_TYPE_DEFAULT, "Default ACL")
> +
> +                attrs = bb.xattr.get_all_xattr(path, follow=False)
> +                # Ignore ACLs; those are covered above
> +                attrs = {k: v for k, v in attrs.items() if filter_xattr(k)}
> +                if attrs:
> +                    update_hash("XATTR:\n")
> +                    for k, v in attrs.items():
> +                        update_hash("%s: %s\n" % (k, v))
> +
>               # Process this directory and all its child files
>               if include_root or root != ".":
>                   process(root)
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#186379): https://lists.openembedded.org/g/openembedded-core/message/186379
> Mute This Topic: https://lists.openembedded.org/mt/100823926/7527613
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [p.lobacz@welotec.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
diff mbox series

Patch

diff --git a/meta/lib/oe/sstatesig.py b/meta/lib/oe/sstatesig.py
index 633a0fd4502..fb39efa933e 100644
--- a/meta/lib/oe/sstatesig.py
+++ b/meta/lib/oe/sstatesig.py
@@ -478,6 +478,8 @@  def OEOuthashBasic(path, sigfile, task, d):
     import grp
     import re
     import fnmatch
+    import bb.xattr
+    import bb.acl
 
     def update_hash(s):
         s = s.encode('utf-8')
@@ -640,6 +642,46 @@  def OEOuthashBasic(path, sigfile, task, d):
 
                 update_hash("\n")
 
+                def filter_acl(entry):
+                    # Skip owner user, owner group, and other tags. These are
+                    # covered by the stat permissions above
+                    if entry.tag in (bb.acl.ACL_USER_OBJ, bb.acl.ACL_GROUP_OBJ, bb.acl.ACL_OTHER):
+                        return False
+                    return True
+
+                def add_acl(path, typ, name):
+                    acl = bb.acl.ACL.from_path(path, typ)
+                    entries = [e for e in acl.entries() if filter_acl(e)]
+                    if entries:
+                        update_hash(name)
+                        update_hash(":\n")
+                        entries.sort(key=lambda x: (x.tag, x.qualifier, x.mode))
+                        for e in entries:
+                            update_hash(str(e))
+                            update_hash("\n")
+
+                def filter_xattr(name):
+                    # ACLs are handled above
+                    if name == "system.posix_acl_access":
+                        return False
+                    if name == "system.posix_acl_default":
+                        return False
+                    return True
+
+                # libacl always follows symlinks, so skip them
+                if not stat.S_ISLNK(s.st_mode):
+                    add_acl(path, bb.acl.ACL_TYPE_ACCESS, "ACL")
+                    if stat.S_ISDIR(s.st_mode):
+                        add_acl(path, bb.acl.ACL_TYPE_DEFAULT, "Default ACL")
+
+                attrs = bb.xattr.get_all_xattr(path, follow=False)
+                # Ignore ACLs; those are covered above
+                attrs = {k: v for k, v in attrs.items() if filter_xattr(k)}
+                if attrs:
+                    update_hash("XATTR:\n")
+                    for k, v in attrs.items():
+                        update_hash("%s: %s\n" % (k, v))
+
             # Process this directory and all its child files
             if include_root or root != ".":
                 process(root)