Commit 39e16d93 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'selinux-pr-20200430' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

Pull SELinux fixes from Paul Moore:
 "Two more SELinux patches to fix problems in the v5.7-rcX releases.

  Wei Yongjun's patch fixes a return code in an error path, and my patch
  fixes a problem where we were not correctly applying access controls
  to all of the netlink messages in the netlink_send LSM hook"

* tag 'selinux-pr-20200430' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: properly handle multiple messages in selinux_netlink_send()
  selinux: fix error return code in cond_read_list()
parents 0468915b fb739741
...@@ -5842,40 +5842,60 @@ static unsigned int selinux_ipv6_postroute(void *priv, ...@@ -5842,40 +5842,60 @@ static unsigned int selinux_ipv6_postroute(void *priv,
static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
{ {
int err = 0; int rc = 0;
u32 perm; unsigned int msg_len;
unsigned int data_len = skb->len;
unsigned char *data = skb->data;
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
struct sk_security_struct *sksec = sk->sk_security; struct sk_security_struct *sksec = sk->sk_security;
u16 sclass = sksec->sclass;
u32 perm;
if (skb->len < NLMSG_HDRLEN) { while (data_len >= nlmsg_total_size(0)) {
err = -EINVAL; nlh = (struct nlmsghdr *)data;
goto out;
} /* NOTE: the nlmsg_len field isn't reliably set by some netlink
nlh = nlmsg_hdr(skb); * users which means we can't reject skb's with bogus
* length fields; our solution is to follow what
* netlink_rcv_skb() does and simply skip processing at
* messages with length fields that are clearly junk
*/
if (nlh->nlmsg_len < NLMSG_HDRLEN || nlh->nlmsg_len > data_len)
return 0;
err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm); rc = selinux_nlmsg_lookup(sclass, nlh->nlmsg_type, &perm);
if (err) { if (rc == 0) {
if (err == -EINVAL) { rc = sock_has_perm(sk, perm);
if (rc)
return rc;
} else if (rc == -EINVAL) {
/* -EINVAL is a missing msg/perm mapping */
pr_warn_ratelimited("SELinux: unrecognized netlink" pr_warn_ratelimited("SELinux: unrecognized netlink"
" message: protocol=%hu nlmsg_type=%hu sclass=%s" " message: protocol=%hu nlmsg_type=%hu sclass=%s"
" pid=%d comm=%s\n", " pid=%d comm=%s\n",
sk->sk_protocol, nlh->nlmsg_type, sk->sk_protocol, nlh->nlmsg_type,
secclass_map[sksec->sclass - 1].name, secclass_map[sclass - 1].name,
task_pid_nr(current), current->comm); task_pid_nr(current), current->comm);
if (!enforcing_enabled(&selinux_state) || if (enforcing_enabled(&selinux_state) &&
security_get_allow_unknown(&selinux_state)) !security_get_allow_unknown(&selinux_state))
err = 0; return rc;
rc = 0;
} else if (rc == -ENOENT) {
/* -ENOENT is a missing socket/class mapping, ignore */
rc = 0;
} else {
return rc;
} }
/* Ignore */ /* move to the next message after applying netlink padding */
if (err == -ENOENT) msg_len = NLMSG_ALIGN(nlh->nlmsg_len);
err = 0; if (msg_len >= data_len)
goto out; return 0;
data_len -= msg_len;
data += msg_len;
} }
err = sock_has_perm(sk, perm); return rc;
out:
return err;
} }
static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass) static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass)
......
...@@ -429,7 +429,7 @@ int cond_read_list(struct policydb *p, void *fp) ...@@ -429,7 +429,7 @@ int cond_read_list(struct policydb *p, void *fp)
p->cond_list = kcalloc(len, sizeof(*p->cond_list), GFP_KERNEL); p->cond_list = kcalloc(len, sizeof(*p->cond_list), GFP_KERNEL);
if (!p->cond_list) if (!p->cond_list)
return rc; return -ENOMEM;
rc = avtab_alloc(&(p->te_cond_avtab), p->te_avtab.nel); rc = avtab_alloc(&(p->te_cond_avtab), p->te_avtab.nel);
if (rc) if (rc)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment