libselinux/0005-libselinux-safely-acce...

81 lines
2.3 KiB
Diff

From ef902db9c842553fd1a6a81068f3d844d487f2fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Tue, 25 Aug 2020 17:32:04 +0200
Subject: [PATCH] libselinux: safely access shared memory in
selinux_status_updated()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Access the shared nenory safe in regard to consistent view of the SELinux
kernel status page - not in regard to thread-safety.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
---
libselinux/src/sestatus.c | 40 ++++++++++++++++++++++++---------------
1 file changed, 25 insertions(+), 15 deletions(-)
diff --git a/libselinux/src/sestatus.c b/libselinux/src/sestatus.c
index 814e86ee10e7..ca2d3bbf9cb2 100644
--- a/libselinux/src/sestatus.c
+++ b/libselinux/src/sestatus.c
@@ -91,7 +91,9 @@ static inline uint32_t read_sequence(struct selinux_status_t *status)
int selinux_status_updated(void)
{
uint32_t curr_seqno;
- int result = 0;
+ uint32_t tmp_seqno;
+ uint32_t enforcing;
+ uint32_t policyload;
if (selinux_status == NULL) {
errno = EINVAL;
@@ -117,21 +119,29 @@ int selinux_status_updated(void)
if (last_seqno & 0x0001)
last_seqno = curr_seqno;
- if (last_seqno != curr_seqno)
- {
- if (avc_enforcing != (int) selinux_status->enforcing) {
- if (avc_process_setenforce(selinux_status->enforcing) < 0)
- return -1;
- }
- if (last_policyload != selinux_status->policyload) {
- if (avc_process_policyload(selinux_status->policyload) < 0)
- return -1;
- last_policyload = selinux_status->policyload;
- }
- last_seqno = curr_seqno;
- result = 1;
+ if (last_seqno == curr_seqno)
+ return 0;
+
+ /* sequence must not be changed during references */
+ do {
+ enforcing = selinux_status->enforcing;
+ policyload = selinux_status->policyload;
+ tmp_seqno = curr_seqno;
+ curr_seqno = read_sequence(selinux_status);
+ } while (tmp_seqno != curr_seqno);
+
+ if (avc_enforcing != (int) enforcing) {
+ if (avc_process_setenforce(enforcing) < 0)
+ return -1;
+ }
+ if (last_policyload != policyload) {
+ if (avc_process_policyload(policyload) < 0)
+ return -1;
+ last_policyload = policyload;
}
- return result;
+ last_seqno = curr_seqno;
+
+ return 1;
}
/*
--
2.29.0