From patchwork Tue Sep 27 19:53:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12991226 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 B323FC54EE9 for ; Tue, 27 Sep 2022 20:04:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232439AbiI0UEW (ORCPT ); Tue, 27 Sep 2022 16:04:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54168 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232428AbiI0UD5 (ORCPT ); Tue, 27 Sep 2022 16:03:57 -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 5146F1E76B2 for ; Tue, 27 Sep 2022 13:02:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664308964; bh=IyZSFo5018fj4sTvPWuUspKouZDyi3IU5Yce539hXgo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=Zsf4Uk9SPwAp/rtvZyudJITGQRcRDRzaRRMmUV/Qbdvi64k/TtJlUMgnOPBXGjK4ef1beycZVaBzaw2h6bv2VFSUI2Kuqnthvjhl3GyMbuCQFU3Vra4ajDshKw/p/OIl8Hl1vJ8UIGjgmokWbHiHq5EXHNw89HRNdP0qUOBSa//bqen5CPq1Gl/aAc4Tj70srdQCO3JalTfsPSP2BS003tpxvA4eh5n6cGMDnzoCUEdIUAXSzF6t5/kUbWx+VCmnjSz5Sv4/z7Qr21PX02MkNZC6IUQWD5/UmzUzd3huJODgOl/rgoLz831f3+WLwNZzjCcK9YOwAnj586LVs20qFQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1664308964; bh=VPXvNrSUjp4CnrAKblZ28b+IHaBf8LADSG69L1xOBpK=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=XLdARf5vdWEPOWQCwEnzvDIf2bf9nJWfE7ercMpNSeDdvGN+W7Gr7rIpaPdUmv+BeeWuT9u3FSIoGbcFgjGSkA6Xk6clMj/BVKQ3FEYKYdNt+CDGtNo8TyH1iH+hcr6Zk5mHW5Y/VJ92zOZAaqyiLVcnGwpOn2TnBOejFsCFYlwqfvcYTjZitXXKQJ8y0APT+3PLMOa1hrJqS3wtnh/1xY31C3gwYsNkprz7ZbBZ5KboMVV8meHaJRWvOUniUV89oCxU1Lak4+OvbQXRn+rrxsICRQvyQ9qQJOiYvnpYUbODqLxQEGK2htvUQQ4gv+ueoMpSt1MZesC1z4yPKtkjpw== X-YMail-OSG: I6PNIdEVM1lj8uGHiWPC_bv.uBFGppAnMsVPO1J74p.XgB2MX0L.qgOkY_KFiGL fBkXYtjfGVyKENrQa.dk.WOKest52zix3F6Ent.OgUUGIR7GRNvMQSHb6s08iUPAfZ7R0yDw444m 8e59xrL_I3K6QdJDVJSZYzPhiGmJ87mW_N6nbiYcY5.esyqinLKn70ucjXxTXA1bt58HGH_y6Kl7 Zj._ecm7erB24n9WHEybl052Cej0cBN_Uz9MVL5hkX1S.gwom.UCSn2DTisn6bAA_Oe8eOwzdgxd q5YJCPuO7SW1aurOo.fqNNWYJzwBi_EAHtNsf._ujv8xLqQa5T51N7vgGWqQ_izOlfFI2NiewBya zu1RP2swhUNfx9nF3Ec1AAFLSigvY66MY8YLa6Hef9Muxo98.L993bumk5CkWZaZiOtcnTGhFBYR 085wTta75vlH4Y2O0sMEywt4zN9.olTI.tvvPVMUgSVq5CdpChO.FG.HTcKCBFTA8MBUHvsS4rZE _KZ2x.eBCcWdmQw4s5fANC19RG.SrMTXdKessHuNXyukah2WrH8yz_4iJ2BDDO2LglhW1LGWTs5m pG.ezruvmksrG_BtU58eKjRB4XGC46QHlFEwLzk7WSqzgHxlSDIm22kD0mUFv8bH4JSyybGCsTBs GX.hf3CilczHZzeBmcwzpf0ISnjTQ4FtKGJABCYf2bTi6Pzz1jr7OGhXqb40CEIw5v8rAWX1Ishe qrVJtS71sVOgp1.JktmGmol4f9uY0bLMbUTXi3oWN91nsPYU1U7s7Rt3.ai4ui68NvePfiC5g7RI jrmAblot6XN7ks8XHPjuUgACgbhPo_CDK7XT6J4GWTZsCuqNYFeHSPMm6RYKKbY7WFPEc1eU8m6j yNeSQDmficD_zfZCb_EjFWANbnigkPhNcx6m15ti4RPEFE8_M9m92rlbf437RIwVPI1uFB7Y8S8s i_rNJQSb7xNq4NpFXUk.O52qKtPE259V3HsPV6lpA6lSbn0DbtjrSDcyB.RvexUFA3XC892c9Fy3 8kezpSX3sN_DTa8QRb8YTuD6n2ui2.b2x5mH5yyRGI.GB.CRDUTM5iQKYBwY7GLHq59pXt0zihW1 I.9YeW5aTftukKzr9SNHGMLDpQfLQCE5hgKUK7_K5MI7sGX_O_MPeElaaEeOdcG9MGBx0BjNTzB1 dAA9dWnYcQ7r_wLaRpeWwRWbhzQ9OhBlwCs5o3eyJ78Fe8YDhd8AE4NZOtx0FtMvKOYQIIkndJzS ZHOlTMlA5syEIy2UW1vXVIiyAA_NhEJEiE5OzvA6hu4uHupWyRIr9SOsODsNIqP7IRUtVc88BVbg iqqJvi_DVeEBWEjDnoJ_MVFDbZhiWyxaPnwoUlz12b0wKyoVWIc5KxtvJDmzUwgpkWQv8c.amzsB 6pGY0LV21yMI9QSbG_Pcy.nAbnBU19Z9bCO5_ijsFJ9CPs5FAd.D2KiN4lZiVsKtzYNlrKX4Vg1L 6GJcrDzluI.PxmkuWHrrdfeO_clCgU8bU9dyMkpOtkiIUXV8fajkX80BLmM6a86ge98.8WpQpXrL xY6fVICmBr4qM84j0D.npYUoiX7ja1eAF4TW09.spNBxBtzxo6XE9PEDXE2q0z1ebnXnVjQw6Kbq p5AqnUXNccU9wkL7kJ1BmG_gy3QFoCfvHH2Y31X7cWd0oCPLWHR8Xyd4W9MQN0_wn.JeJbpZYFjE K3epA5KI6JlIf92irtSfSeUhUe66a8UyW5uNrin8cyR6aO361ns19b7Wd_foA3HkZFECSYzvvCvz faY8Bfc7.xmVn5.2a.sprWNA0EHqzWAxhNPnCf.fTJ4V1KtcYBbuQhAQF46sBe6DKmDb6Du2HAQj eAKxfDi.En4l6lj67UTVdx_RQBK_RgUfdKXDw1Gp9PVYVjVRup4dE25iH1YZICiFqPab.G38XknV ypPflG9hIOJfMHnGV1HI_oeEW3oIhxkI0Vj6W.Ct6qhwY5.UG8ndRUDTC.SZ1CWbgImjtKMFCvkk PxpM2UmzPRPFNcE7cwA2P0Uctk4QXfjc_jwIxdfb3bmkxtHlV8qHZyg8Ld42TE4pTn9BN2Vd2s0l OXkOrWxpt3fSquMF_23YFmAHpMTakSrewLOA3OYupxB4nZ6Y0nPDgQxuGT.WkmyTEhfOqxvjHcrE 6X_Rv.AEeCUhUKuxoC1JcfFgYl5HJoBJrFMHZA51rI.GvVOecf9SM0BueKzvvRm_Ekb8cN3EcwlL Ouijs2i8.jwUW1C73Zau70ILmuk4iJBH2Toy1OviLNp5Dt6E1_TWBOitdqpux61idzmy9cq9jXB4 xWxTcDwsAXA_j X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.ne1.yahoo.com with HTTP; Tue, 27 Sep 2022 20:02:44 +0000 Received: by hermes--production-ne1-6dd4f99767-97ndb (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID 0896e936b45c39858cb958d2af309d20; Tue, 27 Sep 2022 20:02:41 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, paul@paul-moore.com, linux-security-module@vger.kernel.org Cc: casey@schaufler-ca.com, linux-audit@redhat.com, jmorris@namei.org, selinux@vger.kernel.org, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, stephen.smalley.work@gmail.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v38 15/39] LSM: Use lsmblob in security_secid_to_secctx Date: Tue, 27 Sep 2022 12:53:57 -0700 Message-Id: <20220927195421.14713-16-casey@schaufler-ca.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220927195421.14713-1-casey@schaufler-ca.com> References: <20220927195421.14713-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 6428f6be69e3..34602b68d2a1 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3170,10 +3170,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 0134a938fd65..d9ab76c909e0 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -569,7 +569,7 @@ int security_getprocattr(struct task_struct *p, int lsmid, char *name, int security_setprocattr(int lsmid, 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); @@ -1426,7 +1426,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 a75978ae38ad..6aa7db400d10 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 5fab2367bfd0..d083c050d660 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, @@ -1093,6 +1107,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) @@ -1102,7 +1117,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 { @@ -1393,8 +1409,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 { @@ -1560,9 +1578,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 e49a61a053a6..bb8e2af31d4f 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 7562b215b932..2e257aa4f61b 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 4ffe84c5a82c..da61eb8cde76 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 87a9009d5234..bc25d49575e4 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 87fb0747d3e9..980ad209b57e 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 0c5be69d8146..9c49406e5ff9 100644 --- a/security/security.c +++ b/security/security.c @@ -2209,17 +2209,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; }