Merge tag 'v3.4.113' into lineage-16.0

This is the 3.4.113 stable release

Change-Id: I80791430656359c5447a675cbff4431362d18df0
Signed-off-by: Kevin F. Haggerty <haggertk@lineageos.org>
This commit is contained in:
Kevin F. Haggerty
2019-08-05 14:20:47 +02:00
committed by Francescodario Cuzzocrea
parent 36738e5d0d
commit 238a0fb5ad
3036 changed files with 50479 additions and 23994 deletions
+2 -2
View File
@@ -205,9 +205,9 @@ int evm_update_evmxattr(struct dentry *dentry, const char *xattr_name,
rc = __vfs_setxattr_noperm(dentry, XATTR_NAME_EVM,
&xattr_data,
sizeof(xattr_data), 0);
}
else if (rc == -ENODATA)
} else if (rc == -ENODATA && inode->i_op->removexattr) {
rc = inode->i_op->removexattr(dentry, XATTR_NAME_EVM);
}
return rc;
}
+13 -2
View File
@@ -271,12 +271,23 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
* @xattr_value: pointer to the new extended attribute value
* @xattr_value_len: pointer to the new extended attribute value length
*
* Updating 'security.evm' requires CAP_SYS_ADMIN privileges and that
* the current value is valid.
* Before allowing the 'security.evm' protected xattr to be updated,
* verify the existing value is valid. As only the kernel should have
* access to the EVM encrypted key needed to calculate the HMAC, prevent
* userspace from writing HMAC value. Writing 'security.evm' requires
* requires CAP_SYS_ADMIN privileges.
*/
int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
const void *xattr_value, size_t xattr_value_len)
{
const struct evm_ima_xattr_data *xattr_data = xattr_value;
if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) {
if (!xattr_value_len)
return -EINVAL;
if (xattr_data->type != EVM_IMA_XATTR_DIGSIG)
return -EPERM;
}
return evm_protect_xattr(dentry, xattr_name, xattr_value,
xattr_value_len);
}
-1
View File
@@ -62,7 +62,6 @@ static struct ima_measure_rule_entry default_rules[] = {
{.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
{.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
{.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
{.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC},
{.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
{.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
{.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC,
+2 -2
View File
@@ -40,12 +40,12 @@ long compat_keyctl_instantiate_key_iov(
ARRAY_SIZE(iovstack),
iovstack, &iov, 1);
if (ret < 0)
return ret;
goto err;
if (ret == 0)
goto no_payload_free;
ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid);
err:
if (iov != iovstack)
kfree(iov);
return ret;
+4 -1
View File
@@ -1015,10 +1015,13 @@ static int __init init_encrypted(void)
ret = encrypted_shash_alloc();
if (ret < 0)
return ret;
ret = aes_get_sizes();
if (ret < 0)
goto out;
ret = register_key_type(&key_type_encrypted);
if (ret < 0)
goto out;
return aes_get_sizes();
return 0;
out:
encrypted_shash_release();
return ret;
+2 -2
View File
@@ -1086,12 +1086,12 @@ long keyctl_instantiate_key_iov(key_serial_t id,
ret = rw_copy_check_uvector(WRITE, _payload_iov, ioc,
ARRAY_SIZE(iovstack), iovstack, &iov, 1);
if (ret < 0)
return ret;
goto err;
if (ret == 0)
goto no_payload_free;
ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid);
err:
if (iov != iovstack)
kfree(iov);
return ret;
+1 -1
View File
@@ -54,7 +54,7 @@ int install_user_keyrings(void)
kenter("%p{%u}", user, user->uid);
if (user->uid_keyring) {
if (user->uid_keyring && user->session_keyring) {
kleave(" = 0 [exist]");
return 0;
}
+147 -39
View File
@@ -52,6 +52,7 @@
#include <net/icmp.h>
#include <net/ip.h> /* for local_port_range[] */
#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */
#include <net/inet_connection_sock.h>
#include <net/net_namespace.h>
#include <net/netlabel.h>
#include <linux/uaccess.h>
@@ -1027,7 +1028,7 @@ static void selinux_write_opts(struct seq_file *m,
seq_puts(m, prefix);
if (has_comma)
seq_putc(m, '\"');
seq_puts(m, opts->mnt_opts[i]);
seq_escape(m, opts->mnt_opts[i], "\"\n\\");
if (has_comma)
seq_putc(m, '\"');
}
@@ -1344,15 +1345,33 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
isec->sid = sbsec->sid;
if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
if (opt_dentry) {
isec->sclass = inode_mode_to_security_class(inode->i_mode);
rc = selinux_proc_get_sid(opt_dentry,
isec->sclass,
&sid);
if (rc)
goto out_unlock;
isec->sid = sid;
}
/* We must have a dentry to determine the label on
* procfs inodes */
if (opt_dentry)
/* Called from d_instantiate or
* d_splice_alias. */
dentry = dget(opt_dentry);
else
/* Called from selinux_complete_init, try to
* find a dentry. */
dentry = d_find_alias(inode);
/*
* This can be hit on boot when a file is accessed
* before the policy is loaded. When we load policy we
* may find inodes that have no dentry on the
* sbsec->isec_head list. No reason to complain as
* these will get fixed up the next time we go through
* inode_doinit() with a dentry, before these inodes
* could be used again by userspace.
*/
if (!dentry)
goto out_unlock;
isec->sclass = inode_mode_to_security_class(inode->i_mode);
rc = selinux_proc_get_sid(dentry, isec->sclass, &sid);
dput(dentry);
if (rc)
goto out_unlock;
isec->sid = sid;
}
break;
}
@@ -2291,7 +2310,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
int fd;
j++;
i = j * __NFDBITS;
i = j * BITS_PER_LONG;
fdt = files_fdtable(files);
if (i >= fdt->max_fds)
break;
@@ -3936,7 +3955,7 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
u32 nlbl_sid;
u32 nlbl_type;
selinux_skb_xfrm_sid(skb, &xfrm_sid);
selinux_xfrm_skb_sid(skb, &xfrm_sid);
selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid);
@@ -3950,6 +3969,30 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
return 0;
}
/**
* selinux_conn_sid - Determine the child socket label for a connection
* @sk_sid: the parent socket's SID
* @skb_sid: the packet's SID
* @conn_sid: the resulting connection SID
*
* If @skb_sid is valid then the user:role:type information from @sk_sid is
* combined with the MLS information from @skb_sid in order to create
* @conn_sid. If @skb_sid is not valid then then @conn_sid is simply a copy
* of @sk_sid. Returns zero on success, negative values on failure.
*
*/
static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid)
{
int err = 0;
if (skb_sid != SECSID_NULL)
err = security_sid_mls_copy(sk_sid, skb_sid, conn_sid);
else
*conn_sid = sk_sid;
return err;
}
/* socket security operations */
static int socket_sockcreate_sid(const struct task_security_struct *tsec,
@@ -4437,8 +4480,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
}
err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER,
PEER__RECV, &ad);
if (err)
if (err) {
selinux_netlbl_err(skb, err, 0);
return err;
}
}
if (secmark_active) {
@@ -4576,7 +4621,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
struct sk_security_struct *sksec = sk->sk_security;
int err;
u16 family = sk->sk_family;
u32 newsid;
u32 connsid;
u32 peersid;
/* handle mapped IPv4 packets arriving via IPv6 sockets */
@@ -4586,16 +4631,11 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
err = selinux_skb_peerlbl_sid(skb, family, &peersid);
if (err)
return err;
if (peersid == SECSID_NULL) {
req->secid = sksec->sid;
req->peer_secid = SECSID_NULL;
} else {
err = security_sid_mls_copy(sksec->sid, peersid, &newsid);
if (err)
return err;
req->secid = newsid;
req->peer_secid = peersid;
}
err = selinux_conn_sid(sksec->sid, peersid, &connsid);
if (err)
return err;
req->secid = connsid;
req->peer_secid = peersid;
return selinux_netlbl_inet_conn_request(req, family);
}
@@ -4831,6 +4871,7 @@ static unsigned int selinux_ipv6_forward(unsigned int hooknum,
static unsigned int selinux_ip_output(struct sk_buff *skb,
u16 family)
{
struct sock *sk;
u32 sid;
if (!netlbl_enabled())
@@ -4839,8 +4880,27 @@ static unsigned int selinux_ip_output(struct sk_buff *skb,
/* we do this in the LOCAL_OUT path and not the POST_ROUTING path
* because we want to make sure we apply the necessary labeling
* before IPsec is applied so we can leverage AH protection */
if (skb->sk) {
struct sk_security_struct *sksec = skb->sk->sk_security;
sk = skb->sk;
if (sk) {
struct sk_security_struct *sksec;
if (sk->sk_state == TCP_LISTEN)
/* if the socket is the listening state then this
* packet is a SYN-ACK packet which means it needs to
* be labeled based on the connection/request_sock and
* not the parent socket. unfortunately, we can't
* lookup the request_sock yet as it isn't queued on
* the parent socket until after the SYN-ACK is sent.
* the "solution" is to simply pass the packet as-is
* as any IP option based labeling should be copied
* from the initial connection request (in the IP
* layer). it is far from ideal, but until we get a
* security label in the packet itself this is the
* best we can do. */
return NF_ACCEPT;
/* standard practice, label using the parent socket */
sksec = sk->sk_security;
sid = sksec->sid;
} else
sid = SECINITSID_KERNEL;
@@ -4913,27 +4973,37 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
* as fast and as clean as possible. */
if (!selinux_policycap_netpeer)
return selinux_ip_postroute_compat(skb, ifindex, family);
secmark_active = selinux_secmark_enabled();
peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
if (!secmark_active && !peerlbl_active)
return NF_ACCEPT;
sk = skb->sk;
#ifdef CONFIG_XFRM
/* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
* packet transformation so allow the packet to pass without any checks
* since we'll have another chance to perform access control checks
* when the packet is on it's final way out.
* NOTE: there appear to be some IPv6 multicast cases where skb->dst
* is NULL, in this case go ahead and apply access control. */
if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL)
* is NULL, in this case go ahead and apply access control.
* is NULL, in this case go ahead and apply access control.
* NOTE: if this is a local socket (skb->sk != NULL) that is in the
* TCP listening state we cannot wait until the XFRM processing
* is done as we will miss out on the SA label if we do;
* unfortunately, this means more work, but it is only once per
* connection. */
if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
!(sk != NULL && sk->sk_state == TCP_LISTEN))
return NF_ACCEPT;
#endif
secmark_active = selinux_secmark_enabled();
peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
if (!secmark_active && !peerlbl_active)
return NF_ACCEPT;
/* if the packet is being forwarded then get the peer label from the
* packet itself; otherwise check to see if it is from a local
* application or the kernel, if from an application get the peer label
* from the sending socket, otherwise use the kernel's sid */
sk = skb->sk;
if (sk == NULL) {
/* Without an associated socket the packet is either coming
* from the kernel or it is being forwarded; check the packet
* to determine which and if the packet is being forwarded
* query the packet directly to determine the security label. */
if (skb->skb_iif) {
secmark_perm = PACKET__FORWARD_OUT;
if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
@@ -4942,7 +5012,45 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
secmark_perm = PACKET__SEND;
peer_sid = SECINITSID_KERNEL;
}
} else if (sk->sk_state == TCP_LISTEN) {
/* Locally generated packet but the associated socket is in the
* listening state which means this is a SYN-ACK packet. In
* this particular case the correct security label is assigned
* to the connection/request_sock but unfortunately we can't
* query the request_sock as it isn't queued on the parent
* socket until after the SYN-ACK packet is sent; the only
* viable choice is to regenerate the label like we do in
* selinux_inet_conn_request(). See also selinux_ip_output()
* for similar problems. */
u32 skb_sid;
struct sk_security_struct *sksec = sk->sk_security;
if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
return NF_DROP;
/* At this point, if the returned skb peerlbl is SECSID_NULL
* and the packet has been through at least one XFRM
* transformation then we must be dealing with the "final"
* form of labeled IPsec packet; since we've already applied
* all of our access controls on this packet we can safely
* pass the packet. */
if (skb_sid == SECSID_NULL) {
switch (family) {
case PF_INET:
if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
return NF_ACCEPT;
break;
case PF_INET6:
if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
return NF_ACCEPT;
default:
return NF_DROP_ERR(-ECONNREFUSED);
}
}
if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
return NF_DROP;
secmark_perm = PACKET__SEND;
} else {
/* Locally generated packet, fetch the security label from the
* associated socket. */
struct sk_security_struct *sksec = sk->sk_security;
peer_sid = sksec->sid;
secmark_perm = PACKET__SEND;
@@ -5610,11 +5718,11 @@ static int selinux_setprocattr(struct task_struct *p,
/* Check for ptracing, and update the task SID if ok.
Otherwise, leave SID unchanged and fail. */
ptsid = 0;
task_lock(p);
rcu_read_lock();
tracer = ptrace_parent(p);
if (tracer)
ptsid = task_sid(tracer);
task_unlock(p);
rcu_read_unlock();
if (tracer) {
error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS,
+2 -2
View File
@@ -38,10 +38,10 @@ struct task_security_struct {
struct inode_security_struct {
struct inode *inode; /* back pointer to inode object */
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 */
+7 -6
View File
@@ -47,6 +47,7 @@ int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb,
int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
struct common_audit_data *ad, u8 proto);
int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid);
static inline void selinux_xfrm_notify_policyload(void)
{
@@ -79,12 +80,12 @@ static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int
static inline void selinux_xfrm_notify_policyload(void)
{
}
static inline int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
{
*sid = SECSID_NULL;
return 0;
}
#endif
static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid)
{
int err = selinux_xfrm_decode_session(skb, sid, 0);
BUG_ON(err);
}
#endif /* _SELINUX_XFRM_H_ */
+2 -4
View File
@@ -442,8 +442,7 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
sksec->nlbl_state != NLBL_CONNLABELED)
return 0;
local_bh_disable();
bh_lock_sock_nested(sk);
lock_sock(sk);
/* connected sockets are allowed to disconnect when the address family
* is set to AF_UNSPEC, if that is what is happening we want to reset
@@ -464,7 +463,6 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
sksec->nlbl_state = NLBL_CONNLABELED;
socket_connect_return:
bh_unlock_sock(sk);
local_bh_enable();
release_sock(sk);
return rc;
}
+2 -1
View File
@@ -174,7 +174,8 @@ static void sel_netnode_insert(struct sel_netnode *node)
if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) {
struct sel_netnode *tail;
tail = list_entry(
rcu_dereference(sel_netnode_hash[idx].list.prev),
rcu_dereference_protected(sel_netnode_hash[idx].list.prev,
lockdep_is_held(&sel_netnode_lock)),
struct sel_netnode, list);
list_del_rcu(&tail->list);
kfree_rcu(tail, rcu);
+6
View File
@@ -103,6 +103,12 @@ static struct nlmsg_perm nlmsg_xfrm_perms[] =
{ XFRM_MSG_FLUSHPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
{ XFRM_MSG_NEWAE, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
{ XFRM_MSG_GETAE, NETLINK_XFRM_SOCKET__NLMSG_READ },
{ XFRM_MSG_REPORT, NETLINK_XFRM_SOCKET__NLMSG_READ },
{ XFRM_MSG_MIGRATE, NETLINK_XFRM_SOCKET__NLMSG_WRITE },
{ XFRM_MSG_NEWSADINFO, NETLINK_XFRM_SOCKET__NLMSG_READ },
{ XFRM_MSG_GETSADINFO, NETLINK_XFRM_SOCKET__NLMSG_READ },
{ XFRM_MSG_GETSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_READ },
{ XFRM_MSG_MAPPING, NETLINK_XFRM_SOCKET__NLMSG_READ },
};
static struct nlmsg_perm nlmsg_audit_perms[] =
+5 -4
View File
@@ -158,7 +158,7 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
goto out;
/* No partial writes. */
length = EINVAL;
length = -EINVAL;
if (*ppos != 0)
goto out;
@@ -1221,7 +1221,7 @@ static void sel_remove_entries(struct dentry *de)
spin_lock(&de->d_lock);
node = de->d_subdirs.next;
while (node != &de->d_subdirs) {
struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
struct dentry *d = list_entry(node, struct dentry, d_child);
spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
list_del_init(node);
@@ -1262,6 +1262,7 @@ static int sel_make_bools(void)
kfree(bool_pending_names[i]);
kfree(bool_pending_names);
kfree(bool_pending_values);
bool_num = 0;
bool_pending_names = NULL;
bool_pending_values = NULL;
@@ -1723,12 +1724,12 @@ static void sel_remove_classes(void)
list_for_each(class_node, &class_dir->d_subdirs) {
struct dentry *class_subdir = list_entry(class_node,
struct dentry, d_u.d_child);
struct dentry, d_child);
struct list_head *class_subdir_node;
list_for_each(class_subdir_node, &class_subdir->d_subdirs) {
struct dentry *d = list_entry(class_subdir_node,
struct dentry, d_u.d_child);
struct dentry, d_child);
if (d->d_inode)
if (d->d_inode->i_mode & S_IFDIR)
+17 -5
View File
@@ -2000,7 +2000,19 @@ static int filename_trans_read(struct policydb *p, void *fp)
if (rc)
goto out;
hashtab_insert(p->filename_trans, ft, otype);
rc = hashtab_insert(p->filename_trans, ft, otype);
if (rc) {
/*
* Do not return -EEXIST to the caller, or the system
* will not boot.
*/
if (rc != -EEXIST)
goto out;
/* But free memory to avoid memory leak. */
kfree(ft);
kfree(name);
kfree(otype);
}
}
hash_eval(p->filename_trans, "filenametr");
return 0;
@@ -3329,10 +3341,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)
+43 -12
View File
@@ -152,21 +152,13 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
return rc;
}
/*
* LSM hook implementation that checks and/or returns the xfrm sid for the
* incoming packet.
*/
int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb,
u32 *sid, int ckall)
{
struct sec_path *sp;
struct sec_path *sp = skb->sp;
*sid = SECSID_NULL;
if (skb == NULL)
return 0;
sp = skb->sp;
if (sp) {
int i, sid_set = 0;
@@ -190,6 +182,45 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
return 0;
}
static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
struct xfrm_state *x;
if (dst == NULL)
return SECSID_NULL;
x = dst->xfrm;
if (x == NULL || !selinux_authorizable_xfrm(x))
return SECSID_NULL;
return x->security->ctx_sid;
}
/*
* LSM hook implementation that checks and/or returns the xfrm sid for the
* incoming packet.
*/
int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
{
if (skb == NULL) {
*sid = SECSID_NULL;
return 0;
}
return selinux_xfrm_skb_sid_ingress(skb, sid, ckall);
}
int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
{
int rc;
rc = selinux_xfrm_skb_sid_ingress(skb, sid, 0);
if (rc == 0 && *sid == SECSID_NULL)
*sid = selinux_xfrm_skb_sid_egress(skb);
return rc;
}
/*
* Security blob allocation for xfrm_policy and xfrm_state
* CTX does not have a meaningful value on input
@@ -310,7 +341,7 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
if (old_ctx) {
new_ctx = kmalloc(sizeof(*old_ctx) + old_ctx->ctx_len,
GFP_KERNEL);
GFP_ATOMIC);
if (!new_ctx)
return -ENOMEM;
+10
View File
@@ -298,6 +298,16 @@ static inline char *smk_of_current(void)
return smk_of_task(current_security());
}
static inline char *smk_of_task_struct(const struct task_struct *t)
{
char *skp;
rcu_read_lock();
skp = smk_of_task(__task_cred(t)->security);
rcu_read_unlock();
return skp;
}
/*
* logging functions
*/
+13 -11
View File
@@ -41,8 +41,6 @@
#include <linux/binfmts.h>
#include "smack.h"
#define task_security(task) (task_cred_xxx((task), security))
#define TRANS_TRUE "TRUE"
#define TRANS_TRUE_SIZE 4
@@ -164,7 +162,7 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
if (rc != 0)
return rc;
tsp = smk_of_task(task_security(ctp));
tsp = smk_of_task_struct(ctp);
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
smk_ad_setfield_u_tsk(&ad, ctp);
@@ -190,7 +188,7 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
if (rc != 0)
return rc;
tsp = smk_of_task(task_security(ptp));
tsp = smk_of_task_struct(ptp);
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
smk_ad_setfield_u_tsk(&ad, ptp);
@@ -1518,7 +1516,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access,
smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
smk_ad_setfield_u_tsk(&ad, p);
return smk_curacc(smk_of_task(task_security(p)), access, &ad);
return smk_curacc(smk_of_task_struct(p), access, &ad);
}
/**
@@ -1564,7 +1562,7 @@ static int smack_task_getsid(struct task_struct *p)
*/
static void smack_task_getsecid(struct task_struct *p, u32 *secid)
{
*secid = smack_to_secid(smk_of_task(task_security(p)));
*secid = smack_to_secid(smk_of_task_struct(p));
}
/**
@@ -1676,7 +1674,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
* can write the receiver.
*/
if (secid == 0)
return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE,
return smk_curacc(smk_of_task_struct(p), MAY_WRITE,
&ad);
/*
* If the secid isn't 0 we're dealing with some USB IO
@@ -1684,7 +1682,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
* we can't take privilege into account.
*/
return smk_access(smack_from_secid(secid),
smk_of_task(task_security(p)), MAY_WRITE, &ad);
smk_of_task_struct(p), MAY_WRITE, &ad);
}
/**
@@ -1697,9 +1695,13 @@ static int smack_task_wait(struct task_struct *p)
{
struct smk_audit_info ad;
char *sp = smk_of_current();
char *tsp = smk_of_forked(task_security(p));
char *tsp;
int rc;
rcu_read_lock();
tsp = smk_of_forked(__task_cred(p)->security);
rcu_read_unlock();
/* we don't log here, we can be overriden */
rc = smk_access(tsp, sp, MAY_WRITE, NULL);
if (rc == 0)
@@ -1736,7 +1738,7 @@ static int smack_task_wait(struct task_struct *p)
static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
{
struct inode_smack *isp = inode->i_security;
isp->smk_inode = smk_of_task(task_security(p));
isp->smk_inode = smk_of_task_struct(p);
}
/*
@@ -2719,7 +2721,7 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value)
if (strcmp(name, "current") != 0)
return -EINVAL;
cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL);
cp = kstrdup(smk_of_task_struct(p), GFP_KERNEL);
if (cp == NULL)
return -ENOMEM;
+1 -1
View File
@@ -138,7 +138,7 @@ static int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
if (arg2 == 0) {
yama_ptracer_del(NULL, myself);
rc = 0;
} else if (arg2 == PR_SET_PTRACER_ANY) {
} else if (arg2 == PR_SET_PTRACER_ANY || (int)arg2 == -1) {
rc = yama_ptracer_add(NULL, myself);
} else {
struct task_struct *tracer;