You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'stable-4.9' of git://git.infradead.org/users/pcmoore/selinux into next
This commit is contained in:
@@ -99,7 +99,7 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
/**
|
||||
* ipv6_skb_to_auditdata : fill auditdata from skb
|
||||
* @skb : the skb
|
||||
@@ -257,7 +257,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
|
||||
audit_log_format(ab, " ino=%lu", inode->i_ino);
|
||||
}
|
||||
|
||||
audit_log_format(ab, " ioctlcmd=%hx", a->u.op->cmd);
|
||||
audit_log_format(ab, " ioctlcmd=0x%hx", a->u.op->cmd);
|
||||
break;
|
||||
}
|
||||
case LSM_AUDIT_DATA_DENTRY: {
|
||||
|
||||
@@ -364,6 +364,15 @@ int security_dentry_init_security(struct dentry *dentry, int mode,
|
||||
}
|
||||
EXPORT_SYMBOL(security_dentry_init_security);
|
||||
|
||||
int security_dentry_create_files_as(struct dentry *dentry, int mode,
|
||||
struct qstr *name,
|
||||
const struct cred *old, struct cred *new)
|
||||
{
|
||||
return call_int_hook(dentry_create_files_as, 0, dentry, mode,
|
||||
name, old, new);
|
||||
}
|
||||
EXPORT_SYMBOL(security_dentry_create_files_as);
|
||||
|
||||
int security_inode_init_security(struct inode *inode, struct inode *dir,
|
||||
const struct qstr *qstr,
|
||||
const initxattrs initxattrs, void *fs_data)
|
||||
@@ -748,6 +757,18 @@ void security_inode_getsecid(struct inode *inode, u32 *secid)
|
||||
call_void_hook(inode_getsecid, inode, secid);
|
||||
}
|
||||
|
||||
int security_inode_copy_up(struct dentry *src, struct cred **new)
|
||||
{
|
||||
return call_int_hook(inode_copy_up, 0, src, new);
|
||||
}
|
||||
EXPORT_SYMBOL(security_inode_copy_up);
|
||||
|
||||
int security_inode_copy_up_xattr(const char *name)
|
||||
{
|
||||
return call_int_hook(inode_copy_up_xattr, -EOPNOTSUPP, name);
|
||||
}
|
||||
EXPORT_SYMBOL(security_inode_copy_up_xattr);
|
||||
|
||||
int security_file_permission(struct file *file, int mask)
|
||||
{
|
||||
int ret;
|
||||
@@ -1623,6 +1644,8 @@ struct security_hook_heads security_hook_heads = {
|
||||
LIST_HEAD_INIT(security_hook_heads.sb_parse_opts_str),
|
||||
.dentry_init_security =
|
||||
LIST_HEAD_INIT(security_hook_heads.dentry_init_security),
|
||||
.dentry_create_files_as =
|
||||
LIST_HEAD_INIT(security_hook_heads.dentry_create_files_as),
|
||||
#ifdef CONFIG_SECURITY_PATH
|
||||
.path_unlink = LIST_HEAD_INIT(security_hook_heads.path_unlink),
|
||||
.path_mkdir = LIST_HEAD_INIT(security_hook_heads.path_mkdir),
|
||||
@@ -1684,6 +1707,10 @@ struct security_hook_heads security_hook_heads = {
|
||||
LIST_HEAD_INIT(security_hook_heads.inode_listsecurity),
|
||||
.inode_getsecid =
|
||||
LIST_HEAD_INIT(security_hook_heads.inode_getsecid),
|
||||
.inode_copy_up =
|
||||
LIST_HEAD_INIT(security_hook_heads.inode_copy_up),
|
||||
.inode_copy_up_xattr =
|
||||
LIST_HEAD_INIT(security_hook_heads.inode_copy_up_xattr),
|
||||
.file_permission =
|
||||
LIST_HEAD_INIT(security_hook_heads.file_permission),
|
||||
.file_alloc_security =
|
||||
|
||||
@@ -93,41 +93,3 @@ config SECURITY_SELINUX_CHECKREQPROT_VALUE
|
||||
via /selinux/checkreqprot if authorized by policy.
|
||||
|
||||
If you are unsure how to answer this question, answer 0.
|
||||
|
||||
config SECURITY_SELINUX_POLICYDB_VERSION_MAX
|
||||
bool "NSA SELinux maximum supported policy format version"
|
||||
depends on SECURITY_SELINUX
|
||||
default n
|
||||
help
|
||||
This option enables the maximum policy format version supported
|
||||
by SELinux to be set to a particular value. This value is reported
|
||||
to userspace via /selinux/policyvers and used at policy load time.
|
||||
It can be adjusted downward to support legacy userland (init) that
|
||||
does not correctly handle kernels that support newer policy versions.
|
||||
|
||||
Examples:
|
||||
For the Fedora Core 3 or 4 Linux distributions, enable this option
|
||||
and set the value via the next option. For Fedora Core 5 and later,
|
||||
do not enable this option.
|
||||
|
||||
If you are unsure how to answer this question, answer N.
|
||||
|
||||
config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
|
||||
int "NSA SELinux maximum supported policy format version value"
|
||||
depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX
|
||||
range 15 23
|
||||
default 19
|
||||
help
|
||||
This option sets the value for the maximum policy format version
|
||||
supported by SELinux.
|
||||
|
||||
Examples:
|
||||
For Fedora Core 3, use 18.
|
||||
For Fedora Core 4, use 19.
|
||||
|
||||
If you are unsure how to answer this question, look for the
|
||||
policy format version supported by your policy toolchain, by
|
||||
running 'checkpolicy -V'. Or look at what policy you have
|
||||
installed under /etc/selinux/$SELINUXTYPE/policy, where
|
||||
SELINUXTYPE is defined in your /etc/selinux/config.
|
||||
|
||||
|
||||
+75
-15
@@ -1808,13 +1808,13 @@ out:
|
||||
/*
|
||||
* Determine the label for an inode that might be unioned.
|
||||
*/
|
||||
static int selinux_determine_inode_label(struct inode *dir,
|
||||
const struct qstr *name,
|
||||
u16 tclass,
|
||||
u32 *_new_isid)
|
||||
static int
|
||||
selinux_determine_inode_label(const struct task_security_struct *tsec,
|
||||
struct inode *dir,
|
||||
const struct qstr *name, u16 tclass,
|
||||
u32 *_new_isid)
|
||||
{
|
||||
const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
|
||||
const struct task_security_struct *tsec = current_security();
|
||||
|
||||
if ((sbsec->flags & SE_SBINITIALIZED) &&
|
||||
(sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) {
|
||||
@@ -1857,8 +1857,8 @@ static int may_create(struct inode *dir,
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = selinux_determine_inode_label(dir, &dentry->d_name, tclass,
|
||||
&newsid);
|
||||
rc = selinux_determine_inode_label(current_security(), dir,
|
||||
&dentry->d_name, tclass, &newsid);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -2838,7 +2838,8 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
|
||||
u32 newsid;
|
||||
int rc;
|
||||
|
||||
rc = selinux_determine_inode_label(d_inode(dentry->d_parent), name,
|
||||
rc = selinux_determine_inode_label(current_security(),
|
||||
d_inode(dentry->d_parent), name,
|
||||
inode_mode_to_security_class(mode),
|
||||
&newsid);
|
||||
if (rc)
|
||||
@@ -2847,6 +2848,27 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
|
||||
return security_sid_to_context(newsid, (char **)ctx, ctxlen);
|
||||
}
|
||||
|
||||
static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,
|
||||
struct qstr *name,
|
||||
const struct cred *old,
|
||||
struct cred *new)
|
||||
{
|
||||
u32 newsid;
|
||||
int rc;
|
||||
struct task_security_struct *tsec;
|
||||
|
||||
rc = selinux_determine_inode_label(old->security,
|
||||
d_inode(dentry->d_parent), name,
|
||||
inode_mode_to_security_class(mode),
|
||||
&newsid);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
tsec = new->security;
|
||||
tsec->create_sid = newsid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
|
||||
const struct qstr *qstr,
|
||||
const char **name,
|
||||
@@ -2863,7 +2885,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
|
||||
sid = tsec->sid;
|
||||
newsid = tsec->create_sid;
|
||||
|
||||
rc = selinux_determine_inode_label(
|
||||
rc = selinux_determine_inode_label(current_security(),
|
||||
dir, qstr,
|
||||
inode_mode_to_security_class(inode->i_mode),
|
||||
&newsid);
|
||||
@@ -3293,6 +3315,41 @@ static void selinux_inode_getsecid(struct inode *inode, u32 *secid)
|
||||
*secid = isec->sid;
|
||||
}
|
||||
|
||||
static int selinux_inode_copy_up(struct dentry *src, struct cred **new)
|
||||
{
|
||||
u32 sid;
|
||||
struct task_security_struct *tsec;
|
||||
struct cred *new_creds = *new;
|
||||
|
||||
if (new_creds == NULL) {
|
||||
new_creds = prepare_creds();
|
||||
if (!new_creds)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
tsec = new_creds->security;
|
||||
/* Get label from overlay inode and set it in create_sid */
|
||||
selinux_inode_getsecid(d_inode(src), &sid);
|
||||
tsec->create_sid = sid;
|
||||
*new = new_creds;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int selinux_inode_copy_up_xattr(const char *name)
|
||||
{
|
||||
/* The copy_up hook above sets the initial context on an inode, but we
|
||||
* don't then want to overwrite it by blindly copying all the lower
|
||||
* xattrs up. Instead, we have to filter out SELinux-related xattrs.
|
||||
*/
|
||||
if (strcmp(name, XATTR_NAME_SELINUX) == 0)
|
||||
return 1; /* Discard */
|
||||
/*
|
||||
* Any other attribute apart from SELINUX is not claimed, supported
|
||||
* by selinux.
|
||||
*/
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* file security operations */
|
||||
|
||||
static int selinux_revalidate_file_permission(struct file *file, int mask)
|
||||
@@ -3984,7 +4041,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
|
||||
/* Returns error only if unable to parse addresses */
|
||||
static int selinux_parse_skb_ipv6(struct sk_buff *skb,
|
||||
@@ -4075,7 +4132,7 @@ static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
|
||||
&ad->u.net->v4info.daddr);
|
||||
goto okay;
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
case PF_INET6:
|
||||
ret = selinux_parse_skb_ipv6(skb, ad, proto);
|
||||
if (ret)
|
||||
@@ -5029,7 +5086,7 @@ static unsigned int selinux_ipv4_forward(void *priv,
|
||||
return selinux_ip_forward(skb, state->in, PF_INET);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
static unsigned int selinux_ipv6_forward(void *priv,
|
||||
struct sk_buff *skb,
|
||||
const struct nf_hook_state *state)
|
||||
@@ -5087,7 +5144,7 @@ static unsigned int selinux_ipv4_output(void *priv,
|
||||
return selinux_ip_output(skb, PF_INET);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
static unsigned int selinux_ipv6_output(void *priv,
|
||||
struct sk_buff *skb,
|
||||
const struct nf_hook_state *state)
|
||||
@@ -5273,7 +5330,7 @@ static unsigned int selinux_ipv4_postroute(void *priv,
|
||||
return selinux_ip_postroute(skb, state->out, PF_INET);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
static unsigned int selinux_ipv6_postroute(void *priv,
|
||||
struct sk_buff *skb,
|
||||
const struct nf_hook_state *state)
|
||||
@@ -6062,6 +6119,7 @@ static struct security_hook_list selinux_hooks[] = {
|
||||
LSM_HOOK_INIT(sb_parse_opts_str, selinux_parse_opts_str),
|
||||
|
||||
LSM_HOOK_INIT(dentry_init_security, selinux_dentry_init_security),
|
||||
LSM_HOOK_INIT(dentry_create_files_as, selinux_dentry_create_files_as),
|
||||
|
||||
LSM_HOOK_INIT(inode_alloc_security, selinux_inode_alloc_security),
|
||||
LSM_HOOK_INIT(inode_free_security, selinux_inode_free_security),
|
||||
@@ -6088,6 +6146,8 @@ static struct security_hook_list selinux_hooks[] = {
|
||||
LSM_HOOK_INIT(inode_setsecurity, selinux_inode_setsecurity),
|
||||
LSM_HOOK_INIT(inode_listsecurity, selinux_inode_listsecurity),
|
||||
LSM_HOOK_INIT(inode_getsecid, selinux_inode_getsecid),
|
||||
LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up),
|
||||
LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr),
|
||||
|
||||
LSM_HOOK_INIT(file_permission, selinux_file_permission),
|
||||
LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
|
||||
@@ -6317,7 +6377,7 @@ static struct nf_hook_ops selinux_nf_ops[] = {
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_SELINUX_FIRST,
|
||||
},
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
{
|
||||
.hook = selinux_ipv6_postroute,
|
||||
.pf = NFPROTO_IPV6,
|
||||
|
||||
@@ -39,11 +39,7 @@
|
||||
|
||||
/* Range of policy versions we understand*/
|
||||
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
|
||||
#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
|
||||
#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
|
||||
#else
|
||||
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_XPERMS_IOCTL
|
||||
#endif
|
||||
|
||||
/* Mask for just the mount related flags */
|
||||
#define SE_MNTMASK 0x0f
|
||||
|
||||
@@ -242,6 +242,8 @@ int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp)
|
||||
goto err;
|
||||
|
||||
len = le32_to_cpu(buf[2]);
|
||||
if (((len == 0) || (len == (u32)-1)))
|
||||
goto err;
|
||||
|
||||
rc = -ENOMEM;
|
||||
key = kmalloc(len + 1, GFP_KERNEL);
|
||||
|
||||
@@ -374,6 +374,9 @@ int ebitmap_read(struct ebitmap *e, void *fp)
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if (e->highbit && !count)
|
||||
goto bad;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
rc = next_entry(&startbit, fp, sizeof(u32));
|
||||
if (rc < 0) {
|
||||
|
||||
@@ -541,21 +541,21 @@ static int policydb_index(struct policydb *p)
|
||||
|
||||
rc = -ENOMEM;
|
||||
p->class_val_to_struct =
|
||||
kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)),
|
||||
kzalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)),
|
||||
GFP_KERNEL);
|
||||
if (!p->class_val_to_struct)
|
||||
goto out;
|
||||
|
||||
rc = -ENOMEM;
|
||||
p->role_val_to_struct =
|
||||
kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)),
|
||||
kzalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)),
|
||||
GFP_KERNEL);
|
||||
if (!p->role_val_to_struct)
|
||||
goto out;
|
||||
|
||||
rc = -ENOMEM;
|
||||
p->user_val_to_struct =
|
||||
kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)),
|
||||
kzalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)),
|
||||
GFP_KERNEL);
|
||||
if (!p->user_val_to_struct)
|
||||
goto out;
|
||||
@@ -964,7 +964,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
|
||||
* Role must be authorized for the type.
|
||||
*/
|
||||
role = p->role_val_to_struct[c->role - 1];
|
||||
if (!ebitmap_get_bit(&role->types, c->type - 1))
|
||||
if (!role || !ebitmap_get_bit(&role->types, c->type - 1))
|
||||
/* role may not be associated with type */
|
||||
return 0;
|
||||
|
||||
@@ -1094,6 +1094,9 @@ static int str_read(char **strp, gfp_t flags, void *fp, u32 len)
|
||||
int rc;
|
||||
char *str;
|
||||
|
||||
if ((len == 0) || (len == (u32)-1))
|
||||
return -EINVAL;
|
||||
|
||||
str = kmalloc(len + 1, flags);
|
||||
if (!str)
|
||||
return -ENOMEM;
|
||||
@@ -2414,6 +2417,7 @@ int policydb_read(struct policydb *p, void *fp)
|
||||
} else
|
||||
tr->tclass = p->process_class;
|
||||
|
||||
rc = -EINVAL;
|
||||
if (!policydb_role_isvalid(p, tr->role) ||
|
||||
!policydb_type_isvalid(p, tr->type) ||
|
||||
!policydb_class_isvalid(p, tr->tclass) ||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <net/inet_sock.h>
|
||||
#include "smack.h"
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
|
||||
static unsigned int smack_ipv6_output(void *priv,
|
||||
struct sk_buff *skb,
|
||||
@@ -64,7 +64,7 @@ static struct nf_hook_ops smack_nf_ops[] = {
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_SELINUX_FIRST,
|
||||
},
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
{
|
||||
.hook = smack_ipv6_output,
|
||||
.pf = NFPROTO_IPV6,
|
||||
|
||||
Reference in New Issue
Block a user