From 995e6fd3702b5cb9d34478bd13839ce8d157a646 Mon Sep 17 00:00:00 2001 From: Dhanraj E Date: Wed, 21 Oct 2026 13:41:04 +0530 Subject: [PATCH] Fixed out-of-bounds read of extended attribute values in filestat() The "xattr" branch of filestat() reads each extended attribute value into an uninitialized stack buffer and then uses it as a C string: char data[CF_BUFSIZE]; int datasize = lgetxattr(path, current, data, sizeof(data)); ... if (!StringIsPrintable(data)) ... BufferPrintf(printattr, "%s=%s", current, data); lgetxattr() returns raw bytes and never adds a terminating NUL. An unprivileged user can set user.* attributes on files they own, so when a policy run as root calls filestat() on such a file, a printable value of exactly 4096 bytes makes StringIsPrintable() read past the end of data. Shorter values are followed by whatever stale stack bytes come before the next NUL, which either makes a valid attribute get skipped as non-printable or copies stack contents into the returned string. Read at most sizeof(data) - 1 bytes and terminate the value at datasize. CopyFileExtendedAttributesDisk() in files_copy.c, the other lgetxattr() caller, handles values by length and is not affected. Changelog: Title Signed-off-by: Dhanraj E --- libpromises/evalfunction.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libpromises/evalfunction.c b/libpromises/evalfunction.c index 7707b18d0cb..01f1d455294 100644 --- a/libpromises/evalfunction.c +++ b/libpromises/evalfunction.c @@ -5193,7 +5193,7 @@ static FnCallResult FnCallFileStatDetails(ARG_UNUSED EvalContext *ctx, } char data[CF_BUFSIZE]; - int datasize = lgetxattr(path, current, data, sizeof(data)); + int datasize = lgetxattr(path, current, data, sizeof(data) - 1); if (datasize < 0) { if (errno == ENOTSUP) @@ -5208,6 +5208,8 @@ static FnCallResult FnCallFileStatDetails(ARG_UNUSED EvalContext *ctx, } else { + data[datasize] = '\0'; + if (!StringIsPrintable(data)) { Log(LOG_LEVEL_INFO, "Skipping extended attribute of '%s', it has non-printable data: '%s=%s'",