selinux/stable-6.10 PR 20240513

-----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCAAyFiEES0KozwfymdVUl37v6iDy2pc3iXMFAmZCWd4UHHBhdWxAcGF1
 bC1tb29yZS5jb20ACgkQ6iDy2pc3iXMFMQ/8DlQhbe+NzeAjBg2O7RqNKoE/UU2l
 JAkzgQ7h35/sgsfDIEhPv0VOzq2cwLSaw5/qSGGrQDWR4AKz55HvBSJQDElgzPo2
 wtL2lozjJ03+P391aeXEHdkqzgp2F3c6oNthIcFvRmi3EVcWr7eqnjWU+bJzFtMA
 z4IgX01yiUF6EMdTJcWjSLclk3dOqHWPV657RadYyp2pr3u9rc9gqgxichs0dQW0
 X/vexUBg81TdSeHS+u9Jgrz+TCsQdP3CHSFibXDv1rX89bqCbG9wYNTyTBHH9f0j
 LPpV2bKaesxIZV6dZyIKKSqCtHGBcjcJEjUbl7JFkQOS/a8NPMDH2ZYkHqbyq4BH
 SX+kRhthmXZiZ2IWhMRikaE4FBIWI7JAC4riKB2Dd0RzJrNEgaawU0wM+evKai9F
 s3GCk/P7wnTT4GlDHSkYEiiRF9c3DNkfVb9mqG78PRMR4X+z/0dsX5iaJTwlyMxo
 69JSoTNzMxVdDtvD+K89V7GCm8NmGFjLwQUqb282L/6ibzC/5CCUQXn8ZWvNRPql
 IUoQhKbveCWR3m9vAMeGpE61oNgFp0mHj3Zb/vE5Yu7HxOn2y1lFv2XGxR6bGyTF
 T53AaHM15uFomhqhG+iM3b4FDhNIJpbUc4MJsq3iMgFC941n1ceXyeBEgf31+Z2x
 k1ZlxqLAWn05auA=
 =2Wbi
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2024-05-15 08:36:30 -07:00
commit ccae19c623
12 changed files with 145 additions and 125 deletions

View File

@ -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;
@ -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;
@ -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,
@ -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);
@ -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;
@ -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);
@ -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);
}
@ -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;
}

View File

@ -571,11 +571,18 @@ 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,
@ -583,26 +590,22 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
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");
@ -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);
@ -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;
}

View File

@ -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;
}
@ -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;
@ -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;
@ -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++;
@ -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;
@ -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;
@ -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);

View File

@ -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_ */

View File

