From patchwork Mon Apr 18 14:59:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12816752 X-Patchwork-Delegate: paul@paul-moore.com 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 6B45CC433F5 for ; Mon, 18 Apr 2022 15:38:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245019AbiDRPkz (ORCPT ); Mon, 18 Apr 2022 11:40:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49542 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344147AbiDRPkc (ORCPT ); Mon, 18 Apr 2022 11:40:32 -0400 Received: from sonic317-38.consmr.mail.ne1.yahoo.com (sonic317-38.consmr.mail.ne1.yahoo.com [66.163.184.49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EF368122 for ; Mon, 18 Apr 2022 08:04:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650294286; bh=VpP2hMspUDTZOC44Pn2gznN8CZnccBSv5oPb5zsRzdY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=AIxcu/1ULZbCxBEhz19t0zDMizjS2vAxmsM3aIF0Cn3TdGWeGQ4rWmvg5DfcficirUWsNX0pmI9zo3KHvgbtCLtTjRZLJoB0oKlyp3avyfnefHUZ/f2HvhllVbtf19T5dFHfEbMJx3qCOX6VvC0RE2t4KcGwDWPcqFkgTb1fUY0dy/mDwRZ4/nPcFDHGPF5I2llCrpz5UAyBiDklu+ONS0Jim02CQ/MXPGDlvi8rYKH1qer5/ZyWLDRoR29KbdYtEh5Y9R+6qwnT1ql2xsMDedyXBFC9fPTPKq9BvBiwK8Uv0zY2WSd7Y9BAuRn4iHRFn2a0n4NzGdxhUMVE+hn60A== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1650294286; bh=f7XuLINAji/LqXhXrhy7TUb7qAMZAzSUiEfbtmLNJ7V=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=psP3HeN7QRp+8Ucpb7xEZLlzPe5rdadFClwAtAVBPuvx7zl/U/676rCQa9S6iwP5f9oiBcUJBvp4X8gAfwW+eq4qLKEeCNoZpTRMgPnRSMpr3rXLrpxr9yqpdtnnMr5w8gNSXfxtV96P3a4+OQJhingTGNuiQAdhyrBDXtrTqe7j9igPF6Oxj6h5B2uXVme45huGAkBbVTMbbdl2D0CCWoJPro3T7lKc/O4/oHdKeazHxCOjQUiFFTjOXO/k81W7b5fFnoX/R43Dsvr2zfdFQTDIx0KjajU6Ey/KJ44u/lHRGiRjTQr8v2uZMEKP/y8W7x4gr1bbo/dSLh+vFOia1g== X-YMail-OSG: MNxgzA8VM1kxaOtRIcyqbFWfZKPiAC3mlRJ1dHn7EeFtdyw3fAe2PlplrM.nE6Z LlKDS2exOMQQ1roZ816UmM6ujHD2cV9vMAUaDCox4W3tKLeSAh6FHXOMZpcGUzGxOKSvxcngMNY_ aHgMZ6nevDz67TVHucaEM4sgIN3ebKA1Nb2sU.2IPKS2xh3VupL95Q8_3piV9zcs0KzUAeBcU8wi PsKZ__HgceCGlbBbNNa.7MGpZhly4WL2FJl_OTCSLwMiY7rqQNKrWrkMUiwBEY82OZFPb7cSw8jX 3__UItNHHcpGjLWzUKtlzVg.O5MA68uQ0fwAeGrzzIY2ypx6B4edT6mgpcNI2cW8pXoQR7JpOOeq qbLWXA1XJCmzoPr_dzOc_II3AE1FxCzoDtbf2XV9Yg6LBBvBs1l2zwV9NK_W3od.pPayqMFZDPC0 _vWPrQP14Ivy3NXSeitqrI3G4qUiZNcydvE1uFtYa_giEqNP1LjBmo_cJiT6fT.J0sY2dlb2WG7O Gd4Jl6n7SwjpaOpq4yLhHYgOmJ2UbcRFdyN0zhgOzieIzuRre8Ucaw6JcwkJnbHltPJUlctzmN0S PAK.MJ7ceEJsfHARUKdJqJ1dsScMS3v3yz__TNO4a05h1jLkSEuvYyiwmLWAQyANUQsEbeuvwT.N 5T26TkF_4daijoVDKe3XTemJftEGujIe.zxqyPU8vOyboNktMWuFNuJR5CQQhd8A.QGdfbIN8D8q NT5Gzh.0WPbI8BZfUrDB1PfkRXrAGvi0_b_Cw46I7YEk5PKSSTZ2N_Sw7mPs.IWc90jb7zQXZ3W7 2UBdtsxljASF18tND9O_mItD2QFUiYMVaTPOhnvAnvVd3kXekJCS5G7YLIBaIQlsvW5lgx1W3ks. irMUStu5Q5CdpA846OBta4mdROkXgIeXVi1uMnDfFNeoynhF9HmsDNyiB5u3hsA8ptClkRvScikg OjcvT9B7pRiC.eyE.smbqUjxK5HM9vhluerXGPJn_D.d.RdV9iamDemqFIFLuMjgxWaXmZbAJ23F uYudLJ99xKa_pODzvvQKQhVQ4MJmrDE2H15fdUBJY0W4Cw8nZF2B0kUwiEz6ggh0hCZRT9ohpL_S xrDVs0eHdLbjIeZh7TlXkgCJ5hVfT4bmcsSbvQQvxA13EA8xJrVXG3_EOA3._6clveeoPvpQj6Kf m.lEKMA7xQrI5THetkBmCNZFrUtZrHKQNwYOG9krKa020FTmucwkv278xptlf2z9VWpfN_SOwPpH exF1AngBSY8ri0i5q3P_L0XUg_vQK4vkFKtikVkYbCjBuQSTNwgIfxyP0CQvALdsrtEdFDrXf_JU WVSzhJ1ZKSdgLeiVCYFIQ3xuNj.zKWx3PAze.if1kaJfzcyo7sE2MnZ9p6Evt8qy.ZDPG3Dhh_hK eaAU52Ikc8vstRwfW1Mu5BIEshzPpEaRRqVE_lGbUubQPQ_s4cDb1ah_yQsPR_fJFY_B01oOj9WH IB.KNokGFbDGKErbeJzS0Is29cIfvXUxiaE.7Eh0wyvs0x.RZsA1FGLTxfe0OYJP0TrwMPvtPiPz gshBHYA15Aanicu_4RRu2mXX4nUtrJNpOw9DAVd_1B2zLg0E9wnNaLR7dCVTZd9Z6z1ySyqC3NmB 7tKzAJMEOJDT6XmTKySpMzmF09grlLawzkg2JrLROBRLYFPDo.vF6C416jKquj4mCNW616mB9ThT UfyHgZdRPhTW01Gqc2uWE2PSAsNRAqcbrizF1xEdZ2JJ1C0SS7qeQ6eNL_CFLoCKLxfSk5r8WEsS umjRaZufgrmofHX2KT0fjYtp2GMGPHv8Vssd_4Loz0LtnfK9WBEjFYnp2g6CGG5rI5Nb4qDTVklG xEzTkVGKxLJFrWtiMhFdO_56VG7f2TliEf._9N.ZoU9PXYYXV21od7bjR2JaQH5Elx3mOFEUX8TT LgZEG1WdbmXZAKD_FXO2D0UFzP.5OVG2XkC3efqVTiZz5w8ygW7n.3LfswEAYa7MiWu__5JYRFBm QfDI5wAOnHTBLj4DQx0r6yuX6n4aNLsHSKs.P2t7Hi7KROgVQbyZvBhx4DEpFaaUVYx8R9xBAvEA xncyLEt7aF1xhwDvrsS_ENuA0y28Edf1eUddVhIft0queBXzw5hQS5Gzc9J6Cm5FACCXsS_3SGmD oxxpsJPUJvYU8NFVQmttXUBFCw6x_vNmKK6IhLUewhXxK_KU5b4hflru5T5rx7QmPVX9j2PXThKY LktkjJw1m76JepmoAGP5OAG9_1imH1We83rGvHpvHn_Ml_mEiZaBsikhw_N7yZAK4rf2biOEGuYq XDnq0cKPRSz783eNzMVQGOuCW.kvDUGDzyBq0F9lFYMPbVQRsuJmoYK2c0iK7hADpgU4eNXNU23p FdLgskcy2 X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Mon, 18 Apr 2022 15:04:46 +0000 Received: by hermes--canary-production-gq1-665697845d-ftzwk (VZM Hermes SMTP Server) with ESMTPA ID e42a5033a868ecfd55a4e02ebf801990; Mon, 18 Apr 2022 15:04:43 +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 v35 09/29] LSM: Use lsmblob in security_secid_to_secctx Date: Mon, 18 Apr 2022 07:59:25 -0700 Message-Id: <20220418145945.38797-10-casey@schaufler-ca.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220418145945.38797-1-casey@schaufler-ca.com> References: <20220418145945.38797-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: selinux@vger.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 8351c5638880..381a4fddd4a5 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2981,10 +2981,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) { return_error = BR_FAILED_REPLY; return_error_param = ret; diff --git a/include/linux/security.h b/include/linux/security.h index 57879f0b9f89..6ce44b9ae464 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -549,7 +549,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); @@ -1399,7 +1399,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 a9d5bfa37cb3..10b9dc253555 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 1ea2ad732d57..a28e275981d4 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 3e1afd10a9b6..bba3a66f5636 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 f814a41c5d9f..6e6e44213d80 100644 --- a/security/security.c +++ b/security/security.c @@ -2192,17 +2192,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; }