From: Anton Gerasimov <an...@advancedtelematic.com>

The difference between what we see in pseudo and what happens without
pseudo can be seen by typing:

    mkdir setfattr-test
    setfattr -n system.posix_acl_default -v 0x02000000 setfattr-test
    getfattr -n system.posix_acl_default setfattr-test

Under some kernel configurations this difference leads to annoying
errors, e.g. directories copied with 'cp -a' get broken in a fancy way.

Signed-off-by: Anton Gerasimov <an...@advancedtelematic.com>
---
 ports/linux/xattr/pseudo_wrappers.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/ports/linux/xattr/pseudo_wrappers.c 
b/ports/linux/xattr/pseudo_wrappers.c
index 46bc053..31a6baf 100644
--- a/ports/linux/xattr/pseudo_wrappers.c
+++ b/ports/linux/xattr/pseudo_wrappers.c
@@ -64,7 +64,7 @@ posix_permissions(const acl_header *header, int entries, int 
*extra, int *mode)
        if (le32(header->version) != 2) {
                pseudo_diag("Fatal: ACL support no available for header version 
%d.\n",
                        le32(header->version));
-               return 1;
+               return -1;
        }
        *mode = 0;
        *extra = 0;
@@ -140,12 +140,27 @@ static int shared_setxattr(const char *path, int fd, 
const char *name, const voi
        pseudo_debug(PDBGF_XATTR, "setxattr(%s [fd %d], %s => '%.*s')\n",
                path ? path : "<no path>", fd, name, (int) size, (char *) 
value);
 
+       /* Filter out erroneous sizes for POSIX ACL
+        *  see posix_acl_xattr_count in include/linux/posix_acl_xattr.h of 
Linux source code */
+       if (!strcmp(name, "system.posix_acl_access") || !strcmp(name, 
"system.posix_acl_default")) {
+               // ACL is corrupt, issue an error
+               if(size < sizeof(acl_header) || (size - sizeof(acl_header)) % 
sizeof(acl_entry) != 0) {
+                       errno = EINVAL;
+                       return -1;
+               }
+
+               // ACL is empty, do nothing
+               if((size - sizeof(acl_header)) / sizeof(acl_entry) == 0) {
+                       return 0;
+               }
+       }
        /* this may be a plain chmod */
        if (!strcmp(name, "system.posix_acl_access")) {
                int extra;
                int mode;
                int entries = (size - sizeof(acl_header)) / sizeof(acl_entry);
-               if (!posix_permissions(value, entries, &extra, &mode)) {
+               int res = posix_permissions(value, entries, &extra, &mode);
+               if (res == 0) {
                        pseudo_debug(PDBGF_XATTR, "posix_acl_access translated 
to mode %04o. Remaining attribute(s): %d.\n",
                                mode, extra);
                        buf.st_mode = mode;
@@ -164,8 +179,12 @@ static int shared_setxattr(const char *path, int fd, const 
char *name, const voi
                        if (!extra) {
                                return 0;
                        }
+               } else if (res == -1) {
+                       errno = EOPNOTSUPP;
+                       return -1;
                }
        }
+
        if (!strcmp(name, "user.pseudo_data")) {
                pseudo_debug(PDBGF_XATTR | PDBGF_XATTRDB, "user.pseudo_data 
xattribute does not get to go in database.\n");
                return -1;
-- 
2.11.1

-- 
_______________________________________________
yocto mailing list
yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/yocto

Reply via email to