From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2AB0AC3B1BF for ; Fri, 14 Feb 2020 23:43:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 037B124649 for ; Fri, 14 Feb 2020 23:43:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="Kv70HIUO" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727932AbgBNXnM (ORCPT ); Fri, 14 Feb 2020 18:43:12 -0500 Received: from sonic308-16.consmr.mail.ne1.yahoo.com ([66.163.187.39]:37573 "EHLO sonic308-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728068AbgBNXnM (ORCPT ); Fri, 14 Feb 2020 18:43:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723790; bh=pJrAQQDy16N+C5H2badS//vd/Z5Dh3P9pJ/xvpazbLs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=Kv70HIUO6EIfNmpJLiWvuv/5pQPIB8LW0ewWanBECCpds3Ihc7yV99POGt1wz0OXC9apQ/lEbtupRXWswm0Y0iM5jgjwpSLx6ioPe7++Zw5hADARdjYNt/yA8vHOKS396EfTe7ydaD+QlgRFrTbzsRVUECWW8xiQLjyY1bO1dtJxbXCI7UVnSvG3WT1mAfNVeFuVNxeYHRngWwocAbf8lvLNLBe/UntqXyvGmAb/GcP9UgV2ug/iLsS/h7EiSFmd/eQ4i9+EWqlV0F94gPSa1Bda8TLdlzkFSnY2ruT6hb8OmlXTIQQvwnizvLfOHJZpmRs7j8pReFJuFaSs5k0Mow== X-YMail-OSG: v.qx020VM1ndcT9evCZW6MIPoXusuQETtP4l4_qsLhtpP6LRClL2.mrB8A3qDUO Df9NQY5mtQfRXKs.wLsb8Hta.RCicegQ5O5XfaKlvyi4xMF8qFjTLVPnNVEIFGN3ER5yt9CRNAcW LlRtAznR37YEsvU_8LaUv97y4_5ccoyfCh.nSyBzGUOny0DB4YbAgVVIPj80bj6RjQppWC6_EyWV ZeAZMjxUGyIYCy3UuYcFTNw8oGDR0dxTxHMQlzUsUl5qD._qubmEVUdRULkhVQCmbZoJ74q7UdZ_ c8X9RFyzxwljtlya6I5yZknNNljBmilFmdiMZUNM79lmAstnGUn0BEhL.ePidtWW15rkVaYp8oFp WWxD1HkAZxAyPWv3hNYBmRXqhugGXOH2E0znh4gnUaPw39kdQemzQ0FWGRWdrzt0w7p0KpoAEaOY IhKPIsMdYedltwOfxxlye6L1bJsM1PzEur8Ml4ML8geXDAyGvfB2ELK_OUIAzxVQutZSLlD.vyCt eyTsQBE1tl3OOf4ltOUkr7rnirF6AH8D9AFAt76T6tThnRqejyPnzNv2Q_AqCul4sBFeIh5L6nkc 9VjkuN3xUkSiNHIpGvbhQQ6HjEND72DZY8cl08MvjH17iUOlCmY7xaHfI2OcLgMLtRa6FOrfOVK8 OtbNIGlEEXmbzl7iIrXPdDH.i.S4NPECZPqezh0_q.iw6gKBOOvtd7hcQ6fU8m7oFyGWBslxv2W2 4jIlvG_FsFR7Wofm18vinLV0sB4_KbCWZeB6puNhmDK8eZa9m5QFmey6AU_NeC9iSSSNYzmFjCB6 3E1JkSRIrTpPwEH0HotsK.QmyAnq33opK.aUZj4vDSahEFhIWLrHjPtnZisrN1O_DlMoo1tg9YW7 sTr8.pqDMZAar9QbDR1nXHMvViG1QzKr4RzDb25Bnu50cweAMa5iCnYqyCr_t_Tv9es3Vs4CtR4x uDpxxrcCde96RJ5vWtNBM1Y33Vp9OcQVtnFktnLSogz4RWZv0FbMNtXRspI0gldfG2hBmxyGrqKP aRIJ3YSjmZbXAO.WqGrFFgwIbsBymHfXqSkRHg08jfuqTwjEZIIsMtFWZ9oAjqVh9EPytk4Orenx OYzHJgdccYI.olB99YNFxruasr04b1AOZOmMU9bxGBmQyhcXLINu8m_q_3gFjQUuc4ObryXzCZ8y qdJKnLGCK1eeh4KM3Unqt5NCiUBnpeM8yYIoZ7.gHkKRi0zKd2EyAHL27XKhWQ67QGau6mc5BX6P 9vmelvdV5kaqhd8wgWdlMDqOczAtJ2EWhhhgnAXs5vEY0j2o.jlcWO.9pZKiIMTbOmHaAMWoJGdr eB20qj_q70WylREUDh8UfENLBMqiJFiNt8zTfZB2FScNRttRwHNBg21OjdbR527yhrQd6ZF1hsDX HF6UCWOOi_iMRxs4LJGvGY.LH.TLowROem9wveMFHIB4FfOtaID8U6vNJzEypxScK0bE- Received: from sonic.gate.mail.ne1.yahoo.com by sonic308.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:43:10 +0000 Received: by smtp421.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 034a07a14f1305e890adf12d8ef35b61; Fri, 14 Feb 2020 23:43:07 +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, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 07/23] LSM: Use lsmblob in security_secid_to_secctx Date: Fri, 14 Feb 2020 15:41:47 -0800 Message-Id: <20200214234203.7086-8-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: owner-linux-security-module@vger.kernel.org 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. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler cc: netdev@vger.kernel.org --- drivers/android/binder.c | 4 +++- include/linux/security.h | 5 +++-- include/net/scm.h | 5 ++--- kernel/audit.c | 9 +++++++-- kernel/auditsc.c | 14 ++++++++++---- net/ipv4/ip_sockglue.c | 3 +-- net/netfilter/nf_conntrack_netlink.c | 8 ++++++-- net/netfilter/nf_conntrack_standalone.c | 4 +++- net/netfilter/nfnetlink_queue.c | 8 ++++++-- net/netlabel/netlabel_unlabeled.c | 18 ++++++++++++++---- net/netlabel/netlabel_user.c | 6 +++--- security/security.c | 16 +++++++++++++--- 12 files changed, 71 insertions(+), 29 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index a6b2082c24f8..a9d9b69d5596 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3107,10 +3107,12 @@ 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_task_getsecid(proc->tsk, &secid); - ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); + 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 65adcffafee9..fdcba6e8d242 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -497,7 +497,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); @@ -1298,7 +1298,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 e2e71c4bf9d0..31ae605fcc0a 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -97,9 +97,8 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - /* Scaffolding - it has to be element 0 for now */ - err = security_secid_to_secctx(scm->lsmblob.secid[0], - &secdata, &seclen); + err = security_secid_to_secctx(&scm->lsmblob, &secdata, + &seclen); if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); diff --git a/kernel/audit.c b/kernel/audit.c index 17b0d523afb3..0fdd51d03598 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1418,7 +1418,10 @@ 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(&blob, audit_sig_sid); + err = security_secid_to_secctx(&blob, &ctx, &len); if (err) return err; } @@ -2061,12 +2064,14 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; u32 sid; + struct lsmblob blob; security_task_getsecid(current, &sid); if (!sid) return 0; - error = security_secid_to_secctx(sid, &ctx, &len); + 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 ef2f5e7eec7b..d6723c225c7e 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -966,6 +966,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) @@ -975,7 +976,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 { @@ -1218,7 +1220,10 @@ static void show_special(struct audit_context *context, int *call_panic) if (osid) { char *ctx = NULL; u32 len; - if (security_secid_to_secctx(osid, &ctx, &len)) { + struct lsmblob blob; + + lsmblob_init(&blob, osid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { @@ -1368,9 +1373,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 6cf57d5ac899..1ca97d0cb4a9 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -139,8 +139,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) if (err) return; - /* Scaffolding - it has to be element 0 */ - err = security_secid_to_secctx(lb.secid[0], &secdata, &seclen); + 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 6a1c8f1f6171..68c74c28eae9 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -331,8 +331,10 @@ 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(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, &secctx, &len); if (ret) return 0; @@ -643,8 +645,10 @@ 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(&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 410809c669e1..183a85412155 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -175,8 +175,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 76535fd9278c..b7b296fe0c0b 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -305,13 +305,17 @@ 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(&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 7a5a87f15736..0cda17cb44a0 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -375,6 +375,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)) @@ -437,7 +438,8 @@ 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(&blob, secid); + if (security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); @@ -474,6 +476,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 +496,10 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); if (dev != NULL) dev_put(dev); + 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 +541,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); @@ -554,8 +560,10 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); if (dev != NULL) dev_put(dev); + 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); @@ -1076,6 +1084,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, @@ -1130,7 +1139,8 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, secid = addr6->secid; } - ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len); + 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 e0f9287483aa..dae86629a2f6 100644 --- a/security/security.c +++ b/security/security.c @@ -1995,10 +1995,20 @@ 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) { - return call_int_hook(secid_to_secctx, -EOPNOTSUPP, secid, secdata, - seclen); + struct security_hook_list *hp; + int rc; + + hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { + 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 != 0) + return rc; + } + return 0; } EXPORT_SYMBOL(security_secid_to_secctx); -- 2.24.1