Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp3871892ybz; Mon, 4 May 2020 11:14:56 -0700 (PDT) X-Google-Smtp-Source: APiQypKZkX1N2vzqQgT/kDZ8ashCgBIBp7+JcYRVyruzMwrDrKlROAM1Lik8ZW8Rp4kKUVBPTjQG X-Received: by 2002:a50:e68e:: with SMTP id z14mr16240695edm.307.1588616096749; Mon, 04 May 2020 11:14:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588616096; cv=none; d=google.com; s=arc-20160816; b=zkxSY/3SE0gBov32SDHn8cODs0GMPE8ozc/XNWH6NL2c0jO0+1zMWMHfJjgGUjQ9fr szWUA3Dnqgp8tPfTiUQDzQzmk/Ht9uw9fkwu1QNQK0iQAFdaKTb4iNg/pBs423NOdSdj +AkTT1QhCmK7Go/jitPc3eYUaxfSZ1DCTwby5pDe0hCrPCKpVhy8kSrx15OuNtjyRrVb Fj9o+b39nRTBTaNaXzibyd8Vijn27A5WSavDqI7QcOHGOFksTSMmyynGQl9Hf9lVNwCH ljvfJhCSrT0Hj/Nkjg/ub/ZhQT3FfEz05Mx+zJPJ6V9hWEgmo+h8roYsneUBLveVZyOr OOhg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=W4QZSC9IsDU4bbk9hNqr1VAxhnZNldA7FqEldh7d05Y=; b=qPPQ4LoDyoRERVIY4kFBb89sDxAwQJx7kGba9BkcFKukwW5MViFFJPJQFRBG74rpOf 0F6wsl5Yj36Ppz/e8ZJyp/nMqKrNFrLn+9/Whd0Po6TLqiD9lI3JEyqvswnVIbragaDV MiqTk8f6DBoPJjFepeTLTy458eeFAdKfoTZERq1KIvk2TQ7psKEXh3yeGnkgS9gQEPlK nwxuNETS6Ya3ruONK4ofTZHCCS8ufo4zSGUnUVR9mU6Ako72hg5aEnEnuzr75PI7Dlye 9mtaGHMUzZKY/M6gqpTdTpinQILHRg2QaS1LFM9QMmiQ4uJo4iQrLHs0O9ZQvGj3s/pN x/FQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=ArToTF0y; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bc23si7003379edb.241.2020.05.04.11.14.32; Mon, 04 May 2020 11:14:56 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=ArToTF0y; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731931AbgEDSJy (ORCPT + 99 others); Mon, 4 May 2020 14:09:54 -0400 Received: from mail.kernel.org ([198.145.29.99]:36288 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731910AbgEDSGI (ORCPT ); Mon, 4 May 2020 14:06:08 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 23DA1205ED; Mon, 4 May 2020 18:06:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1588615567; bh=E4u7xH45/jlO1EBws73tdhHlwPB/QyI0cMl8bdPV9Uw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ArToTF0yiuO7b+Nn7DHEOxOpchcJm5oaovOGszMt3nFjlRSHFqUeSMiKsteEec4kv t+9F314s0MpisiFI/oHQcXLcKkx44BVFkSQdRSf0eu2K2e5zghXS5E7+Hl7ncPcj2E 3P6u3AyJd2Uw6ZK1g7zyGE7elFTKC/y9sJIW5B0o= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Dmitry Vyukov , Stephen Smalley , Paul Moore Subject: [PATCH 5.6 32/73] selinux: properly handle multiple messages in selinux_netlink_send() Date: Mon, 4 May 2020 19:57:35 +0200 Message-Id: <20200504165507.399686778@linuxfoundation.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200504165501.781878940@linuxfoundation.org> References: <20200504165501.781878940@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 @@ -5829,40 +5829,60 @@ static unsigned int selinux_ipv6_postrou static int selinux_netlink_send(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" - " pid=%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; } static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass)