81 lines
2.3 KiB
Diff
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
|
||
|
|