From patchwork Tue Jun 28 00:55:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12897403 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49DC7CCA480 for ; Tue, 28 Jun 2022 01:04:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242929AbiF1BE3 (ORCPT ); Mon, 27 Jun 2022 21:04:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60460 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242881AbiF1BEQ (ORCPT ); Mon, 27 Jun 2022 21:04:16 -0400 Received: from sonic304-28.consmr.mail.ne1.yahoo.com (sonic304-28.consmr.mail.ne1.yahoo.com [66.163.191.154]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BDF4E22B31 for ; Mon, 27 Jun 2022 18:04:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1656378244; bh=SEDujFIIf9a7F3wg8aOHzGN1rhozmxWwcgf1f6Nw8pc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=bXPDlz+w3V/JKxuIRD5s7Q1jtS/6lnTLVPrMzkhahsqFsIGyCYj4ldSiHbz6yTO9uKKKepYM8K4obZNY9AoYhRkbmUe9coRFIzDhxSsFeQN5n5SytjGCuJgk5Tq61l/A1/inwha4Idk+I/T3h3fhhz1ZmA9j1hoCcqTjpKRi+4PS4npM4k1t5Zj7+diAaM1ncpcMglbIuj8sZ+Fap9fIUtKCpObAiHIeuAjfBC3IXHsovS4QJECQ7jeRpSPtOc5DWF0VT+LJYezAnUldjaM4z3RWpgpM0+iGV5/uB72OMHt6QZQGiJq4HQtIMqaMkQFz7WgpS5vPWaWxSrMBU9419g== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1656378244; bh=L67yYUQwK6wU1ow7uhiFWRYMVl3bxhnv9kSLuMHcpwD=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=N4zt5wwgjnA/mqT1RawwkCT2IU1SZUHRLXucCVktTswvmLElfFBC27V/yrcf26LNWNvKok6lVzJ2YOMshDnuCV3X4nYoklD89aR2CkL4L+RrBwxi7eYNgwcll/K7SllJTrJ9cVdQ3LqleMra927N0gaFIbMMDNQvCegyWtpNMzWj0ZK3/0T7CAcdHOS3uiXLjxmfeJgD9sCeYSt1Tzny9TdPevDcHsUQMxlcQnI6riw6aQKsIWhBqTw8XPX8WR+vnF1qUB08Hpq+vJuZrpDdWDShA17QyTOg+sFb3+HE009HQq19LPfKy/rEsXPSu6y4h5gPHd9QnzH8bH8T3+Czuw== X-YMail-OSG: X6JkT.YVM1lG75mSc8_fcWmpY_w4IBznuLFq7dgxHrVdJQitnBCmGR9BnvWJYYu U6mRIjBCZKq3e5_HTyOgKKbTmmvFLzZ8VXg9fAOpBAwvXGAQFupUSM5bLTyqlt2jManY4aINasNP aVfClf3hgozv18NiHcdkIoEPE3rivqNSuRV4ax72xe14YBudZsK4VeuFwhHCpDMxnqrLovE4WTHs lLi4U7HbBEEUSwxB4I8O561zWbHtfgB9kxNeEnnzUQC8T4sq0i2VTAaoKJZYQCDvo_wD8VabzA5b cJvdpFVTGJs_ZQuvKm4bKIeJOf1VpefVhwtCbFO4G.ZTHX1Yc47D.6rcaj1uHfp3opA1hS1T7ixZ mHSk9SybnskzTOwq9Q2gjaBSJbuxC3wTRFcjrtD8GWqqS_bq_qQlQY1axNiR3JIqRSbdqXIMCiLg JHQNd3r7xdymj1d8i4aQR9UdiCuZfJoPagrPdvj_AefuZ9u.HDnle4qE3L341tnn8Cc2gqQfhZTv nZkrXMmgEVQxXywgkZPTGRXt7h6nwQzb.04NU1uU.YQF.fBEvE7hqeFbwwNXsoaXFORP7JzUjXl1 EXbKAVnBAvpKA.6mQqGjt4d1r3LBd3JChCLXkAJQ177pOGKFyAStU_0zYp6JdLEEBSjVxUnC7SKb hjx6xfMMyYbT7c6cP.hHjh4o5dUkGKmYHB5Z2E96d0fsHBDeBlzfAaO5qZ_xA_ebuEqITncGesht HDI1bRFiT4LaYAVcYSv.KqrThVcQN30tJ477G67YN.nE31ZYB1KFxzn7DUFqqq9Kd_T7JhEfw1ln nR0F6zGm5Q1YykQsatTgnsxlenXgrbkafuTzT6oak5pEXbReYYinjUBQvG1IvrWNJ8U9O7pAGhwr C8oiTuEjj1ElJEsaYxjbYfjPb4Bfp_wYGcXFZJWzAmKBWE7FPhgubxM3mnS6zwnMBsjErqzwkPVA .DFyvrF3xS5U18_W7e3uUnX9fIpKpoBC8J3jOjVguVniksxEd2zVZisN7q61kICxX6n2VFBb98aC AZxdyFMKhiv0bjKkIpLw1xG_PP9tWl2qY410mnddHxjxRkxQzHbJ1wGMC_KAI7IOse3B2Cp4tb5z Eek4wdAelOWihE0sc7sl.VN9wTSqF_MNjsFnLysSn4gHUurlhO6HJ8EdG7utoqBgttz5EDZCM9ou tftXR12nj2eVQYloUUq6sTXOVnqk9n1sUbBUyIfXxCm5Z2Pt7mhpHPuMFu9TAKV3vVpwoDOM4yXO Px_uz8Z.c2yRuErSMgvo0cU9yMCyfcbI616aCaxEp5tMIwM.ZRB1SiVOcdJC0BVrU285OIng6Z8O x94wmOvYA0L8onR7EXkIiyekov73bOIpk6xPQOimr4O8pdg7mKnaBzBZunIb7xZoHBShFHRovkkl RwXj8FK3D8cgn6x6EEcoHw.ymz_devPUv0.kXmtuk0vZHWPk.u4j3NNNERPyGotB3QyATSIHllpk l7jYpJdY2symeR_YloGMoVL5QhUZu8YYjHPytUZzE8EiYb5t8uDzvgu8MzMbqeriOUTprGTV6X_u fK9WP0eMDh5v3OTVRong7kdE3DHVS.ftu1PFribcHPozrs3ihdFjpaGc_fNRnt4syNhkvnUcZwUr EhVHsYpTSrsfetnhLu6Hooel9LDAtUpIdavjQffoIQomAKGMqi2AaySK7usCKg4LY9d0VV1stTWR M98gDeu7ObaEavW396ucz9UQmz6ZsuYx1XLttfa8k4JXZlBAPd38vHQzvXhCRY_PVAbQAbz80iF0 n.ui4OGbqsOp1AM.Pnh8jUSzq1GG2MNicFQ9hOswfdjx.gJbTVor3fys7iXLWCypdeP1PqaPccOt NcXdC6srhNAkvr4LAyhqXHRahCYBYifJB5lClMoKQPKCsS4fSL0xDwPmYzwO5mYuyMmaKw_89Yhs THP6XzKPJBnFI0YxC1V3c3g_DUQCpD_njDqEvkwB9kBXnjDwo_9GU2iB_6Wz3KJahzqUagAq6WBx W3_bbST_rILH4T.PMIdAu7RUNahpqWkpdDQxJ6omXpRe604jut7pBx939d6fx82ubmlMFf25oL3Z mPLQrONvfTW06GrJZ1PzBsH6n7WJyxFVD4wif_yZcWMB4.5Y2vFb9zqucf7n6jv45ZTaYgqW_OSF GYKQa0ihti8F5mFYI.VK8JRsbbENF.Bo.vKfFSUvTHX69fTTbjEq0x2fgr7oFJ2EccFck5JvrbjO Nua4XrJtbp9wvA2ibt1sZeFmkQ6_DN4z7AbSvVmfwrJQugD77hzjYmQnfVX9DU7uB1Xk6B24DehN Aa05wYFod_gD3i4LB_l2eoK1fJHdmCZbhoiMsG.mML7a8.h4D8KL.Nk1jPGqN9K1B X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.ne1.yahoo.com with HTTP; Tue, 28 Jun 2022 01:04:04 +0000 Received: by hermes--production-ne1-7459d5c5c9-fdkvw (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 7521274ed3fde3701c40279c1a2b59fb; Tue, 28 Jun 2022 01:03:58 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v37 09/33] LSM: Use lsmblob in security_secid_to_secctx Date: Mon, 27 Jun 2022 17:55:47 -0700 Message-Id: <20220628005611.13106-10-casey@schaufler-ca.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220628005611.13106-1-casey@schaufler-ca.com> References: <20220628005611.13106-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Change security_secid_to_secctx() to take a lsmblob as input instead of a u32 secid. It will then call the LSM hooks using the lsmblob element allocated for that module. The callers have been updated as well. This allows for the possibility that more than one module may be called upon to translate a secid to a string, as can occur in the audit code. Acked-by: Paul Moore Reviewed-by: Kees Cook Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com Cc: netfilter-devel@vger.kernel.org To: Pablo Neira Ayuso --- drivers/android/binder.c | 12 +++++++++- include/linux/security.h | 5 +++-- include/net/scm.h | 7 +++++- kernel/audit.c | 21 +++++++++++++++-- kernel/auditsc.c | 27 ++++++++++++++++++---- net/ipv4/ip_sockglue.c | 4 +++- net/netfilter/nf_conntrack_netlink.c | 14 ++++++++++-- net/netfilter/nf_conntrack_standalone.c | 4 +++- net/netfilter/nfnetlink_queue.c | 11 +++++++-- net/netlabel/netlabel_unlabeled.c | 30 +++++++++++++++++++++---- net/netlabel/netlabel_user.c | 6 ++--- security/security.c | 11 +++++---- 12 files changed, 123 insertions(+), 29 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 362c0deb65f1..4ead3360a1c0 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3055,10 +3055,20 @@ static void binder_transaction(struct binder_proc *proc, if (target_node && target_node->txn_security_ctx) { u32 secid; + struct lsmblob blob; size_t added_size; security_cred_getsecid(proc->cred, &secid); - ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); + /* + * Later in this patch set security_task_getsecid() will + * provide a lsmblob instead of a secid. lsmblob_init + * is used to ensure that all the secids in the lsmblob + * get the value returned from security_task_getsecid(), + * which means that the one expected by + * security_secid_to_secctx() will be set. + */ + lsmblob_init(&blob, secid); + ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); if (ret) { binder_txn_error("%d:%d failed to get security context\n", thread->pid, proc->pid); diff --git a/include/linux/security.h b/include/linux/security.h index 8e09302bded7..e8e4a7a1029b 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -551,7 +551,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value, size_t size); int security_netlink_send(struct sock *sk, struct sk_buff *skb); int security_ismaclabel(const char *name); -int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); +int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); void security_release_secctx(char *secdata, u32 seclen); @@ -1401,7 +1401,8 @@ static inline int security_ismaclabel(const char *name) return 0; } -static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +static inline int security_secid_to_secctx(struct lsmblob *blob, + char **secdata, u32 *seclen) { return -EOPNOTSUPP; } diff --git a/include/net/scm.h b/include/net/scm.h index 1ce365f4c256..23a35ff1b3f2 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -92,12 +92,17 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, #ifdef CONFIG_SECURITY_NETWORK static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) { + struct lsmblob lb; char *secdata; u32 seclen; int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - err = security_secid_to_secctx(scm->secid, &secdata, &seclen); + /* There can only be one security module using the secid, + * and the infrastructure will know which it is. + */ + lsmblob_init(&lb, scm->secid); + err = security_secid_to_secctx(&lb, &secdata, &seclen); if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); diff --git a/kernel/audit.c b/kernel/audit.c index 7690c29d4ee4..2acf95cf9895 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1464,7 +1464,16 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) case AUDIT_SIGNAL_INFO: len = 0; if (audit_sig_sid) { - err = security_secid_to_secctx(audit_sig_sid, &ctx, &len); + struct lsmblob blob; + + /* + * lsmblob_init sets all values in the lsmblob + * to audit_sig_sid. This is temporary until + * audit_sig_sid is converted to a lsmblob, which + * happens later in this patch set. + */ + lsmblob_init(&blob, audit_sig_sid); + err = security_secid_to_secctx(&blob, &ctx, &len); if (err) return err; } @@ -2170,12 +2179,20 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; u32 sid; + struct lsmblob blob; security_current_getsecid_subj(&sid); if (!sid) return 0; - error = security_secid_to_secctx(sid, &ctx, &len); + /* + * lsmblob_init sets all values in the lsmblob to sid. + * This is temporary until security_task_getsecid is converted + * to use a lsmblob, which happens later in this patch set. + */ + lsmblob_init(&blob, sid); + error = security_secid_to_secctx(&blob, &ctx, &len); + if (error) { if (error != -EINVAL) goto error_path; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 221196b0cde3..f2ba966c8838 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -679,6 +679,13 @@ static int audit_filter_rules(struct task_struct *tsk, security_current_getsecid_subj(&sid); need_sid = 0; } + /* + * lsmblob_init sets all values in the lsmblob + * to sid. This is temporary until + * security_task_getsecid() is converted to + * provide a lsmblob, which happens later in + * this patch set. + */ lsmblob_init(&blob, sid); result = security_audit_rule_match(&blob, f->type, f->op, @@ -695,6 +702,13 @@ static int audit_filter_rules(struct task_struct *tsk, if (f->lsm_str) { /* Find files that match */ if (name) { + /* + * lsmblob_init sets all values in the + * lsmblob to sid. This is temporary + * until name->osid is converted to a + * lsmblob, which happens later in + * this patch set. + */ lsmblob_init(&blob, name->osid); result = security_audit_rule_match( &blob, @@ -1118,6 +1132,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, char *ctx = NULL; u32 len; int rc = 0; + struct lsmblob blob; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); if (!ab) @@ -1127,7 +1142,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, from_kuid(&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid); if (sid) { - if (security_secid_to_secctx(sid, &ctx, &len)) { + lsmblob_init(&blob, sid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { @@ -1418,8 +1434,10 @@ static void show_special(struct audit_context *context, int *call_panic) if (osid) { char *ctx = NULL; u32 len; + struct lsmblob blob; - if (security_secid_to_secctx(osid, &ctx, &len)) { + lsmblob_init(&blob, osid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { @@ -1585,9 +1603,10 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, if (n->osid != 0) { char *ctx = NULL; u32 len; + struct lsmblob blob; - if (security_secid_to_secctx( - n->osid, &ctx, &len)) { + lsmblob_init(&blob, n->osid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " osid=%u", n->osid); if (call_panic) *call_panic = 2; diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 445a9ecaefa1..933a8f94f93a 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -130,6 +130,7 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb, static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { + struct lsmblob lb; char *secdata; u32 seclen, secid; int err; @@ -138,7 +139,8 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) if (err) return; - err = security_secid_to_secctx(secid, &secdata, &seclen); + lsmblob_init(&lb, secid); + err = security_secid_to_secctx(&lb, &secdata, &seclen); if (err) return; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 722af5e309ba..ddc8cd65ed12 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -347,8 +347,13 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) struct nlattr *nest_secctx; int len, ret; char *secctx; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, &secctx, &len); + /* lsmblob_init() puts ct->secmark into all of the secids in blob. + * security_secid_to_secctx() will know which security module + * to use to create the secctx. */ + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, &secctx, &len); if (ret) return 0; @@ -656,8 +661,13 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) { #ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, NULL, &len); + /* lsmblob_init() puts ct->secmark into all of the secids in blob. + * security_secid_to_secctx() will know which security module + * to use to create the secctx. */ + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, NULL, &len); if (ret) return 0; diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 6ad7bbc90d38..2c1f3280d56e 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -178,8 +178,10 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) int ret; u32 len; char *secctx; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, &secctx, &len); + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, &secctx, &len); if (ret) return; diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index a364f8e5e698..6269fe122345 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -305,13 +305,20 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) { u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) + struct lsmblob blob; + if (!skb || !sk_fullsock(skb->sk)) return 0; read_lock_bh(&skb->sk->sk_callback_lock); - if (skb->secmark) - security_secid_to_secctx(skb->secmark, secdata, &seclen); + if (skb->secmark) { + /* lsmblob_init() puts ct->secmark into all of the secids in + * blob. security_secid_to_secctx() will know which security + * module to use to create the secctx. */ + lsmblob_init(&blob, skb->secmark); + security_secid_to_secctx(&blob, secdata, &seclen); + } read_unlock_bh(&skb->sk->sk_callback_lock); #endif diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index f3e2cde76919..0a99663e6edb 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -376,6 +376,7 @@ int netlbl_unlhsh_add(struct net *net, struct audit_buffer *audit_buf = NULL; char *secctx = NULL; u32 secctx_len; + struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && addr_len != sizeof(struct in6_addr)) @@ -438,7 +439,11 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - if (security_secid_to_secctx(secid, + /* lsmblob_init() puts secid into all of the secids in blob. + * security_secid_to_secctx() will know which security module + * to use to create the secctx. */ + lsmblob_init(&blob, secid); + if (security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); @@ -475,6 +480,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct net_device *dev; char *secctx; u32 secctx_len; + struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, @@ -493,8 +499,13 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, (dev != NULL ? dev->name : NULL), addr->s_addr, mask->s_addr); dev_put(dev); + /* lsmblob_init() puts entry->secid into all of the secids + * in blob. security_secid_to_secctx() will know which + * security module to use to create the secctx. */ + if (entry != NULL) + lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(entry->secid, + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); security_release_secctx(secctx, secctx_len); @@ -536,6 +547,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct net_device *dev; char *secctx; u32 secctx_len; + struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); @@ -553,8 +565,13 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, (dev != NULL ? dev->name : NULL), addr, mask); dev_put(dev); + /* lsmblob_init() puts entry->secid into all of the secids + * in blob. security_secid_to_secctx() will know which + * security module to use to create the secctx. */ + if (entry != NULL) + lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(entry->secid, + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); security_release_secctx(secctx, secctx_len); @@ -1080,6 +1097,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, u32 secid; char *secctx; u32 secctx_len; + struct lsmblob blob; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family, @@ -1134,7 +1152,11 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, secid = addr6->secid; } - ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len); + /* lsmblob_init() secid into all of the secids in blob. + * security_secid_to_secctx() will know which security module + * to use to create the secctx. */ + lsmblob_init(&blob, secid); + ret_val = security_secid_to_secctx(&blob, &secctx, &secctx_len); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 3ed4fea2a2de..893301ae0131 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -86,6 +86,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, struct audit_buffer *audit_buf; char *secctx; u32 secctx_len; + struct lsmblob blob; if (audit_enabled == AUDIT_OFF) return NULL; @@ -98,10 +99,9 @@ struct audit_buffer *netlbl_audit_start_common(int type, from_kuid(&init_user_ns, audit_info->loginuid), audit_info->sessionid); + lsmblob_init(&blob, audit_info->secid); if (audit_info->secid != 0 && - security_secid_to_secctx(audit_info->secid, - &secctx, - &secctx_len) == 0) { + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " subj=%s", secctx); security_release_secctx(secctx, secctx_len); } diff --git a/security/security.c b/security/security.c index 08ed7acf4205..552a08750843 100644 --- a/security/security.c +++ b/security/security.c @@ -2186,17 +2186,16 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) { struct security_hook_list *hp; int rc; - /* - * Currently, only one LSM can implement secid_to_secctx (i.e this - * LSM hook is not "stackable"). - */ hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { - rc = hp->hook.secid_to_secctx(secid, secdata, seclen); + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.secid_to_secctx(blob->secid[hp->lsmid->slot], + secdata, seclen); if (rc != LSM_RET_DEFAULT(secid_to_secctx)) return rc; }