Skip to content

Commit ccae19c

Browse files
committed
Merge tag 'selinux-pr-20240513' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore: - Attempt to pre-allocate the SELinux status page so it doesn't appear to userspace that we are skipping SELinux policy sequence numbers - Reject invalid SELinux policy bitmaps with an error at policy load time - Consistently use the same type, u32, for ebitmap offsets - Improve the "symhash" hash function for better distribution on common policies - Correct a number of printk format specifiers in the ebitmap code - Improved error checking in sel_write_load() - Ensure we have a proper return code in the filename_trans_read_helper_compat() function - Make better use of the current_sid() helper function - Allow for more hash table statistics when debugging is enabled - Migrate from printk_ratelimit() to pr_warn_ratelimited() - Miscellaneous cleanups and tweaks to selinux_lsm_getattr() - More consitification work in the conditional policy space * tag 'selinux-pr-20240513' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: constify source policy in cond_policydb_dup() selinux: avoid printk_ratelimit() selinux: pre-allocate the status page selinux: clarify return code in filename_trans_read_helper_compat() selinux: use u32 as bit position type in ebitmap code selinux: improve symtab string hashing selinux: dump statistics for more hash tables selinux: make more use of current_sid() selinux: update numeric format specifiers for ebitmaps selinux: improve error checking in sel_write_load() selinux: cleanup selinux_lsm_getattr() selinux: reject invalid ebitmaps
2 parents 4cd4e4b + 581646c commit ccae19c

File tree

12 files changed

+146
-126
lines changed

12 files changed

+146
-126
lines changed

