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 commit 'v3.14' into next
This commit is contained in:
+1
-1
@@ -103,7 +103,7 @@ config INTEL_TXT
|
||||
config LSM_MMAP_MIN_ADDR
|
||||
int "Low address space for LSM to protect from user allocation"
|
||||
depends on SECURITY && SECURITY_SELINUX
|
||||
default 32768 if ARM
|
||||
default 32768 if ARM || (ARM64 && COMPAT)
|
||||
default 65536
|
||||
help
|
||||
This is the portion of low virtual memory which should be protected
|
||||
|
||||
@@ -757,7 +757,8 @@ static void cap_skb_owned_by(struct sk_buff *skb, struct sock *sk)
|
||||
|
||||
#ifdef CONFIG_SECURITY_NETWORK_XFRM
|
||||
static int cap_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp,
|
||||
struct xfrm_user_sec_ctx *sec_ctx)
|
||||
struct xfrm_user_sec_ctx *sec_ctx,
|
||||
gfp_t gfp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -274,10 +274,9 @@ static void set_majmin(char *str, unsigned m)
|
||||
sprintf(str, "%u", m);
|
||||
}
|
||||
|
||||
static int devcgroup_seq_read(struct cgroup_subsys_state *css,
|
||||
struct cftype *cft, struct seq_file *m)
|
||||
static int devcgroup_seq_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct dev_cgroup *devcgroup = css_to_devcgroup(css);
|
||||
struct dev_cgroup *devcgroup = css_to_devcgroup(seq_css(m));
|
||||
struct dev_exception_item *ex;
|
||||
char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN];
|
||||
|
||||
@@ -679,7 +678,7 @@ static struct cftype dev_cgroup_files[] = {
|
||||
},
|
||||
{
|
||||
.name = "list",
|
||||
.read_seq_string = devcgroup_seq_read,
|
||||
.seq_show = devcgroup_seq_show,
|
||||
.private = DEVCG_LIST,
|
||||
},
|
||||
{ } /* terminate */
|
||||
|
||||
@@ -1000,7 +1000,11 @@ static int keyring_detect_cycle_iterator(const void *object,
|
||||
|
||||
kenter("{%d}", key->serial);
|
||||
|
||||
BUG_ON(key != ctx->match_data);
|
||||
/* We might get a keyring with matching index-key that is nonetheless a
|
||||
* different keyring. */
|
||||
if (key != ctx->match_data)
|
||||
return 0;
|
||||
|
||||
ctx->result = ERR_PTR(-EDEADLK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+4
-2
@@ -1317,9 +1317,11 @@ void security_skb_owned_by(struct sk_buff *skb, struct sock *sk)
|
||||
|
||||
#ifdef CONFIG_SECURITY_NETWORK_XFRM
|
||||
|
||||
int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx)
|
||||
int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
|
||||
struct xfrm_user_sec_ctx *sec_ctx,
|
||||
gfp_t gfp)
|
||||
{
|
||||
return security_ops->xfrm_policy_alloc_security(ctxp, sec_ctx);
|
||||
return security_ops->xfrm_policy_alloc_security(ctxp, sec_ctx, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL(security_xfrm_policy_alloc);
|
||||
|
||||
|
||||
@@ -233,6 +233,14 @@ static int inode_alloc_security(struct inode *inode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void inode_free_rcu(struct rcu_head *head)
|
||||
{
|
||||
struct inode_security_struct *isec;
|
||||
|
||||
isec = container_of(head, struct inode_security_struct, rcu);
|
||||
kmem_cache_free(sel_inode_cache, isec);
|
||||
}
|
||||
|
||||
static void inode_free_security(struct inode *inode)
|
||||
{
|
||||
struct inode_security_struct *isec = inode->i_security;
|
||||
@@ -243,8 +251,16 @@ static void inode_free_security(struct inode *inode)
|
||||
list_del_init(&isec->list);
|
||||
spin_unlock(&sbsec->isec_lock);
|
||||
|
||||
inode->i_security = NULL;
|
||||
kmem_cache_free(sel_inode_cache, isec);
|
||||
/*
|
||||
* The inode may still be referenced in a path walk and
|
||||
* a call to selinux_inode_permission() can be made
|
||||
* after inode_free_security() is called. Ideally, the VFS
|
||||
* wouldn't do this, but fixing that is a much harder
|
||||
* job. For now, simply free the i_security via RCU, and
|
||||
* leave the current inode->i_security pointer intact.
|
||||
* The inode will be freed after the RCU grace period too.
|
||||
*/
|
||||
call_rcu(&isec->rcu, inode_free_rcu);
|
||||
}
|
||||
|
||||
static int file_alloc_security(struct file *file)
|
||||
@@ -652,7 +668,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
|
||||
if (flags[i] == SBLABEL_MNT)
|
||||
continue;
|
||||
rc = security_context_to_sid(mount_options[i],
|
||||
strlen(mount_options[i]), &sid);
|
||||
strlen(mount_options[i]), &sid, GFP_KERNEL);
|
||||
if (rc) {
|
||||
printk(KERN_WARNING "SELinux: security_context_to_sid"
|
||||
"(%s) failed for (dev %s, type %s) errno=%d\n",
|
||||
@@ -2491,7 +2507,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
|
||||
if (flags[i] == SBLABEL_MNT)
|
||||
continue;
|
||||
len = strlen(mount_options[i]);
|
||||
rc = security_context_to_sid(mount_options[i], len, &sid);
|
||||
rc = security_context_to_sid(mount_options[i], len, &sid,
|
||||
GFP_KERNEL);
|
||||
if (rc) {
|
||||
printk(KERN_WARNING "SELinux: security_context_to_sid"
|
||||
"(%s) failed for (dev %s, type %s) errno=%d\n",
|
||||
@@ -2895,7 +2912,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = security_context_to_sid(value, size, &newsid);
|
||||
rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL);
|
||||
if (rc == -EINVAL) {
|
||||
if (!capable(CAP_MAC_ADMIN)) {
|
||||
struct audit_buffer *ab;
|
||||
@@ -3052,7 +3069,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
|
||||
if (!value || !size)
|
||||
return -EACCES;
|
||||
|
||||
rc = security_context_to_sid((void *)value, size, &newsid);
|
||||
rc = security_context_to_sid((void *)value, size, &newsid, GFP_KERNEL);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@@ -5527,7 +5544,7 @@ static int selinux_setprocattr(struct task_struct *p,
|
||||
str[size-1] = 0;
|
||||
size--;
|
||||
}
|
||||
error = security_context_to_sid(value, size, &sid);
|
||||
error = security_context_to_sid(value, size, &sid, GFP_KERNEL);
|
||||
if (error == -EINVAL && !strcmp(name, "fscreate")) {
|
||||
if (!capable(CAP_MAC_ADMIN)) {
|
||||
struct audit_buffer *ab;
|
||||
@@ -5636,7 +5653,7 @@ static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
|
||||
|
||||
static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
|
||||
{
|
||||
return security_context_to_sid(secdata, seclen, secid);
|
||||
return security_context_to_sid(secdata, seclen, secid, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static void selinux_release_secctx(char *secdata, u32 seclen)
|
||||
|
||||
@@ -38,7 +38,10 @@ struct task_security_struct {
|
||||
|
||||
struct inode_security_struct {
|
||||
struct inode *inode; /* back pointer to inode object */
|
||||
struct list_head list; /* list of inode_security_struct */
|
||||
union {
|
||||
struct list_head list; /* list of inode_security_struct */
|
||||
struct rcu_head rcu; /* for freeing the inode_security_struct */
|
||||
};
|
||||
u32 task_sid; /* SID of creating task */
|
||||
u32 sid; /* SID of this object */
|
||||
u16 sclass; /* security class of this object */
|
||||
|
||||
@@ -134,7 +134,7 @@ int security_sid_to_context(u32 sid, char **scontext,
|
||||
int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len);
|
||||
|
||||
int security_context_to_sid(const char *scontext, u32 scontext_len,
|
||||
u32 *out_sid);
|
||||
u32 *out_sid, gfp_t gfp);
|
||||
|
||||
int security_context_to_sid_default(const char *scontext, u32 scontext_len,
|
||||
u32 *out_sid, u32 def_sid, gfp_t gfp_flags);
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
#include <net/flow.h>
|
||||
|
||||
int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
|
||||
struct xfrm_user_sec_ctx *uctx);
|
||||
struct xfrm_user_sec_ctx *uctx,
|
||||
gfp_t gfp);
|
||||
int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
|
||||
struct xfrm_sec_ctx **new_ctxp);
|
||||
void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/inet_diag.h>
|
||||
#include <linux/xfrm.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/sock_diag.h>
|
||||
|
||||
#include "flask.h"
|
||||
#include "av_permissions.h"
|
||||
@@ -78,6 +79,7 @@ static struct nlmsg_perm nlmsg_tcpdiag_perms[] =
|
||||
{
|
||||
{ TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ },
|
||||
{ DCCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ },
|
||||
{ SOCK_DIAG_BY_FAMILY, NETLINK_TCPDIAG_SOCKET__NLMSG_READ },
|
||||
};
|
||||
|
||||
static struct nlmsg_perm nlmsg_xfrm_perms[] =
|
||||
|
||||
@@ -576,7 +576,7 @@ static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
|
||||
if (length)
|
||||
goto out;
|
||||
|
||||
length = security_context_to_sid(buf, size, &sid);
|
||||
length = security_context_to_sid(buf, size, &sid, GFP_KERNEL);
|
||||
if (length)
|
||||
goto out;
|
||||
|
||||
@@ -731,11 +731,13 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
|
||||
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
|
||||
goto out;
|
||||
|
||||
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
|
||||
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid,
|
||||
GFP_KERNEL);
|
||||
if (length)
|
||||
goto out;
|
||||
|
||||
length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
|
||||
length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid,
|
||||
GFP_KERNEL);
|
||||
if (length)
|
||||
goto out;
|
||||
|
||||
@@ -817,11 +819,13 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
|
||||
objname = namebuf;
|
||||
}
|
||||
|
||||
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
|
||||
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid,
|
||||
GFP_KERNEL);
|
||||
if (length)
|
||||
goto out;
|
||||
|
||||
length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
|
||||
length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid,
|
||||
GFP_KERNEL);
|
||||
if (length)
|
||||
goto out;
|
||||
|
||||
@@ -878,11 +882,13 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
|
||||
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
|
||||
goto out;
|
||||
|
||||
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
|
||||
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid,
|
||||
GFP_KERNEL);
|
||||
if (length)
|
||||
goto out;
|
||||
|
||||
length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
|
||||
length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid,
|
||||
GFP_KERNEL);
|
||||
if (length)
|
||||
goto out;
|
||||
|
||||
@@ -934,7 +940,7 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
|
||||
if (sscanf(buf, "%s %s", con, user) != 2)
|
||||
goto out;
|
||||
|
||||
length = security_context_to_sid(con, strlen(con) + 1, &sid);
|
||||
length = security_context_to_sid(con, strlen(con) + 1, &sid, GFP_KERNEL);
|
||||
if (length)
|
||||
goto out;
|
||||
|
||||
@@ -994,11 +1000,13 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
|
||||
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
|
||||
goto out;
|
||||
|
||||
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
|
||||
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid,
|
||||
GFP_KERNEL);
|
||||
if (length)
|
||||
goto out;
|
||||
|
||||
length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
|
||||
length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid,
|
||||
GFP_KERNEL);
|
||||
if (length)
|
||||
goto out;
|
||||
|
||||
|
||||
@@ -3338,10 +3338,10 @@ static int filename_write_helper(void *key, void *data, void *ptr)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
buf[0] = ft->stype;
|
||||
buf[1] = ft->ttype;
|
||||
buf[2] = ft->tclass;
|
||||
buf[3] = otype->otype;
|
||||
buf[0] = cpu_to_le32(ft->stype);
|
||||
buf[1] = cpu_to_le32(ft->ttype);
|
||||
buf[2] = cpu_to_le32(ft->tclass);
|
||||
buf[3] = cpu_to_le32(otype->otype);
|
||||
|
||||
rc = put_entry(buf, sizeof(u32), 4, fp);
|
||||
if (rc)
|
||||
|
||||
@@ -1232,6 +1232,10 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
|
||||
struct context context;
|
||||
int rc = 0;
|
||||
|
||||
/* An empty security context is never valid. */
|
||||
if (!scontext_len)
|
||||
return -EINVAL;
|
||||
|
||||
if (!ss_initialized) {
|
||||
int i;
|
||||
|
||||
@@ -1285,16 +1289,18 @@ out:
|
||||
* @scontext: security context
|
||||
* @scontext_len: length in bytes
|
||||
* @sid: security identifier, SID
|
||||
* @gfp: context for the allocation
|
||||
*
|
||||
* Obtains a SID associated with the security context that
|
||||
* has the string representation specified by @scontext.
|
||||
* Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
|
||||
* memory is available, or 0 on success.
|
||||
*/
|
||||
int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid)
|
||||
int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid,
|
||||
gfp_t gfp)
|
||||
{
|
||||
return security_context_to_sid_core(scontext, scontext_len,
|
||||
sid, SECSID_NULL, GFP_KERNEL, 0);
|
||||
sid, SECSID_NULL, gfp, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2948,25 +2954,21 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule,
|
||||
struct selinux_audit_rule *rule = vrule;
|
||||
int match = 0;
|
||||
|
||||
if (!rule) {
|
||||
audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
|
||||
"selinux_audit_rule_match: missing rule\n");
|
||||
if (unlikely(!rule)) {
|
||||
WARN_ONCE(1, "selinux_audit_rule_match: missing rule\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
read_lock(&policy_rwlock);
|
||||
|
||||
if (rule->au_seqno < latest_granting) {
|
||||
audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
|
||||
"selinux_audit_rule_match: stale rule\n");
|
||||
match = -ESTALE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctxt = sidtab_search(&sidtab, sid);
|
||||
if (!ctxt) {
|
||||
audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
|
||||
"selinux_audit_rule_match: unrecognized SID %d\n",
|
||||
if (unlikely(!ctxt)) {
|
||||
WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n",
|
||||
sid);
|
||||
match = -ENOENT;
|
||||
goto out;
|
||||
|
||||
@@ -78,7 +78,8 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
|
||||
* xfrm_user_sec_ctx context.
|
||||
*/
|
||||
static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
|
||||
struct xfrm_user_sec_ctx *uctx)
|
||||
struct xfrm_user_sec_ctx *uctx,
|
||||
gfp_t gfp)
|
||||
{
|
||||
int rc;
|
||||
const struct task_security_struct *tsec = current_security();
|
||||
@@ -94,7 +95,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
|
||||
if (str_len >= PAGE_SIZE)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx = kmalloc(sizeof(*ctx) + str_len + 1, GFP_KERNEL);
|
||||
ctx = kmalloc(sizeof(*ctx) + str_len + 1, gfp);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -103,7 +104,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
|
||||
ctx->ctx_len = str_len;
|
||||
memcpy(ctx->ctx_str, &uctx[1], str_len);
|
||||
ctx->ctx_str[str_len] = '\0';
|
||||
rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid);
|
||||
rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid, gfp);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
@@ -282,9 +283,10 @@ int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
|
||||
* LSM hook implementation that allocs and transfers uctx spec to xfrm_policy.
|
||||
*/
|
||||
int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
|
||||
struct xfrm_user_sec_ctx *uctx)
|
||||
struct xfrm_user_sec_ctx *uctx,
|
||||
gfp_t gfp)
|
||||
{
|
||||
return selinux_xfrm_alloc_user(ctxp, uctx);
|
||||
return selinux_xfrm_alloc_user(ctxp, uctx, gfp);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -332,7 +334,7 @@ int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
|
||||
int selinux_xfrm_state_alloc(struct xfrm_state *x,
|
||||
struct xfrm_user_sec_ctx *uctx)
|
||||
{
|
||||
return selinux_xfrm_alloc_user(&x->security, uctx);
|
||||
return selinux_xfrm_alloc_user(&x->security, uctx, GFP_KERNEL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -3616,9 +3616,8 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule,
|
||||
struct smack_known *skp;
|
||||
char *rule = vrule;
|
||||
|
||||
if (!rule) {
|
||||
audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
|
||||
"Smack: missing rule\n");
|
||||
if (unlikely(!rule)) {
|
||||
WARN_ONCE(1, "Smack: missing rule\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user