@ -21,7 +21,7 @@
#include "ebitmap.h"
#include "policydb.h"
#define BITS_PER_U64 (sizeof(u64) * 8)
#define BITS_PER_U64 ((u32)(sizeof(u64) * 8))
static struct kmem_cache *ebitmap_node_cachep __ro_after_init;
@ -79,7 +79,8 @@ int ebitmap_and(struct ebitmap *dst, const struct ebitmap *e1,
const struct ebitmap *e2)
{
struct ebitmap_node *n;
int bit, rc;
u32 bit;
int rc;
ebitmap_init(dst);
@ -256,7 +257,7 @@ int ebitmap_contains(const struct ebitmap *e1, const struct ebitmap *e2,
return 1;
}
int ebitmap_get_bit(const struct ebitmap *e, unsigned long bit)
int ebitmap_get_bit(const struct ebitmap *e, u32 bit)
{
const struct ebitmap_node *n;
@ -273,7 +274,7 @@ int ebitmap_get_bit(const struct ebitmap *e, unsigned long bit)
return 0;
}
int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
int ebitmap_set_bit(struct ebitmap *e, u32 bit, int value)
{
struct ebitmap_node *n, *prev, *new;
@ -284,7 +285,7 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
if (value) {
ebitmap_node_set_bit(n, bit);
} else {
unsigned int s;
u32 s;
ebitmap_node_clr_bit(n, bit);
@ -362,12 +363,12 @@ void ebitmap_destroy(struct ebitmap *e)
int ebitmap_read(struct ebitmap *e, void *fp)
{
struct ebitmap_node *n = NULL;
u32 mapunit, count, startbit, index;
u32 mapunit, count, startbit, index, i;
__le32 ebitmap_start;
u64 map;
__le64 mapbits;
__le32 buf[3];
int rc, i;
int rc;
ebitmap_init(e);
@ -381,7 +382,7 @@ int ebitmap_read(struct ebitmap *e, void *fp)
if (mapunit != BITS_PER_U64) {
pr_err("SELinux: ebitmap: map size %u does not "
"match my size %zd (high bit was %d)\n",
"match my size %u (high bit was %u)\n",
mapunit, BITS_PER_U64, e->highbit);
goto bad;
}
@ -407,13 +408,13 @@ int ebitmap_read(struct ebitmap *e, void *fp)
startbit = le32_to_cpu(ebitmap_start);
if (startbit & (mapunit - 1)) {
pr_err("SELinux: ebitmap start bit (%d) is "
pr_err("SELinux: ebitmap start bit (%u) is "
"not a multiple of the map unit size (%u)\n",
startbit, mapunit);
goto bad;
}
if (startbit > e->highbit - mapunit) {
pr_err("SELinux: ebitmap start bit (%d) is "
pr_err("SELinux: ebitmap start bit (%u) is "
"beyond the end of the bitmap (%u)\n",
startbit, (e->highbit - mapunit));
goto bad;
@ -436,8 +437,8 @@ int ebitmap_read(struct ebitmap *e, void *fp)
e->node = tmp;
n = tmp;
} else if (startbit <= n->startbit) {
pr_err("SELinux: ebitmap: start bit %d"
" comes after start bit %d\n",
pr_err("SELinux: ebitmap: start bit %u"
" comes after start bit %u\n",
startbit, n->startbit);
goto bad;
}
@ -448,6 +449,10 @@ int ebitmap_read(struct ebitmap *e, void *fp)
goto bad;
}
map = le64_to_cpu(mapbits);
if (!map) {
pr_err("SELinux: ebitmap: empty map\n");
goto bad;
}
index = (startbit - n->startbit) / EBITMAP_UNIT_SIZE;
while (map) {
@ -455,6 +460,13 @@ int ebitmap_read(struct ebitmap *e, void *fp)
map = EBITMAP_SHIFT_UNIT_SIZE(map);
}
}
if (n && n->startbit + EBITMAP_SIZE != e->highbit) {
pr_err("SELinux: ebitmap: high bit %u is not equal to the expected value %zu\n",
e->highbit, n->startbit + EBITMAP_SIZE);
goto bad;
}
ok:
rc = 0;
out:
@ -469,19 +481,20 @@ bad:
int ebitmap_write(const struct ebitmap *e, void *fp)
{
struct ebitmap_node *n;
u32 count;
u32 bit, count, last_bit, last_startbit;
__le32 buf[3];
u64 map;
int bit, last_bit, last_startbit, rc;
int rc;
buf[0] = cpu_to_le32(BITS_PER_U64);
count = 0;
last_bit = 0;
last_startbit = -1;
last_startbit = U32_MAX;
ebitmap_for_each_positive_bit(e, n, bit)
{
if (rounddown(bit, (int)BITS_PER_U64) > last_startbit) {
if (last_startbit == U32_MAX ||
rounddown(bit, BITS_PER_U64) > last_startbit) {
count++;
last_startbit = rounddown(bit, BITS_PER_U64);
}
@ -495,10 +508,11 @@ int ebitmap_write(const struct ebitmap *e, void *fp)
return rc;
map = 0;
last_startbit = INT_MIN;
last_startbit = U32_MAX;
ebitmap_for_each_positive_bit(e, n, bit)
{
if (rounddown(bit, (int)BITS_PER_U64) > last_startbit) {
if (last_startbit == U32_MAX ||
rounddown(bit, BITS_PER_U64) > last_startbit) {
__le64 buf64[1];
/* this is the very first bit */

View File

@ -46,10 +46,10 @@ struct ebitmap {
#define ebitmap_length(e) ((e)->highbit)
static inline unsigned int ebitmap_start_positive(const struct ebitmap *e,
struct ebitmap_node **n)
static inline u32 ebitmap_start_positive(const struct ebitmap *e,
struct ebitmap_node **n)
{
unsigned int ofs;
u32 ofs;
for (*n = e->node; *n; *n = (*n)->next) {
ofs = find_first_bit((*n)->maps, EBITMAP_SIZE);
@ -64,11 +64,10 @@ static inline void ebitmap_init(struct ebitmap *e)
memset(e, 0, sizeof(*e));
}
static inline unsigned int ebitmap_next_positive(const struct ebitmap *e,
struct ebitmap_node **n,
unsigned int bit)
static inline u32 ebitmap_next_positive(const struct ebitmap *e,
struct ebitmap_node **n, u32 bit)
{
unsigned int ofs;
u32 ofs;
ofs = find_next_bit((*n)->maps, EBITMAP_SIZE, bit - (*n)->startbit + 1);
if (ofs < EBITMAP_SIZE)
@ -87,11 +86,10 @@ static inline unsigned int ebitmap_next_positive(const struct ebitmap *e,
#define EBITMAP_NODE_OFFSET(node, bit) \
(((bit) - (node)->startbit) % EBITMAP_UNIT_SIZE)
static inline int ebitmap_node_get_bit(const struct ebitmap_node *n,
unsigned int bit)
static inline int ebitmap_node_get_bit(const struct ebitmap_node *n, u32 bit)
{
unsigned int index = EBITMAP_NODE_INDEX(n, bit);
unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit);
u32 index = EBITMAP_NODE_INDEX(n, bit);
u32 ofs = EBITMAP_NODE_OFFSET(n, bit);
BUG_ON(index >= EBITMAP_UNIT_NUMS);
if ((n->maps[index] & (EBITMAP_BIT << ofs)))
@ -99,21 +97,19 @@ static inline int ebitmap_node_get_bit(const struct ebitmap_node *n,
return 0;
}
static inline void ebitmap_node_set_bit(struct ebitmap_node *n,
unsigned int bit)
static inline void ebitmap_node_set_bit(struct ebitmap_node *n, u32 bit)
{
unsigned int index = EBITMAP_NODE_INDEX(n, bit);
unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit);
u32 index = EBITMAP_NODE_INDEX(n, bit);
u32 ofs = EBITMAP_NODE_OFFSET(n, bit);
BUG_ON(index >= EBITMAP_UNIT_NUMS);
n->maps[index] |= (EBITMAP_BIT << ofs);
}
static inline void ebitmap_node_clr_bit(struct ebitmap_node *n,
unsigned int bit)
static inline void ebitmap_node_clr_bit(struct ebitmap_node *n, u32 bit)
{
unsigned int index = EBITMAP_NODE_INDEX(n, bit);
unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit);
u32 index = EBITMAP_NODE_INDEX(n, bit);
u32 ofs = EBITMAP_NODE_OFFSET(n, bit);
BUG_ON(index >= EBITMAP_UNIT_NUMS);
n->maps[index] &= ~(EBITMAP_BIT << ofs);
@ -130,8 +126,8 @@ int ebitmap_and(struct ebitmap *dst, const struct ebitmap *e1,
const struct ebitmap *e2);
int ebitmap_contains(const struct ebitmap *e1, const struct ebitmap *e2,
u32 last_e2bit);
int ebitmap_get_bit(const struct ebitmap *e, unsigned long bit);
int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value);
int ebitmap_get_bit(const struct ebitmap *e, u32 bit);
int ebitmap_set_bit(struct ebitmap *e, u32 bit, int value);
void ebitmap_destroy(struct ebitmap *e);
int ebitmap_read(struct ebitmap *e, void *fp);
int ebitmap_write(const struct ebitmap *e, void *fp);

View File

@ -136,11 +136,12 @@ void hashtab_stat(struct hashtab *h, struct hashtab_info *info)
}
#endif /* CONFIG_SECURITY_SELINUX_DEBUG */
int hashtab_duplicate(struct hashtab *new, struct hashtab *orig,
int hashtab_duplicate(struct hashtab *new, const struct hashtab *orig,
int (*copy)(struct hashtab_node *new,
struct hashtab_node *orig, void *args),
const struct hashtab_node *orig, void *args),
int (*destroy)(void *k, void *d, void *args), void *args)
{
const struct hashtab_node *orig_cur;
struct hashtab_node *cur, *tmp, *tail;
u32 i;
int rc;
@ -155,12 +156,13 @@ int hashtab_duplicate(struct hashtab *new, struct hashtab *orig,
for (i = 0; i < orig->size; i++) {
tail = NULL;
for (cur = orig->htable[i]; cur; cur = cur->next) {
for (orig_cur = orig->htable[i]; orig_cur;
orig_cur = orig_cur->next) {
tmp = kmem_cache_zalloc(hashtab_node_cachep,
GFP_KERNEL);
if (!tmp)
goto error;
rc = copy(tmp, cur, args);
rc = copy(tmp, orig_cur, args);
if (rc) {
kmem_cache_free(hashtab_node_cachep, tmp);
goto error;

View File

@ -136,9 +136,9 @@ void hashtab_destroy(struct hashtab *h);
int hashtab_map(struct hashtab *h, int (*apply)(void *k, void *d, void *args),
void *args);
int hashtab_duplicate(struct hashtab *new, struct hashtab *orig,
int hashtab_duplicate(struct hashtab *new, const struct hashtab *orig,
int (*copy)(struct hashtab_node *new,
struct hashtab_node *orig, void *args),
const struct hashtab_node *orig, void *args),
int (*destroy)(void *k, void *d, void *args), void *args);
#ifdef CONFIG_SECURITY_SELINUX_DEBUG

View File

@ -672,14 +672,16 @@ static int (*const index_f[SYM_NUM])(void *key, void *datum, void *datap) = {
/* clang-format on */
#ifdef CONFIG_SECURITY_SELINUX_DEBUG
static void hash_eval(struct hashtab *h, const char *hash_name)
static void hash_eval(struct hashtab *h, const char *hash_name,
const char *hash_details)
{
struct hashtab_info info;
hashtab_stat(h, &info);
pr_debug(
"SELinux: %s: %d entries and %d/%d buckets used, longest chain length %d, sum of chain length^2 %llu\n",
hash_name, h->nel, info.slots_used, h->size, info.max_chain_len,
"SELinux: %s%s%s: %d entries and %d/%d buckets used, longest chain length %d, sum of chain length^2 %llu\n",
hash_name, hash_details ? "@" : "", hash_details ?: "", h->nel,
info.slots_used, h->size, info.max_chain_len,
info.chain2_len_sum);
}
@ -688,11 +690,12 @@ static void symtab_hash_eval(struct symtab *s)
int i;
for (i = 0; i < SYM_NUM; i++)
hash_eval(&s[i].table, symtab_name[i]);
hash_eval(&s[i].table, symtab_name[i], NULL);
}
#else
static inline void hash_eval(struct hashtab *h, const char *hash_name)
static inline void hash_eval(struct hashtab *h, const char *hash_name,
const char *hash_details)
{
}
static inline void symtab_hash_eval(struct symtab *s)
@ -1178,6 +1181,8 @@ static int common_read(struct policydb *p, struct symtab *s, void *fp)
goto bad;
}
hash_eval(&comdatum->permissions.table, "common_permissions", key);
rc = symtab_insert(s, key, comdatum);
if (rc)
goto bad;
@ -1358,6 +1363,8 @@ static int class_read(struct policydb *p, struct symtab *s, void *fp)
goto bad;
}
hash_eval(&cladatum->permissions.table, "class_permissions", key);
rc = read_cons_helper(p, &cladatum->constraints, ncons, 0, fp);
if (rc)
goto bad;
@ -1898,7 +1905,7 @@ static int range_read(struct policydb *p, void *fp)
rt = NULL;
r = NULL;
}
hash_eval(&p->range_tr, "rangetr");
hash_eval(&p->range_tr, "rangetr", NULL);
rc = 0;
out:
kfree(rt);
@ -1943,6 +1950,7 @@ static int filename_trans_read_helper_compat(struct policydb *p, void *fp)
if (unlikely(ebitmap_get_bit(&datum->stypes, stype - 1))) {
/* conflicting/duplicate rules are ignored */
datum = NULL;
rc = 0;
goto out;
}
if (likely(datum->otype == otype))
@ -2116,7 +2124,7 @@ static int filename_trans_read(struct policydb *p, void *fp)
return rc;
}
}
hash_eval(&p->filename_trans, "filenametr");
hash_eval(&p->filename_trans, "filenametr", NULL);
return 0;
}
@ -2649,6 +2657,8 @@ int policydb_read(struct policydb *p, void *fp)
rtd = NULL;
}
hash_eval(&p->role_tr, "roletr", NULL);
rc = next_entry(buf, fp, sizeof(u32));
if (rc)
goto bad;

View File

@ -633,8 +633,7 @@ static void context_struct_compute_av(struct policydb *policydb,
}
if (unlikely(!tclass || tclass > policydb->p_classes.nprim)) {
if (printk_ratelimit())
pr_warn("SELinux: Invalid class %hu\n", tclass);
pr_warn_ratelimited("SELinux: Invalid class %u\n", tclass);
return;
}

View File

@ -12,17 +12,17 @@
static unsigned int symhash(const void *key)
{
const char *p, *keyp;
unsigned int size;
unsigned int val;
/*
* djb2a
* Public domain from cdb v0.75
*/
unsigned int hash = 5381;
unsigned char c;
val = 0;
keyp = key;
size = strlen(keyp);
for (p = keyp; (p - keyp) < size; p++)
val = (val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^
(*p);
return val;
while ((c = *(const unsigned char *)key++))
hash = ((hash << 5) + hash) ^ c;
return hash;
}
static int symcmp(const void *key1, const void *key2)

View File

@ -76,7 +76,6 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
gfp_t gfp)
{
int rc;
const struct task_security_struct *tsec = selinux_cred(current_cred());
struct xfrm_sec_ctx *ctx = NULL;
u32 str_len;
@ -103,7 +102,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
if (rc)
goto err;
rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
rc = avc_has_perm(current_sid(), ctx->ctx_sid,
SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, NULL);
if (rc)
goto err;
@ -134,12 +133,10 @@ static void selinux_xfrm_free(struct xfrm_sec_ctx *ctx)
*/
static int selinux_xfrm_delete(struct xfrm_sec_ctx *ctx)
{
const struct task_security_struct *tsec = selinux_cred(current_cred());
if (!ctx)
return 0;
return avc_has_perm(tsec->sid, ctx->ctx_sid,
return avc_has_perm(current_sid(), ctx->ctx_sid,
SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT,
NULL);
}