Skip to content

Commit

Permalink
Merge tag 'selinux-pr-20240513' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
Linus Torvalds committed May 15, 2024
2 parents 4cd4e4b + 581646c commit ccae19c
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 126 deletions.
58 changes: 24 additions & 34 deletions security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -2961,7 +2961,7 @@ static int selinux_inode_init_security_anon(struct inode *inode,
const struct qstr *name,
const struct inode *context_inode)
{
const struct task_security_struct *tsec = selinux_cred(current_cred());
u32 sid = current_sid();
struct common_audit_data ad;
struct inode_security_struct *isec;
int rc;
Expand Down Expand Up @@ -2990,7 +2990,7 @@ static int selinux_inode_init_security_anon(struct inode *inode,
} else {
isec->sclass = SECCLASS_ANON_INODE;
rc = security_transition_sid(
tsec->sid, tsec->sid,
sid, sid,
isec->sclass, name, &isec->sid);
if (rc)
return rc;
Expand All @@ -3005,7 +3005,7 @@ static int selinux_inode_init_security_anon(struct inode *inode,
ad.type = LSM_AUDIT_DATA_ANONINODE;
ad.u.anonclass = name ? (const char *)name->name : "?";

return avc_has_perm(tsec->sid,
return avc_has_perm(sid,
isec->sid,
isec->sclass,
FILE__CREATE,
Expand Down Expand Up @@ -3063,14 +3063,12 @@ static int selinux_inode_readlink(struct dentry *dentry)
static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
bool rcu)
{
const struct cred *cred = current_cred();
struct common_audit_data ad;
struct inode_security_struct *isec;
u32 sid;
u32 sid = current_sid();

ad.type = LSM_AUDIT_DATA_DENTRY;
ad.u.dentry = dentry;
sid = cred_sid(cred);
isec = inode_security_rcu(inode, rcu);
if (IS_ERR(isec))
return PTR_ERR(isec);
Expand All @@ -3094,12 +3092,11 @@ static noinline int audit_inode_permission(struct inode *inode,

static int selinux_inode_permission(struct inode *inode, int mask)
{
const struct cred *cred = current_cred();
u32 perms;
bool from_access;
bool no_block = mask & MAY_NOT_BLOCK;
struct inode_security_struct *isec;
u32 sid;
u32 sid = current_sid();
struct av_decision avd;
int rc, rc2;
u32 audited, denied;
Expand All @@ -3116,7 +3113,6 @@ static int selinux_inode_permission(struct inode *inode, int mask)

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

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

static int selinux_secmark_relabel_packet(u32 sid)
{
const struct task_security_struct *tsec;
u32 tsid;

tsec = selinux_cred(current_cred());
tsid = tsec->sid;

return avc_has_perm(tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO,
return avc_has_perm(current_sid(), sid, SECCLASS_PACKET, PACKET__RELABELTO,
NULL);
}

Expand Down Expand Up @@ -6348,55 +6338,55 @@ static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode)
static int selinux_lsm_getattr(unsigned int attr, struct task_struct *p,
char **value)
{
const struct task_security_struct *__tsec;
u32 sid;
const struct task_security_struct *tsec;
int error;
unsigned len;
u32 sid;
u32 len;

rcu_read_lock();
__tsec = selinux_cred(__task_cred(p));

if (current != p) {
error = avc_has_perm(current_sid(), __tsec->sid,
tsec = selinux_cred(__task_cred(p));
if (p != current) {
error = avc_has_perm(current_sid(), tsec->sid,
SECCLASS_PROCESS, PROCESS__GETATTR, NULL);
if (error)
goto bad;
goto err_unlock;
}

switch (attr) {
case LSM_ATTR_CURRENT:
sid = __tsec->sid;
sid = tsec->sid;
break;
case LSM_ATTR_PREV:
sid = __tsec->osid;
sid = tsec->osid;
break;
case LSM_ATTR_EXEC:
sid = __tsec->exec_sid;
sid = tsec->exec_sid;
break;
case LSM_ATTR_FSCREATE:
sid = __tsec->create_sid;
sid = tsec->create_sid;
break;
case LSM_ATTR_KEYCREATE:
sid = __tsec->keycreate_sid;
sid = tsec->keycreate_sid;
break;
case LSM_ATTR_SOCKCREATE:
sid = __tsec->sockcreate_sid;
sid = tsec->sockcreate_sid;
break;
default:
error = -EOPNOTSUPP;
goto bad;
goto err_unlock;
}
rcu_read_unlock();

if (!sid)
if (sid == SECSID_NULL) {
*value = NULL;
return 0;
}

error = security_sid_to_context(sid, value, &len);
if (error)
return error;
return len;

bad:
err_unlock:
rcu_read_unlock();
return error;
}
Expand Down
36 changes: 22 additions & 14 deletions security/selinux/selinuxfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -571,38 +571,41 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)

{
struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
struct selinux_fs_info *fsi;
struct selinux_load_state load_state;
ssize_t length;
void *data = NULL;

/* no partial writes */
if (*ppos)
return -EINVAL;
/* no empty policies */
if (!count)
return -EINVAL;

mutex_lock(&selinux_state.policy_mutex);

length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
SECCLASS_SECURITY, SECURITY__LOAD_POLICY, NULL);
if (length)
goto out;

/* No partial writes. */
length = -EINVAL;
if (*ppos != 0)
goto out;

length = -ENOMEM;
data = vmalloc(count);
if (!data)
if (!data) {
length = -ENOMEM;
goto out;

length = -EFAULT;
if (copy_from_user(data, buf, count) != 0)
}
if (copy_from_user(data, buf, count) != 0) {
length = -EFAULT;
goto out;
}

length = security_load_policy(data, count, &load_state);
if (length) {
pr_warn_ratelimited("SELinux: failed to load policy\n");
goto out;
}

fsi = file_inode(file)->i_sb->s_fs_info;
length = sel_make_policy_nodes(fsi, load_state.policy);
if (length) {
pr_warn_ratelimited("SELinux: failed to initialize selinuxfs\n");
Expand All @@ -611,13 +614,12 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
}

selinux_policy_commit(&load_state);

length = count;

audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
"auid=%u ses=%u lsm=selinux res=1",
from_kuid(&init_user_ns, audit_get_loginuid(current)),
audit_get_sessionid(current));

out:
mutex_unlock(&selinux_state.policy_mutex);
vfree(data);
Expand Down Expand Up @@ -2161,6 +2163,12 @@ static int __init init_sel_fs(void)
return err;
}

/*
* Try to pre-allocate the status page, so the sequence number of the
* initial policy load can be stored.
*/
(void) selinux_kernel_status_page();

return err;
}

Expand Down
18 changes: 11 additions & 7 deletions security/selinux/ss/conditional.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ int cond_init_bool_indexes(struct policydb *p)
p->p_bools.nprim, sizeof(*p->bool_val_to_struct), GFP_KERNEL);
if (!p->bool_val_to_struct)
return -ENOMEM;

avtab_hash_eval(&p->te_cond_avtab, "conditional_rules");

return 0;
}

Expand Down Expand Up @@ -600,7 +603,8 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key,
}
}

static int cond_dup_av_list(struct cond_av_list *new, struct cond_av_list *orig,
static int cond_dup_av_list(struct cond_av_list *new,
const struct cond_av_list *orig,
struct avtab *avtab)
{
u32 i;
Expand All @@ -623,7 +627,7 @@ static int cond_dup_av_list(struct cond_av_list *new, struct cond_av_list *orig,
}

static int duplicate_policydb_cond_list(struct policydb *newp,
struct policydb *origp)
const struct policydb *origp)
{
int rc;
u32 i;
Expand All @@ -640,7 +644,7 @@ static int duplicate_policydb_cond_list(struct policydb *newp,

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

newp->cond_list_len++;

Expand Down Expand Up @@ -680,8 +684,8 @@ static int cond_bools_destroy(void *key, void *datum, void *args)
return 0;
}

static int cond_bools_copy(struct hashtab_node *new, struct hashtab_node *orig,
void *args)
static int cond_bools_copy(struct hashtab_node *new,
const struct hashtab_node *orig, void *args)
{
struct cond_bool_datum *datum;

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

static int duplicate_policydb_bools(struct policydb *newdb,
struct policydb *orig)
const struct policydb *orig)
{
struct cond_bool_datum **cond_bool_array;
int rc;
Expand Down Expand Up @@ -740,7 +744,7 @@ void cond_policydb_destroy_dup(struct policydb *p)
cond_policydb_destroy(p);
}

int cond_policydb_dup(struct policydb *new, struct policydb *orig)
int cond_policydb_dup(struct policydb *new, const struct policydb *orig)
{
cond_policydb_init(new);

Expand Down
2 changes: 1 addition & 1 deletion security/selinux/ss/conditional.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,6 @@ void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key,
struct extended_perms_decision *xpermd);
void evaluate_cond_nodes(struct policydb *p);
void cond_policydb_destroy_dup(struct policydb *p);
int cond_policydb_dup(struct policydb *new, struct policydb *orig);
int cond_policydb_dup(struct policydb *new, const struct policydb *orig);

#endif /* _CONDITIONAL_H_ */
Loading

0 comments on commit ccae19c

Please sign in to comment.