Skip to content

Commit 8861d0a

Browse files
nramaspcmoore
authored andcommitted
selinux: Add helper functions to get and set checkreqprot
checkreqprot data member in selinux_state struct is accessed directly by SELinux functions to get and set. This could cause unexpected read or write access to this data member due to compiler optimizations and/or compiler's reordering of access to this field. Add helper functions to get and set checkreqprot data member in selinux_state struct. These helper functions use READ_ONCE and WRITE_ONCE macros to ensure atomic read or write of memory for this data member. Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com> Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com> Suggested-by: Paul Moore <paul@paul-moore.com> Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
1 parent e8ba53d commit 8861d0a

3 files changed

Lines changed: 16 additions & 5 deletions

File tree

security/selinux/hooks.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3718,7 +3718,7 @@ static int selinux_mmap_file(struct file *file, unsigned long reqprot,
37183718
return rc;
37193719
}
37203720

3721-
if (selinux_state.checkreqprot)
3721+
if (checkreqprot_get(&selinux_state))
37223722
prot = reqprot;
37233723

37243724
return file_map_prot_check(file, prot,
@@ -3732,7 +3732,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
37323732
const struct cred *cred = current_cred();
37333733
u32 sid = cred_sid(cred);
37343734

3735-
if (selinux_state.checkreqprot)
3735+
if (checkreqprot_get(&selinux_state))
37363736
prot = reqprot;
37373737

37383738
if (default_noexec &&
@@ -7234,7 +7234,7 @@ static __init int selinux_init(void)
72347234

72357235
memset(&selinux_state, 0, sizeof(selinux_state));
72367236
enforcing_set(&selinux_state, selinux_enforcing_boot);
7237-
selinux_state.checkreqprot = selinux_checkreqprot_boot;
7237+
checkreqprot_set(&selinux_state, selinux_checkreqprot_boot);
72387238
selinux_avc_init(&selinux_state.avc);
72397239
mutex_init(&selinux_state.status_lock);
72407240
mutex_init(&selinux_state.policy_mutex);

security/selinux/include/security.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,16 @@ static inline void enforcing_set(struct selinux_state *state, bool value)
143143
}
144144
#endif
145145

146+
static inline bool checkreqprot_get(const struct selinux_state *state)
147+
{
148+
return READ_ONCE(state->checkreqprot);
149+
}
150+
151+
static inline void checkreqprot_set(struct selinux_state *state, bool value)
152+
{
153+
WRITE_ONCE(state->checkreqprot, value);
154+
}
155+
146156
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
147157
static inline bool selinux_disabled(struct selinux_state *state)
148158
{

security/selinux/selinuxfs.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,8 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
717717
char tmpbuf[TMPBUFLEN];
718718
ssize_t length;
719719

720-
length = scnprintf(tmpbuf, TMPBUFLEN, "%u", fsi->state->checkreqprot);
720+
length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
721+
checkreqprot_get(fsi->state));
721722
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
722723
}
723724

@@ -759,7 +760,7 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
759760
comm, current->pid);
760761
}
761762

762-
fsi->state->checkreqprot = new_value ? 1 : 0;
763+
checkreqprot_set(fsi->state, (new_value ? 1 : 0));
763764
length = count;
764765
out:
765766
kfree(page);

0 commit comments

Comments
 (0)