Skip to content

Commit 9ff9abc

Browse files
stephensmalleypcmoore
authored andcommitted
selinux: move policy mutex to selinux_state, use in lockdep checks
Move the mutex used to synchronize policy changes (reloads and setting of booleans) from selinux_fs_info to selinux_state and use it in lockdep checks for rcu_dereference_protected() calls in the security server functions. This makes the dependency on the mutex explicit in the code rather than relying on comments. Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com> Reviewed-by: Ondrej Mosnacek <omosnace@redhat.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
1 parent 0256b0a commit 9ff9abc

4 files changed

Lines changed: 22 additions & 43 deletions

File tree

security/selinux/hooks.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7237,6 +7237,7 @@ static __init int selinux_init(void)
72377237
selinux_state.checkreqprot = selinux_checkreqprot_boot;
72387238
selinux_avc_init(&selinux_state.avc);
72397239
mutex_init(&selinux_state.status_lock);
7240+
mutex_init(&selinux_state.policy_mutex);
72407241

72417242
/* Set the security state for the initial task. */
72427243
cred_init_security();

security/selinux/include/security.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ struct selinux_state {
103103

104104
struct selinux_avc *avc;
105105
struct selinux_policy __rcu *policy;
106+
struct mutex policy_mutex;
106107
} __randomize_layout;
107108

108109
void selinux_avc_init(struct selinux_avc **avc);

security/selinux/selinuxfs.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ struct selinux_fs_info {
7575
unsigned long last_class_ino;
7676
bool policy_opened;
7777
struct dentry *policycap_dir;
78-
struct mutex mutex;
7978
unsigned long last_ino;
8079
struct selinux_state *state;
8180
struct super_block *sb;
@@ -89,7 +88,6 @@ static int selinux_fs_info_create(struct super_block *sb)
8988
if (!fsi)
9089
return -ENOMEM;
9190

92-
mutex_init(&fsi->mutex);
9391
fsi->last_ino = SEL_INO_NEXT - 1;
9492
fsi->state = &selinux_state;
9593
fsi->sb = sb;
@@ -400,7 +398,7 @@ static int sel_open_policy(struct inode *inode, struct file *filp)
400398

401399
BUG_ON(filp->private_data);
402400

403-
mutex_lock(&fsi->mutex);
401+
mutex_lock(&fsi->state->policy_mutex);
404402

405403
rc = avc_has_perm(&selinux_state,
406404
current_sid(), SECINITSID_SECURITY,
@@ -431,11 +429,11 @@ static int sel_open_policy(struct inode *inode, struct file *filp)
431429

432430
filp->private_data = plm;
433431

434-
mutex_unlock(&fsi->mutex);
432+
mutex_unlock(&fsi->state->policy_mutex);
435433

436434
return 0;
437435
err:
438-
mutex_unlock(&fsi->mutex);
436+
mutex_unlock(&fsi->state->policy_mutex);
439437

440438
if (plm)
441439
vfree(plm->data);
@@ -622,7 +620,7 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
622620
ssize_t length;
623621
void *data = NULL;
624622

625-
mutex_lock(&fsi->mutex);
623+
mutex_lock(&fsi->state->policy_mutex);
626624

627625
length = avc_has_perm(&selinux_state,
628626
current_sid(), SECINITSID_SECURITY,
@@ -666,7 +664,7 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
666664
from_kuid(&init_user_ns, audit_get_loginuid(current)),
667665
audit_get_sessionid(current));
668666
out:
669-
mutex_unlock(&fsi->mutex);
667+
mutex_unlock(&fsi->state->policy_mutex);
670668
vfree(data);
671669
return length;
672670
}
@@ -1271,7 +1269,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
12711269
unsigned index = file_inode(filep)->i_ino & SEL_INO_MASK;
12721270
const char *name = filep->f_path.dentry->d_name.name;
12731271

1274-
mutex_lock(&fsi->mutex);
1272+
mutex_lock(&fsi->state->policy_mutex);
12751273

12761274
ret = -EINVAL;
12771275
if (index >= fsi->bool_num || strcmp(name,
@@ -1290,14 +1288,14 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
12901288
}
12911289
length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
12921290
fsi->bool_pending_values[index]);
1293-
mutex_unlock(&fsi->mutex);
1291+
mutex_unlock(&fsi->state->policy_mutex);
12941292
ret = simple_read_from_buffer(buf, count, ppos, page, length);
12951293
out_free:
12961294
free_page((unsigned long)page);
12971295
return ret;
12981296

12991297
out_unlock:
1300-
mutex_unlock(&fsi->mutex);
1298+
mutex_unlock(&fsi->state->policy_mutex);
13011299
goto out_free;
13021300
}
13031301

