| From 58be58c2aefa794692c3a73312a68e175dd374f1 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 10 Sep 2020 10:28:05 -0400 |
| Subject: selinux: access policycaps with READ_ONCE/WRITE_ONCE |
| |
| From: Stephen Smalley <stephen.smalley.work@gmail.com> |
| |
| [ Upstream commit e8ba53d0023a76ba0f50e6ee3e6288c5442f9d33 ] |
| |
| Use READ_ONCE/WRITE_ONCE for all accesses to the |
| selinux_state.policycaps booleans to prevent compiler |
| mischief. |
| |
| Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com> |
| Signed-off-by: Paul Moore <paul@paul-moore.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| security/selinux/include/security.h | 14 +++++++------- |
| security/selinux/ss/services.c | 3 ++- |
| 2 files changed, 9 insertions(+), 8 deletions(-) |
| |
| diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h |
| index b0e02cfe3ce14..8a432f646967e 100644 |
| --- a/security/selinux/include/security.h |
| +++ b/security/selinux/include/security.h |
| @@ -177,49 +177,49 @@ static inline bool selinux_policycap_netpeer(void) |
| { |
| struct selinux_state *state = &selinux_state; |
| |
| - return state->policycap[POLICYDB_CAPABILITY_NETPEER]; |
| + return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_NETPEER]); |
| } |
| |
| static inline bool selinux_policycap_openperm(void) |
| { |
| struct selinux_state *state = &selinux_state; |
| |
| - return state->policycap[POLICYDB_CAPABILITY_OPENPERM]; |
| + return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_OPENPERM]); |
| } |
| |
| static inline bool selinux_policycap_extsockclass(void) |
| { |
| struct selinux_state *state = &selinux_state; |
| |
| - return state->policycap[POLICYDB_CAPABILITY_EXTSOCKCLASS]; |
| + return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_EXTSOCKCLASS]); |
| } |
| |
| static inline bool selinux_policycap_alwaysnetwork(void) |
| { |
| struct selinux_state *state = &selinux_state; |
| |
| - return state->policycap[POLICYDB_CAPABILITY_ALWAYSNETWORK]; |
| + return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_ALWAYSNETWORK]); |
| } |
| |
| static inline bool selinux_policycap_cgroupseclabel(void) |
| { |
| struct selinux_state *state = &selinux_state; |
| |
| - return state->policycap[POLICYDB_CAPABILITY_CGROUPSECLABEL]; |
| + return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_CGROUPSECLABEL]); |
| } |
| |
| static inline bool selinux_policycap_nnp_nosuid_transition(void) |
| { |
| struct selinux_state *state = &selinux_state; |
| |
| - return state->policycap[POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION]; |
| + return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION]); |
| } |
| |
| static inline bool selinux_policycap_genfs_seclabel_symlinks(void) |
| { |
| struct selinux_state *state = &selinux_state; |
| |
| - return state->policycap[POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS]; |
| + return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS]); |
| } |
| |
| int security_mls_enabled(struct selinux_state *state); |
| diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c |
| index 1caf4e6033096..c55b3063753ab 100644 |
| --- a/security/selinux/ss/services.c |
| +++ b/security/selinux/ss/services.c |
| @@ -2103,7 +2103,8 @@ static void security_load_policycaps(struct selinux_state *state) |
| struct ebitmap_node *node; |
| |
| for (i = 0; i < ARRAY_SIZE(state->policycap); i++) |
| - state->policycap[i] = ebitmap_get_bit(&p->policycaps, i); |
| + WRITE_ONCE(state->policycap[i], |
| + ebitmap_get_bit(&p->policycaps, i)); |
| |
| for (i = 0; i < ARRAY_SIZE(selinux_policycap_names); i++) |
| pr_info("SELinux: policy capability %s=%d\n", |
| -- |
| 2.27.0 |
| |