Received: by 2002:a05:6a10:1a4d:0:0:0:0 with SMTP id nk13csp4878237pxb; Sat, 12 Feb 2022 23:42:28 -0800 (PST) X-Google-Smtp-Source: ABdhPJxaHt1iAZypTItIvw/EVbWKAKFIDJFAQttdbS5BsA6tIgZ9qplpFVWsMGQ3RHWZMqaB97il X-Received: by 2002:a17:907:60cb:: with SMTP id hv11mr6984977ejc.122.1644738148598; Sat, 12 Feb 2022 23:42:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1644738148; cv=none; d=google.com; s=arc-20160816; b=evFUCXu/BR93zGdPnlqnr/zFB/W+59XdflqppEpRrlRzaXYW9lIPw/pOR03pGQtfNJ CnhbQsTFCS+fgsladoQwe8L/56KKhFRP7TD2wuyh4UXWndNHQtwDKaGcSdweHkfR0DWq nesEP6cATkkIW53/eB8w/xIO05Xfsvggw9hoqFvUfvRXszbL2FWYQafjtVVNhlaKcXAC zHUIAS9EWhpNMlzLEATR+YnrOlyClhtmtLzaInncy3/PRNunHuO0VWncfJRb57YSwGgc 7LQtw2Qh7UfBGujza5SNROL/xUd63eY+gLMiIQlXK0a8NV8CAvr+2geE2Td1Odt/zs9U fw4A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=K5RblU/muR32surpJb7XXaw9mmDJULWUJNTXUxoEyEQ=; b=qU5Hr7n8keqmOk+dznCEc2pITl+MOvdbwonLBdWzCGd+rI2wjzOk7sBm18eFG2d8JY njTkbApYnaFvUCtD9sq+6FDNtTnrHs3vlWxXhv5kYlYHeIH5C1l3cq82kWVowht9iXxp CSd26Cy0OOpcBDRSJW0MurIK/txFfIRU1x0unyKGWQ+CLpREsNUb+bqeGEqW2BEmjJPC sS4FlxSVNLiEjwe5+ammUVO64/Z5ik7ALYFK+5C4RFN6Sol596t4U2ibsAvFY8DMuRBS sZZ6DALx26Vx9WabQSeILY0oGr1ESYMjWe8aSD9tjUFX2KjxCSxE2yIeL8WaGcDg4MKn vJ9Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="KiVjzx6/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id co7si11534773edb.187.2022.02.12.23.42.05; Sat, 12 Feb 2022 23:42:28 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="KiVjzx6/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231865AbiBLR7k (ORCPT + 99 others); Sat, 12 Feb 2022 12:59:40 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:37906 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230183AbiBLR7f (ORCPT ); Sat, 12 Feb 2022 12:59:35 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 1A8CE2E0A6 for ; Sat, 12 Feb 2022 09:59:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1644688770; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=K5RblU/muR32surpJb7XXaw9mmDJULWUJNTXUxoEyEQ=; b=KiVjzx6/7IqPjB8zZD00Y8GlXUCp2XlPxFS6G12H1uU3WabNyjRA6jBV+Y45JcV5rXu9K9 HlLylWn8WiMLcLlVZbMBzEJZQq79lcBMBY2jA2l5GgA/4FZU6nyQQEvM0QGF/sy4X9Xbta kJ39Sh8LcFxsKZ322wMRyZTN9lDW2II= Received: from mail-ed1-f69.google.com (mail-ed1-f69.google.com [209.85.208.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-155-xdJHkzsuMLqj1FjZaBqbWA-1; Sat, 12 Feb 2022 12:59:29 -0500 X-MC-Unique: xdJHkzsuMLqj1FjZaBqbWA-1 Received: by mail-ed1-f69.google.com with SMTP id j10-20020a05640211ca00b004090fd8a936so2787997edw.23 for ; Sat, 12 Feb 2022 09:59:28 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=K5RblU/muR32surpJb7XXaw9mmDJULWUJNTXUxoEyEQ=; b=GqHmMH0NdDv13qsJRZb/DV6GjJjrrbnDhWkwuA1kLdccWvEpPulMZdmYtCPmtJjt1e vBi84ZkcSv6E61WTzYgAnGxAexnxlmWwaHxxnlWnT0k4wkhjhEsL3WLRiySKpzIkZO3N 0Bs4niagsVBgFeKzCinu525r0nDacBatF2Z3zhdkxuCW+c++sW+ZDijuDmfsQ+nIBDGK +5DiLDuAi/P1KOM406r9Xsbjdfbum3URTZvi2Z/Jv+yJ1f1ELQLGw+HzkkKaZ03uQgvX bqkX/91CC2+p+WP+oa84mp6me7XdNykCmil0nru4hKQ6Yf8wVwp2ZcbatADRHax7R0Z8 ld8w== X-Gm-Message-State: AOAM531EhABoKZ25PGljWfafOk6eNBUOAc481GG4ak6a72gpWpnyxsS4 w8HIougVJEvEjkr6YZ+Xo1T/FAmGUGJQJHxV+XfyJ6V9fg5e1J0bbGoAUAwwgUgtWX8WcjXthvY 8kIHlF2DJXYQUy4utUb9s7Dap X-Received: by 2002:a17:906:72c2:: with SMTP id m2mr5408240ejl.185.1644688767798; Sat, 12 Feb 2022 09:59:27 -0800 (PST) X-Received: by 2002:a17:906:72c2:: with SMTP id m2mr5408220ejl.185.1644688767482; Sat, 12 Feb 2022 09:59:27 -0800 (PST) Received: from localhost.localdomain ([2a02:8308:b106:e300:32b0:6ebb:8ca4:d4d3]) by smtp.gmail.com with ESMTPSA id d10sm437409ejo.207.2022.02.12.09.59.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Feb 2022 09:59:27 -0800 (PST) From: Ondrej Mosnacek To: netdev@vger.kernel.org, davem@davemloft.net, kuba@kernel.org, selinux@vger.kernel.org, Paul Moore Cc: Xin Long , Richard Haines , Vlad Yasevich , Neil Horman , Marcelo Ricardo Leitner , linux-sctp@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, Prashanth Prahlad Subject: [PATCH net v3 2/2] security: implement sctp_assoc_established hook in selinux Date: Sat, 12 Feb 2022 18:59:22 +0100 Message-Id: <20220212175922.665442-3-omosnace@redhat.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220212175922.665442-1-omosnace@redhat.com> References: <20220212175922.665442-1-omosnace@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Do this by extracting the peer labeling per-association logic from selinux_sctp_assoc_request() into a new helper selinux_sctp_process_new_assoc() and use this helper in both selinux_sctp_assoc_request() and selinux_sctp_assoc_established(). This ensures that the peer labeling behavior as documented in Documentation/security/SCTP.rst is applied both on the client and server side: """ An SCTP socket will only have one peer label assigned to it. This will be assigned during the establishment of the first association. Any further associations on this socket will have their packet peer label compared to the sockets peer label, and only if they are different will the ``association`` permission be validated. This is validated by checking the socket peer sid against the received packets peer sid to determine whether the association should be allowed or denied. """ At the same time, it also ensures that the peer label of the association is set to the correct value, such that if it is peeled off into a new socket, the socket's peer label will then be set to the association's peer label, same as it already works on the server side. While selinux_inet_conn_established() (which we are replacing by selinux_sctp_assoc_established() for SCTP) only deals with assigning a peer label to the connection (socket), in case of SCTP we need to also copy the (local) socket label to the association, so that selinux_sctp_sk_clone() can then pick it up for the new socket in case of SCTP peeloff. Careful readers will notice that the selinux_sctp_process_new_assoc() helper also includes the "IPv4 packet received over an IPv6 socket" check, even though it hadn't been in selinux_sctp_assoc_request() before. While such check is not necessary in selinux_inet_conn_request() (because struct request_sock's family field is already set according to the skb's family), here it is needed, as we don't have request_sock and we take the initial family from the socket. In selinux_sctp_assoc_established() it is similarly needed as well (and also selinux_inet_conn_established() already has it). Fixes: 72e89f50084c ("security: Add support for SCTP security hooks") Reported-by: Prashanth Prahlad Based-on-patch-by: Xin Long Signed-off-by: Ondrej Mosnacek --- security/selinux/hooks.c | 90 +++++++++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 24 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ab32303e6618..dafabb4dcc64 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -5238,37 +5238,38 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent) sksec->sclass = isec->sclass; } -/* Called whenever SCTP receives an INIT chunk. This happens when an incoming - * connect(2), sctp_connectx(3) or sctp_sendmsg(3) (with no association - * already present). +/* + * Determines peer_secid for the asoc and updates socket's peer label + * if it's the first association on the socket. */ -static int selinux_sctp_assoc_request(struct sctp_association *asoc, - struct sk_buff *skb) +static int selinux_sctp_process_new_assoc(struct sctp_association *asoc, + struct sk_buff *skb) { - struct sk_security_struct *sksec = asoc->base.sk->sk_security; + struct sock *sk = asoc->base.sk; + u16 family = sk->sk_family; + struct sk_security_struct *sksec = sk->sk_security; struct common_audit_data ad; struct lsm_network_audit net = {0,}; - u8 peerlbl_active; - u32 peer_sid = SECINITSID_UNLABELED; - u32 conn_sid; - int err = 0; + int err; - if (!selinux_policycap_extsockclass()) - return 0; + /* handle mapped IPv4 packets arriving via IPv6 sockets */ + if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) + family = PF_INET; - peerlbl_active = selinux_peerlbl_enabled(); + if (selinux_peerlbl_enabled()) { + asoc->peer_secid = SECSID_NULL; - if (peerlbl_active) { /* This will return peer_sid = SECSID_NULL if there are * no peer labels, see security_net_peersid_resolve(). */ - err = selinux_skb_peerlbl_sid(skb, asoc->base.sk->sk_family, - &peer_sid); + err = selinux_skb_peerlbl_sid(skb, family, &asoc->peer_secid); if (err) return err; - if (peer_sid == SECSID_NULL) - peer_sid = SECINITSID_UNLABELED; + if (asoc->peer_secid == SECSID_NULL) + asoc->peer_secid = SECINITSID_UNLABELED; + } else { + asoc->peer_secid = SECINITSID_UNLABELED; } if (sksec->sctp_assoc_state == SCTP_ASSOC_UNSET) { @@ -5279,8 +5280,8 @@ static int selinux_sctp_assoc_request(struct sctp_association *asoc, * then it is approved by policy and used as the primary * peer SID for getpeercon(3). */ - sksec->peer_sid = peer_sid; - } else if (sksec->peer_sid != peer_sid) { + sksec->peer_sid = asoc->peer_secid; + } else if (sksec->peer_sid != asoc->peer_secid) { /* Other association peer SIDs are checked to enforce * consistency among the peer SIDs. */ @@ -5288,11 +5289,32 @@ static int selinux_sctp_assoc_request(struct sctp_association *asoc, ad.u.net = &net; ad.u.net->sk = asoc->base.sk; err = avc_has_perm(&selinux_state, - sksec->peer_sid, peer_sid, sksec->sclass, - SCTP_SOCKET__ASSOCIATION, &ad); + sksec->peer_sid, asoc->peer_secid, + sksec->sclass, SCTP_SOCKET__ASSOCIATION, + &ad); if (err) return err; } + return 0; +} + +/* Called whenever SCTP receives an INIT or COOKIE ECHO chunk. This + * happens on an incoming connect(2), sctp_connectx(3) or + * sctp_sendmsg(3) (with no association already present). + */ +static int selinux_sctp_assoc_request(struct sctp_association *asoc, + struct sk_buff *skb) +{ + struct sk_security_struct *sksec = asoc->base.sk->sk_security; + u32 conn_sid; + int err; + + if (!selinux_policycap_extsockclass()) + return 0; + + err = selinux_sctp_process_new_assoc(asoc, skb); + if (err) + return err; /* Compute the MLS component for the connection and store * the information in asoc. This will be used by SCTP TCP type @@ -5300,17 +5322,36 @@ static int selinux_sctp_assoc_request(struct sctp_association *asoc, * socket to be generated. selinux_sctp_sk_clone() will then * plug this into the new socket. */ - err = selinux_conn_sid(sksec->sid, peer_sid, &conn_sid); + err = selinux_conn_sid(sksec->sid, asoc->peer_secid, &conn_sid); if (err) return err; asoc->secid = conn_sid; - asoc->peer_secid = peer_sid; /* Set any NetLabel labels including CIPSO/CALIPSO options. */ return selinux_netlbl_sctp_assoc_request(asoc, skb); } +/* Called when SCTP receives a COOKIE ACK chunk as the final + * response to an association request (initited by us). + */ +static int selinux_sctp_assoc_established(struct sctp_association *asoc, + struct sk_buff *skb) +{ + struct sk_security_struct *sksec = asoc->base.sk->sk_security; + + if (!selinux_policycap_extsockclass()) + return 0; + + /* Inherit secid from the parent socket - this will be picked up + * by selinux_sctp_sk_clone() if the association gets peeled off + * into a new socket. + */ + asoc->secid = sksec->sid; + + return selinux_sctp_process_new_assoc(asoc, skb); +} + /* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting * based on their @optname. */ @@ -7131,6 +7172,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(sctp_assoc_request, selinux_sctp_assoc_request), LSM_HOOK_INIT(sctp_sk_clone, selinux_sctp_sk_clone), LSM_HOOK_INIT(sctp_bind_connect, selinux_sctp_bind_connect), + LSM_HOOK_INIT(sctp_assoc_established, selinux_sctp_assoc_established), LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request), LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone), LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established), -- 2.34.1