From 616a7e9dcc1d21dbc5e0025296edd8beaa6fdb8b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 4 May 2020 17:52:41 +0200 Subject: [PATCH] 4.19-stable patches added patches: selinux-properly-handle-multiple-messages-in-selinux_netlink_send.patch --- ...ple-messages-in-selinux_netlink_send.patch | 112 ++++++++++++++++++ queue-4.19/series | 1 + 2 files changed, 113 insertions(+) create mode 100644 queue-4.19/selinux-properly-handle-multiple-messages-in-selinux_netlink_send.patch diff --git a/queue-4.19/selinux-properly-handle-multiple-messages-in-selinux_netlink_send.patch b/queue-4.19/selinux-properly-handle-multiple-messages-in-selinux_netlink_send.patch new file mode 100644 index 00000000000..03ec3b51d11 --- /dev/null +++ b/queue-4.19/selinux-properly-handle-multiple-messages-in-selinux_netlink_send.patch @@ -0,0 +1,112 @@ +From fb73974172ffaaf57a7c42f35424d9aece1a5af6 Mon Sep 17 00:00:00 2001 +From: Paul Moore +Date: Tue, 28 Apr 2020 09:59:02 -0400 +Subject: selinux: properly handle multiple messages in selinux_netlink_send() + +From: Paul Moore + +commit fb73974172ffaaf57a7c42f35424d9aece1a5af6 upstream. + +Fix the SELinux netlink_send hook to properly handle multiple netlink +messages in a single sk_buff; each message is parsed and subject to +SELinux access control. Prior to this patch, SELinux only inspected +the first message in the sk_buff. + +Cc: stable@vger.kernel.org +Reported-by: Dmitry Vyukov +Reviewed-by: Stephen Smalley +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + security/selinux/hooks.c | 70 ++++++++++++++++++++++++++++++----------------- + 1 file changed, 45 insertions(+), 25 deletions(-) + +--- a/security/selinux/hooks.c ++++ b/security/selinux/hooks.c +@@ -5595,40 +5595,60 @@ static int selinux_tun_dev_open(void *se + + static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) + { +- int err = 0; +- u32 perm; ++ int rc = 0; ++ unsigned int msg_len; ++ unsigned int data_len = skb->len; ++ unsigned char *data = skb->data; + struct nlmsghdr *nlh; + struct sk_security_struct *sksec = sk->sk_security; ++ u16 sclass = sksec->sclass; ++ u32 perm; + +- if (skb->len < NLMSG_HDRLEN) { +- err = -EINVAL; +- goto out; +- } +- nlh = nlmsg_hdr(skb); ++ while (data_len >= nlmsg_total_size(0)) { ++ nlh = (struct nlmsghdr *)data; + +- err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm); +- if (err) { +- if (err == -EINVAL) { ++ /* NOTE: the nlmsg_len field isn't reliably set by some netlink ++ * 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; ++ ++ rc = selinux_nlmsg_lookup(sclass, nlh->nlmsg_type, &perm); ++ if (rc == 0) { ++ 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" +- " message: protocol=%hu nlmsg_type=%hu sclass=%s" +- " pig=%d comm=%s\n", +- sk->sk_protocol, nlh->nlmsg_type, +- secclass_map[sksec->sclass - 1].name, +- task_pid_nr(current), current->comm); +- if (!enforcing_enabled(&selinux_state) || +- security_get_allow_unknown(&selinux_state)) +- err = 0; ++ " message: protocol=%hu nlmsg_type=%hu sclass=%s" ++ " pid=%d comm=%s\n", ++ sk->sk_protocol, nlh->nlmsg_type, ++ secclass_map[sclass - 1].name, ++ task_pid_nr(current), current->comm); ++ if (enforcing_enabled(&selinux_state) && ++ !security_get_allow_unknown(&selinux_state)) ++ return rc; ++ rc = 0; ++ } else if (rc == -ENOENT) { ++ /* -ENOENT is a missing socket/class mapping, ignore */ ++ rc = 0; ++ } else { ++ return rc; + } + +- /* Ignore */ +- if (err == -ENOENT) +- err = 0; +- goto out; ++ /* move to the next message after applying netlink padding */ ++ msg_len = NLMSG_ALIGN(nlh->nlmsg_len); ++ if (msg_len >= data_len) ++ return 0; ++ data_len -= msg_len; ++ data += msg_len; + } + +- err = sock_has_perm(sk, perm); +-out: +- return err; ++ return rc; + } + + #ifdef CONFIG_NETFILTER diff --git a/queue-4.19/series b/queue-4.19/series index f83bd5f5f09..35894086930 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -26,6 +26,7 @@ iommu-amd-fix-legacy-interrupt-remapping-for-x2apic-enabled-system.patch alsa-opti9xx-shut-up-gcc-10-range-warning.patch nfs-fix-potential-posix_acl-refcnt-leak-in-nfs3_set_acl.patch dmaengine-dmatest-fix-iteration-non-stop-logic.patch +selinux-properly-handle-multiple-messages-in-selinux_netlink_send.patch btrfs-fix-partial-loss-of-prealloc-extent-past-i_size-after-fsync.patch btrfs-transaction-avoid-deadlock-due-to-bad-initialization-timing-of-fs_info-journal_info.patch mmc-cqhci-avoid-false-cqhci-cqe-stuck-on-by-not-open-coding-timeout-loop.patch -- 2.47.3