security/selinux/hooks.c

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2961,7 +2961,7 @@ static int selinux_inode_init_security_anon(struct inode *inode,
29612961
const struct qstr *name,
29622962
const struct inode *context_inode)
29632963
{
2964-
const struct task_security_struct *tsec = selinux_cred(current_cred());
2964+
u32 sid = current_sid();
29652965
struct common_audit_data ad;
29662966
struct inode_security_struct *isec;
29672967
int rc;
@@ -2990,7 +2990,7 @@ static int selinux_inode_init_security_anon(struct inode *inode,
29902990
} else {
29912991
isec->sclass = SECCLASS_ANON_INODE;
29922992
rc = security_transition_sid(
2993-
tsec->sid, tsec->sid,
2993+
sid, sid,
29942994
isec->sclass, name, &isec->sid);
29952995
if (rc)
29962996
return rc;
@@ -3005,7 +3005,7 @@ static int selinux_inode_init_security_anon(struct inode *inode,
30053005
ad.type = LSM_AUDIT_DATA_ANONINODE;
30063006
ad.u.anonclass = name ? (const char *)name->name : "?";
30073007

3008-
return avc_has_perm(tsec->sid,
3008+
return avc_has_perm(sid,
30093009
isec->sid,
30103010
isec->sclass,
30113011
FILE__CREATE,
@@ -3063,14 +3063,12 @@ static int selinux_inode_readlink(struct dentry *dentry)
30633063
static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
30643064
bool rcu)
30653065
{
3066-
const struct cred *cred = current_cred();
30673066
struct common_audit_data ad;
30683067
struct inode_security_struct *isec;
3069-
u32 sid;
3068+
u32 sid = current_sid();
30703069

30713070
ad.type = LSM_AUDIT_DATA_DENTRY;
30723071
ad.u.dentry = dentry;
3073-
sid = cred_sid(cred);
30743072
isec = inode_security_rcu(inode, rcu);
30753073
if (IS_ERR(isec))
30763074
return PTR_ERR(isec);
@@ -3094,12 +3092,11 @@ static noinline int audit_inode_permission(struct inode *inode,
30943092

30953093
static int selinux_inode_permission(struct inode *inode, int mask)
30963094
{
3097-
const struct cred *cred = current_cred();
30983095
u32 perms;
30993096
bool from_access;
31003097
bool no_block = mask & MAY_NOT_BLOCK;
31013098
struct inode_security_struct *isec;
3102-
u32 sid;
3099+
u32 sid = current_sid();
31033100
struct av_decision avd;
31043101
int rc, rc2;
31053102
u32 audited, denied;
@@ -3116,7 +3113,6 @@ static int selinux_inode_permission(struct inode *inode, int mask)
31163113

31173114
perms = file_mask_to_av(inode->i_mode, mask);
31183115

3119-
sid = cred_sid(cred);
31203116
isec = inode_security_rcu(inode, no_block);
31213117
if (IS_ERR(isec))
31223118
return PTR_ERR(isec);
@@ -5564,13 +5560,7 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
55645560

55655561
static int selinux_secmark_relabel_packet(u32 sid)
55665562
{
5567-
const struct task_security_struct *tsec;
5568-
u32 tsid;
5569-
5570-
tsec = selinux_cred(current_cred());
5571-
tsid = tsec->sid;
5572-
5573-
return avc_has_perm(tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO,
5563+
return avc_has_perm(current_sid(), sid, SECCLASS_PACKET, PACKET__RELABELTO,
55745564
NULL);
55755565
}
55765566

@@ -6348,55 +6338,55 @@ static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode)
63486338
static int selinux_lsm_getattr(unsigned int attr, struct task_struct *p,
63496339
char **value)
63506340
{
6351-
const struct task_security_struct *__tsec;
6352-
u32 sid;
6341+
const struct task_security_struct *tsec;
63536342
int error;
6354-
unsigned len;
6343+
u32 sid;
6344+
u32 len;
63556345

63566346
rcu_read_lock();
6357-
__tsec = selinux_cred(__task_cred(p));
6358-
6359-
if (current != p) {
6360-
error = avc_has_perm(current_sid(), __tsec->sid,
6347+
tsec = selinux_cred(__task_cred(p));
6348+
if (p != current) {
6349+
error = avc_has_perm(current_sid(), tsec->sid,
63616350
SECCLASS_PROCESS, PROCESS__GETATTR, NULL);
63626351
if (error)
6363-
goto bad;
6352+
goto err_unlock;
63646353
}
6365-
63666354
switch (attr) {
63676355
case LSM_ATTR_CURRENT:
6368-
sid = __tsec->sid;
6356+
sid = tsec->sid;
63696357
break;
63706358
case LSM_ATTR_PREV:
6371-
sid = __tsec->osid;
6359+
sid = tsec->osid;
63726360
break;
63736361
case LSM_ATTR_EXEC:
6374-
sid = __tsec->exec_sid;
6362+
sid = tsec->exec_sid;
63756363
break;
63766364
case LSM_ATTR_FSCREATE:
6377-
sid = __tsec->create_sid;
6365+
sid = tsec->create_sid;
63786366
break;
63796367
case LSM_ATTR_KEYCREATE:
6380-
sid = __tsec->keycreate_sid;
6368+
sid = tsec->keycreate_sid;
63816369
break;
63826370
case LSM_ATTR_SOCKCREATE:
6383-
sid = __tsec->sockcreate_sid;
6371+
sid = tsec->sockcreate_sid;
63846372
break;
63856373
default:
63866374
error = -EOPNOTSUPP;
6387-
goto bad;
6375+
goto err_unlock;
63886376
}
63896377
rcu_read_unlock();
63906378

6391-
if (!sid)
6379+
if (sid == SECSID_NULL) {
6380+
*value = NULL;
63926381
return 0;
6382+
}
63936383

63946384
error = security_sid_to_context(sid, value, &len);
63956385
if (error)
63966386
return error;
63976387
return len;
63986388

6399-
bad:
6389+
err_unlock:
64006390
rcu_read_unlock();
64016391
return error;
64026392
}

security/selinux/selinuxfs.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -571,38 +571,41 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
571571
size_t count, loff_t *ppos)
572572

573573
{
574-
struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
574+
struct selinux_fs_info *fsi;
575575
struct selinux_load_state load_state;
576576
ssize_t length;
577577
void *data = NULL;
578578

579+
/* no partial writes */
580+
if (*ppos)
581+
return -EINVAL;
582+
/* no empty policies */
583+
if (!count)
584+
return -EINVAL;
585+
579586
mutex_lock(&selinux_state.policy_mutex);
580587

581588
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
582589
SECCLASS_SECURITY, SECURITY__LOAD_POLICY, NULL);
583590
if (length)
584591
goto out;
585592

586-
/* No partial writes. */
587-
length = -EINVAL;
588-
if (*ppos != 0)
589-
goto out;
590-
591-
length = -ENOMEM;
592593
data = vmalloc(count);
593-
if (!data)
594+
if (!data) {
595+
length = -ENOMEM;
594596
goto out;
595-
596-
length = -EFAULT;
597-
if (copy_from_user(data, buf, count) != 0)
597+
}
598+
if (copy_from_user(data, buf, count) != 0) {
599+
length = -EFAULT;
598600
goto out;
601+
}
599602

600603
length = security_load_policy(data, count, &load_state);
601604
if (length) {
602605
pr_warn_ratelimited("SELinux: failed to load policy\n");
603606
goto out;
604607
}
605-
608+
fsi = file_inode(file)->i_sb->s_fs_info;
606609
length = sel_make_policy_nodes(fsi, load_state.policy);
607610
if (length) {
608611
pr_warn_ratelimited("SELinux: failed to initialize selinuxfs\n");
@@ -611,13 +614,12 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
611614
}
612615

613616
selinux_policy_commit(&load_state);
614-
615617
length = count;
616-
617618
audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
618619
"auid=%u ses=%u lsm=selinux res=1",
619620
from_kuid(&init_user_ns, audit_get_loginuid(current)),
620621
audit_get_sessionid(current));
622+
621623
out:
622624
mutex_unlock(&selinux_state.policy_mutex);
623625
vfree(data);
@@ -2161,6 +2163,12 @@ static int __init init_sel_fs(void)
21612163
return err;
21622164
}
21632165

2166+
/*
2167+
* Try to pre-allocate the status page, so the sequence number of the
2168+
* initial policy load can be stored.
2169+
*/
2170+
(void) selinux_kernel_status_page();
2171+
21642172
return err;
21652173
}
21662174

security/selinux/ss/conditional.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@ int cond_init_bool_indexes(struct policydb *p)
169169
p->p_bools.nprim, sizeof(*p->bool_val_to_struct), GFP_KERNEL);
170170
if (!p->bool_val_to_struct)
171171
return -ENOMEM;
172+
173+
avtab_hash_eval(&p->te_cond_avtab, "conditional_rules");
174+
172175
return 0;
173176
}
174177

@@ -600,7 +603,8 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key,
600603
}
601604
}
602605

603-
static int cond_dup_av_list(struct cond_av_list *new, struct cond_av_list *orig,
606+
static int cond_dup_av_list(struct cond_av_list *new,
607+
const struct cond_av_list *orig,
604608
struct avtab *avtab)
605609
{
606610
u32 i;
@@ -623,7 +627,7 @@ static int cond_dup_av_list(struct cond_av_list *new, struct cond_av_list *orig,
623627
}
624628

625629
static int duplicate_policydb_cond_list(struct policydb *newp,
626-
struct policydb *origp)
630+
const struct policydb *origp)
627631
{
628632
int rc;
629633
u32 i;
@@ -640,7 +644,7 @@ static int duplicate_policydb_cond_list(struct policydb *newp,
640644

641645
for (i = 0; i < origp->cond_list_len; i++) {
642646
struct cond_node *newn = &newp->cond_list[i];
643-
struct cond_node *orign = &origp->cond_list[i];
647+
const struct cond_node *orign = &origp->cond_list[i];
644648

645649
newp->cond_list_len++;
646650

@@ -680,8 +684,8 @@ static int cond_bools_destroy(void *key, void *datum, void *args)
680684
return 0;
681685
}
682686

683-
static int cond_bools_copy(struct hashtab_node *new, struct hashtab_node *orig,
684-
void *args)
687+
static int cond_bools_copy(struct hashtab_node *new,
688+
const struct hashtab_node *orig, void *args)
685689
{
686690
struct cond_bool_datum *datum;
687691

@@ -707,7 +711,7 @@ static int cond_bools_index(void *key, void *datum, void *args)
707711
}
708712

709713
static int duplicate_policydb_bools(struct policydb *newdb,
710-
struct policydb *orig)
714+
const struct policydb *orig)
711715
{
712716
struct cond_bool_datum **cond_bool_array;
713717
int rc;
@@ -740,7 +744,7 @@ void cond_policydb_destroy_dup(struct policydb *p)
740744
cond_policydb_destroy(p);
741745
}
742746

743-
int cond_policydb_dup(struct policydb *new, struct policydb *orig)
747+
int cond_policydb_dup(struct policydb *new, const struct policydb *orig)
744748
{
745749
cond_policydb_init(new);
746750

security/selinux/ss/conditional.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,6 @@ void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key,
7979
struct extended_perms_decision *xpermd);
8080
void evaluate_cond_nodes(struct policydb *p);
8181
void cond_policydb_destroy_dup(struct policydb *p);
82-
int cond_policydb_dup(struct policydb *new, struct policydb *orig);
82+
int cond_policydb_dup(struct policydb *new, const struct policydb *orig);
8383

8484
#endif /* _CONDITIONAL_H_ */

0 commit comments

Comments
 (0)