From patchwork Mon Dec 13 23:40:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12674951 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 71202C433EF for ; Mon, 13 Dec 2021 23:50:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239253AbhLMXup (ORCPT ); Mon, 13 Dec 2021 18:50:45 -0500 Received: from sonic315-27.consmr.mail.ne1.yahoo.com ([66.163.190.153]:42408 "EHLO sonic315-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231599AbhLMXuo (ORCPT ); Mon, 13 Dec 2021 18:50:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1639439444; bh=4DGh/JM0QhmeTFRLj4qUlvPwzAsptonLJlq2DPQNd6g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=TCZmH7xIgpQBbo+jxRo28BK+loPYFWOrQC+5dQNOUmuMks31yultzW2RY/YRc0qacwfjHt3KSr0BemMpOctoFZCd2/wg43XdKWKsjQIt+XT90EcTIo3xMnWutCE1bz1MNO+UlH3RSj2QkLNsJQYWnmpv5UO31nimmfI7uaedOE4v0sKz+XUuxe1qGtIGajOtmHVArUWneWySalY3jG75sJu9Y1Exwl/h2XE8F34M+ZRcdogTPD8LMRpcK01w6w3uW/ct1NVNI+XVZyfn4xS+1qX1pCgRibsHm0O57pnuqu8yYQEw93ixLcyJ3IxOlwlKubSqQB0gRq0BjSx3dcBmGw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1639439444; bh=lAw7NxdpvQt21T1uv17BItigZvUklMnHpeY8CDny0z5=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=BPzuj8B7xLj42GC5TwOUYHShWKsfXIh7vdm3i0zVj6KYtGp6F0Iv7X2Ok9APdb68k9nhw30bFw7Ubfp3zYIaCUbz/+KLSvpw5JDVKNxmldpAvX0eKGHBsGXC19JGZC/BPjl7za5qhOhLv1zKYZnP1cEBohLWS9uidzpYPFN51tfVnEL0ygPAoqekt+KbyBlV8gkUHvNJVZMFznDupa38WDkPkxnSCio5m28kGXFB6lrXGsNxL9xQLAhbyU2KGSY2og4CxGZ03i4b72h7NpRA/lEFMk9TdLuuIyxkVz3K1x3jCsj87jebd0TBxj9IdYUmIv6WJJhPtePZi15eOixcvA== X-YMail-OSG: R7I091AVM1nKhsbJkLLpNRrEidQ3CCFDZ1QO3dRgE42V70_beT34NuGz6D.XBHM KHngGSK4I30212WLBgCfsh6Q5CQbv9xRrfW9Ca9vNfmDKXe7l.OkIE_Zd5Yio5urYvYZvHTWrKKQ gb2w7TM_v4hqBNwScPqOKyJcBsi7VZvZQU5LD6F3rUck9EBvXbxSREJHT1d.wk.MhDWMa1V_48vZ 52_kxoEhjEQw_U5iZz11BKF3URmxXQ7MXVz6H9OeaGMEweB_mF3stYgZW3ThF0pzSNVeQsd2y6jZ NqS02rVPzjj0dYHvkfzG67eUKK7NzCKL_zbolRQMzCpzUtVNBp8bu.RRDNA64GIJkMPoiYys9oBX 2qcysRQQC6B6jQdXXV6Bd2GEOERq.7LWVXXh5HW082U9GMFKvXtk9ADmmZzcnaTtU8A41BhstszS z8gaLbZ.1ec5ShB1DC2Fao6kIgSHZYGBPS3cf_Ax2Pwa.OSFGtV9ivGtO7hNspse4sT9sPRuu91u .aKHmVUhqVeLDHidBy1l0B1afczseQeTQahOcBu_qDX.hGi82xq16Oe9KpJh3nExIB_pMpatj8z1 3Gw9JPTIr5kK5Z3ovtFzs9L6l_NZtCKAYfcLs8S51Uzq8QjtrvBVyb79E94OdMEOUTh.lCRZhgBg z9jENebH5ARp95F_GMAws5UQfu8AcFjFI3nvlZrdibnW6oReg5_drFfHTBisl9UGVViBQFO0llDe uAL12jw0xl8HCWd9UDKt_BOd9YThgNuowwbksWDnIj9KHXXRjxrtVGTN9owvN9G0xhxOwDSc90Om LUxYCZ5Q3Bi53GJhwmGhDd8k2pn.t6lH0PdvBw8EJlctl8JH2NoTkrmK_.uTYMQUy4C9vq6fA_iq POR.ywLsDZ4vV17ZgT7re8MzsJRRedRagHokZhFcOpjg3uWR2dIg2mVi3is.gCwkZZhb40sodGE6 K4Tm93CUB0LsqXpMGYb3yiYxP_vnIX4UZnEUpDgbO8fgLKiDkr6OKnazYZ6p4G5dUD_bUBX4z5kJ TSDoovqZE3xJGyqQRvsFZnzhhdlmorF7T4C3AEG9.ZTxJsK01hZPBdK5t0ae6CZ2IL4F.kauflaq 9PTHk9aHdoaQj0ZteYD2OYXtVprpwn96nOTiGqbG92ABr5ctKZfEu8j6e9XI4P8BcDuSTw7f.SK5 G4n7Mx0eP2TC8wFNaa09ujMY_D9odjwavUKLnrX48ajhch9c5SZkExsl278LWdh53toXKcLp0N8d dcvMFU4ON_o1KHlixO39_Ce97eUcEeqwfVGGQYeRriMHLx9rna65LqmC.E2iXiAl6fpB0d76kTa_ gutmaQsNQsWd2WDZ1HmypTvF6m7VW81.DrgPm45AlMH07AFV7IwCYuQ1pspuR_GGOe2jlIo.QHyy 6iMFpb1cfHMhWgR4i.kbHQesQbNOYuDJqD261SW2HCxaZX00l36NQ3oxfG5uaZ407dSss0fD482o eYsHtf_kcMYdG5q6TJXbPYiqVE4PC7YtVTsHKi5Ncl5c7_LjIJiB0d74y5MarzZOFmnIm6FSeiJn byy4Eb8QSUVXPszL_7zyLW9nCqkZM0QKdCiDD6FHKGeGWgXUW_KrtfWdfizHCuLEatnE96DZO8PO nHE5mVip3avsg4CU8Yd_hy4PuS0AW6gpNeInf1T9vB_WlAoCqCwF8lkPHZ9JVK8Gj08ZRiNosrK2 ZcOyeEXhjji78aWSN.rlnwRv4LF47gFjIaWPgkzICXWuw3Y4T_omIfNr4DbQzml3B0umasdL0fWn fSgdquIyBm9vEboAfF1lBIvjvIrl1YnJe36XSniwr5VOX25FnNwhcqHSEt435AcjhwGBtFgIrovI SwMAYk4N9Sx5Xn2dj3hW.yCkXZRy3uORsDRlYswV3txqROvxU2SEjmv7snF5LaiEjBn7_t9e.q7S NyH7YlSFGmz6HRLDuFyC9tGXyC2yhMd_nmIAOHA2oTA21PsxdS.BBprZZxqPkKE5dwhkIE9OxG98 CPAaUbYD_VGLItLzU0AE_moY7Hxw_Qzl_KYMqiWBBVqofmLcxTZ2B_pa7lb6_4iek4HVeiYHYa.e SWp57qQh9OA2xr.HYpU1omJrU_6zA_UtqceUzgsnzhWnmng3tSxvDGQ4nEmgcjq15j0g6ATvQ.2l 4kdOr11q8oZIXE0s5AzkcjMDsK8cQqE8NQu2EH8wbcMbjIiB5FE59fMoMJ3XyOJEKBC0qtMB1TLU BBloHtBuI8AA65NQyg5_ocQuwfvupXr9OWXuaHHUxHLrBsXo6crXM691hzB9iCYIeTKA- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic315.consmr.mail.ne1.yahoo.com with HTTP; Mon, 13 Dec 2021 23:50:44 +0000 Received: by kubenode527.mail-prod1.omega.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 57efa93688f26ab0173e0a80180e1c16; Mon, 13 Dec 2021 23:50:39 +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, sds@tycho.nsa.gov, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, netfilter-devel@vger.kernel.org Subject: [PATCH v31 09/28] LSM: Use lsmblob in security_secid_to_secctx Date: Mon, 13 Dec 2021 15:40:15 -0800 Message-Id: <20211213234034.111891-10-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211213234034.111891-1-casey@schaufler-ca.com> References: <20211213234034.111891-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: 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 | 20 +++++++++++++++-- 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, 122 insertions(+), 29 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index cffbe57a8e08..7805d08cd1e7 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2719,10 +2719,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 8a547fc4affa..669eff47737a 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -550,7 +550,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); @@ -1406,7 +1406,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 121d37e700a6..22286163e93e 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1442,7 +1442,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; } @@ -2131,12 +2140,19 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; u32 sid; + struct lsmblob blob; security_task_getsecid_subj(current, &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 e0c71fe27c2f..b28e2cbcc92c 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -670,6 +670,13 @@ static int audit_filter_rules(struct task_struct *tsk, security_task_getsecid_subj(tsk, &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, @@ -686,6 +693,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, @@ -1109,6 +1123,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) @@ -1118,7 +1133,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 { @@ -1362,8 +1378,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 { @@ -1524,9 +1542,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 38d29b175ca6..be7073df19a5 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 c7708bde057c..67b0f3cfc5c7 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -341,8 +341,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; @@ -650,8 +655,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 80f675d884b2..79c280d1efce 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 4acc4b8e9fe5..62c0c5b847c6 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 762561318d78..51cb4fce5edf 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 7ae68b6ffc7f..a0612afefc24 100644 --- a/security/security.c +++ b/security/security.c @@ -2176,17 +2176,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; }