libselinux-3.11-2

- restorecon_xattr: reset dir_xattr_list on every call

Resolves: RHEL-217622
This commit is contained in:
Vit Mojzis 2026-08-18 20:59:42 +02:00
parent 646f7027a0
commit 55e1b1e540
3 changed files with 64 additions and 1 deletions

View File

@ -0,0 +1,59 @@
From 638abdc5e0f40d1c8c4a8c0f0a2f9e37c4204125 Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
Date: Thu, 6 Aug 2026 21:37:35 +0200
Subject: [PATCH] libselinux: restorecon_xattr: reset dir_xattr_list on every
call
selinux_restorecon_xattr(3) documents that "xattr_list must be set to
NULL before calling selinux_restorecon_xattr(3). The caller is
responsible for freeing the returned xattr_list entries." Commit
b5a23d7f30c1 ("libselinux: restorecon_xattr: clear dir_xattr_* after
freeing") reset the dir_xattr_list/dir_xattr_last statics after
freeing them on the internal error-cleanup path of the recursive
walk, but not on the normal success path.
After a successful call, dir_xattr_list/dir_xattr_last are left
pointing at the just-returned, now caller-owned list. Once the caller
frees it as required and calls the function again, add_xattr_entry()
finds dir_xattr_list non-NULL and appends the next entry through
dir_xattr_last->next, a dangling pointer into memory the caller has
already freed - a use-after-free write.
Reset both pointers to NULL at the top of every call instead of only
in the error path: by the API description, any list from a prior call
is not valid.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
---
libselinux/src/selinux_restorecon.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c
index d48d5a83..da61f9de 100644
--- a/libselinux/src/selinux_restorecon.c
+++ b/libselinux/src/selinux_restorecon.c
@@ -1963,6 +1963,18 @@ int selinux_restorecon_xattr(const char *pathname, unsigned int xattr_flags,
if (!fc_sehandle)
return -1;
+ /*
+ * The API contract requires the caller to have already freed any
+ * xattr_list returned by a previous call before calling again.
+ * Forget our own head/tail pointers to that now caller-owned memory
+ * here instead of carrying them over: leaving them set would make
+ * the next add_xattr_entry() append a new entry through
+ * dir_xattr_last, which would be dangling once the caller has freed
+ * it, resulting in a use-after-free.
+ */
+ dir_xattr_list = NULL;
+ dir_xattr_last = NULL;
+
if (lstat(pathname, &sb) < 0) {
if (errno == ENOENT)
return 0;
--
2.53.0

View File

@ -1,3 +1,6 @@
* Tue Aug 18 2026 Vit Mojzis <vmojzis@redhat.com> - 3.11-2
- restorecon_xattr: reset dir_xattr_list on every call (RHEL-217622)
* Wed Jul 01 2026 Petr Lautrbach <lautrbach@redhat.com> - 3.11-1
- SELinux userspace 3.11 release

View File

@ -4,7 +4,7 @@
Summary: SELinux library and simple utilities
Name: libselinux
Version: 3.11
Release: 1%{?dist}
Release: 2%{?dist}
License: LicenseRef-Fedora-Public-Domain
# https://github.com/SELinuxProject/selinux/wiki/Releases
Source0: https://github.com/SELinuxProject/selinux/releases/download/%{version}/libselinux-%{version}.tar.gz
@ -22,6 +22,7 @@ Url: https://github.com/SELinuxProject/selinux/wiki
Patch0001: 0001-Use-SHA-2-instead-of-SHA-1.patch
Patch0002: 0002-Revert-libselinux-python-Use-system-Python3-build-mo.patch
Patch0003: 0003-Revert-libselinux-update-pywrap-targets-for-modern-p.patch
Patch0004: 0004-libselinux-restorecon_xattr-reset-dir_xattr_list-on-.patch
# Patch list end
BuildRequires: gcc make
BuildRequires: ruby-devel ruby libsepol-static >= %{libsepolver} swig pcre2-devel