libselinux: safely access shared memory in selinux_status_updated()

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>
This commit is contained in:
Christian Göttsche 2020-08-25 17:32:04 +02:00 committed by Stephen Smalley
parent 9e4480b921
commit ef902db9c8

View File

@ -91,7 +91,9 @@ static inline uint32_t read_sequence(struct selinux_status_t *status)
int selinux_status_updated(void) int selinux_status_updated(void)
{ {
uint32_t curr_seqno; uint32_t curr_seqno;
int result = 0; uint32_t tmp_seqno;
uint32_t enforcing;
uint32_t policyload;
if (selinux_status == NULL) { if (selinux_status == NULL) {
errno = EINVAL; errno = EINVAL;
@ -117,21 +119,29 @@ int selinux_status_updated(void)
if (last_seqno & 0x0001) if (last_seqno & 0x0001)
last_seqno = curr_seqno; last_seqno = curr_seqno;
if (last_seqno != curr_seqno) if (last_seqno == curr_seqno)
{ return 0;
if (avc_enforcing != (int) selinux_status->enforcing) {
if (avc_process_setenforce(selinux_status->enforcing) < 0) /* sequence must not be changed during references */
return -1; do {
} enforcing = selinux_status->enforcing;
if (last_policyload != selinux_status->policyload) { policyload = selinux_status->policyload;
if (avc_process_policyload(selinux_status->policyload) < 0) tmp_seqno = curr_seqno;
return -1; curr_seqno = read_sequence(selinux_status);
last_policyload = selinux_status->policyload; } while (tmp_seqno != curr_seqno);
}
last_seqno = curr_seqno; if (avc_enforcing != (int) enforcing) {
result = 1; if (avc_process_setenforce(enforcing) < 0)
return -1;
} }
return result; if (last_policyload != policyload) {
if (avc_process_policyload(policyload) < 0)
return -1;
last_policyload = policyload;
}
last_seqno = curr_seqno;
return 1;
} }
/* /*