From patchwork Fri Sep 24 17:54:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 12516417 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 mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D2172C43217 for ; Fri, 24 Sep 2021 18:03:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B235C61107 for ; Fri, 24 Sep 2021 18:03:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347804AbhIXSFS (ORCPT ); Fri, 24 Sep 2021 14:05:18 -0400 Received: from sonic317-38.consmr.mail.ne1.yahoo.com ([66.163.184.49]:36998 "EHLO sonic317-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347796AbhIXSFR (ORCPT ); Fri, 24 Sep 2021 14:05:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632506623; bh=FLureY33Ru8CkMBIhaVMjd/jlAfUxcbfvb2ii7d0J3E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject:Reply-To; b=DTSgg82pZJ+x0TlSbCZQvsRVN5jIdQnbHyMKRYLh/5+04XAAhI+au5oWkeOqQtlz9mkPMqRLWuHEffW/wurVHbAtYkWKVEL3My7tdR2XnL4sAM897xilFH6KNSGk8YXHiYN6lnrmyWq5fn0y+RP1MQzqZd2fhNHOMoKiUNL+bWIUPuysiHGbdOdtf05YmQG+wVABmxZSaqd5DwllH0u742zd6a+OYtM+vfsIbmgFrmuqqt8CyiSXlA/eqgmK3VrlKC4B3XMtmasBE94dlb6W94CK6L/h9lV8UV6wY1IrA3opQ5n8puDK1GH+E4w3MBQQbhCsjZ/SbGqL/a1+2UaoyQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1632506623; bh=nraNd34jcqMZSRrT3Mn+7zd2PjpBbcwbZkDv/La9D73=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=IskwGNeQ8P7HyddwRZsNvPQdBhqVFIcGSqwOTcsvW4j/xHLBCNBLFPL/HGzSMf0hMMOQhhAlGq8HM+2ncX400IQZgXedytBxKVm7f1mxTFvFOPfbrWPoVxnMU13MdeJs5+cWED7QWc+hxCi3GjTtjaZOPgmtTY7ylYE2OAUVR3CwCXIJQHkataHNmZ9tmRbc2r5QF5kvu50A+FOUGegArZ5wtk8rDqt0c7s1Y3AqR6Es9MBkSrxEb/U4iiLyBHQ4OIX/yFsdyS3jh6HfGmsgJ0P4RJDC06pomH7FytbwycRqv1SJF7vz5//QsyAE7J2szj2+LUqYG+PmYxyo/MVfDQ== X-YMail-OSG: 7px3tTAVM1lTrEdKzAF3aBHK5D8bpdCaSmCivJj1kz4_rUL0bx8TAPUvL5wOY5J i0sBridApx0c5ZBo3vG9XaPo2c9ZxglB.QlTnuK_y7jrzBVZb5.2TaULh8L6NSCxnoGDs5pQ89IF NL7uj8NbWwW6HCINPrSU6t7tE.stcBCSqLo7ZPwsvwCkiJID.9zUGQEoOCuXAsjSzQNnIl_tXsZK GA20kOEzDAp7ZTdiHrBTAB_YIs3FHzj756JnuYqhLy0m9tUUxHA_lDkwRRBD6LNaKcq8SKSeio0b Jj09ccWf2dCsZV5CWuWp5PjRmVsgp1QmBCu.kdJC3qaeXzaJZ8T3neLMaRWpk7lQB_m1RMXi09vL CWJvXjGaDa3FVz3IyC0YPYA81dNxjSJ70mOrSdGoEDWLE3TvDVPQAjTjJLuAyW96pUYIdyU.VPX8 qEX.NDGVMeVKlo8i6fObnzNU8PT8i1h2qngD8gbABQBKrWBpVicr17Wg10ry408dHSZix5ZdN3hD K8rRwyk46NfbiveiTuw0C6jrgnM4GnHJkn33hFU3RgNMsiMKZ4A27aI5oNrBmmQ_P3xrQ_oR991K 9WL56.kWwoj2pOX9R8XVYqydjoLCIgPGx8w6Vs5Bbpqa1sDBgv4AwibiMNPrvGWbV9sOfeh5OITg Ww3bBmQXr2gN4skwomTqb_HpYqq2x4bwZIWwiCaab0QHX9qJVnoB9bN3ZnK8ueQirsXdFqPMTdcS PJcKszCwNMDNaFKjBNBucHL0oQqB7UOpTwmo6uUuqMLqol9U5FyFmBHt6wk2poTKhZlDDQyLr41p CtKqpV0gS_OWQMy_NIY5V6H5fr0dT_XmdNscFWILXuqOn6xZstkR9OdSsb9P7.eAeh8JT9UFgbkl oEMdJqb2EUSDkJ1i8aOJy6QFTV0WICL_Su4nQUfhCld4BsMY8zSZ6hNoQDVn2BRh1ucYoNS1HxbT qkBz1iSak7wZ2MhBf42OVuJMqtpinqxdUpP.ajlNDpgY1IsSMrNAXuaGLBEJkT6SkIrFFwcVJf9i doCpitb0ioh0NndLR4G_OwCIDe2N.hnJovIXcjc3B4We_5kQOvlD5JvBpelF8YaGZSLAB_IwFsQ1 1yLM4Uw.48jdA5ijmO6OMCeguiWq1ytEWQx2H.KhQrY5V_nOsWSjqOMm5TykRWmyBBkfy84XQYv0 JPhQ6A3PyTEFwFhA3Mf9xb1WKs5fAGH2G5sHMNArB1xLxG0i_113YtXmukBb03YwCJK6_vQr3HJB CyWMiWCZMYiqFbj5991d76YAR1Mex.bbulmQssRWI_9U5jD9qeEPJhQYt5CAGIqQkbSzMMkZVJ_h KSwuVRKN_yFWxC1PRs1PNzxI1HOUV.T59vISDFB7yPQ8zaqK.b5hSpxrLZz_vzmCUCkLz_CGpg7R wfddVs8dD2cOEuEmS0mYp46Bm859fd7LQMltA16f1AEZmj4e3xWVStxv1zDbIsbAEB.f3mpwTcc9 BhDu8157XCOzMChy0LMVgioJwesVJ1wqU41RT9sfktaDpJ3.U5oomHWlZqpnsicn0jdWtY5klFm1 O_bYUeeHgIDJiFU9i.H.8rDhPpAzyq3KP0gLfOUYebI3HfTfgxOQkik0S9_IPysHRgTFQnv36kS1 w_IYmn3UAX2zDgL1M2.f.DXecT1NCKdvTW4cyxkSCQlV.1fxD2YLPiFkvDojiFsxNTNMGAUyeKII eVssrtOagAU3wzz8_NpQuXlKs1lH5jvHzjV6_PzZOf.uCYOm2NjGyh9Q8gc_haeNCZjZYRMNEw.f DeW_rLWBH8FGAw1WwHiULzMPVG7H8b_zoGQ8rP1r1D8VaF.JiH_0rF6T1rqsq72b0YAxNtR.4w6t kjhgCTolqtE_YGVck2TZ.32lkPZIvX4SsZxHFFtyJ6m._GL5Tw5qMaydf9OAoQAjh410XUX2bO0d M3jY6tAa7S55cnz_kCgvuox5drb5q4TblGj2ENGA.om6H6FbSaO7f6m13agj_f1Py7cE2bORT0sG c8twEOzKWoYJNx5XVmkA98KPgEglOP_nmlVd3vMCAEQ5H1MK0wt5WpBify7bUdSqBaMf0GSfrKPH UL4BBTBscnFAiHQdcFJ_c0yIbSArLnfhtXr2wwhVHsR7Mp.2nTyi0q.1e4fM2jeWXj2T0kIaZlbS GIzfGe3_GgDc9vFbfmN4o15jg0tYKT.vlJLCbx2Ze95e5m3XgxUn189flzHAfzGEln7E8BeBY.zr iI.dkSoRWwxW9M.5rChskGF3zLnCf7ONfnqdx1vga.IBZE5f.1wYF3B1OiK448G3AqdacLDeZMUc nKOGHF7o3S1a836Yc2l8Evp67YfnNMU9g2J_Yh1LeWDY_sqhdx1uJtQ-- X-Sonic-MF: Received: from sonic.gate.mail.ne1.yahoo.com by sonic317.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Sep 2021 18:03:43 +0000 Received: by kubenode532.mail-prod1.omega.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 6b6c86a25dd254bc610006144a96024f; Fri, 24 Sep 2021 18:03:38 +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 v29 08/28] LSM: Use lsmblob in security_secid_to_secctx Date: Fri, 24 Sep 2021 10:54:21 -0700 Message-Id: <20210924175441.7943-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210924175441.7943-1-casey@schaufler-ca.com> References: <20210924175441.7943-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 | 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 d9030cb6b1e4..42bcf22d1e50 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2711,6 +2711,7 @@ 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; /* @@ -2723,7 +2724,16 @@ static void binder_transaction(struct binder_proc *proc, * case well anyway. */ security_task_getsecid_obj(proc->tsk, &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 e2ca097b58db..60f0a56f43ed 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -548,7 +548,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); @@ -1398,7 +1398,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 447614b7a50b..df8a57c5355d 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -677,6 +677,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, @@ -693,6 +700,13 @@ static int audit_filter_rules(struct task_struct *tsk, if (f->lsm_isset) { /* 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, @@ -999,6 +1013,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) @@ -1008,7 +1023,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 { @@ -1252,8 +1268,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 { @@ -1408,9 +1426,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 b297bb28556e..cb10b5f03cf4 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 f1e5443fe7c7..daf554915e07 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 4c3fbaaeb103..bb97e8af8345 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 520fa287c90c..8163dc615ba6 100644 --- a/security/security.c +++ b/security/security.c @@ -2175,17 +2175,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; }