mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
selinux: wrap global selinux state
Define a selinux state structure (struct selinux_state) for global SELinux state and pass it explicitly to all security server functions. The public portion of the structure contains state that is used throughout the SELinux code, such as the enforcing mode. The structure also contains a pointer to a selinux_ss structure whose definition is private to the security server and contains security server specific state such as the policy database and SID table. This change should have no effect on SELinux behavior or APIs (userspace or LSM). It merely wraps SELinux state and passes it explicitly as needed. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> [PM: minor fixups needed due to collisions with the SCTP patches] Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
parent
2572f5b424
commit
aa8e712cee
@ -149,7 +149,8 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
|
|||||||
char *scontext;
|
char *scontext;
|
||||||
u32 scontext_len;
|
u32 scontext_len;
|
||||||
|
|
||||||
rc = security_sid_to_context(ssid, &scontext, &scontext_len);
|
rc = security_sid_to_context(&selinux_state, ssid,
|
||||||
|
&scontext, &scontext_len);
|
||||||
if (rc)
|
if (rc)
|
||||||
audit_log_format(ab, "ssid=%d", ssid);
|
audit_log_format(ab, "ssid=%d", ssid);
|
||||||
else {
|
else {
|
||||||
@ -157,7 +158,8 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
|
|||||||
kfree(scontext);
|
kfree(scontext);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = security_sid_to_context(tsid, &scontext, &scontext_len);
|
rc = security_sid_to_context(&selinux_state, tsid,
|
||||||
|
&scontext, &scontext_len);
|
||||||
if (rc)
|
if (rc)
|
||||||
audit_log_format(ab, " tsid=%d", tsid);
|
audit_log_format(ab, " tsid=%d", tsid);
|
||||||
else {
|
else {
|
||||||
@ -969,7 +971,8 @@ static noinline struct avc_node *avc_compute_av(u32 ssid, u32 tsid,
|
|||||||
{
|
{
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
INIT_LIST_HEAD(&xp_node->xpd_head);
|
INIT_LIST_HEAD(&xp_node->xpd_head);
|
||||||
security_compute_av(ssid, tsid, tclass, avd, &xp_node->xp);
|
security_compute_av(&selinux_state, ssid, tsid, tclass,
|
||||||
|
avd, &xp_node->xp);
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
return avc_insert(ssid, tsid, tclass, avd, xp_node);
|
return avc_insert(ssid, tsid, tclass, avd, xp_node);
|
||||||
}
|
}
|
||||||
@ -982,7 +985,8 @@ static noinline int avc_denied(u32 ssid, u32 tsid,
|
|||||||
if (flags & AVC_STRICT)
|
if (flags & AVC_STRICT)
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
|
||||||
if (selinux_enforcing && !(avd->flags & AVD_FLAGS_PERMISSIVE))
|
if (is_enforcing(&selinux_state) &&
|
||||||
|
!(avd->flags & AVD_FLAGS_PERMISSIVE))
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
|
||||||
avc_update_node(AVC_CALLBACK_GRANT, requested, driver, xperm, ssid,
|
avc_update_node(AVC_CALLBACK_GRANT, requested, driver, xperm, ssid,
|
||||||
@ -1043,8 +1047,8 @@ int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested,
|
|||||||
goto decision;
|
goto decision;
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
security_compute_xperms_decision(ssid, tsid, tclass, driver,
|
security_compute_xperms_decision(&selinux_state, ssid, tsid,
|
||||||
&local_xpd);
|
tclass, driver, &local_xpd);
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
avc_update_node(AVC_CALLBACK_ADD_XPERMS, requested, driver, xperm,
|
avc_update_node(AVC_CALLBACK_ADD_XPERMS, requested, driver, xperm,
|
||||||
ssid, tsid, tclass, avd.seqno, &local_xpd, 0);
|
ssid, tsid, tclass, avd.seqno, &local_xpd, 0);
|
||||||
|
@ -100,20 +100,24 @@
|
|||||||
#include "audit.h"
|
#include "audit.h"
|
||||||
#include "avc_ss.h"
|
#include "avc_ss.h"
|
||||||
|
|
||||||
|
struct selinux_state selinux_state;
|
||||||
|
|
||||||
/* SECMARK reference count */
|
/* SECMARK reference count */
|
||||||
static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
|
static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0);
|
||||||
|
|
||||||
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
|
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
|
||||||
int selinux_enforcing;
|
static int selinux_enforcing_boot;
|
||||||
|
|
||||||
static int __init enforcing_setup(char *str)
|
static int __init enforcing_setup(char *str)
|
||||||
{
|
{
|
||||||
unsigned long enforcing;
|
unsigned long enforcing;
|
||||||
if (!kstrtoul(str, 0, &enforcing))
|
if (!kstrtoul(str, 0, &enforcing))
|
||||||
selinux_enforcing = enforcing ? 1 : 0;
|
selinux_enforcing_boot = enforcing ? 1 : 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
__setup("enforcing=", enforcing_setup);
|
__setup("enforcing=", enforcing_setup);
|
||||||
|
#else
|
||||||
|
#define selinux_enforcing_boot 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
|
#ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
|
||||||
@ -131,6 +135,19 @@ __setup("selinux=", selinux_enabled_setup);
|
|||||||
int selinux_enabled = 1;
|
int selinux_enabled = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static unsigned int selinux_checkreqprot_boot =
|
||||||
|
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
|
||||||
|
|
||||||
|
static int __init checkreqprot_setup(char *str)
|
||||||
|
{
|
||||||
|
unsigned long checkreqprot;
|
||||||
|
|
||||||
|
if (!kstrtoul(str, 0, &checkreqprot))
|
||||||
|
selinux_checkreqprot_boot = checkreqprot ? 1 : 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
__setup("checkreqprot=", checkreqprot_setup);
|
||||||
|
|
||||||
static struct kmem_cache *sel_inode_cache;
|
static struct kmem_cache *sel_inode_cache;
|
||||||
static struct kmem_cache *file_security_cache;
|
static struct kmem_cache *file_security_cache;
|
||||||
|
|
||||||
@ -147,7 +164,8 @@ static struct kmem_cache *file_security_cache;
|
|||||||
*/
|
*/
|
||||||
static int selinux_secmark_enabled(void)
|
static int selinux_secmark_enabled(void)
|
||||||
{
|
{
|
||||||
return (selinux_policycap_alwaysnetwork || atomic_read(&selinux_secmark_refcount));
|
return (selinux_policycap_alwaysnetwork() ||
|
||||||
|
atomic_read(&selinux_secmark_refcount));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -162,7 +180,8 @@ static int selinux_secmark_enabled(void)
|
|||||||
*/
|
*/
|
||||||
static int selinux_peerlbl_enabled(void)
|
static int selinux_peerlbl_enabled(void)
|
||||||
{
|
{
|
||||||
return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
|
return (selinux_policycap_alwaysnetwork() ||
|
||||||
|
netlbl_enabled() || selinux_xfrm_enabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
static int selinux_netcache_avc_callback(u32 event)
|
static int selinux_netcache_avc_callback(u32 event)
|
||||||
@ -266,7 +285,8 @@ static int __inode_security_revalidate(struct inode *inode,
|
|||||||
|
|
||||||
might_sleep_if(may_sleep);
|
might_sleep_if(may_sleep);
|
||||||
|
|
||||||
if (ss_initialized && isec->initialized != LABEL_INITIALIZED) {
|
if (selinux_state.initialized &&
|
||||||
|
isec->initialized != LABEL_INITIALIZED) {
|
||||||
if (!may_sleep)
|
if (!may_sleep)
|
||||||
return -ECHILD;
|
return -ECHILD;
|
||||||
|
|
||||||
@ -488,7 +508,7 @@ static int selinux_is_sblabel_mnt(struct super_block *sb)
|
|||||||
!strcmp(sb->s_type->name, "debugfs") ||
|
!strcmp(sb->s_type->name, "debugfs") ||
|
||||||
!strcmp(sb->s_type->name, "tracefs") ||
|
!strcmp(sb->s_type->name, "tracefs") ||
|
||||||
!strcmp(sb->s_type->name, "rootfs") ||
|
!strcmp(sb->s_type->name, "rootfs") ||
|
||||||
(selinux_policycap_cgroupseclabel &&
|
(selinux_policycap_cgroupseclabel() &&
|
||||||
(!strcmp(sb->s_type->name, "cgroup") ||
|
(!strcmp(sb->s_type->name, "cgroup") ||
|
||||||
!strcmp(sb->s_type->name, "cgroup2")));
|
!strcmp(sb->s_type->name, "cgroup2")));
|
||||||
}
|
}
|
||||||
@ -588,7 +608,7 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
|
|||||||
if (!(sbsec->flags & SE_SBINITIALIZED))
|
if (!(sbsec->flags & SE_SBINITIALIZED))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!ss_initialized)
|
if (!selinux_state.initialized)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* make sure we always check enough bits to cover the mask */
|
/* make sure we always check enough bits to cover the mask */
|
||||||
@ -619,21 +639,25 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
|
|||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
if (sbsec->flags & FSCONTEXT_MNT) {
|
if (sbsec->flags & FSCONTEXT_MNT) {
|
||||||
rc = security_sid_to_context(sbsec->sid, &context, &len);
|
rc = security_sid_to_context(&selinux_state, sbsec->sid,
|
||||||
|
&context, &len);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
opts->mnt_opts[i] = context;
|
opts->mnt_opts[i] = context;
|
||||||
opts->mnt_opts_flags[i++] = FSCONTEXT_MNT;
|
opts->mnt_opts_flags[i++] = FSCONTEXT_MNT;
|
||||||
}
|
}
|
||||||
if (sbsec->flags & CONTEXT_MNT) {
|
if (sbsec->flags & CONTEXT_MNT) {
|
||||||
rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len);
|
rc = security_sid_to_context(&selinux_state,
|
||||||
|
sbsec->mntpoint_sid,
|
||||||
|
&context, &len);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
opts->mnt_opts[i] = context;
|
opts->mnt_opts[i] = context;
|
||||||
opts->mnt_opts_flags[i++] = CONTEXT_MNT;
|
opts->mnt_opts_flags[i++] = CONTEXT_MNT;
|
||||||
}
|
}
|
||||||
if (sbsec->flags & DEFCONTEXT_MNT) {
|
if (sbsec->flags & DEFCONTEXT_MNT) {
|
||||||
rc = security_sid_to_context(sbsec->def_sid, &context, &len);
|
rc = security_sid_to_context(&selinux_state, sbsec->def_sid,
|
||||||
|
&context, &len);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
opts->mnt_opts[i] = context;
|
opts->mnt_opts[i] = context;
|
||||||
@ -643,7 +667,8 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
|
|||||||
struct dentry *root = sbsec->sb->s_root;
|
struct dentry *root = sbsec->sb->s_root;
|
||||||
struct inode_security_struct *isec = backing_inode_security(root);
|
struct inode_security_struct *isec = backing_inode_security(root);
|
||||||
|
|
||||||
rc = security_sid_to_context(isec->sid, &context, &len);
|
rc = security_sid_to_context(&selinux_state, isec->sid,
|
||||||
|
&context, &len);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
opts->mnt_opts[i] = context;
|
opts->mnt_opts[i] = context;
|
||||||
@ -706,7 +731,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
|
|||||||
|
|
||||||
mutex_lock(&sbsec->lock);
|
mutex_lock(&sbsec->lock);
|
||||||
|
|
||||||
if (!ss_initialized) {
|
if (!selinux_state.initialized) {
|
||||||
if (!num_opts) {
|
if (!num_opts) {
|
||||||
/* Defer initialization until selinux_complete_init,
|
/* Defer initialization until selinux_complete_init,
|
||||||
after the initial policy is loaded and the security
|
after the initial policy is loaded and the security
|
||||||
@ -752,7 +777,9 @@ static int selinux_set_mnt_opts(struct super_block *sb,
|
|||||||
|
|
||||||
if (flags[i] == SBLABEL_MNT)
|
if (flags[i] == SBLABEL_MNT)
|
||||||
continue;
|
continue;
|
||||||
rc = security_context_str_to_sid(mount_options[i], &sid, GFP_KERNEL);
|
rc = security_context_str_to_sid(&selinux_state,
|
||||||
|
mount_options[i], &sid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_WARNING "SELinux: security_context_str_to_sid"
|
printk(KERN_WARNING "SELinux: security_context_str_to_sid"
|
||||||
"(%s) failed for (dev %s, type %s) errno=%d\n",
|
"(%s) failed for (dev %s, type %s) errno=%d\n",
|
||||||
@ -828,7 +855,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
|
|||||||
* Determine the labeling behavior to use for this
|
* Determine the labeling behavior to use for this
|
||||||
* filesystem type.
|
* filesystem type.
|
||||||
*/
|
*/
|
||||||
rc = security_fs_use(sb);
|
rc = security_fs_use(&selinux_state, sb);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"%s: security_fs_use(%s) returned %d\n",
|
"%s: security_fs_use(%s) returned %d\n",
|
||||||
@ -853,7 +880,9 @@ static int selinux_set_mnt_opts(struct super_block *sb,
|
|||||||
}
|
}
|
||||||
if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
|
if (sbsec->behavior == SECURITY_FS_USE_XATTR) {
|
||||||
sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
|
sbsec->behavior = SECURITY_FS_USE_MNTPOINT;
|
||||||
rc = security_transition_sid(current_sid(), current_sid(),
|
rc = security_transition_sid(&selinux_state,
|
||||||
|
current_sid(),
|
||||||
|
current_sid(),
|
||||||
SECCLASS_FILE, NULL,
|
SECCLASS_FILE, NULL,
|
||||||
&sbsec->mntpoint_sid);
|
&sbsec->mntpoint_sid);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -989,7 +1018,7 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
|
|||||||
* if the parent was able to be mounted it clearly had no special lsm
|
* if the parent was able to be mounted it clearly had no special lsm
|
||||||
* mount options. thus we can safely deal with this superblock later
|
* mount options. thus we can safely deal with this superblock later
|
||||||
*/
|
*/
|
||||||
if (!ss_initialized)
|
if (!selinux_state.initialized)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1016,7 +1045,7 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
|
|||||||
|
|
||||||
if (newsbsec->behavior == SECURITY_FS_USE_NATIVE &&
|
if (newsbsec->behavior == SECURITY_FS_USE_NATIVE &&
|
||||||
!(kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) {
|
!(kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) {
|
||||||
rc = security_fs_use(newsb);
|
rc = security_fs_use(&selinux_state, newsb);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -1299,7 +1328,7 @@ static inline int default_protocol_dgram(int protocol)
|
|||||||
|
|
||||||
static inline u16 socket_type_to_security_class(int family, int type, int protocol)
|
static inline u16 socket_type_to_security_class(int family, int type, int protocol)
|
||||||
{
|
{
|
||||||
int extsockclass = selinux_policycap_extsockclass;
|
int extsockclass = selinux_policycap_extsockclass();
|
||||||
|
|
||||||
switch (family) {
|
switch (family) {
|
||||||
case PF_UNIX:
|
case PF_UNIX:
|
||||||
@ -1473,7 +1502,8 @@ static int selinux_genfs_get_sid(struct dentry *dentry,
|
|||||||
path++;
|
path++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rc = security_genfs_sid(sb->s_type->name, path, tclass, sid);
|
rc = security_genfs_sid(&selinux_state, sb->s_type->name,
|
||||||
|
path, tclass, sid);
|
||||||
}
|
}
|
||||||
free_page((unsigned long)buffer);
|
free_page((unsigned long)buffer);
|
||||||
return rc;
|
return rc;
|
||||||
@ -1591,7 +1621,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
|
|||||||
sid = sbsec->def_sid;
|
sid = sbsec->def_sid;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
rc = security_context_to_sid_default(context, rc, &sid,
|
rc = security_context_to_sid_default(&selinux_state,
|
||||||
|
context, rc, &sid,
|
||||||
sbsec->def_sid,
|
sbsec->def_sid,
|
||||||
GFP_NOFS);
|
GFP_NOFS);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
@ -1624,7 +1655,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
|
|||||||
sid = sbsec->sid;
|
sid = sbsec->sid;
|
||||||
|
|
||||||
/* Try to obtain a transition SID. */
|
/* Try to obtain a transition SID. */
|
||||||
rc = security_transition_sid(task_sid, sid, sclass, NULL, &sid);
|
rc = security_transition_sid(&selinux_state, task_sid, sid,
|
||||||
|
sclass, NULL, &sid);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
break;
|
break;
|
||||||
@ -1885,7 +1917,8 @@ selinux_determine_inode_label(const struct task_security_struct *tsec,
|
|||||||
*_new_isid = tsec->create_sid;
|
*_new_isid = tsec->create_sid;
|
||||||
} else {
|
} else {
|
||||||
const struct inode_security_struct *dsec = inode_security(dir);
|
const struct inode_security_struct *dsec = inode_security(dir);
|
||||||
return security_transition_sid(tsec->sid, dsec->sid, tclass,
|
return security_transition_sid(&selinux_state, tsec->sid,
|
||||||
|
dsec->sid, tclass,
|
||||||
name, _new_isid);
|
name, _new_isid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2108,7 +2141,8 @@ static inline u32 open_file_to_av(struct file *file)
|
|||||||
u32 av = file_to_av(file);
|
u32 av = file_to_av(file);
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = file_inode(file);
|
||||||
|
|
||||||
if (selinux_policycap_openperm && inode->i_sb->s_magic != SOCKFS_MAGIC)
|
if (selinux_policycap_openperm() &&
|
||||||
|
inode->i_sb->s_magic != SOCKFS_MAGIC)
|
||||||
av |= FILE__OPEN;
|
av |= FILE__OPEN;
|
||||||
|
|
||||||
return av;
|
return av;
|
||||||
@ -2353,7 +2387,7 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm,
|
|||||||
* policy allows the corresponding permission between
|
* policy allows the corresponding permission between
|
||||||
* the old and new contexts.
|
* the old and new contexts.
|
||||||
*/
|
*/
|
||||||
if (selinux_policycap_nnp_nosuid_transition) {
|
if (selinux_policycap_nnp_nosuid_transition()) {
|
||||||
av = 0;
|
av = 0;
|
||||||
if (nnp)
|
if (nnp)
|
||||||
av |= PROCESS2__NNP_TRANSITION;
|
av |= PROCESS2__NNP_TRANSITION;
|
||||||
@ -2370,7 +2404,8 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm,
|
|||||||
* i.e. SIDs that are guaranteed to only be allowed a subset
|
* i.e. SIDs that are guaranteed to only be allowed a subset
|
||||||
* of the permissions of the current SID.
|
* of the permissions of the current SID.
|
||||||
*/
|
*/
|
||||||
rc = security_bounded_transition(old_tsec->sid, new_tsec->sid);
|
rc = security_bounded_transition(&selinux_state, old_tsec->sid,
|
||||||
|
new_tsec->sid);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -2422,8 +2457,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
|
|||||||
return rc;
|
return rc;
|
||||||
} else {
|
} else {
|
||||||
/* Check for a default transition on this program. */
|
/* Check for a default transition on this program. */
|
||||||
rc = security_transition_sid(old_tsec->sid, isec->sid,
|
rc = security_transition_sid(&selinux_state, old_tsec->sid,
|
||||||
SECCLASS_PROCESS, NULL,
|
isec->sid, SECCLASS_PROCESS, NULL,
|
||||||
&new_tsec->sid);
|
&new_tsec->sid);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
@ -2781,7 +2816,9 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
|
|||||||
|
|
||||||
if (flags[i] == SBLABEL_MNT)
|
if (flags[i] == SBLABEL_MNT)
|
||||||
continue;
|
continue;
|
||||||
rc = security_context_str_to_sid(mount_options[i], &sid, GFP_KERNEL);
|
rc = security_context_str_to_sid(&selinux_state,
|
||||||
|
mount_options[i], &sid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_WARNING "SELinux: security_context_str_to_sid"
|
printk(KERN_WARNING "SELinux: security_context_str_to_sid"
|
||||||
"(%s) failed for (dev %s, type %s) errno=%d\n",
|
"(%s) failed for (dev %s, type %s) errno=%d\n",
|
||||||
@ -2906,7 +2943,8 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
|
|||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
return security_sid_to_context(newsid, (char **)ctx, ctxlen);
|
return security_sid_to_context(&selinux_state, newsid, (char **)ctx,
|
||||||
|
ctxlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
|
static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
|
||||||
@ -2960,14 +2998,15 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
|
|||||||
isec->initialized = LABEL_INITIALIZED;
|
isec->initialized = LABEL_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT))
|
if (!selinux_state.initialized || !(sbsec->flags & SBLABEL_MNT))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
*name = XATTR_SELINUX_SUFFIX;
|
*name = XATTR_SELINUX_SUFFIX;
|
||||||
|
|
||||||
if (value && len) {
|
if (value && len) {
|
||||||
rc = security_sid_to_context_force(newsid, &context, &clen);
|
rc = security_sid_to_context_force(&selinux_state, newsid,
|
||||||
|
&context, &clen);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
*value = context;
|
*value = context;
|
||||||
@ -3128,7 +3167,7 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
|
|||||||
ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
|
ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
|
||||||
return dentry_has_perm(cred, dentry, FILE__SETATTR);
|
return dentry_has_perm(cred, dentry, FILE__SETATTR);
|
||||||
|
|
||||||
if (selinux_policycap_openperm &&
|
if (selinux_policycap_openperm() &&
|
||||||
inode->i_sb->s_magic != SOCKFS_MAGIC &&
|
inode->i_sb->s_magic != SOCKFS_MAGIC &&
|
||||||
(ia_valid & ATTR_SIZE) &&
|
(ia_valid & ATTR_SIZE) &&
|
||||||
!(ia_valid & ATTR_FILE))
|
!(ia_valid & ATTR_FILE))
|
||||||
@ -3190,7 +3229,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
|
|||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL);
|
rc = security_context_to_sid(&selinux_state, value, size, &newsid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (rc == -EINVAL) {
|
if (rc == -EINVAL) {
|
||||||
if (!has_cap_mac_admin(true)) {
|
if (!has_cap_mac_admin(true)) {
|
||||||
struct audit_buffer *ab;
|
struct audit_buffer *ab;
|
||||||
@ -3215,7 +3255,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
|
|||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
rc = security_context_to_sid_force(value, size, &newsid);
|
rc = security_context_to_sid_force(&selinux_state, value,
|
||||||
|
size, &newsid);
|
||||||
}
|
}
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
@ -3225,8 +3266,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
|
|||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
rc = security_validate_transition(isec->sid, newsid, sid,
|
rc = security_validate_transition(&selinux_state, isec->sid, newsid,
|
||||||
isec->sclass);
|
sid, isec->sclass);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@ -3251,7 +3292,8 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = security_context_to_sid_force(value, size, &newsid);
|
rc = security_context_to_sid_force(&selinux_state, value, size,
|
||||||
|
&newsid);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_ERR "SELinux: unable to map context to SID"
|
printk(KERN_ERR "SELinux: unable to map context to SID"
|
||||||
"for (%s, %lu), rc=%d\n",
|
"for (%s, %lu), rc=%d\n",
|
||||||
@ -3326,10 +3368,12 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
|
|||||||
*/
|
*/
|
||||||
isec = inode_security(inode);
|
isec = inode_security(inode);
|
||||||
if (has_cap_mac_admin(false))
|
if (has_cap_mac_admin(false))
|
||||||
error = security_sid_to_context_force(isec->sid, &context,
|
error = security_sid_to_context_force(&selinux_state,
|
||||||
|
isec->sid, &context,
|
||||||
&size);
|
&size);
|
||||||
else
|
else
|
||||||
error = security_sid_to_context(isec->sid, &context, &size);
|
error = security_sid_to_context(&selinux_state, isec->sid,
|
||||||
|
&context, &size);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
error = size;
|
error = size;
|
||||||
@ -3355,7 +3399,8 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
|
|||||||
if (!value || !size)
|
if (!value || !size)
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
|
||||||
rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL);
|
rc = security_context_to_sid(&selinux_state, value, size, &newsid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@ -3617,7 +3662,7 @@ static int selinux_mmap_file(struct file *file, unsigned long reqprot,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selinux_checkreqprot)
|
if (selinux_state.checkreqprot)
|
||||||
prot = reqprot;
|
prot = reqprot;
|
||||||
|
|
||||||
return file_map_prot_check(file, prot,
|
return file_map_prot_check(file, prot,
|
||||||
@ -3631,7 +3676,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
|
|||||||
const struct cred *cred = current_cred();
|
const struct cred *cred = current_cred();
|
||||||
u32 sid = cred_sid(cred);
|
u32 sid = cred_sid(cred);
|
||||||
|
|
||||||
if (selinux_checkreqprot)
|
if (selinux_state.checkreqprot)
|
||||||
prot = reqprot;
|
prot = reqprot;
|
||||||
|
|
||||||
if (default_noexec &&
|
if (default_noexec &&
|
||||||
@ -4319,7 +4364,8 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
|
|||||||
if (unlikely(err))
|
if (unlikely(err))
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
|
||||||
err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid);
|
err = security_net_peersid_resolve(&selinux_state, nlbl_sid,
|
||||||
|
nlbl_type, xfrm_sid, sid);
|
||||||
if (unlikely(err)) {
|
if (unlikely(err)) {
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"SELinux: failure in selinux_skb_peerlbl_sid(),"
|
"SELinux: failure in selinux_skb_peerlbl_sid(),"
|
||||||
@ -4347,7 +4393,8 @@ static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (skb_sid != SECSID_NULL)
|
if (skb_sid != SECSID_NULL)
|
||||||
err = security_sid_mls_copy(sk_sid, skb_sid, conn_sid);
|
err = security_sid_mls_copy(&selinux_state, sk_sid, skb_sid,
|
||||||
|
conn_sid);
|
||||||
else
|
else
|
||||||
*conn_sid = sk_sid;
|
*conn_sid = sk_sid;
|
||||||
|
|
||||||
@ -4364,8 +4411,8 @@ static int socket_sockcreate_sid(const struct task_security_struct *tsec,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return security_transition_sid(tsec->sid, tsec->sid, secclass, NULL,
|
return security_transition_sid(&selinux_state, tsec->sid, tsec->sid,
|
||||||
socksid);
|
secclass, NULL, socksid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sock_has_perm(struct sock *sk, u32 perms)
|
static int sock_has_perm(struct sock *sk, u32 perms)
|
||||||
@ -4741,8 +4788,8 @@ static int selinux_socket_unix_stream_connect(struct sock *sock,
|
|||||||
|
|
||||||
/* server child socket */
|
/* server child socket */
|
||||||
sksec_new->peer_sid = sksec_sock->sid;
|
sksec_new->peer_sid = sksec_sock->sid;
|
||||||
err = security_sid_mls_copy(sksec_other->sid, sksec_sock->sid,
|
err = security_sid_mls_copy(&selinux_state, sksec_other->sid,
|
||||||
&sksec_new->sid);
|
sksec_sock->sid, &sksec_new->sid);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -4847,7 +4894,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
|||||||
* to the selinux_sock_rcv_skb_compat() function to deal with the
|
* to the selinux_sock_rcv_skb_compat() function to deal with the
|
||||||
* special handling. We do this in an attempt to keep this function
|
* special handling. We do this in an attempt to keep this function
|
||||||
* as fast and as clean as possible. */
|
* as fast and as clean as possible. */
|
||||||
if (!selinux_policycap_netpeer)
|
if (!selinux_policycap_netpeer())
|
||||||
return selinux_sock_rcv_skb_compat(sk, skb, family);
|
return selinux_sock_rcv_skb_compat(sk, skb, family);
|
||||||
|
|
||||||
secmark_active = selinux_secmark_enabled();
|
secmark_active = selinux_secmark_enabled();
|
||||||
@ -4909,7 +4956,8 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
|
|||||||
if (peer_sid == SECSID_NULL)
|
if (peer_sid == SECSID_NULL)
|
||||||
return -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
|
|
||||||
err = security_sid_to_context(peer_sid, &scontext, &scontext_len);
|
err = security_sid_to_context(&selinux_state, peer_sid, &scontext,
|
||||||
|
&scontext_len);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -5032,7 +5080,7 @@ static int selinux_sctp_assoc_request(struct sctp_endpoint *ep,
|
|||||||
u32 conn_sid;
|
u32 conn_sid;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (!selinux_policycap_extsockclass)
|
if (!selinux_policycap_extsockclass())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
peerlbl_active = selinux_peerlbl_enabled();
|
peerlbl_active = selinux_peerlbl_enabled();
|
||||||
@ -5101,7 +5149,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname,
|
|||||||
struct sockaddr *addr;
|
struct sockaddr *addr;
|
||||||
struct socket *sock;
|
struct socket *sock;
|
||||||
|
|
||||||
if (!selinux_policycap_extsockclass)
|
if (!selinux_policycap_extsockclass())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Process one or more addresses that may be IPv4 or IPv6 */
|
/* Process one or more addresses that may be IPv4 or IPv6 */
|
||||||
@ -5173,7 +5221,7 @@ static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk,
|
|||||||
/* If policy does not support SECCLASS_SCTP_SOCKET then call
|
/* If policy does not support SECCLASS_SCTP_SOCKET then call
|
||||||
* the non-sctp clone version.
|
* the non-sctp clone version.
|
||||||
*/
|
*/
|
||||||
if (!selinux_policycap_extsockclass)
|
if (!selinux_policycap_extsockclass())
|
||||||
return selinux_sk_clone_security(sk, newsk);
|
return selinux_sk_clone_security(sk, newsk);
|
||||||
|
|
||||||
newsksec->sid = ep->secid;
|
newsksec->sid = ep->secid;
|
||||||
@ -5359,7 +5407,8 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
|
|||||||
sk->sk_protocol, nlh->nlmsg_type,
|
sk->sk_protocol, nlh->nlmsg_type,
|
||||||
secclass_map[sksec->sclass - 1].name,
|
secclass_map[sksec->sclass - 1].name,
|
||||||
task_pid_nr(current), current->comm);
|
task_pid_nr(current), current->comm);
|
||||||
if (!selinux_enforcing || security_get_allow_unknown())
|
if (!is_enforcing(&selinux_state) ||
|
||||||
|
security_get_allow_unknown(&selinux_state))
|
||||||
err = 0;
|
err = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5389,7 +5438,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb,
|
|||||||
u8 netlbl_active;
|
u8 netlbl_active;
|
||||||
u8 peerlbl_active;
|
u8 peerlbl_active;
|
||||||
|
|
||||||
if (!selinux_policycap_netpeer)
|
if (!selinux_policycap_netpeer())
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
secmark_active = selinux_secmark_enabled();
|
secmark_active = selinux_secmark_enabled();
|
||||||
@ -5558,7 +5607,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb,
|
|||||||
* to the selinux_ip_postroute_compat() function to deal with the
|
* to the selinux_ip_postroute_compat() function to deal with the
|
||||||
* special handling. We do this in an attempt to keep this function
|
* special handling. We do this in an attempt to keep this function
|
||||||
* as fast and as clean as possible. */
|
* as fast and as clean as possible. */
|
||||||
if (!selinux_policycap_netpeer)
|
if (!selinux_policycap_netpeer())
|
||||||
return selinux_ip_postroute_compat(skb, ifindex, family);
|
return selinux_ip_postroute_compat(skb, ifindex, family);
|
||||||
|
|
||||||
secmark_active = selinux_secmark_enabled();
|
secmark_active = selinux_secmark_enabled();
|
||||||
@ -5864,8 +5913,8 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
|
|||||||
* Compute new sid based on current process and
|
* Compute new sid based on current process and
|
||||||
* message queue this message will be stored in
|
* message queue this message will be stored in
|
||||||
*/
|
*/
|
||||||
rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG,
|
rc = security_transition_sid(&selinux_state, sid, isec->sid,
|
||||||
NULL, &msec->sid);
|
SECCLASS_MSG, NULL, &msec->sid);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -6174,7 +6223,7 @@ static int selinux_getprocattr(struct task_struct *p,
|
|||||||
if (!sid)
|
if (!sid)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error = security_sid_to_context(sid, value, &len);
|
error = security_sid_to_context(&selinux_state, sid, value, &len);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
return len;
|
return len;
|
||||||
@ -6221,7 +6270,8 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
|
|||||||
str[size-1] = 0;
|
str[size-1] = 0;
|
||||||
size--;
|
size--;
|
||||||
}
|
}
|
||||||
error = security_context_to_sid(value, size, &sid, GFP_KERNEL);
|
error = security_context_to_sid(&selinux_state, value, size,
|
||||||
|
&sid, GFP_KERNEL);
|
||||||
if (error == -EINVAL && !strcmp(name, "fscreate")) {
|
if (error == -EINVAL && !strcmp(name, "fscreate")) {
|
||||||
if (!has_cap_mac_admin(true)) {
|
if (!has_cap_mac_admin(true)) {
|
||||||
struct audit_buffer *ab;
|
struct audit_buffer *ab;
|
||||||
@ -6240,8 +6290,9 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
|
|||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
error = security_context_to_sid_force(value, size,
|
error = security_context_to_sid_force(
|
||||||
&sid);
|
&selinux_state,
|
||||||
|
value, size, &sid);
|
||||||
}
|
}
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
@ -6278,7 +6329,8 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
|
|||||||
/* Only allow single threaded processes to change context */
|
/* Only allow single threaded processes to change context */
|
||||||
error = -EPERM;
|
error = -EPERM;
|
||||||
if (!current_is_single_threaded()) {
|
if (!current_is_single_threaded()) {
|
||||||
error = security_bounded_transition(tsec->sid, sid);
|
error = security_bounded_transition(&selinux_state,
|
||||||
|
tsec->sid, sid);
|
||||||
if (error)
|
if (error)
|
||||||
goto abort_change;
|
goto abort_change;
|
||||||
}
|
}
|
||||||
@ -6320,12 +6372,14 @@ static int selinux_ismaclabel(const char *name)
|
|||||||
|
|
||||||
static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
|
static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
|
||||||
{
|
{
|
||||||
return security_sid_to_context(secid, secdata, seclen);
|
return security_sid_to_context(&selinux_state, secid,
|
||||||
|
secdata, seclen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
|
static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
|
||||||
{
|
{
|
||||||
return security_context_to_sid(secdata, seclen, secid, GFP_KERNEL);
|
return security_context_to_sid(&selinux_state, secdata, seclen,
|
||||||
|
secid, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void selinux_release_secctx(char *secdata, u32 seclen)
|
static void selinux_release_secctx(char *secdata, u32 seclen)
|
||||||
@ -6427,7 +6481,8 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
|
|||||||
unsigned len;
|
unsigned len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = security_sid_to_context(ksec->sid, &context, &len);
|
rc = security_sid_to_context(&selinux_state, ksec->sid,
|
||||||
|
&context, &len);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
rc = len;
|
rc = len;
|
||||||
*_buffer = context;
|
*_buffer = context;
|
||||||
@ -6466,7 +6521,8 @@ static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name,
|
|||||||
struct ib_security_struct *sec = ib_sec;
|
struct ib_security_struct *sec = ib_sec;
|
||||||
struct lsm_ibendport_audit ibendport;
|
struct lsm_ibendport_audit ibendport;
|
||||||
|
|
||||||
err = security_ib_endport_sid(dev_name, port_num, &sid);
|
err = security_ib_endport_sid(&selinux_state, dev_name, port_num,
|
||||||
|
&sid);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
@ -6880,6 +6936,11 @@ static __init int selinux_init(void)
|
|||||||
|
|
||||||
printk(KERN_INFO "SELinux: Initializing.\n");
|
printk(KERN_INFO "SELinux: Initializing.\n");
|
||||||
|
|
||||||
|
memset(&selinux_state, 0, sizeof(selinux_state));
|
||||||
|
set_enforcing(&selinux_state, selinux_enforcing_boot);
|
||||||
|
selinux_state.checkreqprot = selinux_checkreqprot_boot;
|
||||||
|
selinux_ss_init(&selinux_state.ss);
|
||||||
|
|
||||||
/* Set the security state for the initial task. */
|
/* Set the security state for the initial task. */
|
||||||
cred_init_security();
|
cred_init_security();
|
||||||
|
|
||||||
@ -6893,6 +6954,12 @@ static __init int selinux_init(void)
|
|||||||
0, SLAB_PANIC, NULL);
|
0, SLAB_PANIC, NULL);
|
||||||
avc_init();
|
avc_init();
|
||||||
|
|
||||||
|
avtab_cache_init();
|
||||||
|
|
||||||
|
ebitmap_cache_init();
|
||||||
|
|
||||||
|
hashtab_cache_init();
|
||||||
|
|
||||||
security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux");
|
security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux");
|
||||||
|
|
||||||
if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
|
if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
|
||||||
@ -6901,7 +6968,7 @@ static __init int selinux_init(void)
|
|||||||
if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
|
if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
|
||||||
panic("SELinux: Unable to register AVC LSM notifier callback\n");
|
panic("SELinux: Unable to register AVC LSM notifier callback\n");
|
||||||
|
|
||||||
if (selinux_enforcing)
|
if (selinux_enforcing_boot)
|
||||||
printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n");
|
printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n");
|
||||||
else
|
else
|
||||||
printk(KERN_DEBUG "SELinux: Starting in permissive mode\n");
|
printk(KERN_DEBUG "SELinux: Starting in permissive mode\n");
|
||||||
@ -7022,23 +7089,22 @@ static void selinux_nf_ip_exit(void)
|
|||||||
#endif /* CONFIG_NETFILTER */
|
#endif /* CONFIG_NETFILTER */
|
||||||
|
|
||||||
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
|
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
|
||||||
static int selinux_disabled;
|
int selinux_disable(struct selinux_state *state)
|
||||||
|
|
||||||
int selinux_disable(void)
|
|
||||||
{
|
{
|
||||||
if (ss_initialized) {
|
if (state->initialized) {
|
||||||
/* Not permitted after initial policy load. */
|
/* Not permitted after initial policy load. */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selinux_disabled) {
|
if (state->disabled) {
|
||||||
/* Only do this once. */
|
/* Only do this once. */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state->disabled = 1;
|
||||||
|
|
||||||
printk(KERN_INFO "SELinux: Disabled at runtime.\n");
|
printk(KERN_INFO "SELinux: Disabled at runtime.\n");
|
||||||
|
|
||||||
selinux_disabled = 1;
|
|
||||||
selinux_enabled = 0;
|
selinux_enabled = 0;
|
||||||
|
|
||||||
security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
|
security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
|
||||||
|
@ -152,7 +152,8 @@ static int sel_ib_pkey_sid_slow(u64 subnet_prefix, u16 pkey_num, u32 *sid)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = security_ib_pkey_sid(subnet_prefix, pkey_num, sid);
|
ret = security_ib_pkey_sid(&selinux_state, subnet_prefix, pkey_num,
|
||||||
|
sid);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -20,12 +20,6 @@
|
|||||||
#include "av_permissions.h"
|
#include "av_permissions.h"
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
|
|
||||||
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
|
|
||||||
extern int selinux_enforcing;
|
|
||||||
#else
|
|
||||||
#define selinux_enforcing 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An entry in the AVC.
|
* An entry in the AVC.
|
||||||
*/
|
*/
|
||||||
|
@ -19,11 +19,5 @@ struct security_class_mapping {
|
|||||||
|
|
||||||
extern struct security_class_mapping secclass_map[];
|
extern struct security_class_mapping secclass_map[];
|
||||||
|
|
||||||
/*
|
|
||||||
* The security server must be initialized before
|
|
||||||
* any labeling or access decisions can be provided.
|
|
||||||
*/
|
|
||||||
extern int ss_initialized;
|
|
||||||
|
|
||||||
#endif /* _SELINUX_AVC_SS_H_ */
|
#endif /* _SELINUX_AVC_SS_H_ */
|
||||||
|
|
||||||
|
@ -13,10 +13,15 @@
|
|||||||
#ifndef _SELINUX_CONDITIONAL_H_
|
#ifndef _SELINUX_CONDITIONAL_H_
|
||||||
#define _SELINUX_CONDITIONAL_H_
|
#define _SELINUX_CONDITIONAL_H_
|
||||||
|
|
||||||
int security_get_bools(int *len, char ***names, int **values);
|
#include "security.h"
|
||||||
|
|
||||||
int security_set_bools(int len, int *values);
|
int security_get_bools(struct selinux_state *state,
|
||||||
|
int *len, char ***names, int **values);
|
||||||
|
|
||||||
int security_get_bool_value(int index);
|
int security_set_bools(struct selinux_state *state,
|
||||||
|
int len, int *values);
|
||||||
|
|
||||||
|
int security_get_bool_value(struct selinux_state *state,
|
||||||
|
int index);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -158,6 +158,4 @@ struct bpf_security_struct {
|
|||||||
u32 sid; /*SID of bpf obj creater*/
|
u32 sid; /*SID of bpf obj creater*/
|
||||||
};
|
};
|
||||||
|
|
||||||
extern unsigned int selinux_checkreqprot;
|
|
||||||
|
|
||||||
#endif /* _SELINUX_OBJSEC_H_ */
|
#endif /* _SELINUX_OBJSEC_H_ */
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#include <linux/dcache.h>
|
#include <linux/dcache.h>
|
||||||
#include <linux/magic.h>
|
#include <linux/magic.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/refcount.h>
|
||||||
|
#include <linux/workqueue.h>
|
||||||
#include "flask.h"
|
#include "flask.h"
|
||||||
|
|
||||||
#define SECSID_NULL 0x00000000 /* unspecified SID */
|
#define SECSID_NULL 0x00000000 /* unspecified SID */
|
||||||
@ -81,13 +83,6 @@ enum {
|
|||||||
|
|
||||||
extern char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX];
|
extern char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX];
|
||||||
|
|
||||||
extern int selinux_policycap_netpeer;
|
|
||||||
extern int selinux_policycap_openperm;
|
|
||||||
extern int selinux_policycap_extsockclass;
|
|
||||||
extern int selinux_policycap_alwaysnetwork;
|
|
||||||
extern int selinux_policycap_cgroupseclabel;
|
|
||||||
extern int selinux_policycap_nnp_nosuid_transition;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* type_datum properties
|
* type_datum properties
|
||||||
* available at the kernel policy version >= POLICYDB_VERSION_BOUNDARY
|
* available at the kernel policy version >= POLICYDB_VERSION_BOUNDARY
|
||||||
@ -98,13 +93,95 @@ extern int selinux_policycap_nnp_nosuid_transition;
|
|||||||
/* limitation of boundary depth */
|
/* limitation of boundary depth */
|
||||||
#define POLICYDB_BOUNDS_MAXDEPTH 4
|
#define POLICYDB_BOUNDS_MAXDEPTH 4
|
||||||
|
|
||||||
int security_mls_enabled(void);
|
struct selinux_ss;
|
||||||
|
|
||||||
int security_load_policy(void *data, size_t len);
|
struct selinux_state {
|
||||||
int security_read_policy(void **data, size_t *len);
|
bool disabled;
|
||||||
size_t security_policydb_len(void);
|
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
|
||||||
|
bool enforcing;
|
||||||
|
#endif
|
||||||
|
bool checkreqprot;
|
||||||
|
bool initialized;
|
||||||
|
bool policycap[__POLICYDB_CAPABILITY_MAX];
|
||||||
|
struct selinux_ss *ss;
|
||||||
|
};
|
||||||
|
|
||||||
int security_policycap_supported(unsigned int req_cap);
|
void selinux_ss_init(struct selinux_ss **ss);
|
||||||
|
|
||||||
|
extern struct selinux_state selinux_state;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
|
||||||
|
static inline bool is_enforcing(struct selinux_state *state)
|
||||||
|
{
|
||||||
|
return state->enforcing;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_enforcing(struct selinux_state *state, bool value)
|
||||||
|
{
|
||||||
|
state->enforcing = value;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline bool is_enforcing(struct selinux_state *state)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void set_enforcing(struct selinux_state *state, bool value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline bool selinux_policycap_netpeer(void)
|
||||||
|
{
|
||||||
|
struct selinux_state *state = &selinux_state;
|
||||||
|
|
||||||
|
return state->policycap[POLICYDB_CAPABILITY_NETPEER];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool selinux_policycap_openperm(void)
|
||||||
|
{
|
||||||
|
struct selinux_state *state = &selinux_state;
|
||||||
|
|
||||||
|
return state->policycap[POLICYDB_CAPABILITY_OPENPERM];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool selinux_policycap_extsockclass(void)
|
||||||
|
{
|
||||||
|
struct selinux_state *state = &selinux_state;
|
||||||
|
|
||||||
|
return state->policycap[POLICYDB_CAPABILITY_EXTSOCKCLASS];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool selinux_policycap_alwaysnetwork(void)
|
||||||
|
{
|
||||||
|
struct selinux_state *state = &selinux_state;
|
||||||
|
|
||||||
|
return state->policycap[POLICYDB_CAPABILITY_ALWAYSNETWORK];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool selinux_policycap_cgroupseclabel(void)
|
||||||
|
{
|
||||||
|
struct selinux_state *state = &selinux_state;
|
||||||
|
|
||||||
|
return state->policycap[POLICYDB_CAPABILITY_CGROUPSECLABEL];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool selinux_policycap_nnp_nosuid_transition(void)
|
||||||
|
{
|
||||||
|
struct selinux_state *state = &selinux_state;
|
||||||
|
|
||||||
|
return state->policycap[POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION];
|
||||||
|
}
|
||||||
|
|
||||||
|
int security_mls_enabled(struct selinux_state *state);
|
||||||
|
int security_load_policy(struct selinux_state *state,
|
||||||
|
void *data, size_t len);
|
||||||
|
int security_read_policy(struct selinux_state *state,
|
||||||
|
void **data, size_t *len);
|
||||||
|
size_t security_policydb_len(struct selinux_state *state);
|
||||||
|
|
||||||
|
int security_policycap_supported(struct selinux_state *state,
|
||||||
|
unsigned int req_cap);
|
||||||
|
|
||||||
#define SEL_VEC_MAX 32
|
#define SEL_VEC_MAX 32
|
||||||
struct av_decision {
|
struct av_decision {
|
||||||
@ -141,76 +218,100 @@ struct extended_perms {
|
|||||||
/* definitions of av_decision.flags */
|
/* definitions of av_decision.flags */
|
||||||
#define AVD_FLAGS_PERMISSIVE 0x0001
|
#define AVD_FLAGS_PERMISSIVE 0x0001
|
||||||
|
|
||||||
void security_compute_av(u32 ssid, u32 tsid,
|
void security_compute_av(struct selinux_state *state,
|
||||||
|
u32 ssid, u32 tsid,
|
||||||
u16 tclass, struct av_decision *avd,
|
u16 tclass, struct av_decision *avd,
|
||||||
struct extended_perms *xperms);
|
struct extended_perms *xperms);
|
||||||
|
|
||||||
void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 tclass,
|
void security_compute_xperms_decision(struct selinux_state *state,
|
||||||
u8 driver, struct extended_perms_decision *xpermd);
|
u32 ssid, u32 tsid, u16 tclass,
|
||||||
|
u8 driver,
|
||||||
|
struct extended_perms_decision *xpermd);
|
||||||
|
|
||||||
void security_compute_av_user(u32 ssid, u32 tsid,
|
void security_compute_av_user(struct selinux_state *state,
|
||||||
u16 tclass, struct av_decision *avd);
|
u32 ssid, u32 tsid,
|
||||||
|
u16 tclass, struct av_decision *avd);
|
||||||
|
|
||||||
int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
|
int security_transition_sid(struct selinux_state *state,
|
||||||
|
u32 ssid, u32 tsid, u16 tclass,
|
||||||
const struct qstr *qstr, u32 *out_sid);
|
const struct qstr *qstr, u32 *out_sid);
|
||||||
|
|
||||||
int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
|
int security_transition_sid_user(struct selinux_state *state,
|
||||||
|
u32 ssid, u32 tsid, u16 tclass,
|
||||||
const char *objname, u32 *out_sid);
|
const char *objname, u32 *out_sid);
|
||||||
|
|
||||||
int security_member_sid(u32 ssid, u32 tsid,
|
int security_member_sid(struct selinux_state *state, u32 ssid, u32 tsid,
|
||||||
u16 tclass, u32 *out_sid);
|
u16 tclass, u32 *out_sid);
|
||||||
|
|
||||||
int security_change_sid(u32 ssid, u32 tsid,
|
int security_change_sid(struct selinux_state *state, u32 ssid, u32 tsid,
|
||||||
u16 tclass, u32 *out_sid);
|
u16 tclass, u32 *out_sid);
|
||||||
|
|
||||||
int security_sid_to_context(u32 sid, char **scontext,
|
int security_sid_to_context(struct selinux_state *state, u32 sid,
|
||||||
u32 *scontext_len);
|
char **scontext, u32 *scontext_len);
|
||||||
|
|
||||||
int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len);
|
int security_sid_to_context_force(struct selinux_state *state,
|
||||||
|
u32 sid, char **scontext, u32 *scontext_len);
|
||||||
|
|
||||||
int security_context_to_sid(const char *scontext, u32 scontext_len,
|
int security_context_to_sid(struct selinux_state *state,
|
||||||
|
const char *scontext, u32 scontext_len,
|
||||||
u32 *out_sid, gfp_t gfp);
|
u32 *out_sid, gfp_t gfp);
|
||||||
|
|
||||||
int security_context_str_to_sid(const char *scontext, u32 *out_sid, gfp_t gfp);
|
int security_context_str_to_sid(struct selinux_state *state,
|
||||||
|
const char *scontext, u32 *out_sid, gfp_t gfp);
|
||||||
|
|
||||||
int security_context_to_sid_default(const char *scontext, u32 scontext_len,
|
int security_context_to_sid_default(struct selinux_state *state,
|
||||||
|
const char *scontext, u32 scontext_len,
|
||||||
u32 *out_sid, u32 def_sid, gfp_t gfp_flags);
|
u32 *out_sid, u32 def_sid, gfp_t gfp_flags);
|
||||||
|
|
||||||
int security_context_to_sid_force(const char *scontext, u32 scontext_len,
|
int security_context_to_sid_force(struct selinux_state *state,
|
||||||
|
const char *scontext, u32 scontext_len,
|
||||||
u32 *sid);
|
u32 *sid);
|
||||||
|
|
||||||
int security_get_user_sids(u32 callsid, char *username,
|
int security_get_user_sids(struct selinux_state *state,
|
||||||
|
u32 callsid, char *username,
|
||||||
u32 **sids, u32 *nel);
|
u32 **sids, u32 *nel);
|
||||||
|
|
||||||
int security_port_sid(u8 protocol, u16 port, u32 *out_sid);
|
int security_port_sid(struct selinux_state *state,
|
||||||
|
u8 protocol, u16 port, u32 *out_sid);
|
||||||
|
|
||||||
int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid);
|
int security_ib_pkey_sid(struct selinux_state *state,
|
||||||
|
u64 subnet_prefix, u16 pkey_num, u32 *out_sid);
|
||||||
|
|
||||||
int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid);
|
int security_ib_endport_sid(struct selinux_state *state,
|
||||||
|
const char *dev_name, u8 port_num, u32 *out_sid);
|
||||||
|
|
||||||
int security_netif_sid(char *name, u32 *if_sid);
|
int security_netif_sid(struct selinux_state *state,
|
||||||
|
char *name, u32 *if_sid);
|
||||||
|
|
||||||
int security_node_sid(u16 domain, void *addr, u32 addrlen,
|
int security_node_sid(struct selinux_state *state,
|
||||||
u32 *out_sid);
|
u16 domain, void *addr, u32 addrlen,
|
||||||
|
u32 *out_sid);
|
||||||
|
|
||||||
int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
|
int security_validate_transition(struct selinux_state *state,
|
||||||
|
u32 oldsid, u32 newsid, u32 tasksid,
|
||||||
u16 tclass);
|
u16 tclass);
|
||||||
|
|
||||||
int security_validate_transition_user(u32 oldsid, u32 newsid, u32 tasksid,
|
int security_validate_transition_user(struct selinux_state *state,
|
||||||
|
u32 oldsid, u32 newsid, u32 tasksid,
|
||||||
u16 tclass);
|
u16 tclass);
|
||||||
|
|
||||||
int security_bounded_transition(u32 oldsid, u32 newsid);
|
int security_bounded_transition(struct selinux_state *state,
|
||||||
|
u32 oldsid, u32 newsid);
|
||||||
|
|
||||||
int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
|
int security_sid_mls_copy(struct selinux_state *state,
|
||||||
|
u32 sid, u32 mls_sid, u32 *new_sid);
|
||||||
|
|
||||||
int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
|
int security_net_peersid_resolve(struct selinux_state *state,
|
||||||
|
u32 nlbl_sid, u32 nlbl_type,
|
||||||
u32 xfrm_sid,
|
u32 xfrm_sid,
|
||||||
u32 *peer_sid);
|
u32 *peer_sid);
|
||||||
|
|
||||||
int security_get_classes(char ***classes, int *nclasses);
|
int security_get_classes(struct selinux_state *state,
|
||||||
int security_get_permissions(char *class, char ***perms, int *nperms);
|
char ***classes, int *nclasses);
|
||||||
int security_get_reject_unknown(void);
|
int security_get_permissions(struct selinux_state *state,
|
||||||
int security_get_allow_unknown(void);
|
char *class, char ***perms, int *nperms);
|
||||||
|
int security_get_reject_unknown(struct selinux_state *state);
|
||||||
|
int security_get_allow_unknown(struct selinux_state *state);
|
||||||
|
|
||||||
#define SECURITY_FS_USE_XATTR 1 /* use xattr */
|
#define SECURITY_FS_USE_XATTR 1 /* use xattr */
|
||||||
#define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */
|
#define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */
|
||||||
@ -221,27 +322,31 @@ int security_get_allow_unknown(void);
|
|||||||
#define SECURITY_FS_USE_NATIVE 7 /* use native label support */
|
#define SECURITY_FS_USE_NATIVE 7 /* use native label support */
|
||||||
#define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */
|
#define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */
|
||||||
|
|
||||||
int security_fs_use(struct super_block *sb);
|
int security_fs_use(struct selinux_state *state, struct super_block *sb);
|
||||||
|
|
||||||
int security_genfs_sid(const char *fstype, char *name, u16 sclass,
|
int security_genfs_sid(struct selinux_state *state,
|
||||||
u32 *sid);
|
const char *fstype, char *name, u16 sclass,
|
||||||
|
u32 *sid);
|
||||||
|
|
||||||
#ifdef CONFIG_NETLABEL
|
#ifdef CONFIG_NETLABEL
|
||||||
int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
|
int security_netlbl_secattr_to_sid(struct selinux_state *state,
|
||||||
|
struct netlbl_lsm_secattr *secattr,
|
||||||
u32 *sid);
|
u32 *sid);
|
||||||
|
|
||||||
int security_netlbl_sid_to_secattr(u32 sid,
|
int security_netlbl_sid_to_secattr(struct selinux_state *state,
|
||||||
|
u32 sid,
|
||||||
struct netlbl_lsm_secattr *secattr);
|
struct netlbl_lsm_secattr *secattr);
|
||||||
#else
|
#else
|
||||||
static inline int security_netlbl_secattr_to_sid(
|
static inline int security_netlbl_secattr_to_sid(struct selinux_state *state,
|
||||||
struct netlbl_lsm_secattr *secattr,
|
struct netlbl_lsm_secattr *secattr,
|
||||||
u32 *sid)
|
u32 *sid)
|
||||||
{
|
{
|
||||||
return -EIDRM;
|
return -EIDRM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int security_netlbl_sid_to_secattr(u32 sid,
|
static inline int security_netlbl_sid_to_secattr(struct selinux_state *state,
|
||||||
struct netlbl_lsm_secattr *secattr)
|
u32 sid,
|
||||||
|
struct netlbl_lsm_secattr *secattr)
|
||||||
{
|
{
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -252,7 +357,7 @@ const char *security_get_initial_sid_context(u32 sid);
|
|||||||
/*
|
/*
|
||||||
* status notifier using mmap interface
|
* status notifier using mmap interface
|
||||||
*/
|
*/
|
||||||
extern struct page *selinux_kernel_status_page(void);
|
extern struct page *selinux_kernel_status_page(struct selinux_state *state);
|
||||||
|
|
||||||
#define SELINUX_KERNEL_STATUS_VERSION 1
|
#define SELINUX_KERNEL_STATUS_VERSION 1
|
||||||
struct selinux_kernel_status {
|
struct selinux_kernel_status {
|
||||||
@ -266,10 +371,12 @@ struct selinux_kernel_status {
|
|||||||
*/
|
*/
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
extern void selinux_status_update_setenforce(int enforcing);
|
extern void selinux_status_update_setenforce(struct selinux_state *state,
|
||||||
extern void selinux_status_update_policyload(int seqno);
|
int enforcing);
|
||||||
|
extern void selinux_status_update_policyload(struct selinux_state *state,
|
||||||
|
int seqno);
|
||||||
extern void selinux_complete_init(void);
|
extern void selinux_complete_init(void);
|
||||||
extern int selinux_disable(void);
|
extern int selinux_disable(struct selinux_state *state);
|
||||||
extern void exit_sel_fs(void);
|
extern void exit_sel_fs(void);
|
||||||
extern struct path selinux_null;
|
extern struct path selinux_null;
|
||||||
extern struct vfsmount *selinuxfs_mount;
|
extern struct vfsmount *selinuxfs_mount;
|
||||||
@ -277,5 +384,8 @@ extern void selnl_notify_setenforce(int val);
|
|||||||
extern void selnl_notify_policyload(u32 seqno);
|
extern void selnl_notify_policyload(u32 seqno);
|
||||||
extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
|
extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
|
||||||
|
|
||||||
#endif /* _SELINUX_SECURITY_H_ */
|
extern void avtab_cache_init(void);
|
||||||
|
extern void ebitmap_cache_init(void);
|
||||||
|
extern void hashtab_cache_init(void);
|
||||||
|
|
||||||
|
#endif /* _SELINUX_SECURITY_H_ */
|
||||||
|
@ -163,7 +163,7 @@ static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid)
|
|||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
ret = security_netif_sid(dev->name, &new->nsec.sid);
|
ret = security_netif_sid(&selinux_state, dev->name, &new->nsec.sid);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto out;
|
goto out;
|
||||||
new->nsec.ns = ns;
|
new->nsec.ns = ns;
|
||||||
|
@ -59,7 +59,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = security_netlbl_secattr_to_sid(secattr, sid);
|
rc = security_netlbl_secattr_to_sid(&selinux_state, secattr, sid);
|
||||||
if (rc == 0 &&
|
if (rc == 0 &&
|
||||||
(secattr->flags & NETLBL_SECATTR_CACHEABLE) &&
|
(secattr->flags & NETLBL_SECATTR_CACHEABLE) &&
|
||||||
(secattr->flags & NETLBL_SECATTR_CACHE))
|
(secattr->flags & NETLBL_SECATTR_CACHE))
|
||||||
@ -90,7 +90,8 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk)
|
|||||||
secattr = netlbl_secattr_alloc(GFP_ATOMIC);
|
secattr = netlbl_secattr_alloc(GFP_ATOMIC);
|
||||||
if (secattr == NULL)
|
if (secattr == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
rc = security_netlbl_sid_to_secattr(sksec->sid, secattr);
|
rc = security_netlbl_sid_to_secattr(&selinux_state, sksec->sid,
|
||||||
|
secattr);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
netlbl_secattr_free(secattr);
|
netlbl_secattr_free(secattr);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -257,7 +258,8 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
|
|||||||
if (secattr == NULL) {
|
if (secattr == NULL) {
|
||||||
secattr = &secattr_storage;
|
secattr = &secattr_storage;
|
||||||
netlbl_secattr_init(secattr);
|
netlbl_secattr_init(secattr);
|
||||||
rc = security_netlbl_sid_to_secattr(sid, secattr);
|
rc = security_netlbl_sid_to_secattr(&selinux_state, sid,
|
||||||
|
secattr);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
goto skbuff_setsid_return;
|
goto skbuff_setsid_return;
|
||||||
}
|
}
|
||||||
@ -297,7 +299,8 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
netlbl_secattr_init(&secattr);
|
netlbl_secattr_init(&secattr);
|
||||||
rc = security_netlbl_sid_to_secattr(ep->secid, &secattr);
|
rc = security_netlbl_sid_to_secattr(&selinux_state,
|
||||||
|
ep->secid, &secattr);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
goto assoc_request_return;
|
goto assoc_request_return;
|
||||||
|
|
||||||
@ -345,7 +348,8 @@ int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
netlbl_secattr_init(&secattr);
|
netlbl_secattr_init(&secattr);
|
||||||
rc = security_netlbl_sid_to_secattr(req->secid, &secattr);
|
rc = security_netlbl_sid_to_secattr(&selinux_state, req->secid,
|
||||||
|
&secattr);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
goto inet_conn_request_return;
|
goto inet_conn_request_return;
|
||||||
rc = netlbl_req_setattr(req, &secattr);
|
rc = netlbl_req_setattr(req, &secattr);
|
||||||
|
@ -215,12 +215,12 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
|
|||||||
goto out;
|
goto out;
|
||||||
switch (family) {
|
switch (family) {
|
||||||
case PF_INET:
|
case PF_INET:
|
||||||
ret = security_node_sid(PF_INET,
|
ret = security_node_sid(&selinux_state, PF_INET,
|
||||||
addr, sizeof(struct in_addr), sid);
|
addr, sizeof(struct in_addr), sid);
|
||||||
new->nsec.addr.ipv4 = *(__be32 *)addr;
|
new->nsec.addr.ipv4 = *(__be32 *)addr;
|
||||||
break;
|
break;
|
||||||
case PF_INET6:
|
case PF_INET6:
|
||||||
ret = security_node_sid(PF_INET6,
|
ret = security_node_sid(&selinux_state, PF_INET6,
|
||||||
addr, sizeof(struct in6_addr), sid);
|
addr, sizeof(struct in6_addr), sid);
|
||||||
new->nsec.addr.ipv6 = *(struct in6_addr *)addr;
|
new->nsec.addr.ipv6 = *(struct in6_addr *)addr;
|
||||||
break;
|
break;
|
||||||
|
@ -161,7 +161,7 @@ static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid)
|
|||||||
new = kzalloc(sizeof(*new), GFP_ATOMIC);
|
new = kzalloc(sizeof(*new), GFP_ATOMIC);
|
||||||
if (new == NULL)
|
if (new == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
ret = security_port_sid(protocol, pnum, sid);
|
ret = security_port_sid(&selinux_state, protocol, pnum, sid);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -41,17 +41,6 @@
|
|||||||
#include "objsec.h"
|
#include "objsec.h"
|
||||||
#include "conditional.h"
|
#include "conditional.h"
|
||||||
|
|
||||||
unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
|
|
||||||
|
|
||||||
static int __init checkreqprot_setup(char *str)
|
|
||||||
{
|
|
||||||
unsigned long checkreqprot;
|
|
||||||
if (!kstrtoul(str, 0, &checkreqprot))
|
|
||||||
selinux_checkreqprot = checkreqprot ? 1 : 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
__setup("checkreqprot=", checkreqprot_setup);
|
|
||||||
|
|
||||||
static DEFINE_MUTEX(sel_mutex);
|
static DEFINE_MUTEX(sel_mutex);
|
||||||
|
|
||||||
/* global data for booleans */
|
/* global data for booleans */
|
||||||
@ -108,7 +97,8 @@ static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
|
|||||||
char tmpbuf[TMPBUFLEN];
|
char tmpbuf[TMPBUFLEN];
|
||||||
ssize_t length;
|
ssize_t length;
|
||||||
|
|
||||||
length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_enforcing);
|
length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
|
||||||
|
is_enforcing(&selinux_state));
|
||||||
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
|
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +109,7 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
|
|||||||
{
|
{
|
||||||
char *page = NULL;
|
char *page = NULL;
|
||||||
ssize_t length;
|
ssize_t length;
|
||||||
int new_value;
|
int old_value, new_value;
|
||||||
|
|
||||||
if (count >= PAGE_SIZE)
|
if (count >= PAGE_SIZE)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -138,7 +128,9 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
|
|||||||
|
|
||||||
new_value = !!new_value;
|
new_value = !!new_value;
|
||||||
|
|
||||||
if (new_value != selinux_enforcing) {
|
old_value = is_enforcing(&selinux_state);
|
||||||
|
|
||||||
|
if (new_value != old_value) {
|
||||||
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
|
length = avc_has_perm(current_sid(), SECINITSID_SECURITY,
|
||||||
SECCLASS_SECURITY, SECURITY__SETENFORCE,
|
SECCLASS_SECURITY, SECURITY__SETENFORCE,
|
||||||
NULL);
|
NULL);
|
||||||
@ -146,15 +138,16 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
|
|||||||
goto out;
|
goto out;
|
||||||
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
|
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
|
||||||
"enforcing=%d old_enforcing=%d auid=%u ses=%u",
|
"enforcing=%d old_enforcing=%d auid=%u ses=%u",
|
||||||
new_value, selinux_enforcing,
|
new_value, old_value,
|
||||||
from_kuid(&init_user_ns, audit_get_loginuid(current)),
|
from_kuid(&init_user_ns, audit_get_loginuid(current)),
|
||||||
audit_get_sessionid(current));
|
audit_get_sessionid(current));
|
||||||
selinux_enforcing = new_value;
|
set_enforcing(&selinux_state, new_value);
|
||||||
if (selinux_enforcing)
|
if (new_value)
|
||||||
avc_ss_reset(0);
|
avc_ss_reset(0);
|
||||||
selnl_notify_setenforce(selinux_enforcing);
|
selnl_notify_setenforce(new_value);
|
||||||
selinux_status_update_setenforce(selinux_enforcing);
|
selinux_status_update_setenforce(&selinux_state,
|
||||||
if (!selinux_enforcing)
|
new_value);
|
||||||
|
if (!new_value)
|
||||||
call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
|
call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
|
||||||
}
|
}
|
||||||
length = count;
|
length = count;
|
||||||
@ -179,7 +172,8 @@ static ssize_t sel_read_handle_unknown(struct file *filp, char __user *buf,
|
|||||||
ssize_t length;
|
ssize_t length;
|
||||||
ino_t ino = file_inode(filp)->i_ino;
|
ino_t ino = file_inode(filp)->i_ino;
|
||||||
int handle_unknown = (ino == SEL_REJECT_UNKNOWN) ?
|
int handle_unknown = (ino == SEL_REJECT_UNKNOWN) ?
|
||||||
security_get_reject_unknown() : !security_get_allow_unknown();
|
security_get_reject_unknown(&selinux_state) :
|
||||||
|
!security_get_allow_unknown(&selinux_state);
|
||||||
|
|
||||||
length = scnprintf(tmpbuf, TMPBUFLEN, "%d", handle_unknown);
|
length = scnprintf(tmpbuf, TMPBUFLEN, "%d", handle_unknown);
|
||||||
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
|
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
|
||||||
@ -192,7 +186,7 @@ static const struct file_operations sel_handle_unknown_ops = {
|
|||||||
|
|
||||||
static int sel_open_handle_status(struct inode *inode, struct file *filp)
|
static int sel_open_handle_status(struct inode *inode, struct file *filp)
|
||||||
{
|
{
|
||||||
struct page *status = selinux_kernel_status_page();
|
struct page *status = selinux_kernel_status_page(&selinux_state);
|
||||||
|
|
||||||
if (!status)
|
if (!status)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -268,7 +262,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (new_value) {
|
if (new_value) {
|
||||||
length = selinux_disable();
|
length = selinux_disable(&selinux_state);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
|
audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
|
||||||
@ -322,7 +316,7 @@ static ssize_t sel_read_mls(struct file *filp, char __user *buf,
|
|||||||
ssize_t length;
|
ssize_t length;
|
||||||
|
|
||||||
length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
|
length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
|
||||||
security_mls_enabled());
|
security_mls_enabled(&selinux_state));
|
||||||
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
|
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,13 +353,13 @@ static int sel_open_policy(struct inode *inode, struct file *filp)
|
|||||||
if (!plm)
|
if (!plm)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (i_size_read(inode) != security_policydb_len()) {
|
if (i_size_read(inode) != security_policydb_len(&selinux_state)) {
|
||||||
inode_lock(inode);
|
inode_lock(inode);
|
||||||
i_size_write(inode, security_policydb_len());
|
i_size_write(inode, security_policydb_len(&selinux_state));
|
||||||
inode_unlock(inode);
|
inode_unlock(inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = security_read_policy(&plm->data, &plm->len);
|
rc = security_read_policy(&selinux_state, &plm->data, &plm->len);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@ -500,7 +494,7 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
|
|||||||
if (copy_from_user(data, buf, count) != 0)
|
if (copy_from_user(data, buf, count) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_load_policy(data, count);
|
length = security_load_policy(&selinux_state, data, count);
|
||||||
if (length) {
|
if (length) {
|
||||||
pr_warn_ratelimited("SELinux: failed to load policy\n");
|
pr_warn_ratelimited("SELinux: failed to load policy\n");
|
||||||
goto out;
|
goto out;
|
||||||
@ -553,11 +547,12 @@ static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
|
|||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_context_to_sid(buf, size, &sid, GFP_KERNEL);
|
length = security_context_to_sid(&selinux_state, buf, size,
|
||||||
|
&sid, GFP_KERNEL);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_sid_to_context(sid, &canon, &len);
|
length = security_sid_to_context(&selinux_state, sid, &canon, &len);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -581,7 +576,7 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
|
|||||||
char tmpbuf[TMPBUFLEN];
|
char tmpbuf[TMPBUFLEN];
|
||||||
ssize_t length;
|
ssize_t length;
|
||||||
|
|
||||||
length = scnprintf(tmpbuf, TMPBUFLEN, "%u", selinux_checkreqprot);
|
length = scnprintf(tmpbuf, TMPBUFLEN, "%u", selinux_state.checkreqprot);
|
||||||
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
|
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,7 +608,7 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
|
|||||||
if (sscanf(page, "%u", &new_value) != 1)
|
if (sscanf(page, "%u", &new_value) != 1)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
selinux_checkreqprot = new_value ? 1 : 0;
|
selinux_state.checkreqprot = new_value ? 1 : 0;
|
||||||
length = count;
|
length = count;
|
||||||
out:
|
out:
|
||||||
kfree(page);
|
kfree(page);
|
||||||
@ -673,19 +668,23 @@ static ssize_t sel_write_validatetrans(struct file *file,
|
|||||||
if (sscanf(req, "%s %s %hu %s", oldcon, newcon, &tclass, taskcon) != 4)
|
if (sscanf(req, "%s %s %hu %s", oldcon, newcon, &tclass, taskcon) != 4)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rc = security_context_str_to_sid(oldcon, &osid, GFP_KERNEL);
|
rc = security_context_str_to_sid(&selinux_state, oldcon, &osid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rc = security_context_str_to_sid(newcon, &nsid, GFP_KERNEL);
|
rc = security_context_str_to_sid(&selinux_state, newcon, &nsid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rc = security_context_str_to_sid(taskcon, &tsid, GFP_KERNEL);
|
rc = security_context_str_to_sid(&selinux_state, taskcon, &tsid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rc = security_validate_transition_user(osid, nsid, tsid, tclass);
|
rc = security_validate_transition_user(&selinux_state, osid, nsid,
|
||||||
|
tsid, tclass);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
rc = count;
|
rc = count;
|
||||||
out:
|
out:
|
||||||
@ -780,15 +779,17 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
|
|||||||
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
|
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
|
length = security_context_str_to_sid(&selinux_state, scon, &ssid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
|
length = security_context_str_to_sid(&selinux_state, tcon, &tsid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
security_compute_av_user(ssid, tsid, tclass, &avd);
|
security_compute_av_user(&selinux_state, ssid, tsid, tclass, &avd);
|
||||||
|
|
||||||
length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
|
length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
|
||||||
"%x %x %x %x %u %x",
|
"%x %x %x %x %u %x",
|
||||||
@ -868,20 +869,23 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
|
|||||||
objname = namebuf;
|
objname = namebuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
|
length = security_context_str_to_sid(&selinux_state, scon, &ssid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
|
length = security_context_str_to_sid(&selinux_state, tcon, &tsid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_transition_sid_user(ssid, tsid, tclass,
|
length = security_transition_sid_user(&selinux_state, ssid, tsid,
|
||||||
objname, &newsid);
|
tclass, objname, &newsid);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_sid_to_context(newsid, &newcon, &len);
|
length = security_sid_to_context(&selinux_state, newsid, &newcon,
|
||||||
|
&len);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -931,19 +935,23 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
|
|||||||
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
|
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
|
length = security_context_str_to_sid(&selinux_state, scon, &ssid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
|
length = security_context_str_to_sid(&selinux_state, tcon, &tsid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_change_sid(ssid, tsid, tclass, &newsid);
|
length = security_change_sid(&selinux_state, ssid, tsid, tclass,
|
||||||
|
&newsid);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_sid_to_context(newsid, &newcon, &len);
|
length = security_sid_to_context(&selinux_state, newsid, &newcon,
|
||||||
|
&len);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -989,18 +997,21 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
|
|||||||
if (sscanf(buf, "%s %s", con, user) != 2)
|
if (sscanf(buf, "%s %s", con, user) != 2)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_context_str_to_sid(con, &sid, GFP_KERNEL);
|
length = security_context_str_to_sid(&selinux_state, con, &sid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_get_user_sids(sid, user, &sids, &nsids);
|
length = security_get_user_sids(&selinux_state, sid, user, &sids,
|
||||||
|
&nsids);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = sprintf(buf, "%u", nsids) + 1;
|
length = sprintf(buf, "%u", nsids) + 1;
|
||||||
ptr = buf + length;
|
ptr = buf + length;
|
||||||
for (i = 0; i < nsids; i++) {
|
for (i = 0; i < nsids; i++) {
|
||||||
rc = security_sid_to_context(sids[i], &newcon, &len);
|
rc = security_sid_to_context(&selinux_state, sids[i],
|
||||||
|
&newcon, &len);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
length = rc;
|
length = rc;
|
||||||
goto out;
|
goto out;
|
||||||
@ -1051,19 +1062,23 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
|
|||||||
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
|
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
|
length = security_context_str_to_sid(&selinux_state, scon, &ssid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
|
length = security_context_str_to_sid(&selinux_state, tcon, &tsid,
|
||||||
|
GFP_KERNEL);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_member_sid(ssid, tsid, tclass, &newsid);
|
length = security_member_sid(&selinux_state, ssid, tsid, tclass,
|
||||||
|
&newsid);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = security_sid_to_context(newsid, &newcon, &len);
|
length = security_sid_to_context(&selinux_state, newsid, &newcon,
|
||||||
|
&len);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -1115,7 +1130,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
|
|||||||
if (!page)
|
if (!page)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
cur_enforcing = security_get_bool_value(index);
|
cur_enforcing = security_get_bool_value(&selinux_state, index);
|
||||||
if (cur_enforcing < 0) {
|
if (cur_enforcing < 0) {
|
||||||
ret = cur_enforcing;
|
ret = cur_enforcing;
|
||||||
goto out;
|
goto out;
|
||||||
@ -1226,7 +1241,8 @@ static ssize_t sel_commit_bools_write(struct file *filep,
|
|||||||
|
|
||||||
length = 0;
|
length = 0;
|
||||||
if (new_value && bool_pending_values)
|
if (new_value && bool_pending_values)
|
||||||
length = security_set_bools(bool_num, bool_pending_values);
|
length = security_set_bools(&selinux_state, bool_num,
|
||||||
|
bool_pending_values);
|
||||||
|
|
||||||
if (!length)
|
if (!length)
|
||||||
length = count;
|
length = count;
|
||||||
@ -1279,7 +1295,7 @@ static int sel_make_bools(void)
|
|||||||
if (!page)
|
if (!page)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = security_get_bools(&num, &names, &values);
|
ret = security_get_bools(&selinux_state, &num, &names, &values);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -1300,7 +1316,8 @@ static int sel_make_bools(void)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
isec = (struct inode_security_struct *)inode->i_security;
|
isec = (struct inode_security_struct *)inode->i_security;
|
||||||
ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid);
|
ret = security_genfs_sid(&selinux_state, "selinuxfs", page,
|
||||||
|
SECCLASS_FILE, &sid);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_warn_ratelimited("SELinux: no sid found, defaulting to security isid for %s\n",
|
pr_warn_ratelimited("SELinux: no sid found, defaulting to security isid for %s\n",
|
||||||
page);
|
page);
|
||||||
@ -1524,7 +1541,7 @@ static ssize_t sel_read_initcon(struct file *file, char __user *buf,
|
|||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
sid = file_inode(file)->i_ino&SEL_INO_MASK;
|
sid = file_inode(file)->i_ino&SEL_INO_MASK;
|
||||||
ret = security_sid_to_context(sid, &con, &len);
|
ret = security_sid_to_context(&selinux_state, sid, &con, &len);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -1617,7 +1634,8 @@ static ssize_t sel_read_policycap(struct file *file, char __user *buf,
|
|||||||
ssize_t length;
|
ssize_t length;
|
||||||
unsigned long i_ino = file_inode(file)->i_ino;
|
unsigned long i_ino = file_inode(file)->i_ino;
|
||||||
|
|
||||||
value = security_policycap_supported(i_ino & SEL_INO_MASK);
|
value = security_policycap_supported(&selinux_state,
|
||||||
|
i_ino & SEL_INO_MASK);
|
||||||
length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value);
|
length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value);
|
||||||
|
|
||||||
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
|
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
|
||||||
@ -1634,7 +1652,8 @@ static int sel_make_perm_files(char *objclass, int classvalue,
|
|||||||
int i, rc, nperms;
|
int i, rc, nperms;
|
||||||
char **perms;
|
char **perms;
|
||||||
|
|
||||||
rc = security_get_permissions(objclass, &perms, &nperms);
|
rc = security_get_permissions(&selinux_state, objclass, &perms,
|
||||||
|
&nperms);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@ -1701,7 +1720,7 @@ static int sel_make_classes(void)
|
|||||||
/* delete any existing entries */
|
/* delete any existing entries */
|
||||||
sel_remove_entries(class_dir);
|
sel_remove_entries(class_dir);
|
||||||
|
|
||||||
rc = security_get_classes(&classes, &nclasses);
|
rc = security_get_classes(&selinux_state, &classes, &nclasses);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
@ -655,7 +655,8 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp)
|
|||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
void avtab_cache_init(void)
|
|
||||||
|
void __init avtab_cache_init(void)
|
||||||
{
|
{
|
||||||
avtab_node_cachep = kmem_cache_create("avtab_node",
|
avtab_node_cachep = kmem_cache_create("avtab_node",
|
||||||
sizeof(struct avtab_node),
|
sizeof(struct avtab_node),
|
||||||
@ -664,9 +665,3 @@ void avtab_cache_init(void)
|
|||||||
sizeof(struct avtab_extended_perms),
|
sizeof(struct avtab_extended_perms),
|
||||||
0, SLAB_PANIC, NULL);
|
0, SLAB_PANIC, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avtab_cache_destroy(void)
|
|
||||||
{
|
|
||||||
kmem_cache_destroy(avtab_node_cachep);
|
|
||||||
kmem_cache_destroy(avtab_xperms_cachep);
|
|
||||||
}
|
|
||||||
|
@ -114,9 +114,6 @@ struct avtab_node *avtab_search_node(struct avtab *h, struct avtab_key *key);
|
|||||||
|
|
||||||
struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified);
|
struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified);
|
||||||
|
|
||||||
void avtab_cache_init(void);
|
|
||||||
void avtab_cache_destroy(void);
|
|
||||||
|
|
||||||
#define MAX_AVTAB_HASH_BITS 16
|
#define MAX_AVTAB_HASH_BITS 16
|
||||||
#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
|
#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
|
||||||
|
|
||||||
|
@ -523,14 +523,9 @@ int ebitmap_write(struct ebitmap *e, void *fp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ebitmap_cache_init(void)
|
void __init ebitmap_cache_init(void)
|
||||||
{
|
{
|
||||||
ebitmap_node_cachep = kmem_cache_create("ebitmap_node",
|
ebitmap_node_cachep = kmem_cache_create("ebitmap_node",
|
||||||
sizeof(struct ebitmap_node),
|
sizeof(struct ebitmap_node),
|
||||||
0, SLAB_PANIC, NULL);
|
0, SLAB_PANIC, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ebitmap_cache_destroy(void)
|
|
||||||
{
|
|
||||||
kmem_cache_destroy(ebitmap_node_cachep);
|
|
||||||
}
|
|
||||||
|
@ -131,9 +131,6 @@ void ebitmap_destroy(struct ebitmap *e);
|
|||||||
int ebitmap_read(struct ebitmap *e, void *fp);
|
int ebitmap_read(struct ebitmap *e, void *fp);
|
||||||
int ebitmap_write(struct ebitmap *e, void *fp);
|
int ebitmap_write(struct ebitmap *e, void *fp);
|
||||||
|
|
||||||
void ebitmap_cache_init(void);
|
|
||||||
void ebitmap_cache_destroy(void);
|
|
||||||
|
|
||||||
#ifdef CONFIG_NETLABEL
|
#ifdef CONFIG_NETLABEL
|
||||||
int ebitmap_netlbl_export(struct ebitmap *ebmap,
|
int ebitmap_netlbl_export(struct ebitmap *ebmap,
|
||||||
struct netlbl_lsm_catmap **catmap);
|
struct netlbl_lsm_catmap **catmap);
|
||||||
|
@ -169,14 +169,10 @@ void hashtab_stat(struct hashtab *h, struct hashtab_info *info)
|
|||||||
info->slots_used = slots_used;
|
info->slots_used = slots_used;
|
||||||
info->max_chain_len = max_chain_len;
|
info->max_chain_len = max_chain_len;
|
||||||
}
|
}
|
||||||
void hashtab_cache_init(void)
|
|
||||||
|
void __init hashtab_cache_init(void)
|
||||||
{
|
{
|
||||||
hashtab_node_cachep = kmem_cache_create("hashtab_node",
|
hashtab_node_cachep = kmem_cache_create("hashtab_node",
|
||||||
sizeof(struct hashtab_node),
|
sizeof(struct hashtab_node),
|
||||||
0, SLAB_PANIC, NULL);
|
0, SLAB_PANIC, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hashtab_cache_destroy(void)
|
|
||||||
{
|
|
||||||
kmem_cache_destroy(hashtab_node_cachep);
|
|
||||||
}
|
|
||||||
|
@ -85,8 +85,4 @@ int hashtab_map(struct hashtab *h,
|
|||||||
/* Fill info with some hash table statistics */
|
/* Fill info with some hash table statistics */
|
||||||
void hashtab_stat(struct hashtab *h, struct hashtab_info *info);
|
void hashtab_stat(struct hashtab *h, struct hashtab_info *info);
|
||||||
|
|
||||||
/* Use kmem_cache for hashtab_node */
|
|
||||||
void hashtab_cache_init(void);
|
|
||||||
void hashtab_cache_destroy(void);
|
|
||||||
|
|
||||||
#endif /* _SS_HASHTAB_H */
|
#endif /* _SS_HASHTAB_H */
|
||||||
|
@ -33,20 +33,20 @@
|
|||||||
* Return the length in bytes for the MLS fields of the
|
* Return the length in bytes for the MLS fields of the
|
||||||
* security context string representation of `context'.
|
* security context string representation of `context'.
|
||||||
*/
|
*/
|
||||||
int mls_compute_context_len(struct context *context)
|
int mls_compute_context_len(struct policydb *p, struct context *context)
|
||||||
{
|
{
|
||||||
int i, l, len, head, prev;
|
int i, l, len, head, prev;
|
||||||
char *nm;
|
char *nm;
|
||||||
struct ebitmap *e;
|
struct ebitmap *e;
|
||||||
struct ebitmap_node *node;
|
struct ebitmap_node *node;
|
||||||
|
|
||||||
if (!policydb.mls_enabled)
|
if (!p->mls_enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
len = 1; /* for the beginning ":" */
|
len = 1; /* for the beginning ":" */
|
||||||
for (l = 0; l < 2; l++) {
|
for (l = 0; l < 2; l++) {
|
||||||
int index_sens = context->range.level[l].sens;
|
int index_sens = context->range.level[l].sens;
|
||||||
len += strlen(sym_name(&policydb, SYM_LEVELS, index_sens - 1));
|
len += strlen(sym_name(p, SYM_LEVELS, index_sens - 1));
|
||||||
|
|
||||||
/* categories */
|
/* categories */
|
||||||
head = -2;
|
head = -2;
|
||||||
@ -56,17 +56,17 @@ int mls_compute_context_len(struct context *context)
|
|||||||
if (i - prev > 1) {
|
if (i - prev > 1) {
|
||||||
/* one or more negative bits are skipped */
|
/* one or more negative bits are skipped */
|
||||||
if (head != prev) {
|
if (head != prev) {
|
||||||
nm = sym_name(&policydb, SYM_CATS, prev);
|
nm = sym_name(p, SYM_CATS, prev);
|
||||||
len += strlen(nm) + 1;
|
len += strlen(nm) + 1;
|
||||||
}
|
}
|
||||||
nm = sym_name(&policydb, SYM_CATS, i);
|
nm = sym_name(p, SYM_CATS, i);
|
||||||
len += strlen(nm) + 1;
|
len += strlen(nm) + 1;
|
||||||
head = i;
|
head = i;
|
||||||
}
|
}
|
||||||
prev = i;
|
prev = i;
|
||||||
}
|
}
|
||||||
if (prev != head) {
|
if (prev != head) {
|
||||||
nm = sym_name(&policydb, SYM_CATS, prev);
|
nm = sym_name(p, SYM_CATS, prev);
|
||||||
len += strlen(nm) + 1;
|
len += strlen(nm) + 1;
|
||||||
}
|
}
|
||||||
if (l == 0) {
|
if (l == 0) {
|
||||||
@ -86,7 +86,8 @@ int mls_compute_context_len(struct context *context)
|
|||||||
* the MLS fields of `context' into the string `*scontext'.
|
* the MLS fields of `context' into the string `*scontext'.
|
||||||
* Update `*scontext' to point to the end of the MLS fields.
|
* Update `*scontext' to point to the end of the MLS fields.
|
||||||
*/
|
*/
|
||||||
void mls_sid_to_context(struct context *context,
|
void mls_sid_to_context(struct policydb *p,
|
||||||
|
struct context *context,
|
||||||
char **scontext)
|
char **scontext)
|
||||||
{
|
{
|
||||||
char *scontextp, *nm;
|
char *scontextp, *nm;
|
||||||
@ -94,7 +95,7 @@ void mls_sid_to_context(struct context *context,
|
|||||||
struct ebitmap *e;
|
struct ebitmap *e;
|
||||||
struct ebitmap_node *node;
|
struct ebitmap_node *node;
|
||||||
|
|
||||||
if (!policydb.mls_enabled)
|
if (!p->mls_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scontextp = *scontext;
|
scontextp = *scontext;
|
||||||
@ -103,7 +104,7 @@ void mls_sid_to_context(struct context *context,
|
|||||||
scontextp++;
|
scontextp++;
|
||||||
|
|
||||||
for (l = 0; l < 2; l++) {
|
for (l = 0; l < 2; l++) {
|
||||||
strcpy(scontextp, sym_name(&policydb, SYM_LEVELS,
|
strcpy(scontextp, sym_name(p, SYM_LEVELS,
|
||||||
context->range.level[l].sens - 1));
|
context->range.level[l].sens - 1));
|
||||||
scontextp += strlen(scontextp);
|
scontextp += strlen(scontextp);
|
||||||
|
|
||||||
@ -119,7 +120,7 @@ void mls_sid_to_context(struct context *context,
|
|||||||
*scontextp++ = '.';
|
*scontextp++ = '.';
|
||||||
else
|
else
|
||||||
*scontextp++ = ',';
|
*scontextp++ = ',';
|
||||||
nm = sym_name(&policydb, SYM_CATS, prev);
|
nm = sym_name(p, SYM_CATS, prev);
|
||||||
strcpy(scontextp, nm);
|
strcpy(scontextp, nm);
|
||||||
scontextp += strlen(nm);
|
scontextp += strlen(nm);
|
||||||
}
|
}
|
||||||
@ -127,7 +128,7 @@ void mls_sid_to_context(struct context *context,
|
|||||||
*scontextp++ = ':';
|
*scontextp++ = ':';
|
||||||
else
|
else
|
||||||
*scontextp++ = ',';
|
*scontextp++ = ',';
|
||||||
nm = sym_name(&policydb, SYM_CATS, i);
|
nm = sym_name(p, SYM_CATS, i);
|
||||||
strcpy(scontextp, nm);
|
strcpy(scontextp, nm);
|
||||||
scontextp += strlen(nm);
|
scontextp += strlen(nm);
|
||||||
head = i;
|
head = i;
|
||||||
@ -140,7 +141,7 @@ void mls_sid_to_context(struct context *context,
|
|||||||
*scontextp++ = '.';
|
*scontextp++ = '.';
|
||||||
else
|
else
|
||||||
*scontextp++ = ',';
|
*scontextp++ = ',';
|
||||||
nm = sym_name(&policydb, SYM_CATS, prev);
|
nm = sym_name(p, SYM_CATS, prev);
|
||||||
strcpy(scontextp, nm);
|
strcpy(scontextp, nm);
|
||||||
scontextp += strlen(nm);
|
scontextp += strlen(nm);
|
||||||
}
|
}
|
||||||
@ -375,12 +376,13 @@ out:
|
|||||||
* the string `str'. This function will allocate temporary memory with the
|
* the string `str'. This function will allocate temporary memory with the
|
||||||
* given constraints of gfp_mask.
|
* given constraints of gfp_mask.
|
||||||
*/
|
*/
|
||||||
int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
|
int mls_from_string(struct policydb *p, char *str, struct context *context,
|
||||||
|
gfp_t gfp_mask)
|
||||||
{
|
{
|
||||||
char *tmpstr, *freestr;
|
char *tmpstr, *freestr;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!policydb.mls_enabled)
|
if (!p->mls_enabled)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* we need freestr because mls_context_to_sid will change
|
/* we need freestr because mls_context_to_sid will change
|
||||||
@ -389,7 +391,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
|
|||||||
if (!tmpstr) {
|
if (!tmpstr) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
} else {
|
} else {
|
||||||
rc = mls_context_to_sid(&policydb, ':', &tmpstr, context,
|
rc = mls_context_to_sid(p, ':', &tmpstr, context,
|
||||||
NULL, SECSID_NULL);
|
NULL, SECSID_NULL);
|
||||||
kfree(freestr);
|
kfree(freestr);
|
||||||
}
|
}
|
||||||
@ -417,10 +419,11 @@ int mls_range_set(struct context *context,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
|
int mls_setup_user_range(struct policydb *p,
|
||||||
|
struct context *fromcon, struct user_datum *user,
|
||||||
struct context *usercon)
|
struct context *usercon)
|
||||||
{
|
{
|
||||||
if (policydb.mls_enabled) {
|
if (p->mls_enabled) {
|
||||||
struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
|
struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
|
||||||
struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
|
struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
|
||||||
struct mls_level *user_low = &(user->range.level[0]);
|
struct mls_level *user_low = &(user->range.level[0]);
|
||||||
@ -470,7 +473,7 @@ int mls_convert_context(struct policydb *oldp,
|
|||||||
struct ebitmap_node *node;
|
struct ebitmap_node *node;
|
||||||
int l, i;
|
int l, i;
|
||||||
|
|
||||||
if (!policydb.mls_enabled)
|
if (!oldp->mls_enabled || !newp->mls_enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (l = 0; l < 2; l++) {
|
for (l = 0; l < 2; l++) {
|
||||||
@ -503,7 +506,8 @@ int mls_convert_context(struct policydb *oldp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mls_compute_sid(struct context *scontext,
|
int mls_compute_sid(struct policydb *p,
|
||||||
|
struct context *scontext,
|
||||||
struct context *tcontext,
|
struct context *tcontext,
|
||||||
u16 tclass,
|
u16 tclass,
|
||||||
u32 specified,
|
u32 specified,
|
||||||
@ -515,7 +519,7 @@ int mls_compute_sid(struct context *scontext,
|
|||||||
struct class_datum *cladatum;
|
struct class_datum *cladatum;
|
||||||
int default_range = 0;
|
int default_range = 0;
|
||||||
|
|
||||||
if (!policydb.mls_enabled)
|
if (!p->mls_enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (specified) {
|
switch (specified) {
|
||||||
@ -524,12 +528,12 @@ int mls_compute_sid(struct context *scontext,
|
|||||||
rtr.source_type = scontext->type;
|
rtr.source_type = scontext->type;
|
||||||
rtr.target_type = tcontext->type;
|
rtr.target_type = tcontext->type;
|
||||||
rtr.target_class = tclass;
|
rtr.target_class = tclass;
|
||||||
r = hashtab_search(policydb.range_tr, &rtr);
|
r = hashtab_search(p->range_tr, &rtr);
|
||||||
if (r)
|
if (r)
|
||||||
return mls_range_set(newcontext, r);
|
return mls_range_set(newcontext, r);
|
||||||
|
|
||||||
if (tclass && tclass <= policydb.p_classes.nprim) {
|
if (tclass && tclass <= p->p_classes.nprim) {
|
||||||
cladatum = policydb.class_val_to_struct[tclass - 1];
|
cladatum = p->class_val_to_struct[tclass - 1];
|
||||||
if (cladatum)
|
if (cladatum)
|
||||||
default_range = cladatum->default_range;
|
default_range = cladatum->default_range;
|
||||||
}
|
}
|
||||||
@ -551,7 +555,7 @@ int mls_compute_sid(struct context *scontext,
|
|||||||
|
|
||||||
/* Fallthrough */
|
/* Fallthrough */
|
||||||
case AVTAB_CHANGE:
|
case AVTAB_CHANGE:
|
||||||
if ((tclass == policydb.process_class) || (sock == true))
|
if ((tclass == p->process_class) || (sock == true))
|
||||||
/* Use the process MLS attributes. */
|
/* Use the process MLS attributes. */
|
||||||
return mls_context_cpy(newcontext, scontext);
|
return mls_context_cpy(newcontext, scontext);
|
||||||
else
|
else
|
||||||
@ -577,10 +581,11 @@ int mls_compute_sid(struct context *scontext,
|
|||||||
* NetLabel MLS sensitivity level field.
|
* NetLabel MLS sensitivity level field.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void mls_export_netlbl_lvl(struct context *context,
|
void mls_export_netlbl_lvl(struct policydb *p,
|
||||||
|
struct context *context,
|
||||||
struct netlbl_lsm_secattr *secattr)
|
struct netlbl_lsm_secattr *secattr)
|
||||||
{
|
{
|
||||||
if (!policydb.mls_enabled)
|
if (!p->mls_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
secattr->attr.mls.lvl = context->range.level[0].sens - 1;
|
secattr->attr.mls.lvl = context->range.level[0].sens - 1;
|
||||||
@ -597,10 +602,11 @@ void mls_export_netlbl_lvl(struct context *context,
|
|||||||
* NetLabel MLS sensitivity level into the context.
|
* NetLabel MLS sensitivity level into the context.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void mls_import_netlbl_lvl(struct context *context,
|
void mls_import_netlbl_lvl(struct policydb *p,
|
||||||
|
struct context *context,
|
||||||
struct netlbl_lsm_secattr *secattr)
|
struct netlbl_lsm_secattr *secattr)
|
||||||
{
|
{
|
||||||
if (!policydb.mls_enabled)
|
if (!p->mls_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
context->range.level[0].sens = secattr->attr.mls.lvl + 1;
|
context->range.level[0].sens = secattr->attr.mls.lvl + 1;
|
||||||
@ -617,12 +623,13 @@ void mls_import_netlbl_lvl(struct context *context,
|
|||||||
* MLS category field. Returns zero on success, negative values on failure.
|
* MLS category field. Returns zero on success, negative values on failure.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int mls_export_netlbl_cat(struct context *context,
|
int mls_export_netlbl_cat(struct policydb *p,
|
||||||
|
struct context *context,
|
||||||
struct netlbl_lsm_secattr *secattr)
|
struct netlbl_lsm_secattr *secattr)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!policydb.mls_enabled)
|
if (!p->mls_enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rc = ebitmap_netlbl_export(&context->range.level[0].cat,
|
rc = ebitmap_netlbl_export(&context->range.level[0].cat,
|
||||||
@ -645,12 +652,13 @@ int mls_export_netlbl_cat(struct context *context,
|
|||||||
* negative values on failure.
|
* negative values on failure.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int mls_import_netlbl_cat(struct context *context,
|
int mls_import_netlbl_cat(struct policydb *p,
|
||||||
|
struct context *context,
|
||||||
struct netlbl_lsm_secattr *secattr)
|
struct netlbl_lsm_secattr *secattr)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!policydb.mls_enabled)
|
if (!p->mls_enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rc = ebitmap_netlbl_import(&context->range.level[0].cat,
|
rc = ebitmap_netlbl_import(&context->range.level[0].cat,
|
||||||
|
@ -25,8 +25,9 @@
|
|||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "policydb.h"
|
#include "policydb.h"
|
||||||
|
|
||||||
int mls_compute_context_len(struct context *context);
|
int mls_compute_context_len(struct policydb *p, struct context *context);
|
||||||
void mls_sid_to_context(struct context *context, char **scontext);
|
void mls_sid_to_context(struct policydb *p, struct context *context,
|
||||||
|
char **scontext);
|
||||||
int mls_context_isvalid(struct policydb *p, struct context *c);
|
int mls_context_isvalid(struct policydb *p, struct context *c);
|
||||||
int mls_range_isvalid(struct policydb *p, struct mls_range *r);
|
int mls_range_isvalid(struct policydb *p, struct mls_range *r);
|
||||||
int mls_level_isvalid(struct policydb *p, struct mls_level *l);
|
int mls_level_isvalid(struct policydb *p, struct mls_level *l);
|
||||||
@ -38,7 +39,8 @@ int mls_context_to_sid(struct policydb *p,
|
|||||||
struct sidtab *s,
|
struct sidtab *s,
|
||||||
u32 def_sid);
|
u32 def_sid);
|
||||||
|
|
||||||
int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
|
int mls_from_string(struct policydb *p, char *str, struct context *context,
|
||||||
|
gfp_t gfp_mask);
|
||||||
|
|
||||||
int mls_range_set(struct context *context, struct mls_range *range);
|
int mls_range_set(struct context *context, struct mls_range *range);
|
||||||
|
|
||||||
@ -46,42 +48,52 @@ int mls_convert_context(struct policydb *oldp,
|
|||||||
struct policydb *newp,
|
struct policydb *newp,
|
||||||
struct context *context);
|
struct context *context);
|
||||||
|
|
||||||
int mls_compute_sid(struct context *scontext,
|
int mls_compute_sid(struct policydb *p,
|
||||||
|
struct context *scontext,
|
||||||
struct context *tcontext,
|
struct context *tcontext,
|
||||||
u16 tclass,
|
u16 tclass,
|
||||||
u32 specified,
|
u32 specified,
|
||||||
struct context *newcontext,
|
struct context *newcontext,
|
||||||
bool sock);
|
bool sock);
|
||||||
|
|
||||||
int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
|
int mls_setup_user_range(struct policydb *p,
|
||||||
|
struct context *fromcon, struct user_datum *user,
|
||||||
struct context *usercon);
|
struct context *usercon);
|
||||||
|
|
||||||
#ifdef CONFIG_NETLABEL
|
#ifdef CONFIG_NETLABEL
|
||||||
void mls_export_netlbl_lvl(struct context *context,
|
void mls_export_netlbl_lvl(struct policydb *p,
|
||||||
|
struct context *context,
|
||||||
struct netlbl_lsm_secattr *secattr);
|
struct netlbl_lsm_secattr *secattr);
|
||||||
void mls_import_netlbl_lvl(struct context *context,
|
void mls_import_netlbl_lvl(struct policydb *p,
|
||||||
|
struct context *context,
|
||||||
struct netlbl_lsm_secattr *secattr);
|
struct netlbl_lsm_secattr *secattr);
|
||||||
int mls_export_netlbl_cat(struct context *context,
|
int mls_export_netlbl_cat(struct policydb *p,
|
||||||
|
struct context *context,
|
||||||
struct netlbl_lsm_secattr *secattr);
|
struct netlbl_lsm_secattr *secattr);
|
||||||
int mls_import_netlbl_cat(struct context *context,
|
int mls_import_netlbl_cat(struct policydb *p,
|
||||||
|
struct context *context,
|
||||||
struct netlbl_lsm_secattr *secattr);
|
struct netlbl_lsm_secattr *secattr);
|
||||||
#else
|
#else
|
||||||
static inline void mls_export_netlbl_lvl(struct context *context,
|
static inline void mls_export_netlbl_lvl(struct policydb *p,
|
||||||
|
struct context *context,
|
||||||
struct netlbl_lsm_secattr *secattr)
|
struct netlbl_lsm_secattr *secattr)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
static inline void mls_import_netlbl_lvl(struct context *context,
|
static inline void mls_import_netlbl_lvl(struct policydb *p,
|
||||||
|
struct context *context,
|
||||||
struct netlbl_lsm_secattr *secattr)
|
struct netlbl_lsm_secattr *secattr)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
static inline int mls_export_netlbl_cat(struct context *context,
|
static inline int mls_export_netlbl_cat(struct policydb *p,
|
||||||
|
struct context *context,
|
||||||
struct netlbl_lsm_secattr *secattr)
|
struct netlbl_lsm_secattr *secattr)
|
||||||
{
|
{
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
static inline int mls_import_netlbl_cat(struct context *context,
|
static inline int mls_import_netlbl_cat(struct policydb *p,
|
||||||
|
struct context *context,
|
||||||
struct netlbl_lsm_secattr *secattr)
|
struct netlbl_lsm_secattr *secattr)
|
||||||
{
|
{
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,28 @@
|
|||||||
#include "policydb.h"
|
#include "policydb.h"
|
||||||
#include "sidtab.h"
|
#include "sidtab.h"
|
||||||
|
|
||||||
extern struct policydb policydb;
|
/* Mapping for a single class */
|
||||||
|
struct selinux_mapping {
|
||||||
|
u16 value; /* policy value for class */
|
||||||
|
unsigned int num_perms; /* number of permissions in class */
|
||||||
|
u32 perms[sizeof(u32) * 8]; /* policy values for permissions */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Map for all of the classes, with array size */
|
||||||
|
struct selinux_map {
|
||||||
|
struct selinux_mapping *mapping; /* indexed by class */
|
||||||
|
u16 size; /* array size of mapping */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct selinux_ss {
|
||||||
|
struct sidtab sidtab;
|
||||||
|
struct policydb policydb;
|
||||||
|
rwlock_t policy_rwlock;
|
||||||
|
u32 latest_granting;
|
||||||
|
struct selinux_map map;
|
||||||
|
struct page *status_page;
|
||||||
|
struct mutex status_lock;
|
||||||
|
};
|
||||||
|
|
||||||
void services_compute_xperms_drivers(struct extended_perms *xperms,
|
void services_compute_xperms_drivers(struct extended_perms *xperms,
|
||||||
struct avtab_node *node);
|
struct avtab_node *node);
|
||||||
@ -19,4 +40,3 @@ void services_compute_xperms_decision(struct extended_perms_decision *xpermd,
|
|||||||
struct avtab_node *node);
|
struct avtab_node *node);
|
||||||
|
|
||||||
#endif /* _SS_SERVICES_H_ */
|
#endif /* _SS_SERVICES_H_ */
|
||||||
|
|
||||||
|
@ -35,8 +35,6 @@
|
|||||||
* In most cases, application shall confirm the kernel status is not
|
* In most cases, application shall confirm the kernel status is not
|
||||||
* changed without any system call invocations.
|
* changed without any system call invocations.
|
||||||
*/
|
*/
|
||||||
static struct page *selinux_status_page;
|
|
||||||
static DEFINE_MUTEX(selinux_status_lock);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* selinux_kernel_status_page
|
* selinux_kernel_status_page
|
||||||
@ -44,21 +42,21 @@ static DEFINE_MUTEX(selinux_status_lock);
|
|||||||
* It returns a reference to selinux_status_page. If the status page is
|
* It returns a reference to selinux_status_page. If the status page is
|
||||||
* not allocated yet, it also tries to allocate it at the first time.
|
* not allocated yet, it also tries to allocate it at the first time.
|
||||||
*/
|
*/
|
||||||
struct page *selinux_kernel_status_page(void)
|
struct page *selinux_kernel_status_page(struct selinux_state *state)
|
||||||
{
|
{
|
||||||
struct selinux_kernel_status *status;
|
struct selinux_kernel_status *status;
|
||||||
struct page *result = NULL;
|
struct page *result = NULL;
|
||||||
|
|
||||||
mutex_lock(&selinux_status_lock);
|
mutex_lock(&state->ss->status_lock);
|
||||||
if (!selinux_status_page) {
|
if (!state->ss->status_page) {
|
||||||
selinux_status_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
|
state->ss->status_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
|
||||||
|
|
||||||
if (selinux_status_page) {
|
if (state->ss->status_page) {
|
||||||
status = page_address(selinux_status_page);
|
status = page_address(state->ss->status_page);
|
||||||
|
|
||||||
status->version = SELINUX_KERNEL_STATUS_VERSION;
|
status->version = SELINUX_KERNEL_STATUS_VERSION;
|
||||||
status->sequence = 0;
|
status->sequence = 0;
|
||||||
status->enforcing = selinux_enforcing;
|
status->enforcing = is_enforcing(state);
|
||||||
/*
|
/*
|
||||||
* NOTE: the next policyload event shall set
|
* NOTE: the next policyload event shall set
|
||||||
* a positive value on the status->policyload,
|
* a positive value on the status->policyload,
|
||||||
@ -66,11 +64,12 @@ struct page *selinux_kernel_status_page(void)
|
|||||||
* So, application can know it was updated.
|
* So, application can know it was updated.
|
||||||
*/
|
*/
|
||||||
status->policyload = 0;
|
status->policyload = 0;
|
||||||
status->deny_unknown = !security_get_allow_unknown();
|
status->deny_unknown =
|
||||||
|
!security_get_allow_unknown(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = selinux_status_page;
|
result = state->ss->status_page;
|
||||||
mutex_unlock(&selinux_status_lock);
|
mutex_unlock(&state->ss->status_lock);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -80,13 +79,14 @@ struct page *selinux_kernel_status_page(void)
|
|||||||
*
|
*
|
||||||
* It updates status of the current enforcing/permissive mode.
|
* It updates status of the current enforcing/permissive mode.
|
||||||
*/
|
*/
|
||||||
void selinux_status_update_setenforce(int enforcing)
|
void selinux_status_update_setenforce(struct selinux_state *state,
|
||||||
|
int enforcing)
|
||||||
{
|
{
|
||||||
struct selinux_kernel_status *status;
|
struct selinux_kernel_status *status;
|
||||||
|
|
||||||
mutex_lock(&selinux_status_lock);
|
mutex_lock(&state->ss->status_lock);
|
||||||
if (selinux_status_page) {
|
if (state->ss->status_page) {
|
||||||
status = page_address(selinux_status_page);
|
status = page_address(state->ss->status_page);
|
||||||
|
|
||||||
status->sequence++;
|
status->sequence++;
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
@ -96,7 +96,7 @@ void selinux_status_update_setenforce(int enforcing)
|
|||||||
smp_wmb();
|
smp_wmb();
|
||||||
status->sequence++;
|
status->sequence++;
|
||||||
}
|
}
|
||||||
mutex_unlock(&selinux_status_lock);
|
mutex_unlock(&state->ss->status_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -105,22 +105,23 @@ void selinux_status_update_setenforce(int enforcing)
|
|||||||
* It updates status of the times of policy reloaded, and current
|
* It updates status of the times of policy reloaded, and current
|
||||||
* setting of deny_unknown.
|
* setting of deny_unknown.
|
||||||
*/
|
*/
|
||||||
void selinux_status_update_policyload(int seqno)
|
void selinux_status_update_policyload(struct selinux_state *state,
|
||||||
|
int seqno)
|
||||||
{
|
{
|
||||||
struct selinux_kernel_status *status;
|
struct selinux_kernel_status *status;
|
||||||
|
|
||||||
mutex_lock(&selinux_status_lock);
|
mutex_lock(&state->ss->status_lock);
|
||||||
if (selinux_status_page) {
|
if (state->ss->status_page) {
|
||||||
status = page_address(selinux_status_page);
|
status = page_address(state->ss->status_page);
|
||||||
|
|
||||||
status->sequence++;
|
status->sequence++;
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
|
|
||||||
status->policyload = seqno;
|
status->policyload = seqno;
|
||||||
status->deny_unknown = !security_get_allow_unknown();
|
status->deny_unknown = !security_get_allow_unknown(state);
|
||||||
|
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
status->sequence++;
|
status->sequence++;
|
||||||
}
|
}
|
||||||
mutex_unlock(&selinux_status_lock);
|
mutex_unlock(&state->ss->status_lock);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,8 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
|
|||||||
ctx->ctx_len = str_len;
|
ctx->ctx_len = str_len;
|
||||||
memcpy(ctx->ctx_str, &uctx[1], str_len);
|
memcpy(ctx->ctx_str, &uctx[1], str_len);
|
||||||
ctx->ctx_str[str_len] = '\0';
|
ctx->ctx_str[str_len] = '\0';
|
||||||
rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid, gfp);
|
rc = security_context_to_sid(&selinux_state, ctx->ctx_str, str_len,
|
||||||
|
&ctx->ctx_sid, gfp);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@ -352,7 +353,8 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
|
|||||||
if (secid == 0)
|
if (secid == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
rc = security_sid_to_context(secid, &ctx_str, &str_len);
|
rc = security_sid_to_context(&selinux_state, secid, &ctx_str,
|
||||||
|
&str_len);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user