@@ -1322,7 +1320,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
13221320
if (IS_ERR(page))
13231321
return PTR_ERR(page);
13241322

1325-
mutex_lock(&fsi->mutex);
1323+
mutex_lock(&fsi->state->policy_mutex);
13261324

13271325
length = avc_has_perm(&selinux_state,
13281326
current_sid(), SECINITSID_SECURITY,
@@ -1347,7 +1345,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
13471345
length = count;
13481346

13491347
out:
1350-
mutex_unlock(&fsi->mutex);
1348+
mutex_unlock(&fsi->state->policy_mutex);
13511349
kfree(page);
13521350
return length;
13531351
}
@@ -1378,7 +1376,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
13781376
if (IS_ERR(page))
13791377
return PTR_ERR(page);
13801378

1381-
mutex_lock(&fsi->mutex);
1379+
mutex_lock(&fsi->state->policy_mutex);
13821380

13831381
length = avc_has_perm(&selinux_state,
13841382
current_sid(), SECINITSID_SECURITY,
@@ -1400,7 +1398,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
14001398
length = count;
14011399

14021400
out:
1403-
mutex_unlock(&fsi->mutex);
1401+
mutex_unlock(&fsi->state->policy_mutex);
14041402
kfree(page);
14051403
return length;
14061404
}

security/selinux/ss/services.c

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,13 +2163,8 @@ void selinux_policy_cancel(struct selinux_state *state,
21632163
{
21642164
struct selinux_policy *oldpolicy;
21652165

2166-
/*
2167-
* NOTE: We do not need to take the rcu read lock
2168-
* around the code below because other policy-modifying
2169-
* operations are already excluded by selinuxfs via
2170-
* fsi->mutex.
2171-
*/
2172-
oldpolicy = rcu_dereference_check(state->policy, 1);
2166+
oldpolicy = rcu_dereference_protected(state->policy,
2167+
lockdep_is_held(&state->policy_mutex));
21732168

21742169
sidtab_cancel_convert(oldpolicy->sidtab);
21752170
selinux_policy_free(policy);
@@ -2192,13 +2187,8 @@ void selinux_policy_commit(struct selinux_state *state,
21922187
struct selinux_policy *oldpolicy;
21932188
u32 seqno;
21942189

2195-
/*
2196-
* NOTE: We do not need to take the rcu read lock
2197-
* around the code below because other policy-modifying
2198-
* operations are already excluded by selinuxfs via
2199-
* fsi->mutex.
2200-
*/
2201-
oldpolicy = rcu_dereference_check(state->policy, 1);
2190+
oldpolicy = rcu_dereference_protected(state->policy,
2191+
lockdep_is_held(&state->policy_mutex));
22022192

22032193
/* If switching between different policy types, log MLS status */
22042194
if (oldpolicy) {
@@ -2291,13 +2281,8 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len,
22912281
return 0;
22922282
}
22932283

2294-
/*
2295-
* NOTE: We do not need to take the rcu read lock
2296-
* around the code below because other policy-modifying
2297-
* operations are already excluded by selinuxfs via
2298-
* fsi->mutex.
2299-
*/
2300-
oldpolicy = rcu_dereference_check(state->policy, 1);
2284+
oldpolicy = rcu_dereference_protected(state->policy,
2285+
lockdep_is_held(&state->policy_mutex));
23012286

23022287
/* Preserve active boolean values from the old policy */
23032288
rc = security_preserve_bools(oldpolicy, newpolicy);
@@ -3013,14 +2998,8 @@ int security_set_bools(struct selinux_state *state, u32 len, int *values)
30132998
if (!selinux_initialized(state))
30142999
return -EINVAL;
30153000

3016-
/*
3017-
* NOTE: We do not need to take the rcu read lock
3018-
* around the code below because other policy-modifying
3019-
* operations are already excluded by selinuxfs via
3020-
* fsi->mutex.
3021-
*/
3022-
3023-
oldpolicy = rcu_dereference_check(state->policy, 1);
3001+
oldpolicy = rcu_dereference_protected(state->policy,
3002+
lockdep_is_held(&state->policy_mutex));
30243003

30253004
/* Consistency check on number of booleans, should never fail */
30263005
if (WARN_ON(len != oldpolicy->policydb.p_bools.nprim))

0 commit comments

Comments
 (0)