[OE-core] [PATCH][PSEUDO 1/4] linux/xattr/pseudo_wrappers.c: Preserve special bits on acl set

Richard Tollerton rich.tollerton at ni.com
Wed Nov 29 18:02:39 UTC 2017


Recently (2015) coreutils cp -Rp changed its behavior such that chmod()
is followed by setxattr(); previously it was the other way around. This
broke pseudo when a copied directory has one of the special
bits (setuid, setgid, sticky) set; the special bit wound up getting
removed.

Root cause is that ACLs never included special bits in the first place,
so we need to merge them back in ourselves.

[YOCTO #12379]

Signed-off-by: Richard Tollerton <rich.tollerton at ni.com>
---
 ports/linux/xattr/pseudo_wrappers.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/ports/linux/xattr/pseudo_wrappers.c b/ports/linux/xattr/pseudo_wrappers.c
index d69d53e..1c228a2 100644
--- a/ports/linux/xattr/pseudo_wrappers.c
+++ b/ports/linux/xattr/pseudo_wrappers.c
@@ -97,6 +97,21 @@ posix_permissions(const acl_header *header, int entries, int *extra, int *mode)
 	return 0;
 }
 
+static int get_special_bits(const char *path, int fd) {
+	int rc;
+	struct stat64 buf;
+	if (path) {
+		rc = lstat64(path, &buf);
+	} else {
+		rc = fstat64(fd, &buf);
+	}
+	if (rc == -1) {
+		return rc;
+	}
+
+	return buf.st_mode & (S_ISUID | S_ISGID | S_ISVTX);
+}
+
 #define RC_AND_BUF \
 	int rc; \
 	PSEUDO_STATBUF buf; \
@@ -172,6 +187,10 @@ static int shared_setxattr(const char *path, int fd, const char *name, const voi
 		int entries = (size - sizeof(acl_header)) / sizeof(acl_entry);
 		int res = posix_permissions(value, entries, &extra, &mode);
 		if (res == 0) {
+			/* POSIX ACLs don't actually include
+			 * setuid/setgid/sticky bit. We need to add those back
+			 * in ourselves. */
+			mode |= get_special_bits(path, fd);
 			pseudo_debug(PDBGF_XATTR, "posix_acl_access translated to mode %04o. Remaining attribute(s): %d.\n",
 				mode, extra);
 			buf.st_mode = mode;
-- 
2.14.1




More information about the Openembedded-core mailing list