Skip to content

Commit 39e16d9

Browse files
committed
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()
2 parents 0468915 + fb73974 commit 39e16d9

File tree

2 files changed

+46
-26
lines changed

2 files changed

+46
-26
lines changed

security/selinux/hooks.c

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5842,40 +5842,60 @@ static unsigned int selinux_ipv6_postroute(void *priv,
58425842

58435843
static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
58445844
{
5845-
int err = 0;
5846-
u32 perm;
5845+
int rc = 0;
5846+
unsigned int msg_len;
5847+
unsigned int data_len = skb->len;
5848+
unsigned char *data = skb->data;
58475849
struct nlmsghdr *nlh;
58485850
struct sk_security_struct *sksec = sk->sk_security;
5851+
u16 sclass = sksec->sclass;
5852+
u32 perm;
58495853

5850-
if (skb->len < NLMSG_HDRLEN) {
5851-
err = -EINVAL;
5852-
goto out;
5853-
}
5854-
nlh = nlmsg_hdr(skb);
5854+
while (data_len >= nlmsg_total_size(0)) {
5855+
nlh = (struct nlmsghdr *)data;
5856+
5857+
/* NOTE: the nlmsg_len field isn't reliably set by some netlink
5858+
* users which means we can't reject skb's with bogus
5859+
* length fields; our solution is to follow what
5860+
* netlink_rcv_skb() does and simply skip processing at
5861+
* messages with length fields that are clearly junk
5862+
*/
5863+
if (nlh->nlmsg_len < NLMSG_HDRLEN || nlh->nlmsg_len > data_len)
5864+
return 0;
58555865

5856-
err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
5857-
if (err) {
5858-
if (err == -EINVAL) {
5866+
rc = selinux_nlmsg_lookup(sclass, nlh->nlmsg_type, &perm);
5867+
if (rc == 0) {
5868+
rc = sock_has_perm(sk, perm);
5869+
if (rc)
5870+
return rc;
5871+
} else if (rc == -EINVAL) {
5872+
/* -EINVAL is a missing msg/perm mapping */
58595873
pr_warn_ratelimited("SELinux: unrecognized netlink"
5860-
" message: protocol=%hu nlmsg_type=%hu sclass=%s"
5861-
" pid=%d comm=%s\n",
5862-
sk->sk_protocol, nlh->nlmsg_type,
5863-
secclass_map[sksec->sclass - 1].name,
5864-
task_pid_nr(current), current->comm);
5865-
if (!enforcing_enabled(&selinux_state) ||
5866-
security_get_allow_unknown(&selinux_state))
5867-
err = 0;
5874+
" message: protocol=%hu nlmsg_type=%hu sclass=%s"
5875+
" pid=%d comm=%s\n",
5876+
sk->sk_protocol, nlh->nlmsg_type,
5877+
secclass_map[sclass - 1].name,
5878+
task_pid_nr(current), current->comm);
5879+
if (enforcing_enabled(&selinux_state) &&
5880+
!security_get_allow_unknown(&selinux_state))
5881+
return rc;
5882+
rc = 0;
5883+
} else if (rc == -ENOENT) {
5884+
/* -ENOENT is a missing socket/class mapping, ignore */
5885+
rc = 0;
5886+
} else {
5887+
return rc;
58685888
}
58695889

5870-
/* Ignore */
5871-
if (err == -ENOENT)
5872-
err = 0;
5873-
goto out;
5890+
/* move to the next message after applying netlink padding */
5891+
msg_len = NLMSG_ALIGN(nlh->nlmsg_len);
5892+
if (msg_len >= data_len)
5893+
return 0;
5894+
data_len -= msg_len;
5895+
data += msg_len;
58745896
}
58755897

5876-
err = sock_has_perm(sk, perm);
5877-
out:
5878-
return err;
5898+
return rc;
58795899
}
58805900

58815901
static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass)

security/selinux/ss/conditional.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ int cond_read_list(struct policydb *p, void *fp)
429429

430430
p->cond_list = kcalloc(len, sizeof(*p->cond_list), GFP_KERNEL);
431431
if (!p->cond_list)
432-
return rc;
432+
return -ENOMEM;
433433

434434
rc = avtab_alloc(&(p->te_cond_avtab), p->te_avtab.nel);
435435
if (rc)

0 commit comments

Comments
 (0)