From patchwork Wed Nov 27 21:37:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11264943 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 723FD139A for ; Wed, 27 Nov 2019 21:37:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 40D192086A for ; Wed, 27 Nov 2019 21:37:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="OCfDa/Mj" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728303AbfK0Vhp (ORCPT ); Wed, 27 Nov 2019 16:37:45 -0500 Received: from sonic311-30.consmr.mail.ne1.yahoo.com ([66.163.188.211]:46562 "EHLO sonic311-30.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728818AbfK0Vho (ORCPT ); Wed, 27 Nov 2019 16:37:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1574890663; bh=Mo4pxsChEWb94RXwY2161OhSVvB+RUXU7Q1KQLhutl8=; h=From:To:Subject:Date:In-Reply-To:References:From:Subject; b=OCfDa/Mjh80SXUnGkERHuHyqTTV4aaPy259xDeAlBs0lNnY98uhBfW6IziZ9tbvAP+n/abXnq4QqCjmGMYe6BG09S7THxdziq0B+GjhlkyW1bArZzTNTYLq+UYzhyZkLBauqi9hhaGwbuKvY/v+c/3uT1/gri58HYcKIp94YpESQZBRnBMZRNSkIUb9RIlIGNyn26e3L8YZ1s/V7H5usuYrQ76yGIcqV11Qas92MDr/u8X5QVBjBI9vIvFk13sMxIbDL7DoCPehdEQFavvjFJaw76JQeA26/ImHVJ5rTLMEhb6XFZyhHaZyo4ub2GmJfjFqCiRnb8niQOq0h9mFE3Q== X-YMail-OSG: 4qEbrn0VM1kP8wTgQbRE0BVchZtEjp9BMltQBeNHr7_m6E7GnocV35G7CwDY0BY Hv1w2lxL1802hegMomvdFKpbidV7ZwAVRSmMtB12nOU3lt9nc5bI2CylFkj1AQ.QAnYl79BaEEWU dxUAX8Nn94XmKbz6ZwsOfEjWBL_BpzzxSBnVLDUCs4koYSHFrstInL0DAqrJZgvPzV4zBcYwVDVe 0NTgsfKjAa3qRi1LUGVY_eXXLW6_c4vGVVRQDx1qU4NekhjodmpcffGMZpTwD01ZcIVKpbmWS_Zg Y7tQbODz80BVTqvMN4YBNWXGKmZeHEwCQ7UvKNMQ_woz9KN5ITVJSmB0dJTqrb6vQlDtz81_j9ZT 1fku0gJ3fM0ZBsrydLzHgr4yTxU7DH6mEhakPZkwmMfH2LP4Yq3ZHCMwy4zgG0dyrTDzdb18gIJB 1vuBS3sUKwmck3ffG4LOJfnVv4ba6Cmc84ptgdZCBhw09hdVmL1c.8.ylLVXBGrQaCIj32BzhUk_ vMLuiz0fEcbYShsjGV9K.3XiS_l6h1gSzWEz9KtJTti.CeGeu8abnqRk4bYhbFCw.dLOG1hXxENT 6k6WLLZmVzusUaHkSL0kPXCs.yVR_8Lyfj_XtPg.tYhcnL3.35kb0MSCctoi14aNZTiVRxWe35ly Flb_o.Hct_bQ.Oxe7ReRs4nc_pcS9tU0dLlM5g6fm4XRiwjgDOGf3GnXMtj7cQk0T9gZUHtKeKJL TZUWrahw66yddNmsua6bi6lNlVws7wVo96XkeY5_E5zLHfrUoUDkoNCrEnIPAd3qjilw50daFfZ3 9xwF6XZ6aK0WrupxevWAPmZjV2nwow4hILUPlu1c2JssMVOjvMYkGeqbyHiTjesf2GnDE_x_z0Rf 4gFBk9B_vHkHMbosI6u54Gqbj6G72Np3HPxPwcVPodDk2PgeBdqJQ_gt8Jj2c0cPUFMpMTFiWopd lKb_HW94f7h6SasMLl.jzTUFjpwvWmSrv2fsLrYGzg4.4.6VwRIaRFeC0k1x5Ui0lk0h7mxIfwDy .4JAxIRvxSDzamA5TlsYSnXA3pxo.I8QVpImJ6Uo.ojAAtqJUhTOyV4Z6jmZhklh1RIvnL3cw_6H 417zRKPXyxqp6FDsPFqrTGD_kvQvkGLDhztT_aV6UUmqjWyIZhd7rEs7qOvE_xqPU6bemDpAuuS1 nOU_pm3KIIDYet19WsAG8zULD.gNKpwRub08wYQ9GfQS7rv79cSMU2DrpNq_vNsTHtOyXiMEWL6c wlZcTfbrqnNDRBBIfvhsV2ZK8GaMABRVo6HU.zjr689qMOkj2JFLh_bRW9ORdONuckQ874.9_xWz AG7EN9ONtcWOWqcPXFsmYVnI__O2LYeKlhpUQY7Da18eU7ssnwWOnC.3wfHkiHu0l_s6fadoItVy b8hcwMBxSSDgSXWmEpa.8emDmNnFIdAio5a4CWbRwoYBtKAY- Received: from sonic.gate.mail.ne1.yahoo.com by sonic311.consmr.mail.ne1.yahoo.com with HTTP; Wed, 27 Nov 2019 21:37:43 +0000 Received: by smtp411.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 1acf01b6929c230fae5ce1ab34c8a381; Wed, 27 Nov 2019 21:37:40 +0000 (UTC) From: Casey Schaufler To: linux-integrity@vger.kernel.org, zohar@linux.ibm.com Subject: [v11-ima PATCH 07/25] LSM: Use lsmblob in security_secid_to_secctx Date: Wed, 27 Nov 2019 13:37:00 -0800 Message-Id: <20191127213718.18267-8-casey@schaufler-ca.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191127213718.18267-1-casey@schaufler-ca.com> References: <20191127213718.18267-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@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. Reviewed-by: Kees Cook Reviewed-by: John Johansen 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 c0a491277aca..33908de32695 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3111,10 +3111,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 7d62721cc18a..2160c160e62c 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -492,7 +492,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); @@ -1293,7 +1293,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 da8dc0db5bd3..2f8e89eaf3e5 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1417,7 +1417,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; } @@ -2060,12 +2063,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 7566e5b1c419..04803c3099b2 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 e2d13cd18875..0412f6744185 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; @@ -621,8 +623,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 feabdfb22920..bfa7f12fde99 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 32bb5383de9b..0fc75a31a6bb 100644 --- a/security/security.c +++ b/security/security.c @@ -1963,10 +1963,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);