From patchwork Wed Nov 4 23:40:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882379 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 E5EC216C1 for ; Wed, 4 Nov 2020 23:44:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A653520825 for ; Wed, 4 Nov 2020 23:44:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="Y7liC29Y" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730361AbgKDXoh (ORCPT ); Wed, 4 Nov 2020 18:44:37 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:39417 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733039AbgKDXnr (ORCPT ); Wed, 4 Nov 2020 18:43:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533423; bh=Wnr3DOH7qGofeaT/FCDDJK2H4g+EnCibappbIfk/7H0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=Y7liC29YX48KGbBepftLuLix9SgWbQbTUWm3HYXi97GewLrpTi7gOn2kWc+BCuqFlBgdsUyXCzoVVDGcvknHcjDdQdEc+sW/rJ8J1c3Eg4//uoQZvWooU2qsV3GzNwrhk+8dyO3RKqWp85WjfDtBikBpCcc4JajPuDN1TaD2rEReOzW8EbbZsGHWxwymcRRM5deTYe8dzPA+heBu98QAPkXRZXBj3q9tfDlpqCXvXNyxjIGe8n4ByJ9F0Xu4wbJoH2G5WlNN5hy+Pu2iwXpPHNsr0bn2WqBpeEkslTo5qHdrpugwE0iWIGE6AjjsKKVxnKoec7VHu9UIhVJmoTZb7g== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533423; bh=iDvLKoF3QS5k/JE6PkLs6mqEmuKVhEuHDvsVcSbQ6wp=; h=From:To:Subject:Date; b=dlOfXx8jMHDDl6PJCRYt0f5XTZKgy/y7Nz86y2mZq4gc97khR+oFIL2rKXEWn3HsIhevYXMQEXQyYqseHYA1x1iOhn+mekf5E9oPE3e22W422B9SqNKNTU1lCKVCCKTDI2Q77cllVJGIsdyei/81vd5b8mrqW/uoA3NgadBlSpj0jJNyvNKtfNkZsWkG/F25W7qvAWcKX+oF5Gshdkfg92oFuC/cxqNBapcjF9GmEWDg5g2k6/RCBNTmQtBG+XWXDNRXRDPBKSJc8too0Ki4pjElpFWQw8ispsXc4Drikubj9z9LDueXAcaf5GUm2UMk9d37CxweIMMfw7PW4FqDQg== X-YMail-OSG: VHT2B8sVM1l34O5jTlPOhPmOz_NU7CgS7q7PNeIFpF43asksz2wjLTJ1FAKR5CY Yoc.k3fz.rS5tXc511RMfeX75PcQ5xts70iVn2wF0eWNcpYqGTIQx2rbC2G3f4fH2y5nRt8B7Bhp x5KZj71ILC5SXsz7QHKjBkDmZOT4haaBNYbXyTpCtgaul3DdoFENQpGODV.tDOuKbAXt9niLHG4W VRr0m1JCcG9l7jGnIHiPcj6YMKeiUl9o0Z1aF6kLCsBnh1wCwLiHETCD4cCRx0i6YjbLPGoKD0Ow d4o2dJaa_s8NLsi0D5FjfMixmN.WI5076j6GkKbO1spVr9Xl1DM4CmZO_xDsOZWSRyreq.380rbc E6ZRlHtbJbBpX71qPt6wmX7dp0kOmGIqLz5FcEQLxykWnEmC0sDsfmEDjz1IXZokOOnUBmZwqUht MMdpIkI8yg1GlMplW2Dw7Q_nnRu3tH5cHCAJh3nNK.yg.GPk2ow2mITn3lHDtXxoS.tv5RXyS3MI JwYSwXAmwxBPmLME_GMJ5L_ehMTvm9SASXNReKPLWAPIai9Kn6LqUzLc6jUkXvfyKFthk0I_Mj81 Jg7f8PkQNbYVWTd1M.V_sRs7EKyI6v7bweCkRmnv5xywx4gqGc4Ldoe9mdllVzFHxGIqqiVtm1QZ Li1HlAJf0YTAiEbmUqSoHMhK.o3DmVB6Zc8oKr5ZzxxKgkyghY_qannBejCnM0ELaTrfzgm5QBEU tkswaZ0MumAoFhiZ6yqn2gcD8kWqzvKMJtHaNe63W1elo1714eG0OhDnsnDdBcF9CHcLDKWDalgG BXr3ji1YnxQISD6GC7r9Km04KtWW5xnGsnYXocwy7i4qnroS4vlxa5R9XviHzFt02DRv5GINiwuB 1VgJcmF6GiVu2zXLJC66ZzaUF1a8XtGthO1XtVYNVHULbhOrq5rF59ChTsf1jHn4eD1Yes2V8w3_ wK_HdHPKdkYXfewjRCEN0zFkA7FhjJLbX4G9d8CQ7KzlNzrf3GYKtA1OriYXBmEjNrylbpN5YXIB 3vPIDVDa8MIHwkVvtC_zHnrrRFtCDz0brqfwue5cwMMTXa1n7JVyCQuBtxtMOaT9OWrjK6.YtOlt VAC_vcOFeBnEiHJ24pUBmKc224NdaNT4xX53IHU6Cr346Mcrhimwqlx73iaVUQBrFLfBst1w3e9m 4vwoBzfw4lTcBXlrwwa4_aBuTs7z7zTdXtoOvPrvBcEcqZb5kfsydyd465.RSWQGxO4bJnZ3DSJG Srw0Si0Zn1Mp7jYctg8LfmTobkeJ._sZXCHYLiyx2c2FlRQesCcz4HDCE9nSH3vg0l4mEkcYWiMN _iuOjavnoFB4Tn2z06WZYeL6ydFDGtPxRk81Zt1_.0wWK4BNuBBeS1y6iuyp.ZIpDrKSYsjdz1RT PokVxW9TltRE.GpqIvNy0YdEhz_EjgMPCYHVw35hy2fVHsWgFzhNbBB2VUhF0PBhc5BZuwf_dEXa d5qMbGU8B99OyezsOPGPzeLXTNMvg80QrBGnyb1DR1uPWQdfl_QjM.v6Xb1E.GsJudxGbivgA846 pmHp_SnVS6mz1zkankUPzXPlOGfx_DDfDtvfAqQHH_uNWSap.JJpO.8wSubaY229Xdl5FzKGcRL4 2gxxCBWSAQ60Q7ccu8ObSgiCoJjeSjYnXB307hgeCDGiTA5gz4fLLzeT6.Rd5sIaTNrzhgSpFayl jnosvHzFY3rWsXjmQfxuODzXr162Ve3W2yb3omH0_s3zPJtyz2_unbUdzVMJGs9uliQL3E4f9qMz .liZLtdSchS5UsQY3PCa6dVf6cuqRE8ctuCduJG500.QqKsGHw9HxDCDYsUwBRTUIim23NU5ChHg YewYxIy3AbeWETbsfU7qArfzq5yOIwth1613sOVaazXJTGx.e3kE1chuGIi8bCxh9nWu4.Qze7za XTT3gbZ0jgnr.wrI.M75wRNArNcaWSvlBuOgSpeEWZkVVmtm7KJmxn31fS4snV3EL72dfIwPDGNT yiOtph3pyeCEicSDx0yVWgtV8jNgv_yjYhtCNwJKQjpZQkacSeVizipUYaWRLbH0wqxJRjs0u5IW A6IWueDQcmoP2sjgZJxUq4EBIqM60iPz51FeYTJ4hSBCDRjlQsYbD7oTIKhD9JLRMQ0Olc7tYnw4 JdGKo1kjxMjB6Vx8wZ1kyd._xQHYKSCt.TVreFksJVw7x29GntGbTQc7mKfxFKOZjRgF2kN0r74B peb08cr3XJqpbzeOQTWCz__V.4yigXv51bviMy_nZPUT62T3nyg5UYETtXbkW8qxv9do._yuQYD1 8u6lx2j3MECxcP8L1.XvdGv.LdszaLpMjS0FDCPtTlRL1r2nboMYWH0USNBnB3BeO98FR5QQBL_Q wP8YfeFwTyG7M_.MAHkZD7u0EwCtTxaBbEi9dzeMwTfb4Ch1zSeDlbDuxzEftOLziJ6_GQJNmSdU IlX0uLh._UG9Lk6BLOxz6hYJQnfym7UtLiq7yXcHmbM9bor0GMDXkLqsLHeHgj7Z36jBQyWJYM4e ymR_ouwCeEyC3nqYnAIVjJbnHgETvVwRL5Q9u6bE1h9cYbYLzoWNAStvGiQEvKzvg2QBX.f9PhU0 tbK1oHglPeGv2yHWZG5HuM_gKZlmrnASDqe1MQX_rDASDuPXe4cm8i95DUZrmw6TH.ynRhBcD7M. OOMD1wAot7zumxKYqIPjHCnNHtdisP1s4DvesdfBOsxJc.lK5TaZNgT8pljFGSb1jkEO8zXTtXvD 9KJ7knQUCtfZmr71gdQGvLOfx5WyT2cipq7a8Gczvk6hh7SrEJ_W_yMxA7oQ3yLTJrndmzzOc81P EnHxlutuc8iddLBgAsQQDphvQj5Ebvs0.yVgRFyeI.7HxU5QP.j84pdmqnlXPrxTOywmGV0Y4yQh 28nTHZRDJSrn9HkfM9KLtiQNCaP3G4ip0TVu4NMn.xAaWT0DTM6h0O7QTlOY5rJudeb8VRsvkoi. gZ2sReMQM_YZ_LlJH3YycIKPDwWbcP0E0ETGGVI9gS83xe.75KHoszzn8CdMYsX0_MgPoopWHMZC AABz5_KENqS7JXo44L1q.R7RxCNKjurfmTW7Es3wvFyBEsc3rKeSgYbnXLII2WrDIRLmBLuAPAJz HXJwaKWG4KsC0uFLYRA4MzgpjEYs0GnDmRgoAqqk2V8tt3BtUD5UCN_NXIH47xh2MtvoQ_kPQdvq 1tT1QLDzfnhns4dlq4pWfPforMaj6QVInJjV3Z0zHkM93MLCne9BwswvW0hnhWSIh1VYtnQYawqq 9wjK3EQNYZIW_SPa8Kr.tl4n72z7bIqb3aZ62vPeWB9qQF.D0MYTPtmUv92dHoB16yUW9XGjLIgh XABRwb2huQxPq Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:43:43 +0000 Received: by smtp420.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID b0c8ff667e40b4055c3d888545fa5fd7; Wed, 04 Nov 2020 23:43:41 +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 Subject: [PATCH v22 01/23] LSM: Infrastructure management of the sock security Date: Wed, 4 Nov 2020 15:40:52 -0800 Message-Id: <20201104234114.11346-2-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: Move management of the sock->sk_security blob out of the individual security modules and into the security infrastructure. Instead of allocating the blobs from within the modules the modules tell the infrastructure how much space is required, and the space is allocated there. Acked-by: Paul Moore Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler --- include/linux/lsm_hooks.h | 1 + security/apparmor/include/net.h | 6 ++- security/apparmor/lsm.c | 38 ++++----------- security/security.c | 36 +++++++++++++- security/selinux/hooks.c | 78 +++++++++++++++---------------- security/selinux/include/objsec.h | 5 ++ security/selinux/netlabel.c | 23 ++++----- security/smack/smack.h | 5 ++ security/smack/smack_lsm.c | 66 ++++++++++++-------------- security/smack/smack_netfilter.c | 8 ++-- 10 files changed, 145 insertions(+), 121 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index c503f7ab8afb..d8f492ed6ebf 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1563,6 +1563,7 @@ struct lsm_blob_sizes { int lbs_cred; int lbs_file; int lbs_inode; + int lbs_sock; int lbs_ipc; int lbs_msg_msg; int lbs_task; diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h index 2431c011800d..5b6f52c62058 100644 --- a/security/apparmor/include/net.h +++ b/security/apparmor/include/net.h @@ -51,7 +51,11 @@ struct aa_sk_ctx { struct aa_label *peer; }; -#define SK_CTX(X) ((X)->sk_security) +static inline struct aa_sk_ctx *aa_sock(const struct sock *sk) +{ + return sk->sk_security + apparmor_blob_sizes.lbs_sock; +} + #define SOCK_ctx(X) SOCK_INODE(X)->i_security #define DEFINE_AUDIT_NET(NAME, OP, SK, F, T, P) \ struct lsm_network_audit NAME ## _net = { .sk = (SK), \ diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index ffeaee5ed968..f1c365905d5e 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -766,33 +766,15 @@ static int apparmor_task_kill(struct task_struct *target, struct kernel_siginfo return error; } -/** - * apparmor_sk_alloc_security - allocate and attach the sk_security field - */ -static int apparmor_sk_alloc_security(struct sock *sk, int family, gfp_t flags) -{ - struct aa_sk_ctx *ctx; - - ctx = kzalloc(sizeof(*ctx), flags); - if (!ctx) - return -ENOMEM; - - SK_CTX(sk) = ctx; - - return 0; -} - /** * apparmor_sk_free_security - free the sk_security field */ static void apparmor_sk_free_security(struct sock *sk) { - struct aa_sk_ctx *ctx = SK_CTX(sk); + struct aa_sk_ctx *ctx = aa_sock(sk); - SK_CTX(sk) = NULL; aa_put_label(ctx->label); aa_put_label(ctx->peer); - kfree(ctx); } /** @@ -801,8 +783,8 @@ static void apparmor_sk_free_security(struct sock *sk) static void apparmor_sk_clone_security(const struct sock *sk, struct sock *newsk) { - struct aa_sk_ctx *ctx = SK_CTX(sk); - struct aa_sk_ctx *new = SK_CTX(newsk); + struct aa_sk_ctx *ctx = aa_sock(sk); + struct aa_sk_ctx *new = aa_sock(newsk); if (new->label) aa_put_label(new->label); @@ -858,7 +840,7 @@ static int apparmor_socket_post_create(struct socket *sock, int family, label = aa_get_current_label(); if (sock->sk) { - struct aa_sk_ctx *ctx = SK_CTX(sock->sk); + struct aa_sk_ctx *ctx = aa_sock(sock->sk); aa_put_label(ctx->label); ctx->label = aa_get_label(label); @@ -1043,7 +1025,7 @@ static int apparmor_socket_shutdown(struct socket *sock, int how) */ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { - struct aa_sk_ctx *ctx = SK_CTX(sk); + struct aa_sk_ctx *ctx = aa_sock(sk); if (!skb->secmark) return 0; @@ -1056,7 +1038,7 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) static struct aa_label *sk_peer_label(struct sock *sk) { - struct aa_sk_ctx *ctx = SK_CTX(sk); + struct aa_sk_ctx *ctx = aa_sock(sk); if (ctx->peer) return ctx->peer; @@ -1140,7 +1122,7 @@ static int apparmor_socket_getpeersec_dgram(struct socket *sock, */ static void apparmor_sock_graft(struct sock *sk, struct socket *parent) { - struct aa_sk_ctx *ctx = SK_CTX(sk); + struct aa_sk_ctx *ctx = aa_sock(sk); if (!ctx->label) ctx->label = aa_get_current_label(); @@ -1150,7 +1132,7 @@ static void apparmor_sock_graft(struct sock *sk, struct socket *parent) static int apparmor_inet_conn_request(struct sock *sk, struct sk_buff *skb, struct request_sock *req) { - struct aa_sk_ctx *ctx = SK_CTX(sk); + struct aa_sk_ctx *ctx = aa_sock(sk); if (!skb->secmark) return 0; @@ -1167,6 +1149,7 @@ struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = { .lbs_cred = sizeof(struct aa_task_ctx *), .lbs_file = sizeof(struct aa_file_ctx), .lbs_task = sizeof(struct aa_task_ctx), + .lbs_sock = sizeof(struct aa_sk_ctx), }; static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { @@ -1203,7 +1186,6 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(getprocattr, apparmor_getprocattr), LSM_HOOK_INIT(setprocattr, apparmor_setprocattr), - LSM_HOOK_INIT(sk_alloc_security, apparmor_sk_alloc_security), LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security), LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security), @@ -1754,7 +1736,7 @@ static unsigned int apparmor_ip_postroute(void *priv, if (sk == NULL) return NF_ACCEPT; - ctx = SK_CTX(sk); + ctx = aa_sock(sk); if (!apparmor_secmark_check(ctx->label, OP_SENDMSG, AA_MAY_SEND, skb->secmark, sk)) return NF_ACCEPT; diff --git a/security/security.c b/security/security.c index a28045dc9e7f..5da8b3643680 100644 --- a/security/security.c +++ b/security/security.c @@ -29,6 +29,7 @@ #include #include #include +#include #define MAX_LSM_EVM_XATTR 2 @@ -202,6 +203,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed) lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode); lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc); lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg); + lsm_set_blob_size(&needed->lbs_sock, &blob_sizes.lbs_sock); lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task); } @@ -337,6 +339,7 @@ static void __init ordered_lsm_init(void) init_debug("inode blob size = %d\n", blob_sizes.lbs_inode); init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc); init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); + init_debug("sock blob size = %d\n", blob_sizes.lbs_sock); init_debug("task blob size = %d\n", blob_sizes.lbs_task); /* @@ -655,6 +658,28 @@ static int lsm_msg_msg_alloc(struct msg_msg *mp) return 0; } +/** + * lsm_sock_alloc - allocate a composite sock blob + * @sock: the sock that needs a blob + * @priority: allocation mode + * + * Allocate the sock blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +static int lsm_sock_alloc(struct sock *sock, gfp_t priority) +{ + if (blob_sizes.lbs_sock == 0) { + sock->sk_security = NULL; + return 0; + } + + sock->sk_security = kzalloc(blob_sizes.lbs_sock, priority); + if (sock->sk_security == NULL) + return -ENOMEM; + return 0; +} + /** * lsm_early_task - during initialization allocate a composite task blob * @task: the task that needs a blob @@ -2193,12 +2218,21 @@ EXPORT_SYMBOL(security_socket_getpeersec_dgram); int security_sk_alloc(struct sock *sk, int family, gfp_t priority) { - return call_int_hook(sk_alloc_security, 0, sk, family, priority); + int rc = lsm_sock_alloc(sk, priority); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(sk_alloc_security, 0, sk, family, priority); + if (unlikely(rc)) + security_sk_free(sk); + return rc; } void security_sk_free(struct sock *sk) { call_void_hook(sk_free_security, sk); + kfree(sk->sk_security); + sk->sk_security = NULL; } void security_sk_clone(const struct sock *sk, struct sock *newsk) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6b1826fc3658..2748281a5cca 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4476,7 +4476,7 @@ static int socket_sockcreate_sid(const struct task_security_struct *tsec, static int sock_has_perm(struct sock *sk, u32 perms) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct common_audit_data ad; struct lsm_network_audit net = {0,}; @@ -4533,7 +4533,7 @@ static int selinux_socket_post_create(struct socket *sock, int family, isec->initialized = LABEL_INITIALIZED; if (sock->sk) { - sksec = sock->sk->sk_security; + sksec = selinux_sock(sock->sk); sksec->sclass = sclass; sksec->sid = sid; /* Allows detection of the first association on this socket */ @@ -4549,8 +4549,8 @@ static int selinux_socket_post_create(struct socket *sock, int family, static int selinux_socket_socketpair(struct socket *socka, struct socket *sockb) { - struct sk_security_struct *sksec_a = socka->sk->sk_security; - struct sk_security_struct *sksec_b = sockb->sk->sk_security; + struct sk_security_struct *sksec_a = selinux_sock(socka->sk); + struct sk_security_struct *sksec_b = selinux_sock(sockb->sk); sksec_a->peer_sid = sksec_b->sid; sksec_b->peer_sid = sksec_a->sid; @@ -4565,7 +4565,7 @@ static int selinux_socket_socketpair(struct socket *socka, static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) { struct sock *sk = sock->sk; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); u16 family; int err; @@ -4700,7 +4700,7 @@ static int selinux_socket_connect_helper(struct socket *sock, struct sockaddr *address, int addrlen) { struct sock *sk = sock->sk; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); int err; err = sock_has_perm(sk, SOCKET__CONNECT); @@ -4879,9 +4879,9 @@ static int selinux_socket_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk) { - struct sk_security_struct *sksec_sock = sock->sk_security; - struct sk_security_struct *sksec_other = other->sk_security; - struct sk_security_struct *sksec_new = newsk->sk_security; + struct sk_security_struct *sksec_sock = selinux_sock(sock); + struct sk_security_struct *sksec_other = selinux_sock(other); + struct sk_security_struct *sksec_new = selinux_sock(newsk); struct common_audit_data ad; struct lsm_network_audit net = {0,}; int err; @@ -4913,8 +4913,8 @@ static int selinux_socket_unix_stream_connect(struct sock *sock, static int selinux_socket_unix_may_send(struct socket *sock, struct socket *other) { - struct sk_security_struct *ssec = sock->sk->sk_security; - struct sk_security_struct *osec = other->sk->sk_security; + struct sk_security_struct *ssec = selinux_sock(sock->sk); + struct sk_security_struct *osec = selinux_sock(other->sk); struct common_audit_data ad; struct lsm_network_audit net = {0,}; @@ -4956,7 +4956,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, u16 family) { int err = 0; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); u32 sk_sid = sksec->sid; struct common_audit_data ad; struct lsm_network_audit net = {0,}; @@ -4989,7 +4989,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { int err; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); u16 family = sk->sk_family; u32 sk_sid = sksec->sid; struct common_audit_data ad; @@ -5057,13 +5057,15 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) return err; } -static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval, - int __user *optlen, unsigned len) +static int selinux_socket_getpeersec_stream(struct socket *sock, + char __user *optval, + int __user *optlen, + unsigned int len) { int err = 0; char *scontext; u32 scontext_len; - struct sk_security_struct *sksec = sock->sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sock->sk); u32 peer_sid = SECSID_NULL; if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET || @@ -5123,34 +5125,27 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff * static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) { - struct sk_security_struct *sksec; - - sksec = kzalloc(sizeof(*sksec), priority); - if (!sksec) - return -ENOMEM; + struct sk_security_struct *sksec = selinux_sock(sk); sksec->peer_sid = SECINITSID_UNLABELED; sksec->sid = SECINITSID_UNLABELED; sksec->sclass = SECCLASS_SOCKET; selinux_netlbl_sk_security_reset(sksec); - sk->sk_security = sksec; return 0; } static void selinux_sk_free_security(struct sock *sk) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); - sk->sk_security = NULL; selinux_netlbl_sk_security_free(sksec); - kfree(sksec); } static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) { - struct sk_security_struct *sksec = sk->sk_security; - struct sk_security_struct *newsksec = newsk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); + struct sk_security_struct *newsksec = selinux_sock(newsk); newsksec->sid = sksec->sid; newsksec->peer_sid = sksec->peer_sid; @@ -5164,7 +5159,7 @@ static void selinux_sk_getsecid(struct sock *sk, u32 *secid) if (!sk) *secid = SECINITSID_ANY_SOCKET; else { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); *secid = sksec->sid; } @@ -5174,7 +5169,7 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent) { struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(parent)); - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 || sk->sk_family == PF_UNIX) @@ -5189,7 +5184,7 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent) static int selinux_sctp_assoc_request(struct sctp_endpoint *ep, struct sk_buff *skb) { - struct sk_security_struct *sksec = ep->base.sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(ep->base.sk); struct common_audit_data ad; struct lsm_network_audit net = {0,}; u8 peerlbl_active; @@ -5340,8 +5335,8 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname, static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk, struct sock *newsk) { - struct sk_security_struct *sksec = sk->sk_security; - struct sk_security_struct *newsksec = newsk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); + struct sk_security_struct *newsksec = selinux_sock(newsk); /* If policy does not support SECCLASS_SCTP_SOCKET then call * the non-sctp clone version. @@ -5358,7 +5353,7 @@ static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk, static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, struct request_sock *req) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); int err; u16 family = req->rsk_ops->family; u32 connsid; @@ -5379,7 +5374,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, static void selinux_inet_csk_clone(struct sock *newsk, const struct request_sock *req) { - struct sk_security_struct *newsksec = newsk->sk_security; + struct sk_security_struct *newsksec = selinux_sock(newsk); newsksec->sid = req->secid; newsksec->peer_sid = req->peer_secid; @@ -5396,7 +5391,7 @@ static void selinux_inet_csk_clone(struct sock *newsk, static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb) { u16 family = sk->sk_family; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); /* handle mapped IPv4 packets arriving via IPv6 sockets */ if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) @@ -5480,7 +5475,7 @@ static int selinux_tun_dev_attach_queue(void *security) static int selinux_tun_dev_attach(struct sock *sk, void *security) { struct tun_security_struct *tunsec = security; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); /* we don't currently perform any NetLabel based labeling here and it * isn't clear that we would want to do so anyway; while we could apply @@ -5624,7 +5619,7 @@ static unsigned int selinux_ip_output(struct sk_buff *skb, return NF_ACCEPT; /* standard practice, label using the parent socket */ - sksec = sk->sk_security; + sksec = selinux_sock(sk); sid = sksec->sid; } else sid = SECINITSID_KERNEL; @@ -5663,7 +5658,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, if (sk == NULL) return NF_ACCEPT; - sksec = sk->sk_security; + sksec = selinux_sock(sk); ad.type = LSM_AUDIT_DATA_NET; ad.u.net = &net; @@ -5755,7 +5750,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, u32 skb_sid; struct sk_security_struct *sksec; - sksec = sk->sk_security; + sksec = selinux_sock(sk); if (selinux_skb_peerlbl_sid(skb, family, &skb_sid)) return NF_DROP; /* At this point, if the returned skb peerlbl is SECSID_NULL @@ -5784,7 +5779,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, } else { /* Locally generated packet, fetch the security label from the * associated socket. */ - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); peer_sid = sksec->sid; secmark_perm = PACKET__SEND; } @@ -5849,7 +5844,7 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) unsigned int data_len = skb->len; unsigned char *data = skb->data; struct nlmsghdr *nlh; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); u16 sclass = sksec->sclass; u32 perm; @@ -6874,6 +6869,7 @@ struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = { .lbs_inode = sizeof(struct inode_security_struct), .lbs_ipc = sizeof(struct ipc_security_struct), .lbs_msg_msg = sizeof(struct msg_security_struct), + .lbs_sock = sizeof(struct sk_security_struct), }; #ifdef CONFIG_PERF_EVENTS diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 330b7b6d44e0..9ca41988281f 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -189,4 +189,9 @@ static inline u32 current_sid(void) return tsec->sid; } +static inline struct sk_security_struct *selinux_sock(const struct sock *sock) +{ + return sock->sk_security + selinux_blob_sizes.lbs_sock; +} + #endif /* _SELINUX_OBJSEC_H_ */ diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index abaab7683840..6a94b31b5472 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -67,7 +68,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb, static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk) { int rc; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr *secattr; if (sksec->nlbl_secattr != NULL) @@ -100,7 +101,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr( const struct sock *sk, u32 sid) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr; if (secattr == NULL) @@ -235,7 +236,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, * being labeled by it's parent socket, if it is just exit */ sk = skb_to_full_sk(skb); if (sk != NULL) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (sksec->nlbl_state != NLBL_REQSKB) return 0; @@ -273,7 +274,7 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep, { int rc; struct netlbl_lsm_secattr secattr; - struct sk_security_struct *sksec = ep->base.sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(ep->base.sk); struct sockaddr_in addr4; struct sockaddr_in6 addr6; @@ -352,7 +353,7 @@ int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family) */ void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (family == PF_INET) sksec->nlbl_state = NLBL_LABELED; @@ -370,8 +371,8 @@ void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) */ void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk) { - struct sk_security_struct *sksec = sk->sk_security; - struct sk_security_struct *newsksec = newsk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); + struct sk_security_struct *newsksec = selinux_sock(newsk); newsksec->nlbl_state = sksec->nlbl_state; } @@ -389,7 +390,7 @@ void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk) int selinux_netlbl_socket_post_create(struct sock *sk, u16 family) { int rc; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr *secattr; if (family != PF_INET && family != PF_INET6) @@ -504,7 +505,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, { int rc = 0; struct sock *sk = sock->sk; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr secattr; if (selinux_netlbl_option(level, optname) && @@ -542,7 +543,7 @@ static int selinux_netlbl_socket_connect_helper(struct sock *sk, struct sockaddr *addr) { int rc; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr *secattr; /* connected sockets are allowed to disconnect when the address family @@ -581,7 +582,7 @@ static int selinux_netlbl_socket_connect_helper(struct sock *sk, int selinux_netlbl_socket_connect_locked(struct sock *sk, struct sockaddr *addr) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (sksec->nlbl_state != NLBL_REQSKB && sksec->nlbl_state != NLBL_CONNLABELED) diff --git a/security/smack/smack.h b/security/smack/smack.h index a9768b12716b..0f8d0feb89a4 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -357,6 +357,11 @@ static inline struct smack_known **smack_ipc(const struct kern_ipc_perm *ipc) return ipc->security + smack_blob_sizes.lbs_ipc; } +static inline struct socket_smack *smack_sock(const struct sock *sock) +{ + return sock->sk_security + smack_blob_sizes.lbs_sock; +} + /* * Is the directory transmuting? */ diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 5c90b9fa4d40..ca4a6c862732 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -1444,7 +1444,7 @@ static int smack_inode_getsecurity(struct inode *inode, if (sock == NULL || sock->sk == NULL) return -EOPNOTSUPP; - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); if (strcmp(name, XATTR_SMACK_IPIN) == 0) isp = ssp->smk_in; @@ -1826,7 +1826,7 @@ static int smack_file_receive(struct file *file) if (inode->i_sb->s_magic == SOCKFS_MAGIC) { sock = SOCKET_I(inode); - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); tsp = smack_cred(current_cred()); /* * If the receiving process can't write to the @@ -2233,11 +2233,7 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode) static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) { struct smack_known *skp = smk_of_current(); - struct socket_smack *ssp; - - ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); - if (ssp == NULL) - return -ENOMEM; + struct socket_smack *ssp = smack_sock(sk); /* * Sockets created by kernel threads receive web label. @@ -2251,11 +2247,10 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) } ssp->smk_packet = NULL; - sk->sk_security = ssp; - return 0; } +#ifdef SMACK_IPV6_PORT_LABELING /** * smack_sk_free_security - Free a socket blob * @sk: the socket @@ -2264,7 +2259,6 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) */ static void smack_sk_free_security(struct sock *sk) { -#ifdef SMACK_IPV6_PORT_LABELING struct smk_port_label *spp; if (sk->sk_family == PF_INET6) { @@ -2277,9 +2271,8 @@ static void smack_sk_free_security(struct sock *sk) } rcu_read_unlock(); } -#endif - kfree(sk->sk_security); } +#endif /** * smack_ipv4host_label - check host based restrictions @@ -2392,7 +2385,7 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip) */ static int smack_netlbl_add(struct sock *sk) { - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smack_known *skp = ssp->smk_out; int rc; @@ -2424,7 +2417,7 @@ static int smack_netlbl_add(struct sock *sk) */ static void smack_netlbl_delete(struct sock *sk) { - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); /* * Take the label off the socket if one is set. @@ -2456,7 +2449,7 @@ static int smk_ipv4_check(struct sock *sk, struct sockaddr_in *sap) struct smack_known *skp; int rc = 0; struct smack_known *hkp; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smk_audit_info ad; rcu_read_lock(); @@ -2529,7 +2522,7 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address) { struct sock *sk = sock->sk; struct sockaddr_in6 *addr6; - struct socket_smack *ssp = sock->sk->sk_security; + struct socket_smack *ssp = smack_sock(sock->sk); struct smk_port_label *spp; unsigned short port = 0; @@ -2618,7 +2611,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, int act) { struct smk_port_label *spp; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smack_known *skp = NULL; unsigned short port; struct smack_known *object; @@ -2711,7 +2704,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, if (sock == NULL || sock->sk == NULL) return -EOPNOTSUPP; - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); if (strcmp(name, XATTR_SMACK_IPIN) == 0) ssp->smk_in = skp; @@ -2759,7 +2752,7 @@ static int smack_socket_post_create(struct socket *sock, int family, * Sockets created by kernel threads receive web label. */ if (unlikely(current->flags & PF_KTHREAD)) { - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); ssp->smk_in = &smack_known_web; ssp->smk_out = &smack_known_web; } @@ -2784,8 +2777,8 @@ static int smack_socket_post_create(struct socket *sock, int family, static int smack_socket_socketpair(struct socket *socka, struct socket *sockb) { - struct socket_smack *asp = socka->sk->sk_security; - struct socket_smack *bsp = sockb->sk->sk_security; + struct socket_smack *asp = smack_sock(socka->sk); + struct socket_smack *bsp = smack_sock(sockb->sk); asp->smk_packet = bsp->smk_out; bsp->smk_packet = asp->smk_out; @@ -2848,7 +2841,7 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, if (__is_defined(SMACK_IPV6_SECMARK_LABELING)) rsp = smack_ipv6host_label(sip); if (rsp != NULL) { - struct socket_smack *ssp = sock->sk->sk_security; + struct socket_smack *ssp = smack_sock(sock->sk); rc = smk_ipv6_check(ssp->smk_out, rsp, sip, SMK_CONNECTING); @@ -3576,9 +3569,9 @@ static int smack_unix_stream_connect(struct sock *sock, { struct smack_known *skp; struct smack_known *okp; - struct socket_smack *ssp = sock->sk_security; - struct socket_smack *osp = other->sk_security; - struct socket_smack *nsp = newsk->sk_security; + struct socket_smack *ssp = smack_sock(sock); + struct socket_smack *osp = smack_sock(other); + struct socket_smack *nsp = smack_sock(newsk); struct smk_audit_info ad; int rc = 0; #ifdef CONFIG_AUDIT @@ -3624,8 +3617,8 @@ static int smack_unix_stream_connect(struct sock *sock, */ static int smack_unix_may_send(struct socket *sock, struct socket *other) { - struct socket_smack *ssp = sock->sk->sk_security; - struct socket_smack *osp = other->sk->sk_security; + struct socket_smack *ssp = smack_sock(sock->sk); + struct socket_smack *osp = smack_sock(other->sk); struct smk_audit_info ad; int rc; @@ -3662,7 +3655,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; #endif #ifdef SMACK_IPV6_SECMARK_LABELING - struct socket_smack *ssp = sock->sk->sk_security; + struct socket_smack *ssp = smack_sock(sock->sk); struct smack_known *rsp; #endif int rc = 0; @@ -3875,7 +3868,7 @@ static struct smack_known *smack_from_netlbl(struct sock *sk, u16 family, netlbl_secattr_init(&secattr); if (sk) - ssp = sk->sk_security; + ssp = smack_sock(sk); if (netlbl_skbuff_getattr(skb, family, &secattr) == 0) { skp = smack_from_secattr(&secattr, ssp); @@ -3897,7 +3890,7 @@ static struct smack_known *smack_from_netlbl(struct sock *sk, u16 family, */ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smack_known *skp = NULL; int rc = 0; struct smk_audit_info ad; @@ -4001,7 +3994,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock, int slen = 1; int rc = 0; - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); if (ssp->smk_packet != NULL) { rcp = ssp->smk_packet->smk_known; slen = strlen(rcp) + 1; @@ -4050,7 +4043,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, switch (family) { case PF_UNIX: - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); s = ssp->smk_out->smk_secid; break; case PF_INET: @@ -4099,7 +4092,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent) (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)) return; - ssp = sk->sk_security; + ssp = smack_sock(sk); ssp->smk_in = skp; ssp->smk_out = skp; /* cssp->smk_packet is already set in smack_inet_csk_clone() */ @@ -4119,7 +4112,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, { u16 family = sk->sk_family; struct smack_known *skp; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct sockaddr_in addr; struct iphdr *hdr; struct smack_known *hskp; @@ -4205,7 +4198,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, static void smack_inet_csk_clone(struct sock *sk, const struct request_sock *req) { - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smack_known *skp; if (req->peer_secid != 0) { @@ -4697,6 +4690,7 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_inode = sizeof(struct inode_smack), .lbs_ipc = sizeof(struct smack_known *), .lbs_msg_msg = sizeof(struct smack_known *), + .lbs_sock = sizeof(struct socket_smack), }; static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { @@ -4806,7 +4800,9 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(socket_getpeersec_stream, smack_socket_getpeersec_stream), LSM_HOOK_INIT(socket_getpeersec_dgram, smack_socket_getpeersec_dgram), LSM_HOOK_INIT(sk_alloc_security, smack_sk_alloc_security), +#ifdef SMACK_IPV6_PORT_LABELING LSM_HOOK_INIT(sk_free_security, smack_sk_free_security), +#endif LSM_HOOK_INIT(sock_graft, smack_sock_graft), LSM_HOOK_INIT(inet_conn_request, smack_inet_conn_request), LSM_HOOK_INIT(inet_csk_clone, smack_inet_csk_clone), diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c index fc7399b45373..635e2339579e 100644 --- a/security/smack/smack_netfilter.c +++ b/security/smack/smack_netfilter.c @@ -28,8 +28,8 @@ static unsigned int smack_ipv6_output(void *priv, struct socket_smack *ssp; struct smack_known *skp; - if (sk && sk->sk_security) { - ssp = sk->sk_security; + if (sk && smack_sock(sk)) { + ssp = smack_sock(sk); skp = ssp->smk_out; skb->secmark = skp->smk_secid; } @@ -46,8 +46,8 @@ static unsigned int smack_ipv4_output(void *priv, struct socket_smack *ssp; struct smack_known *skp; - if (sk && sk->sk_security) { - ssp = sk->sk_security; + if (sk && smack_sock(sk)) { + ssp = smack_sock(sk); skp = ssp->smk_out; skb->secmark = skp->smk_secid; } From patchwork Wed Nov 4 23:40:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882657 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 0108A1130 for ; Wed, 4 Nov 2020 23:50:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A89DF20825 for ; Wed, 4 Nov 2020 23:50:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="pu6YT3gl" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733071AbgKDXuq (ORCPT ); Wed, 4 Nov 2020 18:50:46 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:34577 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733013AbgKDXow (ORCPT ); Wed, 4 Nov 2020 18:44:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533489; bh=Qo1Gfl7M/gEtL7nMaHAd4NMxP4V8Uuw/OZ3CtHIgtCI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=pu6YT3glSeWEuh3ZlSCbMs9jrzoUPf3DAWdO4owI28Gx4+ta5rNQVEa7QYMm+hRcNZeJBLjG7NYXvltMzKmY1mU5QGSDHZ8IbTo1akvoGv2MqfL4KQF7IZaQAC0ihZxZGDjz8sUEdMo6V1LcfGAQRK28la24leRHKWZzbddIPwWWIF5CSYx6Ys08ucNfqaXcUlCslqc4qori9zLpKfl6RbNUElD31B8E0dGIIcvJq92trJTQyF/MhGCOndXKzYP39jdGc0pPP/q53i9YZpjDkO3mNMsh/FXxNDauE0eAgsdbh367mh3ApJni1UN862ywtZzoQ73RFJTP2MNdlMLH7g== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533489; bh=p7bFaraYo9JcuZzFbxQ6Tbwwx1wMeFwd5XLCW2UPODD=; h=From:To:Subject:Date; b=SBFCL2r3VOkatEfEmDcxR0Uf/Lb7AoWcARQD7KZWABR0IEQ/PY88pSs+7lay/+O9JxsP7A/X5/SZMIU47w1ttLbyY9M2SvQcRaLGIHDHuLjGmdb2pNqQTXqsGjp/ixdvL4WLCE3WvpIgv14iY66MS9UnZ9XY39NpNinrh2Ur0yH7Of9j/6r38wsZ3vC6o6XGJKQW+MqjuRPyQRLtHotNmyhDzP8VwKOVun0IEBHGln5pgyy/mRGibORtBpbiZ3yVlc84jSJcs8R+vynzx6pWYbqbhlhl0P9Gw2FoDNEaH/UmQdSLdzlGk2RhEJWUhgaIuBEB5G3+9WlW6QmMiNoNHA== X-YMail-OSG: WEGFifcVM1lzqnInN_yZ07flwHfIC02_zdxiEQ1NhEQogqYhv5GLQGZebb599Lg GRoQgbjrj6RWejD.VjtUE4uKfAKXAAJMfIDzHwLHMKQGuUR84ZlvjWraQXJVZ43kI0mvzwgC2nVz kS4i__vMZB1xZaXU.81qk6bcv5K8_V41sygLyxl1MjwoLly16flhyjqRkoNfQYYY5CjdcV8coN5a aUCO1vWAVHwOkxqFWkTVTR74GTKfaewlaRrHbeI73zDBVUdULvUKx9iYKqLfIjUgepQpoMNZ5x0L M1j244GGUNYU.2Px2HQU1NucMCTlyecafRkXhcQSVbWmaQpNTPtIMpGAnILlMBzWAAx__mllT5MJ 7uVuoa_Mq3nIa.NoRpfx7x.jPSKiVzTwV8QcrzCv4ohF1t6p_xJprR1K.NxkA1LK4Bs4i_gAsvUo NyXbDjRFFd41oAWvQCOd0eC1_Mo77ot1EMmo32SGdixEQ5NSd9XrZcmG8ZSs7GKLU0qSgCGSYPR8 O963GTsNBqbvHQSqNp9orKHlxQQQKttGX_KZwLPodTDwXe9OfL5Y0QQFWToZoguv_UOzZ2AK4y.b 56tM6jj7IaeXgw7.1UrtBIKWgDCvwPJNQH6eFq1eFR1d3mOqtb7ZvFZZ3l08NgWdVeaKW4wfzug4 Cv2lu.fUdokux9pWJiQbJTWEAhAtNzrI0CAynysh_Ws6QbUFHjGIxLrmh6QxEV4YWctwyMPzf40w P2EDppAfxEN5ZSYeiPIqxH9eR4Hgg3nqjFfIKpQnBIMOzPmjXQwMhTP6Wuewsd.7UrZbl3cKGbGO rMiyIvnV5krvF.ONjx2pvRhv6DwUizuVbZX7n0.QYliHnWG7Hc5ynMDkq_VD97eVeVykHuABf.2d S1R58htyQKMlQz1MZiC84OdlBItt8AbqhK3umhsXTJyc3RrlBW5AvmrLWkJYrMIt98tefRxn3tn7 QeoGKzUKkmZUvqugOA.HL1Xvg3KCtdRB4gfEwMyebuFxqI15E6TH5pcfqBzV52jpJlbvwHHpmDya RcyyrUIiUuN0t9vc7D_OKDhYF1YCpIO3ki5m06Jpb3KFk91lTqo2aWHrDs0Ybrp1qUcYqq9TzJbI kUZ5gTlP72hOOWdbT_ieJnA.J3bnv016JcS39v1WCGxn5pfuA1tdJP1BDyMaqQVxLzWz5txPOcLs jGHzp6_y6N0YzIDwZKXrqzJx515O8IA6MURvF2YsYnia.12EqzR_bmG_yadHf.7O0EARNWktAHLG 7KPBY3054SuZz0FhPPqE2K_Z8V0tW_ZnAtHljTRBkqsP_pmK5xcfO05pKTsn.H5okFwV74jupS5u YFi0vYb1YdPVSnTiWs1YqaOMdIckNaSS5nNSPBk8uYY0nhl_sV08GLRxTTLPSlz5TQbkW.L0K2LZ aqhBCkCcQBw9YkM3sYt40Y8WjuZkFaQyGw0b5xdTn4X8ca_7Dze4rdjya9WhH8B8nSp3FIypbzt6 6DluVXKA2xg4GxOFrLAyYM6Ln8qgxUsRIt0wiks.obpTPmyUHu4rnc1U22OlikdF22mNyFFzQPUY Nn2tDCeWczy89AE85vZkKTp06jZjBh7jYT3PcMFR4iGU- Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:44:49 +0000 Received: by smtp419.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID f5adbc43251d1fd62ce46f58c5aaef3e; Wed, 04 Nov 2020 23:44:46 +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, bpf@vger.kernel.org Subject: [PATCH v22 02/23] LSM: Create and manage the lsmblob data structure. Date: Wed, 4 Nov 2020 15:40:53 -0800 Message-Id: <20201104234114.11346-3-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: When more than one security module is exporting data to audit and networking sub-systems a single 32 bit integer is no longer sufficient to represent the data. Add a structure to be used instead. The lsmblob structure is currently an array of u32 "secids". There is an entry for each of the security modules built into the system that would use secids if active. The system assigns the module a "slot" when it registers hooks. If modules are compiled in but not registered there will be unused slots. A new lsm_id structure, which contains the name of the LSM and its slot number, is created. There is an instance for each LSM, which assigns the name and passes it to the infrastructure to set the slot. The audit rules data is expanded to use an array of security module data rather than a single instance. Because IMA uses the audit rule functions it is affected as well. Acked-by: Stephen Smalley Acked-by: Paul Moore Acked-by: John Johansen Signed-off-by: Casey Schaufler Cc: --- include/linux/audit.h | 4 +- include/linux/lsm_hooks.h | 12 ++++- include/linux/security.h | 67 +++++++++++++++++++++++++-- kernel/auditfilter.c | 24 +++++----- kernel/auditsc.c | 12 ++--- security/apparmor/lsm.c | 7 ++- security/bpf/hooks.c | 12 ++++- security/commoncap.c | 7 ++- security/integrity/ima/ima_policy.c | 40 +++++++++++----- security/loadpin/loadpin.c | 8 +++- security/lockdown/lockdown.c | 7 ++- security/safesetid/lsm.c | 8 +++- security/security.c | 72 ++++++++++++++++++++++++----- security/selinux/hooks.c | 8 +++- security/smack/smack_lsm.c | 7 ++- security/tomoyo/tomoyo.c | 8 +++- security/yama/yama_lsm.c | 7 ++- 17 files changed, 254 insertions(+), 56 deletions(-) diff --git a/include/linux/audit.h b/include/linux/audit.h index b3d859831a31..ba1cd38d601b 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -65,8 +66,9 @@ struct audit_field { kuid_t uid; kgid_t gid; struct { + bool lsm_isset; char *lsm_str; - void *lsm_rule; + void *lsm_rules[LSMBLOB_ENTRIES]; }; }; u32 op; diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index d8f492ed6ebf..fe9203f15993 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1545,6 +1545,14 @@ struct security_hook_heads { #undef LSM_HOOK } __randomize_layout; +/* + * Information that identifies a security module. + */ +struct lsm_id { + const char *lsm; /* Name of the LSM */ + int slot; /* Slot in lsmblob if one is allocated */ +}; + /* * Security module hook list structure. * For use with generic list macros for common operations. @@ -1553,7 +1561,7 @@ struct security_hook_list { struct hlist_node list; struct hlist_head *head; union security_list_options hook; - char *lsm; + struct lsm_id *lsmid; } __randomize_layout; /* @@ -1588,7 +1596,7 @@ extern struct security_hook_heads security_hook_heads; extern char *lsm_names; extern void security_add_hooks(struct security_hook_list *hooks, int count, - char *lsm); + struct lsm_id *lsmid); #define LSM_FLAG_LEGACY_MAJOR BIT(0) #define LSM_FLAG_EXCLUSIVE BIT(1) diff --git a/include/linux/security.h b/include/linux/security.h index bc2725491560..fdb6e95c98e8 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -132,6 +132,65 @@ enum lockdown_reason { extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1]; +/* + * Data exported by the security modules + * + * Any LSM that provides secid or secctx based hooks must be included. + */ +#define LSMBLOB_ENTRIES ( \ + (IS_ENABLED(CONFIG_SECURITY_SELINUX) ? 1 : 0) + \ + (IS_ENABLED(CONFIG_SECURITY_SMACK) ? 1 : 0) + \ + (IS_ENABLED(CONFIG_SECURITY_APPARMOR) ? 1 : 0) + \ + (IS_ENABLED(CONFIG_BPF_LSM) ? 1 : 0)) + +struct lsmblob { + u32 secid[LSMBLOB_ENTRIES]; +}; + +#define LSMBLOB_INVALID -1 /* Not a valid LSM slot number */ +#define LSMBLOB_NEEDED -2 /* Slot requested on initialization */ +#define LSMBLOB_NOT_NEEDED -3 /* Slot not requested */ + +/** + * lsmblob_init - initialize an lsmblob structure. + * @blob: Pointer to the data to initialize + * @secid: The initial secid value + * + * Set all secid for all modules to the specified value. + */ +static inline void lsmblob_init(struct lsmblob *blob, u32 secid) +{ + int i; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) + blob->secid[i] = secid; +} + +/** + * lsmblob_is_set - report if there is an value in the lsmblob + * @blob: Pointer to the exported LSM data + * + * Returns true if there is a secid set, false otherwise + */ +static inline bool lsmblob_is_set(struct lsmblob *blob) +{ + struct lsmblob empty = {}; + + return !!memcmp(blob, &empty, sizeof(*blob)); +} + +/** + * lsmblob_equal - report if the two lsmblob's are equal + * @bloba: Pointer to one LSM data + * @blobb: Pointer to the other LSM data + * + * Returns true if all entries in the two are equal, false otherwise + */ +static inline bool lsmblob_equal(struct lsmblob *bloba, struct lsmblob *blobb) +{ + return !memcmp(bloba, blobb, sizeof(*bloba)); +} + /* These functions are in security/commoncap.c */ extern int cap_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); @@ -1833,8 +1892,8 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer) #ifdef CONFIG_SECURITY int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule); int security_audit_rule_known(struct audit_krule *krule); -int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule); -void security_audit_rule_free(void *lsmrule); +int security_audit_rule_match(u32 secid, u32 field, u32 op, void **lsmrule); +void security_audit_rule_free(void **lsmrule); #else @@ -1850,12 +1909,12 @@ static inline int security_audit_rule_known(struct audit_krule *krule) } static inline int security_audit_rule_match(u32 secid, u32 field, u32 op, - void *lsmrule) + void **lsmrule) { return 0; } -static inline void security_audit_rule_free(void *lsmrule) +static inline void security_audit_rule_free(void **lsmrule) { } #endif /* CONFIG_SECURITY */ diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 333b3bcfc545..45da229f9f1f 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -74,7 +74,7 @@ static void audit_free_lsm_field(struct audit_field *f) case AUDIT_OBJ_LEV_LOW: case AUDIT_OBJ_LEV_HIGH: kfree(f->lsm_str); - security_audit_rule_free(f->lsm_rule); + security_audit_rule_free(f->lsm_rules); } } @@ -519,9 +519,10 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, goto exit_free; } entry->rule.buflen += f_val; + f->lsm_isset = true; f->lsm_str = str; err = security_audit_rule_init(f->type, f->op, str, - (void **)&f->lsm_rule); + f->lsm_rules); /* Keep currently invalid fields around in case they * become valid after a policy reload. */ if (err == -EINVAL) { @@ -774,7 +775,7 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b) return 0; } -/* Duplicate LSM field information. The lsm_rule is opaque, so must be +/* Duplicate LSM field information. The lsm_rules is opaque, so must be * re-initialized. */ static inline int audit_dupe_lsm_field(struct audit_field *df, struct audit_field *sf) @@ -788,9 +789,9 @@ static inline int audit_dupe_lsm_field(struct audit_field *df, return -ENOMEM; df->lsm_str = lsm_str; - /* our own (refreshed) copy of lsm_rule */ + /* our own (refreshed) copy of lsm_rules */ ret = security_audit_rule_init(df->type, df->op, df->lsm_str, - (void **)&df->lsm_rule); + df->lsm_rules); /* Keep currently invalid fields around in case they * become valid after a policy reload. */ if (ret == -EINVAL) { @@ -842,7 +843,7 @@ struct audit_entry *audit_dupe_rule(struct audit_krule *old) new->tree = old->tree; memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount); - /* deep copy this information, updating the lsm_rule fields, because + /* deep copy this information, updating the lsm_rules fields, because * the originals will all be freed when the old rule is freed. */ for (i = 0; i < fcount; i++) { switch (new->fields[i].type) { @@ -1358,10 +1359,11 @@ int audit_filter(int msgtype, unsigned int listtype) case AUDIT_SUBJ_TYPE: case AUDIT_SUBJ_SEN: case AUDIT_SUBJ_CLR: - if (f->lsm_rule) { + if (f->lsm_isset) { security_task_getsecid(current, &sid); result = security_audit_rule_match(sid, - f->type, f->op, f->lsm_rule); + f->type, f->op, + f->lsm_rules); } break; case AUDIT_EXE: @@ -1388,7 +1390,7 @@ int audit_filter(int msgtype, unsigned int listtype) return ret; } -static int update_lsm_rule(struct audit_krule *r) +static int update_lsm_rules(struct audit_krule *r) { struct audit_entry *entry = container_of(r, struct audit_entry, rule); struct audit_entry *nentry; @@ -1420,7 +1422,7 @@ static int update_lsm_rule(struct audit_krule *r) return err; } -/* This function will re-initialize the lsm_rule field of all applicable rules. +/* This function will re-initialize the lsm_rules field of all applicable rules. * It will traverse the filter lists serarching for rules that contain LSM * specific filter fields. When such a rule is found, it is copied, the * LSM field is re-initialized, and the old rule is replaced with the @@ -1435,7 +1437,7 @@ int audit_update_lsm_rules(void) for (i = 0; i < AUDIT_NR_FILTERS; i++) { list_for_each_entry_safe(r, n, &audit_rules_list[i], list) { - int res = update_lsm_rule(r); + int res = update_lsm_rules(r); if (!err) err = res; } diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 8dba8f0983b5..16e3430f7d07 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -667,14 +667,14 @@ static int audit_filter_rules(struct task_struct *tsk, match for now to avoid losing information that may be wanted. An error message will also be logged upon error */ - if (f->lsm_rule) { + if (f->lsm_isset) { if (need_sid) { security_task_getsecid(tsk, &sid); need_sid = 0; } result = security_audit_rule_match(sid, f->type, f->op, - f->lsm_rule); + f->lsm_rules); } break; case AUDIT_OBJ_USER: @@ -684,21 +684,21 @@ static int audit_filter_rules(struct task_struct *tsk, case AUDIT_OBJ_LEV_HIGH: /* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR also applies here */ - if (f->lsm_rule) { + if (f->lsm_isset) { /* Find files that match */ if (name) { result = security_audit_rule_match( name->osid, f->type, f->op, - f->lsm_rule); + f->lsm_rules); } else if (ctx) { list_for_each_entry(n, &ctx->names_list, list) { if (security_audit_rule_match( n->osid, f->type, f->op, - f->lsm_rule)) { + f->lsm_rules)) { ++result; break; } @@ -709,7 +709,7 @@ static int audit_filter_rules(struct task_struct *tsk, break; if (security_audit_rule_match(ctx->ipc.osid, f->type, f->op, - f->lsm_rule)) + f->lsm_rules)) ++result; } break; diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index f1c365905d5e..432915c1d427 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1152,6 +1152,11 @@ struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = { .lbs_sock = sizeof(struct aa_sk_ctx), }; +static struct lsm_id apparmor_lsmid __lsm_ro_after_init = { + .lsm = "apparmor", + .slot = LSMBLOB_NEEDED +}; + static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), @@ -1852,7 +1857,7 @@ static int __init apparmor_init(void) goto buffers_out; } security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks), - "apparmor"); + &apparmor_lsmid); /* Report that AppArmor successfully initialized */ apparmor_initialized = 1; diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c index 788667d582ae..a1a5032a4d87 100644 --- a/security/bpf/hooks.c +++ b/security/bpf/hooks.c @@ -14,9 +14,19 @@ static struct security_hook_list bpf_lsm_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(inode_free_security, bpf_inode_storage_free), }; +/* + * slot has to be LSMBLOB_NEEDED because some of the hooks + * supplied by this module require a slot. + */ +struct lsm_id bpf_lsmid __lsm_ro_after_init = { + .lsm = "bpf", + .slot = LSMBLOB_NEEDED +}; + static int __init bpf_lsm_init(void) { - security_add_hooks(bpf_lsm_hooks, ARRAY_SIZE(bpf_lsm_hooks), "bpf"); + security_add_hooks(bpf_lsm_hooks, ARRAY_SIZE(bpf_lsm_hooks), + &bpf_lsmid); pr_info("LSM support for eBPF active\n"); return 0; } diff --git a/security/commoncap.c b/security/commoncap.c index 59bf3c1674c8..959a9f96b7f1 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -1341,6 +1341,11 @@ int cap_mmap_file(struct file *file, unsigned long reqprot, #ifdef CONFIG_SECURITY +static struct lsm_id capability_lsmid __lsm_ro_after_init = { + .lsm = "capability", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list capability_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(capable, cap_capable), LSM_HOOK_INIT(settime, cap_settime), @@ -1365,7 +1370,7 @@ static struct security_hook_list capability_hooks[] __lsm_ro_after_init = { static int __init capability_init(void) { security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks), - "capability"); + &capability_lsmid); return 0; } diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 9b5adeaa47fc..cd393aaa17d5 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -79,7 +79,7 @@ struct ima_rule_entry { bool (*fowner_op)(kuid_t, kuid_t); /* uid_eq(), uid_gt(), uid_lt() */ int pcr; struct { - void *rule; /* LSM file metadata specific */ + void *rules[LSMBLOB_ENTRIES]; /* LSM file metadata specific */ char *args_p; /* audit value */ int type; /* audit type */ } lsm[MAX_LSM_RULES]; @@ -88,6 +88,22 @@ struct ima_rule_entry { struct ima_template_desc *template; }; +/** + * ima_lsm_isset - Is a rule set for any of the active security modules + * @rules: The set of IMA rules to check. + * + * If a rule is set for any LSM return true, otherwise return false. + */ +static inline bool ima_lsm_isset(void *rules[]) +{ + int i; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) + if (rules[i]) + return true; + return false; +} + /* * Without LSM specific knowledge, the default policy can only be * written in terms of .action, .func, .mask, .fsmagic, .uid, and .fowner @@ -326,9 +342,11 @@ static void ima_free_rule_opt_list(struct ima_rule_opt_list *opt_list) static void ima_lsm_free_rule(struct ima_rule_entry *entry) { int i; + int r; for (i = 0; i < MAX_LSM_RULES; i++) { - ima_filter_rule_free(entry->lsm[i].rule); + for (r = 0; r < LSMBLOB_ENTRIES; r++) + ima_filter_rule_free(entry->lsm[i].rules[r]); kfree(entry->lsm[i].args_p); } } @@ -379,8 +397,8 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) ima_filter_rule_init(nentry->lsm[i].type, Audit_equal, nentry->lsm[i].args_p, - &nentry->lsm[i].rule); - if (!nentry->lsm[i].rule) + &nentry->lsm[i].rules[0]); + if (!ima_lsm_isset(nentry->lsm[i].rules)) pr_warn("rule for LSM \'%s\' is undefined\n", nentry->lsm[i].args_p); } @@ -545,7 +563,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, int rc = 0; u32 osid; - if (!rule->lsm[i].rule) { + if (!ima_lsm_isset(rule->lsm[i].rules)) { if (!rule->lsm[i].args_p) continue; else @@ -558,14 +576,14 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, security_inode_getsecid(inode, &osid); rc = ima_filter_rule_match(osid, rule->lsm[i].type, Audit_equal, - rule->lsm[i].rule); + rule->lsm[i].rules); break; case LSM_SUBJ_USER: case LSM_SUBJ_ROLE: case LSM_SUBJ_TYPE: rc = ima_filter_rule_match(secid, rule->lsm[i].type, Audit_equal, - rule->lsm[i].rule); + rule->lsm[i].rules); default: break; } @@ -952,7 +970,7 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, { int result; - if (entry->lsm[lsm_rule].rule) + if (ima_lsm_isset(entry->lsm[lsm_rule].rules)) return -EINVAL; entry->lsm[lsm_rule].args_p = match_strdup(args); @@ -962,8 +980,8 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, entry->lsm[lsm_rule].type = audit_type; result = ima_filter_rule_init(entry->lsm[lsm_rule].type, Audit_equal, entry->lsm[lsm_rule].args_p, - &entry->lsm[lsm_rule].rule); - if (!entry->lsm[lsm_rule].rule) { + &entry->lsm[lsm_rule].rules[0]); + if (!ima_lsm_isset(entry->lsm[lsm_rule].rules)) { pr_warn("rule for LSM \'%s\' is undefined\n", entry->lsm[lsm_rule].args_p); @@ -1733,7 +1751,7 @@ int ima_policy_show(struct seq_file *m, void *v) } for (i = 0; i < MAX_LSM_RULES; i++) { - if (entry->lsm[i].rule) { + if (ima_lsm_isset(entry->lsm[i].rules)) { switch (i) { case LSM_OBJ_USER: seq_printf(m, pt(Opt_obj_user), diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c index b12f7d986b1e..b569f3bc170b 100644 --- a/security/loadpin/loadpin.c +++ b/security/loadpin/loadpin.c @@ -192,6 +192,11 @@ static int loadpin_load_data(enum kernel_load_data_id id, bool contents) return loadpin_read_file(NULL, (enum kernel_read_file_id) id, contents); } +static struct lsm_id loadpin_lsmid __lsm_ro_after_init = { + .lsm = "loadpin", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security), LSM_HOOK_INIT(kernel_read_file, loadpin_read_file), @@ -239,7 +244,8 @@ static int __init loadpin_init(void) pr_info("ready to pin (currently %senforcing)\n", enforce ? "" : "not "); parse_exclude(); - security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), "loadpin"); + security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), + &loadpin_lsmid); return 0; } diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c index 87cbdc64d272..4e24ea3f7b7e 100644 --- a/security/lockdown/lockdown.c +++ b/security/lockdown/lockdown.c @@ -75,6 +75,11 @@ static struct security_hook_list lockdown_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(locked_down, lockdown_is_locked_down), }; +static struct lsm_id lockdown_lsmid __lsm_ro_after_init = { + .lsm = "lockdown", + .slot = LSMBLOB_NOT_NEEDED +}; + static int __init lockdown_lsm_init(void) { #if defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY) @@ -83,7 +88,7 @@ static int __init lockdown_lsm_init(void) lock_kernel_down("Kernel configuration", LOCKDOWN_CONFIDENTIALITY_MAX); #endif security_add_hooks(lockdown_hooks, ARRAY_SIZE(lockdown_hooks), - "lockdown"); + &lockdown_lsmid); return 0; } diff --git a/security/safesetid/lsm.c b/security/safesetid/lsm.c index 8a176b6adbe5..7c7ac9bfe5cd 100644 --- a/security/safesetid/lsm.c +++ b/security/safesetid/lsm.c @@ -244,6 +244,11 @@ static int safesetid_task_fix_setgid(struct cred *new, return -EACCES; } +static struct lsm_id safesetid_lsmid __lsm_ro_after_init = { + .lsm = "safesetid", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list safesetid_security_hooks[] = { LSM_HOOK_INIT(task_fix_setuid, safesetid_task_fix_setuid), LSM_HOOK_INIT(task_fix_setgid, safesetid_task_fix_setgid), @@ -253,7 +258,8 @@ static struct security_hook_list safesetid_security_hooks[] = { static int __init safesetid_security_init(void) { security_add_hooks(safesetid_security_hooks, - ARRAY_SIZE(safesetid_security_hooks), "safesetid"); + ARRAY_SIZE(safesetid_security_hooks), + &safesetid_lsmid); /* Report that SafeSetID successfully initialized */ safesetid_initialized = 1; diff --git a/security/security.c b/security/security.c index 5da8b3643680..d01363cb0082 100644 --- a/security/security.c +++ b/security/security.c @@ -341,6 +341,7 @@ static void __init ordered_lsm_init(void) init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); init_debug("sock blob size = %d\n", blob_sizes.lbs_sock); init_debug("task blob size = %d\n", blob_sizes.lbs_task); + init_debug("lsmblob size = %zu\n", sizeof(struct lsmblob)); /* * Create any kmem_caches needed for blobs @@ -468,21 +469,36 @@ static int lsm_append(const char *new, char **result) return 0; } +/* + * Current index to use while initializing the lsmblob secid list. + */ +static int lsm_slot __lsm_ro_after_init; + /** * security_add_hooks - Add a modules hooks to the hook lists. * @hooks: the hooks to add * @count: the number of hooks to add - * @lsm: the name of the security module + * @lsmid: the the identification information for the security module * * Each LSM has to register its hooks with the infrastructure. + * If the LSM is using hooks that export secids allocate a slot + * for it in the lsmblob. */ void __init security_add_hooks(struct security_hook_list *hooks, int count, - char *lsm) + struct lsm_id *lsmid) { int i; + if (lsmid->slot == LSMBLOB_NEEDED) { + if (lsm_slot >= LSMBLOB_ENTRIES) + panic("%s Too many LSMs registered.\n", __func__); + lsmid->slot = lsm_slot++; + init_debug("%s assigned lsmblob slot %d\n", lsmid->lsm, + lsmid->slot); + } + for (i = 0; i < count; i++) { - hooks[i].lsm = lsm; + hooks[i].lsmid = lsmid; hlist_add_tail_rcu(&hooks[i].list, hooks[i].head); } @@ -491,7 +507,7 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count, * and fix this up afterwards. */ if (slab_is_available()) { - if (lsm_append(lsm, &lsm_names) < 0) + if (lsm_append(lsmid->lsm, &lsm_names) < 0) panic("%s - Cannot get early memory.\n", __func__); } } @@ -2005,7 +2021,7 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name, struct security_hook_list *hp; hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) { - if (lsm != NULL && strcmp(lsm, hp->lsm)) + if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm)) continue; return hp->hook.getprocattr(p, name, value); } @@ -2018,7 +2034,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value, struct security_hook_list *hp; hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) { - if (lsm != NULL && strcmp(lsm, hp->lsm)) + if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm)) continue; return hp->hook.setprocattr(name, value, size); } @@ -2510,7 +2526,24 @@ int security_key_getsecurity(struct key *key, char **_buffer) int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) { - return call_int_hook(audit_rule_init, 0, field, op, rulestr, lsmrule); + struct security_hook_list *hp; + bool one_is_good = false; + int rc = 0; + int trc; + + hlist_for_each_entry(hp, &security_hook_heads.audit_rule_init, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + trc = hp->hook.audit_rule_init(field, op, rulestr, + &lsmrule[hp->lsmid->slot]); + if (trc == 0) + one_is_good = true; + else + rc = trc; + } + if (one_is_good) + return 0; + return rc; } int security_audit_rule_known(struct audit_krule *krule) @@ -2518,14 +2551,31 @@ int security_audit_rule_known(struct audit_krule *krule) return call_int_hook(audit_rule_known, 0, krule); } -void security_audit_rule_free(void *lsmrule) +void security_audit_rule_free(void **lsmrule) { - call_void_hook(audit_rule_free, lsmrule); + struct security_hook_list *hp; + + hlist_for_each_entry(hp, &security_hook_heads.audit_rule_free, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.audit_rule_free(lsmrule[hp->lsmid->slot]); + } } -int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule) +int security_audit_rule_match(u32 secid, u32 field, u32 op, void **lsmrule) { - return call_int_hook(audit_rule_match, 0, secid, field, op, lsmrule); + struct security_hook_list *hp; + int rc; + + hlist_for_each_entry(hp, &security_hook_heads.audit_rule_match, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.audit_rule_match(secid, field, op, + &lsmrule[hp->lsmid->slot]); + if (rc) + return rc; + } + return 0; } #endif /* CONFIG_AUDIT */ diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 2748281a5cca..52a50d7ca534 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6933,6 +6933,11 @@ static int selinux_perf_event_write(struct perf_event *event) } #endif +static struct lsm_id selinux_lsmid __lsm_ro_after_init = { + .lsm = "selinux", + .slot = LSMBLOB_NEEDED +}; + /* * IMPORTANT NOTE: When adding new hooks, please be careful to keep this order: * 1. any hooks that don't belong to (2.) or (3.) below, @@ -7244,7 +7249,8 @@ static __init int selinux_init(void) hashtab_cache_init(); - security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux"); + security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), + &selinux_lsmid); if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) panic("SELinux: Unable to register AVC netcache callback\n"); diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index ca4a6c862732..f96be93d1a75 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4693,6 +4693,11 @@ struct lsm_blob_sizes smack_blob_sizes __lsm_ro_after_init = { .lbs_sock = sizeof(struct socket_smack), }; +static struct lsm_id smack_lsmid __lsm_ro_after_init = { + .lsm = "smack", + .slot = LSMBLOB_NEEDED +}; + static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), @@ -4892,7 +4897,7 @@ static __init int smack_init(void) /* * Register with LSM */ - security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack"); + security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), &smack_lsmid); smack_enabled = 1; pr_info("Smack: Initializing.\n"); diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index 1f3cd432d830..22f62c67f2ec 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c @@ -523,6 +523,11 @@ static void tomoyo_task_free(struct task_struct *task) } } +static struct lsm_id tomoyo_lsmid __lsm_ro_after_init = { + .lsm = "tomoyo", + .slot = LSMBLOB_NOT_NEEDED +}; + /* * tomoyo_security_ops is a "struct security_operations" which is used for * registering TOMOYO. @@ -575,7 +580,8 @@ static int __init tomoyo_init(void) struct tomoyo_task *s = tomoyo_task(current); /* register ourselves with the security framework */ - security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo"); + security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), + &tomoyo_lsmid); pr_info("TOMOYO Linux initialized\n"); s->domain_info = &tomoyo_kernel_domain; atomic_inc(&tomoyo_kernel_domain.users); diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index 06e226166aab..a9639ea541f7 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c @@ -421,6 +421,11 @@ static int yama_ptrace_traceme(struct task_struct *parent) return rc; } +static struct lsm_id yama_lsmid __lsm_ro_after_init = { + .lsm = "yama", + .slot = LSMBLOB_NOT_NEEDED +}; + static struct security_hook_list yama_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme), @@ -477,7 +482,7 @@ static inline void yama_init_sysctl(void) { } static int __init yama_init(void) { pr_info("Yama: becoming mindful.\n"); - security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama"); + security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), &yama_lsmid); yama_init_sysctl(); return 0; } From patchwork Wed Nov 4 23:40:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882383 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 165F21130 for ; Wed, 4 Nov 2020 23:46:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CE40C20704 for ; Wed, 4 Nov 2020 23:46:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="gZ/+HO+w" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732852AbgKDXqZ (ORCPT ); Wed, 4 Nov 2020 18:46:25 -0500 Received: from sonic313-15.consmr.mail.ne1.yahoo.com ([66.163.185.38]:36853 "EHLO sonic313-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730916AbgKDXqA (ORCPT ); Wed, 4 Nov 2020 18:46:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533558; bh=LCB9ydE1w9hHkpb8wYy6jD57eyJtJQ5ce5sXeiV/bXE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=gZ/+HO+w7BQqocEnlUfvRIt8ioh/gFredxe+Ja3kaZ+n8r/lYgYFHXdZFpeghIk81e6/qcTVoba51k6pj9W82yrcnyOdg1IGZotio6p2GRMZSw4SyZ8dnRnUY0I6oaM/dBTOMYjqCD48vBxH1/GNm7U0xoHYri5zV/rjKJFal+IlLVhnjfxzX3DMCLr5jQfg83Cz8X2zftTL+OXvn2fGM3BNCrMPdiY+o61emUJlMABzrNW0HqkodE4cFMnJQ1b9fWFVtypCMXYS9YhlnwVp5kNN4nKzh0m9rMZDZkL6qlbX0Y5tF4teeh7Z1erpjM7m4sSB+ivws5rjI7qcQ1VxcA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533558; bh=1pG/hS+NXpOHsMz7wD5tQTPWY1FNdAEu8otDkklYa2K=; h=From:To:Subject:Date; b=ZSguEc0FFZ11Jg/hTfsxrsG7wExMJmVXNzkZKujXWn9RilsDxwjFIVGldZG5/XS+Eq3znY5xTof75q6wGPJlqpXULuKm6kEN/S7/CeJxwH+JDUx8wcBmBR5p8q8jFQrl3BYyehb+o0wwUWbH/ul9G7LyW9/EY1/MqjW6V+eKkvP9vHF1f6JOI4HUHQms7ID5uZsBtQNIAQDISGwz/JNftj4D2wNfBgnK6W1MUVPD7S6V8XPH42L/qVYNmR1hLYTlUanXfA2VglvWtOHF/8OP+toacJ53idrm8VgRXQ1ZwM0uqBahtK28uGMp0hvhIHG5aDUwpnZ/JL24x1VjuOB4cQ== X-YMail-OSG: Ibqzj4IVM1kVhtR_ahkb1CcoWFYqQBNdOmez4IRmnmFGnQpje4ojfPmbjTph1L0 TiM3AKazRA_XdKb2D2tSG5.TwGo8a25c6gfEebXPVMftW1FaOINKA1.yTNtGn1EiKfiynPDUvDXe Sc4CLal9KYMckzSHSmfTn8DLu39sQ_4eAAHGUqVfFIaVxmhHNT9PPfe8jWZDVu1nicF_B12VvhvV J3H3DXriqp6uD_hj.smMyyYa8h3xPwcNd..O7f_ssbAbgq38Q5s4kz22034zZ_SMhiIfzCEljWtz PKkd4HcmUSnl5QXIVqaQKUIxD0sOtZrig0J2grVjGlIYcYQ.k0cZHCkb2u6_Um7M9rukr_NVp3Ir 2yFzt4ad_ma0y.glNmS7B094B0yJ_lAxBB5kF89XLOf0kJemZTCwVQekMhmsW4LlKcZOuep7AOWy Xx9ivavNKJS1IUDJBvAWPQ3ZnsRc4VjLaHrxBES94q65G0.67lkEx4wUbP93vT3.3opuz7DL5VLq 8vjeVzfDSMVUptI2Svu6s44uh33qpDtX_7uocfZzNd58UB9ULoaxz3yb48ujaM9bGwq_.61GsQpG Ee3f3Cs4HkddOy6Kv6OFIUUiWcVrbHpkWvT_Ytgo7VRnqM34U1KBznu0HelSdc0z3m3Cl4hq6QxE Y488WrMYgNg0b3aZKd7fuwV_7wDGMkLvJMYO4FyIiBzRevZ3PDE7h9eVNbLcazp7DEtyCPExBDyM VhiQTuQHu20sTW2KVBk6E4o5Zez0MlL1LOr4EKc1VdiEi3zfQY3pCVubNMZJK4hETh0echJNN2SR BHnALePl2d55EHYoddJDjEf1eeWQZnih9bYlsWi9g_PAHMv7hwLUCIUAKGsI46Js1DfC4inLJJO0 G5qpZG8QQFleyBP.7RH.sityhbQKo2WBlhgOQqlxyHZDceGWdVsF1Cy8WFrVYiBIKA2ovbcNlBdp o0FgKWQFQe5d7koFGbBu3UzqroC.Vd5xxx3C7_PgCZZ1pFb.wDY4rYpdlAntifz8tCNvL92zGtSC lipaK_MmokHKWy3l4N7mHSDWEtuX2TDY2B8ZArW7b8cJvQPQ7joDJ6cogYb04cz1eFST2wnSGc84 1b4gp_7gg5gT93MD_YjkSrbSQ02uHjj3MSP7pHZ_zs8a59cUCNW4baWL1wYYoiuEKBUB8FFReSGD wF9.VtplKOQ4j4lrbv7Sr3x_Odbq4joar30yieqmUMr5uZhzNuy3VNxeJt91WQtoklNx.tbOPLZg hrcH8_pmWQt8cOI3L06HzPGBPgA3xsuGeKqthhCigd4Cqb67VRXId0vdxnICBkgaHDzeAY4jFma8 5.JbdkOWND7xyanjeyn1m2PPTHu.Ffy8Uo8T6u6fLDh8PT6pGCBSde9hZskb4vBQf6uUOgJ5_ZGG fZRq5a_.0vUJ6CdbQR53j7RvCwOjn45NmtwK1c04R233kr8UAOP6L8HGncGShnmkwr3lMBomHUIN 5xD5fnw9ZjM.UIIl2m7KniZwp92JY1yK0bXCoc_rOMl1ldUGFHq6wTAPHY_hOu03zFnDtC56HjZo B555NnUdQbSEOs7dYRZ1.V52FlTe8vHTa2zchwtkT2B_4sRYFfhreQ0vVnuiLixMlbN0I.qW4SmU MT47Mf8LiaIXIerbZBCcIs5kGG4KlOE8DAKRv1raO39dHbrabBpwVKjIdU9tQ2k8Ib6BPT6YaKPH y1Oq8WBl3Qv3XfsZs_i.Ji12IoufD.IWyeLRyWB3J_.W_LDT_R5TGfMRUmw2uYlnq1C_3zAKUOS3 WUW862mSlH.0zLdR.0zEc2idZTT_4N6QZAfOTGI41KBdzyR0xEkjw47w_w9HHyar3L54vO2HnWn6 IvVh0.QphEsL6IePJJhY3.PkvEjU3eGGjNl5yODVPRgps1kV7iC_lcsvkVRvVzfbnW_4lhP1wE5. 5Y0XdwiqbnXsGaDOJHrXlsqBoOmhJBwjY_V.3ufLdC0BckZo63ODm1Kzz8NsRFUHt4TU1MiTw0XA 9GYmXUCK79vLaLHlt4dAkCr0A4hM_RM8JUfRCwHaD3AIwnBINIlV.Krf.5hkIh8s2yCryhwCT.Q7 ObLxztCYYTgLm119cP.X1Vj5AjwCkMUDDWCbagI6uwKiwqHSmeGXV7emUR2HUP4BPgUUK4CVlsah y2fdSsvxZ4xBF7iNeBI3SyHp2_KD.nszdZqEGHl7_D3HGZWm4vWZCGVBiRFsMeS4aIswjIDfG3CB SS_JdTY6regehqPS486hYGmuJ6VvNE4qqoaxQJrR2V_4ipy1wijr1NcqidlMJnKuO59BSxiF8NWP igd8TB_IiOw5rCEZt_nykSVlKpUUjm7R5GGfbKuQ9FmYsWz50EA34ngstZ3b10k2vudn7mAeSvYh UxfT99Prd_BuMObKrxq4fbBPEIOJEy_WxbFYvt3F3oRxzzkoWoiDB5w2IVIT5LEQMfAXWz6bKGm4 qLAkn0Rm8m15T7Kv7mkUOvef2LL1KMJoTZYnbyQ1lDQlcpxG53ctQheJP2JT6G9gatnmNZgcXw73 cl0dByS.Gxcj1oL61UTv.KR8raZAQbXPlcO2m1fZbVwYgdRU2GLny5iggTj4.FijUeHO5OAjOjls q.bkHpHvQbtDUhaX9MKvFp36cJulWHsu2P6HYxehXyK9cVpBS8Rzf6abRwg.X_YEtpDfDbzd9QUR Lq_4VQ5vKBqA3pIGSzGVabzoup0VZmD3a7s2L91iGWSpKpG50purm89G97FI9mb64U1PXZXnTH_c WGwc5taiVU2lWgqcJ1ZjLXdmbdQG_EgWfTYkmGe6ipWBu3vvV_HfqSS4V3YtE7S6MgUBF6d9aHtK 43xP_i3zMudNW04IpYDD7fOhLuHYqJ25biBLbhdvvYpkXM8u4sp5VO3t7cwefx2L1.vhQIErTcKS VVeIS25KW9tDM7Pjx3isRywDO9eSgVAKcTEcaG5hOCkMVibdogzHfq5Sb.ug7xvFkt9AsRC2Lka8 pSgMrsJmAEYQC5eFN0N6bBHSAq5VOoStFHSCU2qnnNgtN_hmj.mJu.llM7f7kAdXt17RWn0o4c4a WCrQ6rlyXCWJVKZVh1fZHw9.JTy1EXlpD2CCvOSvrM1NvnXz8PzZiublb17p0my9ZdBxxfPhvH3C 0QVIhI4KpVtbClmKmzuei.UQyPRzvk0CDVhkX.AyaYRJSb.TKNNF2bdHkVt.RCbCW13PSqTF_E_f bgIV1QqLKyPgE8X.Pmb.CpQ2D3_Pz1hfjDXuXtDMJNyolwlK5f40qh6y2OwHpTow04gR_uZpXf8B FQMWPo55rXYNrtnTYqJAA4ji8rifpDSHA6bOZHraF5FWZx.pkhluLhjyttIFQ3EsUQaLZotQx_GX wyDb7PPXF08Y- Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:45:58 +0000 Received: by smtp401.mail.gq1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 9b9e375e4e591189f65b01f46bb2c359; Wed, 04 Nov 2020 23:45:52 +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 Subject: [PATCH v22 03/23] LSM: Use lsmblob in security_audit_rule_match Date: Wed, 4 Nov 2020 15:40:54 -0800 Message-Id: <20201104234114.11346-4-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: Change the secid parameter of security_audit_rule_match to a lsmblob structure pointer. Pass the entry from the lsmblob structure for the approprite slot to the LSM hook. Change the users of security_audit_rule_match to use the lsmblob instead of a u32. The scaffolding function lsmblob_init() fills the blob with the value of the old secid, ensuring that it is available to the appropriate module hook. The sources of the secid, security_task_getsecid() and security_inode_getsecid(), will be converted to use the blob structure later in the series. At the point the use of lsmblob_init() is dropped. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler --- include/linux/security.h | 7 ++++--- kernel/auditfilter.c | 6 ++++-- kernel/auditsc.c | 14 ++++++++++---- security/integrity/ima/ima.h | 4 ++-- security/integrity/ima/ima_policy.c | 7 +++++-- security/security.c | 10 ++++++++-- 6 files changed, 33 insertions(+), 15 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index fdb6e95c98e8..89c538aa283e 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1892,7 +1892,8 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer) #ifdef CONFIG_SECURITY int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule); int security_audit_rule_known(struct audit_krule *krule); -int security_audit_rule_match(u32 secid, u32 field, u32 op, void **lsmrule); +int security_audit_rule_match(struct lsmblob *blob, u32 field, u32 op, + void **lsmrule); void security_audit_rule_free(void **lsmrule); #else @@ -1908,8 +1909,8 @@ static inline int security_audit_rule_known(struct audit_krule *krule) return 0; } -static inline int security_audit_rule_match(u32 secid, u32 field, u32 op, - void **lsmrule) +static inline int security_audit_rule_match(struct lsmblob *blob, u32 field, + u32 op, void **lsmrule) { return 0; } diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 45da229f9f1f..e27424216159 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1331,6 +1331,7 @@ int audit_filter(int msgtype, unsigned int listtype) struct audit_field *f = &e->rule.fields[i]; pid_t pid; u32 sid; + struct lsmblob blob; switch (f->type) { case AUDIT_PID: @@ -1361,8 +1362,9 @@ int audit_filter(int msgtype, unsigned int listtype) case AUDIT_SUBJ_CLR: if (f->lsm_isset) { security_task_getsecid(current, &sid); - result = security_audit_rule_match(sid, - f->type, f->op, + lsmblob_init(&blob, sid); + result = security_audit_rule_match( + &blob, f->type, f->op, f->lsm_rules); } break; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 16e3430f7d07..7dd6b815a9eb 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -474,6 +474,7 @@ static int audit_filter_rules(struct task_struct *tsk, const struct cred *cred; int i, need_sid = 1; u32 sid; + struct lsmblob blob; unsigned int sessionid; cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation); @@ -672,7 +673,9 @@ static int audit_filter_rules(struct task_struct *tsk, security_task_getsecid(tsk, &sid); need_sid = 0; } - result = security_audit_rule_match(sid, f->type, + lsmblob_init(&blob, sid); + result = security_audit_rule_match(&blob, + f->type, f->op, f->lsm_rules); } @@ -687,15 +690,17 @@ static int audit_filter_rules(struct task_struct *tsk, if (f->lsm_isset) { /* Find files that match */ if (name) { + lsmblob_init(&blob, name->osid); result = security_audit_rule_match( - name->osid, + &blob, f->type, f->op, f->lsm_rules); } else if (ctx) { list_for_each_entry(n, &ctx->names_list, list) { + lsmblob_init(&blob, name->osid); if (security_audit_rule_match( - n->osid, + &blob, f->type, f->op, f->lsm_rules)) { @@ -707,7 +712,8 @@ static int audit_filter_rules(struct task_struct *tsk, /* Find ipc objects that match */ if (!ctx || ctx->type != AUDIT_IPC) break; - if (security_audit_rule_match(ctx->ipc.osid, + lsmblob_init(&blob, ctx->ipc.osid); + if (security_audit_rule_match(&blob, f->type, f->op, f->lsm_rules)) ++result; diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 38043074ce5e..d7fe1d5ee8c9 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -429,8 +429,8 @@ static inline void ima_filter_rule_free(void *lsmrule) { } -static inline int ima_filter_rule_match(u32 secid, u32 field, u32 op, - void *lsmrule) +static inline int ima_filter_rule_match(struct lsmblob *blob, u32 field, + u32 op, void *lsmrule) { return -EINVAL; } diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index cd393aaa17d5..3e47cc9b7400 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -562,6 +562,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, for (i = 0; i < MAX_LSM_RULES; i++) { int rc = 0; u32 osid; + struct lsmblob lsmdata; if (!ima_lsm_isset(rule->lsm[i].rules)) { if (!rule->lsm[i].args_p) @@ -574,14 +575,16 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, case LSM_OBJ_ROLE: case LSM_OBJ_TYPE: security_inode_getsecid(inode, &osid); - rc = ima_filter_rule_match(osid, rule->lsm[i].type, + lsmblob_init(&lsmdata, osid); + rc = ima_filter_rule_match(&lsmdata, rule->lsm[i].type, Audit_equal, rule->lsm[i].rules); break; case LSM_SUBJ_USER: case LSM_SUBJ_ROLE: case LSM_SUBJ_TYPE: - rc = ima_filter_rule_match(secid, rule->lsm[i].type, + lsmblob_init(&lsmdata, secid); + rc = ima_filter_rule_match(&lsmdata, rule->lsm[i].type, Audit_equal, rule->lsm[i].rules); default: diff --git a/security/security.c b/security/security.c index d01363cb0082..4ecbef074809 100644 --- a/security/security.c +++ b/security/security.c @@ -2558,11 +2558,14 @@ void security_audit_rule_free(void **lsmrule) hlist_for_each_entry(hp, &security_hook_heads.audit_rule_free, list) { if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) continue; + if (lsmrule[hp->lsmid->slot] == NULL) + continue; hp->hook.audit_rule_free(lsmrule[hp->lsmid->slot]); } } -int security_audit_rule_match(u32 secid, u32 field, u32 op, void **lsmrule) +int security_audit_rule_match(struct lsmblob *blob, u32 field, u32 op, + void **lsmrule) { struct security_hook_list *hp; int rc; @@ -2570,7 +2573,10 @@ int security_audit_rule_match(u32 secid, u32 field, u32 op, void **lsmrule) hlist_for_each_entry(hp, &security_hook_heads.audit_rule_match, list) { if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) continue; - rc = hp->hook.audit_rule_match(secid, field, op, + if (lsmrule[hp->lsmid->slot] == NULL) + continue; + rc = hp->hook.audit_rule_match(blob->secid[hp->lsmid->slot], + field, op, &lsmrule[hp->lsmid->slot]); if (rc) return rc; From patchwork Wed Nov 4 23:40:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882431 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 809B81752 for ; Wed, 4 Nov 2020 23:47:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5CA0921527 for ; Wed, 4 Nov 2020 23:47:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="hhRQ4Se6" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733187AbgKDXrH (ORCPT ); Wed, 4 Nov 2020 18:47:07 -0500 Received: from sonic313-15.consmr.mail.ne1.yahoo.com ([66.163.185.38]:46210 "EHLO sonic313-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733050AbgKDXrF (ORCPT ); Wed, 4 Nov 2020 18:47:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533624; bh=31g/5HzX6krn+gOjEWAqS8zvx9XmSVzOa+BADnOe8TY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=hhRQ4Se6GlQa+ajVCItgaX68jJYDVul3nJ60y31wGnIwUwBLIiWJ4L/ke27r49OT8/LlKSovl24uJR+n89T4neFpBHEXatOO98n4djvXBJM0Z10r0uSansjMaiViSxOJpVlud3qJGx4YCviEIqxBmDIdtoKWKxvmpuRHWuVX/4uH5AntlL8YRr1u6GwSmDPPBlkDHMnoXRs0zML+l+LwSm0sfIRa/XtSrYkCC+JZVyWzurfeoZRfCVbBlrD+5yFDF6N2tqFiSktl82ivA17QKvdIt/B3eLxV2zNI+u6fSscby/LYYDvspdFO0Gwydf/xPFLwEen0V0oxKZyuR61MIg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533624; bh=+hH1a8yPR6qaZDCsIMFmKPZ3In+1spyVg/V+Q95yqaF=; h=From:To:Subject:Date; b=XUplVZ9+tom/nUwDN1CcDhHjCwqjjokvwUZB08MdEwQgK5kYCF0/bZ2mche7Wcm8etNXSGB9G65Aas8pSxUM2yI0+ZyljAEvKr+fx5ucbcEeYJ4YjuPcPUaAHfpO1ySfiacoK3tPVKcht9B5GJ++4WVeS51vQVwWoJPjQatHD2UcupkCI4bMcwolAdtEcOSufHnWl+ed2F20+vxplf0xY/imt8L41Wo7I8iUXtQoaszmTLsN1fNO82O4C/kobbilsAw9xxO2BZK+zBR6U/rNvNQ1IIwybXrpSdfLP5yYBf4Yd0/avxXIQ3JQ6mEbkfd7FZYauqrUmuNrfKxB1sq1iA== X-YMail-OSG: goq9a4wVM1m89i6MzLMqvrBtoOWYUOTFtKaYw7MYnE6lT7pvOPcDjw_SqqvRIaa JWkM57E0u6VhI7or7hthIw6Z_1wMvFGuW_Aj0juprAr8a5vIqpUCQ1AiP9TZHTBGDrJeRRCHgZ5V I3p8ewf5XeLbOHUGy_6_8b6gBhk27vZAC7JYCwCcLaykQmeOQJSh6RgW9rNg53p.3JLyTnE7j7VB ZfUYdIVMiYoTyMelvQvMSpjOducxCwI5TPJfLWGPr2HHHIbEsAVNOymXnDzlQLDuIsX_2pUsu.CK bGHxz7SEOpFkZ66WsgChfeupphVr6lYPT0JF6hzGNm7cmuMUDAmvurMDMyiPbAAUIKK.L9gpKzLA fCpek1ZjoloDy_RLqMtUHNviDsxNswQdiV3TqtiCy9w5q.tE6ITG.2ot4QFfV0SY_c0leQVKYkeF oCYymgnVZFcDhvN8FPoAPlPuiWv_J.96IJkDccnLPc95JDuoEttT1kent6HkTbVrCd.CvFPD1aKZ ATYOinCMOBvobmctIefR97LAt8MGGCbuJe4yFaPBwTnuSeixhLwBIgE6T69qVmnyjJg19JnXm5jF 50ejS.9BAxeSyeQaKxTnFdy0XMO76bskIBiI_MFtlHNOzeZ5IkeXsXWANMUavUudMusEK6rD5.av 9WYR.KP_BeOi3wL4fUEjmu4c26Ec_fu4wNFuug84tLnHjzZX_wTJtwVm1Jr4O7RJ4e4ywk8oC4D1 s8qg6ROkJrtuMo5EbshMi0p.aLB2HCSAm_Z3.5nd83Jc_IfF..8mU27rvthpxFhQL__fN8Tu.uok zzPWrmyTlXRzuxpjPzZeJXmagksi98WVVRCI7kXtwhmYpafJtGZbDvN.uNPCGXqM8Dvt_Z7VUXCp yilhC.ObhEypdJiWM0u2rRIZavbv.3sSxbGnvo4_P81zZJTRxz3xz8QswfmreDNZmCwoqnNLfEBl nqJP_y53kb4XvRO3meFNmeP_Xl6NmX9v9S2om3AwEXexeUbCafEDq8RieiDcWSLMpJn1U4U4_8sK QW0ff02RlY98h8EDlkJC.WtYaTwTC17QOa.nS_vM_lRiTeZxIXYE_A1WaYNv.tUm77pzv7Nq3p0Z 6lIVsnyARahdg1KytTk5jE1Thx9iZKHfxcrEOMEwAxZiUxrYocANn4ng.hsmKuroMwSMQqZWxJD9 bsfqBGYVSplCcW2LZTLgljjK5Aj35Hj.ulITfxf2a5HrClxDn7S08cGR1GPCG7w06emabXrgl0l7 htXMd9bxMKqciwC4AVA6X6r1jQDeMoh.dNSEJeQp1mR0RnW_XFkHXnuov_PxXg8pbAInI85wqgJn dTIuycwNToYhYNK8yJHFDJfVvDwA3XKwvZAonVNYu1C_rtJ_bi_v4faQU_v.e4UbKRIl0uVp9GHp b3zUZB3pyt5eMaEe2B4OHK6vgHT3VurxEXE1Flls8wuba0okqUq58K0qGCOgvOW1YbP3lB1ZUSmH vVh8vJ082TaTL1Jus9XrqJ6usxOunS47lsvFGYzSQfM6oufh0.13rHto7VSp8zNmCXBZoMvXvtkB LyL00PikzIpFsZFE_wPObg9VrCx.3Z2nGdVagBpEgwcmaLUPHvzCN7M3WPf8tzMHhXTYakUYGuat h1k_WmuP6DeUULqwaT_PcjkdpohWOqdHVyOF0Kf.hOylwLL8cYnbO_jaPhDepUF4S2RAbg6Ylkjt xDHG.BNerTazlZPr5RdhSqmMtUj6HxDxMTZRxcgo.BB8p6sOQG15Hh.jF5UvQFsHOViN_5hRvyfv WV0zucFgk3ynkB_bw2mitdoCpln2mPSAw7X4BzRNYpF1GQL9iJCfAA_w_4x8QNZrRDTpvSgHix12 ztW_dXTf3.p5ju4bTl4FUvUIv0rtB4QUKrE6o71mz93flIPbMG.g8.fmhPt8Ko1M1dmT61UXNG9G hbASjD9AirjM_yfr5Q8K3ymSiuN92gSgMUY0HSOJ12m_XKAjD6qzKR28YlMt6U9Z_FvCvzteRx0f WRSvnqn.vnCxiGI05KdXmtca9DpsjPedIMiLw9dwHmWYF.8ZmxqM7Tej6zsUawZPSaY7vofzduHS w0mCsuTOh8VSzkfleqadXFXolE0dm.btUT29c4ZfPvC6MSQWKXnBEw05dB02vcL6DEJxRsw_7_BA 1t0tIP9NWFcixe2zJjvC3JVzB9yZjoz0yV0Ab5DyOH2Qb7QyqVQ4h3iYW5ydqlct7SHpzdZ0dSDZ GDf3PZ1dKZxFvcx1miku_P_7IvtBH8As.0zScEn1BORJpVjHpj2JVJTIFaLp.XmnTwjO0eRq8TGb blJBXnkkCPuFFfPttw1ekJ.zOXRDUJYds5wgH_FyligIzii5cXPJslPBxYBuQuRCs7H91CYkrI6_ 1Dv20fIK2CD7BLai6qZIUjj1Lpf8LurlNraSWdBvJJ11ncJOOumzmd8h2Bf6f2VCfPOFEoTRYJv. d3I1lPpn8iUoJ0HcbEGlXIwM8fhvpYe60LxIgBmFdIHKr8KV987wgDMUmR9IMYBu4edIp372LxL6 dTObasPfAXbEeWMdJKYJSYfwCkAf3gwzsZdvDdjNs5fR68fGLmQIyhddV3BE9EYslb_Pe8KBuIUt aFVq3buiiDTZxjaRArTmDaV5izHaTvVI0Tl4or3SVlW6fQhkFxizIhOIMpiBrzPwCRCZA__w.sBE maTDd1s9K3.AEFHmzFZrU0D6pSL3rPyFvbknMAbK_5WA2Muqk.NlMsitJjVcu1TSH6my5OJkZasL RgeXtLQqV5NallU2ESuH_6XyolUWx1xqgCSodTd97pBTGan5P9dpC46CJnDH_gGcFWeUkvWhxnr6 JInA_ayhqSC2zQBgNes1D2WF8vc06oeLBW3h__a6E3KkDKuQaSppzur4xpvvrdNUQStem_Ocm1Z0 v5v4HAeoOGMBHB6srLsqP53o73UqMfrjgAFDqCvTqq2kFfBqXKvRZnxzKvAZeS5yg3jjz2QyZP8K iB56rZGmanZypTvKMRHXcA1LYDWYGrUMT5eaai84QYYsd5qxtEmYl1ZRDUteBUuy0CB_myoKNRRx 9maZRBIdVN478Dp3QsRee8vF4RGmNNpj01BJZ1HZtvoYA3ewC62jrmNRuVdjqyJJxcv4eW2Trisi 2goZZNbJ6hwhkCl0hj5YzU8pTbz8pvNgFIlBvYKmJylvieWF0fsgeKagnKIrrVXbcUZN.qvggQVV F4vuWllVxNf1Dj4TDHo6_Tun7OBgd92n.8dDYfV1otflR6P0Hr7tt2XtM8d0sYx1FI3ztyJNHvE9 DX13U4NXFIM51UeWVZ.CY.VuHIDY9RjZn11qIf17v500XMf4R4i8fjfoGn4Vdhc6IFJFqQti4UTx 1YiVZiv6xDQ-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:47:04 +0000 Received: by smtp422.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 703a38252183f817957522daa59f0b45; Wed, 04 Nov 2020 23:47:00 +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 Subject: [PATCH v22 04/23] LSM: Use lsmblob in security_kernel_act_as Date: Wed, 4 Nov 2020 15:40:55 -0800 Message-Id: <20201104234114.11346-5-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: Change the security_kernel_act_as interface to use a lsmblob structure in place of the single u32 secid in support of module stacking. Change its only caller, set_security_override, to do the same. Change that one's only caller, set_security_override_from_ctx, to call it with the new parameter type. The security module hook is unchanged, still taking a secid. The infrastructure passes the correct entry from the lsmblob. lsmblob_init() is used to fill the lsmblob structure, however this will be removed later in the series when security_secctx_to_secid() is updated to provide a lsmblob instead of a secid. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler --- include/linux/cred.h | 3 ++- include/linux/security.h | 5 +++-- kernel/cred.c | 10 ++++++---- security/security.c | 14 ++++++++++++-- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/include/linux/cred.h b/include/linux/cred.h index 18639c069263..03ae0182cba6 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -18,6 +18,7 @@ struct cred; struct inode; +struct lsmblob; /* * COW Supplementary groups list @@ -165,7 +166,7 @@ extern const struct cred *override_creds(const struct cred *); extern void revert_creds(const struct cred *); extern struct cred *prepare_kernel_cred(struct task_struct *); extern int change_create_files_as(struct cred *, struct inode *); -extern int set_security_override(struct cred *, u32); +extern int set_security_override(struct cred *, struct lsmblob *); extern int set_security_override_from_ctx(struct cred *, const char *); extern int set_create_files_as(struct cred *, struct inode *); extern int cred_fscmp(const struct cred *, const struct cred *); diff --git a/include/linux/security.h b/include/linux/security.h index 89c538aa283e..948d12a5eb25 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -443,7 +443,7 @@ void security_cred_free(struct cred *cred); int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp); void security_transfer_creds(struct cred *new, const struct cred *old); void security_cred_getsecid(const struct cred *c, u32 *secid); -int security_kernel_act_as(struct cred *new, u32 secid); +int security_kernel_act_as(struct cred *new, struct lsmblob *blob); int security_kernel_create_files_as(struct cred *new, struct inode *inode); int security_kernel_module_request(char *kmod_name); int security_kernel_load_data(enum kernel_load_data_id id, bool contents); @@ -1061,7 +1061,8 @@ static inline void security_transfer_creds(struct cred *new, { } -static inline int security_kernel_act_as(struct cred *cred, u32 secid) +static inline int security_kernel_act_as(struct cred *cred, + struct lsmblob *blob) { return 0; } diff --git a/kernel/cred.c b/kernel/cred.c index 421b1149c651..22e0e7cbefde 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -733,14 +733,14 @@ EXPORT_SYMBOL(prepare_kernel_cred); /** * set_security_override - Set the security ID in a set of credentials * @new: The credentials to alter - * @secid: The LSM security ID to set + * @blob: The LSM security information to set * * Set the LSM security ID in a set of credentials so that the subjective * security is overridden when an alternative set of credentials is used. */ -int set_security_override(struct cred *new, u32 secid) +int set_security_override(struct cred *new, struct lsmblob *blob) { - return security_kernel_act_as(new, secid); + return security_kernel_act_as(new, blob); } EXPORT_SYMBOL(set_security_override); @@ -756,6 +756,7 @@ EXPORT_SYMBOL(set_security_override); */ int set_security_override_from_ctx(struct cred *new, const char *secctx) { + struct lsmblob blob; u32 secid; int ret; @@ -763,7 +764,8 @@ int set_security_override_from_ctx(struct cred *new, const char *secctx) if (ret < 0) return ret; - return set_security_override(new, secid); + lsmblob_init(&blob, secid); + return set_security_override(new, &blob); } EXPORT_SYMBOL(set_security_override_from_ctx); diff --git a/security/security.c b/security/security.c index 4ecbef074809..3a88a90ddba6 100644 --- a/security/security.c +++ b/security/security.c @@ -1693,9 +1693,19 @@ void security_cred_getsecid(const struct cred *c, u32 *secid) } EXPORT_SYMBOL(security_cred_getsecid); -int security_kernel_act_as(struct cred *new, u32 secid) +int security_kernel_act_as(struct cred *new, struct lsmblob *blob) { - return call_int_hook(kernel_act_as, 0, new, secid); + struct security_hook_list *hp; + int rc; + + hlist_for_each_entry(hp, &security_hook_heads.kernel_act_as, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.kernel_act_as(new, blob->secid[hp->lsmid->slot]); + if (rc != 0) + return rc; + } + return 0; } int security_kernel_create_files_as(struct cred *new, struct inode *inode) From patchwork Wed Nov 4 23:40:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882517 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 26361174A for ; Wed, 4 Nov 2020 23:48:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 022E320825 for ; Wed, 4 Nov 2020 23:48:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="qSjCSL2S" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387606AbgKDXsQ (ORCPT ); Wed, 4 Nov 2020 18:48:16 -0500 Received: from sonic313-15.consmr.mail.ne1.yahoo.com ([66.163.185.38]:36301 "EHLO sonic313-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387553AbgKDXsL (ORCPT ); Wed, 4 Nov 2020 18:48:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533689; bh=erYMDd+BdGzaMY+IvBFczstUTN3hSKUThjOkBNjJt+c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=qSjCSL2S2gBTEuXRhfCDrlb8RKq1lUu7x2yOcsZId5zsjEJ1kQ9HKLrh/behyMpEEZK19JD64/PCgLiy1L2vRjMMJ3HFhO7fR6pnFC+TzTmvyjJgrrmGF0HS5g/BItFaPoGfEwr+eX+9TgqccCz7zDNeQkxU2X/DJGbiLgBr3BnfgTIp6WyqS95DNacX+5bLSVYylO+PFqY0R2BI2dZCMq+DaDLlW9ixV6GrCXpdYyBFgKh3q/RkWhh/GAgEh0tFVWQdC17VmkYl5+jTRBxbgrNLp3Qdx2QYrVFAl+SFgkCpNFn9O4pXknpUWGm/biTt+j0UMlhjAxM741+zeNFNhA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533689; bh=4lh4PWuyVUUM3xU9NJmf3tXgWtHj3/WbGvOmkowUM2E=; h=From:To:Subject:Date; b=NMG+ICDf3kO+TC8jjtjhtnXz6wlJjRoEkJEexO1YkT1EIW27StyVN6WChmms26tzdFtP7kD1S9eHhNs+XXrZjs74wafvPBtW1blet1vkJUASXa3ycat1KzcYcrdPmror7WnbU0zc+OnCz2pTh+1kpxzOAnRhgWeROzy/tum5cxMwBko727JrIqjo2AJrPzmPmNDeYsSxKGjwTgbzP1GYYoASJBTdnOYfXSKIKFY3LvO+YiyzHXfbzy1GLiR+cc+PBs9ahmvPHAv3emRUhBDjY5eEFvxFlS+s8TYrhZHidJftoLTC+Ax9zufBTeHhNk7sdHefFnDUO5U48+zXF8V10g== X-YMail-OSG: sr93T28VM1n6TGxeFIa62emefs8J6r4XSXUwAUnAyj1PNJ3H6lNuTVA1_U2E7Mg ZSmmEwSymITOoXHHVaYK4x1J9qz9nz83aD_TGzlIs7_PhEgtv.9JuQxTk3ot6bzxp1Xp2uJN3xOK pnu9lz7nhkkKt5c_5TwkPw_qjVZeqfVZ6Ra2jBY_2oR8SAV0KIjcUbhzdUMLHhQ8Hu6zCHjUDk4k Cw653g.CNkl4Z17j58v9adxh3cXFvc9HvxVkpKkXEp2NYfoqnRNu0VNnmPrVn76MGkEGItm.qqkV AQIMvMthHtJcrsK70fvFeH8V8WZ8Pq50UnFekarLI8Acw0OVOJf99gRmD2APZGFG_Y56ptOkiuiG NhkKTO1XAEKmTZeFCwMIcjWn386FpExsBJ.BqP2pmvgoQCyUTAfsMyGOThfMiu7L1No65Rhep6f6 PMvmM5tk0Xd0yFJ7RhmTDEslcoqcSQIrxpiv_h4MAfeQyAH1M_Ox0NnY0zRr4DR1nKNhlvbldwns q9fdASJy6APn.2omVejmsSTwSkdf7Vu7.5wR3dqIZ96wNZumeYSWZ3oFf1nHgwxk0dbK1JU8tnQt 5Wutxnw2dWUrwTCznH432GAp_bpHvYiIT_FF1Bk7Orf13SUbzV.zph39PR_s5tpqhnSKczL.NBBh KljkhkVpkrf0JDijbWCLEtPMIW9F6X_i9lrRBg9hy9JMwprQAcuz.EzccSWh.A9be0IpCuDHD2IR TMduVV3.KkX81HzDnN_m0Hbzc1mWZxOUGSu_x.nJ9aDaQ7qbsWYg59Q1BChLDw2rHGp4kx0ljma6 qKsLoNTtZD0ZMbHhbiEHzBwRbXhtKBGbzNeGm8I6t.SMKFgukIhQ98.pstw24Skm425sMwLNa6_P TKPGiI7SVCcVaDtuMbZUNS.YdAIAiE9gFzsf48I8P2SRPtqW79v3v8eutsnu2hNno6BQiL4Bn3Wn fR93FSXbNTcfYWSPsUvWoYZrpj6HI3PGWgmaE9kr.KenwNEuCSlFM2RHWAFL48bVEaC9oE9C7_dR IWSe4KcZjB_Zrv_7WyyzSyt7_HqAMB8Q8wv_l7YMWab9VDVqFME6nE4WOzMzWzLFzVJtsHGsKbBy UCGydTbxCHHyYACZA60tilGh3lwnDQg8pqXzAFAhb1Z_wAhq.jcv5xihZdKASpPE4y81Py.uC8Wc .QsyLoznKLA1hp2XD.OrYYqI99WNrYzSIqNoH.NkMz9D97DS7DI5VL2HQldxiYP3ZTI6CnUe2eog j4Nro6ER9pvQM9VUo4cjT2rVxEbT3rHMl_pkedFuJK_X.LCpYMqNHRyd.IfKzq05ejZWhzCSxObI CbsRNRkA_uT_c9TmTVXURZ15jXJiviJ7TPj46J1t4_lZ1qQgcVrM7srZrqG1emZPZYJCu8X.uDC0 9NC2oNL3v1iHN7_wVhhRt4pxW68Q55HmTQGaBrcZx9Xb4WVxJdaHHWVtjY_nLEcr8tOl6kPVYgVU A451baUuNtXetTRura0IiZRcmffOm4jpNo3XpjfPpCmnpSe798CTg4U0CywTsRI8LhLhnPKjyvta vK.7GAzR1nH1iSv.Z25CcnNF.KNwcb39MF3xcXmKqRuVXErZPXulOSoUq17JXYMbpF2pyicGPbUM QvPHIYhd0csOjTx2ovhKggaZszXY9SPXXgv_E7qV_N0fnO5xjMk0qHU7jbrtgyQ9hTiQkFBUOKSD ayDdq1u3Q8vpmzoNVloTBlD3kO5FUKDVrwi_fdLysCZ6x0SmwjXbcOQnRYCRmyWw2AeRFcmXIRYv t8IGr5AMl_rpfquSkfHelUkmgi16hp_R_KtzHRbLy4mVlPHOJdJ4vcT8o4SjTa3BYwh4hc5jY1Vw bEB6LlUejv9gI4jjZ3mlC7.hom7zyQKWB0uOLzQJsP8dI8k_ZWRsRuEZRjqES8sBItbrWRltzwR0 3hE.gW7QUjMKDxNXyHV5mXL4rhIifRINBqEWDeDgjSp45gPpPWUgvYc8k_BFuNQl.AXBkNr5h7BN mNhpy_LrTyWyqAPFyFT6r5dBd4Z8wcpABxrFw4317b4aRAh8zulFWbuZKao49bbBSXFRrUs6SYYq 4q95fcJum4oDu5zvVI2bwVZKXtEytzoyVcncqQzbK0WVUdZJ52EzMEIdDUQXhc5KKLE8rluS44PG yEE4DxWY.N2hDpIcioxgNm81xnZdAde68oeoJnyoRad5VIyPpVA4jXaI5k3O1DUDn4QccaEjJHo1 IOwGOZU_Eqe1ejKtq7sWWe0WajzqntOc3aVa.lS24wrDWWBd9rIdQoTvRN3crEI9fKIlmI4SF8f3 _XOVu5PmlO1uU5iAvu4zz_Ug25n2Q5g_HGKXqwbT4BpRpFibyNyRdV81i_rlblYzpToC0duMo_UM GjHg3jeQo_4ivjqX53hKMmUMEw4opYwoH1xZITw6jWAUj04_lsza1aSvzU32UnnoPtdDPJbhiSMN qPIC_FClg_ducXblqeXPVzkBY6QEUV.e0zNQNBdhJS1qf4vTfcNnhHQ_RKvcewdyuBrLO2bFOg5v sxXRdAmSQLAKaixmFX3tTR0UnhMWa4LXHHP51g4Vvp7vt2uOqwylV48x7xorCyuzTRE1nrA9KQLA gA5AuqU2yZwMJ2sxwOukmDLPiZ3yqBaCfUxHtPQ9s0LpVWJbBIqNWtFDaVk555yjder6FaQFBeeS GxJ6A.XHEGKmH4733IJPIITv80LeaLO1ytcH5WVljBxsf7uquFKNrV6ftg6rbiHqoQ3fjkSFrIo5 oEuNeLSydCCmdBi6PYPs3j.gqK.IgnDuQkgrTNfmlpkIm6.lkU5AG9x3tl2VNoKFlokONhK5leJx wr0mQITLkmj49fG.2J47SjPWr.2pIE.potr9K6AQhoGJBVxscO3IxoyMnEF68yeGAJxIrJeWrFSH FQavIdssvVF_TPb.Pmm6GlmPaoOCaF9_ojW4wI1ffNTnrtMUaX4P_LMOTKnCoyLWVFVwgwZsTXTg mhl6aOxW1DNr5QJUwarpxMUmlqvvPQ6ks42wtdR2QwHuO.d4Crwr3IQH3pbBqhjMGq2gmXxzEac_ zYnrhYWfoEijgTTjerCZd01rC4eDke44U339AzUr1rEBuIuY5W.kTYJx8unD_UBqWd1vg3Tldtxu 1RWCwDvwvs3JwNgnF2XasdeiEooozlUuNCQZ9Rghr1WfCTz_ZOJ.fYIvdLNT9qfUZZb97eYY06bq HaJdO6yXbEtXpWIl_3SRiM6LsiftyfRS7UtR5DB5GAqUhu0y7jAxfc7x1vk8W4Pt86avaJ5EhWJz 3.k.3hsP32XFaqQ57cdrCilO8nmIRvy7_SptjajVSYGgwOZy2iOBDeRvujwPEbZkyBpiOsdwsmCd XEUJQ5i0GdoqnI9lJW1Cd00iSjPzAoqZII2Ps0PjHmA-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:48:09 +0000 Received: by smtp425.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID d53b5fa43e99ee2806ceeb620b264b91; Wed, 04 Nov 2020 23:48:06 +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 Subject: [PATCH v22 05/23] LSM: Use lsmblob in security_secctx_to_secid Date: Wed, 4 Nov 2020 15:40:56 -0800 Message-Id: <20201104234114.11346-6-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: Change the security_secctx_to_secid interface to use a lsmblob structure in place of the single u32 secid in support of module stacking. Change its callers to do the same. The security module hook is unchanged, still passing back a secid. The infrastructure passes the correct entry from the lsmblob. Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org --- include/linux/security.h | 26 ++++++++++++++++++-- kernel/cred.c | 4 +--- net/netfilter/nft_meta.c | 10 ++++---- net/netfilter/xt_SECMARK.c | 7 +++++- net/netlabel/netlabel_unlabeled.c | 23 +++++++++++------- security/security.c | 40 ++++++++++++++++++++++++++----- 6 files changed, 85 insertions(+), 25 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 948d12a5eb25..0766725a6b21 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -191,6 +191,27 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, struct lsmblob *blobb) return !memcmp(bloba, blobb, sizeof(*bloba)); } +/** + * lsmblob_value - find the first non-zero value in an lsmblob structure. + * @blob: Pointer to the data + * + * This needs to be used with extreme caution, as the cases where + * it is appropriate are rare. + * + * Return the first secid value set in the lsmblob. + * There should only be one. + */ +static inline u32 lsmblob_value(const struct lsmblob *blob) +{ + int i; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) + if (blob->secid[i]) + return blob->secid[i]; + + return 0; +} + /* These functions are in security/commoncap.c */ extern int cap_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); @@ -508,7 +529,8 @@ int security_setprocattr(const char *lsm, const char *name, void *value, 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_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); +int security_secctx_to_secid(const char *secdata, u32 seclen, + struct lsmblob *blob); void security_release_secctx(char *secdata, u32 seclen); void security_inode_invalidate_secctx(struct inode *inode); int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); @@ -1335,7 +1357,7 @@ static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *secle static inline int security_secctx_to_secid(const char *secdata, u32 seclen, - u32 *secid) + struct lsmblob *blob) { return -EOPNOTSUPP; } diff --git a/kernel/cred.c b/kernel/cred.c index 22e0e7cbefde..848306c7d823 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -757,14 +757,12 @@ EXPORT_SYMBOL(set_security_override); int set_security_override_from_ctx(struct cred *new, const char *secctx) { struct lsmblob blob; - u32 secid; int ret; - ret = security_secctx_to_secid(secctx, strlen(secctx), &secid); + ret = security_secctx_to_secid(secctx, strlen(secctx), &blob); if (ret < 0) return ret; - lsmblob_init(&blob, secid); return set_security_override(new, &blob); } EXPORT_SYMBOL(set_security_override_from_ctx); diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index b37bd02448d8..f1b9b0021414 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -811,21 +811,21 @@ static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = { static int nft_secmark_compute_secid(struct nft_secmark *priv) { - u32 tmp_secid = 0; + struct lsmblob blob; int err; - err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &tmp_secid); + err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &blob); if (err) return err; - if (!tmp_secid) + if (!lsmblob_is_set(&blob)) return -ENOENT; - err = security_secmark_relabel_packet(tmp_secid); + err = security_secmark_relabel_packet(lsmblob_value(&blob)); if (err) return err; - priv->secid = tmp_secid; + priv->secid = lsmblob_value(&blob); return 0; } diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index 75625d13e976..9845d98e6b77 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c @@ -43,13 +43,14 @@ secmark_tg(struct sk_buff *skb, const struct xt_action_param *par) static int checkentry_lsm(struct xt_secmark_target_info *info) { + struct lsmblob blob; int err; info->secctx[SECMARK_SECCTX_MAX - 1] = '\0'; info->secid = 0; err = security_secctx_to_secid(info->secctx, strlen(info->secctx), - &info->secid); + &blob); if (err) { if (err == -EINVAL) pr_info_ratelimited("invalid security context \'%s\'\n", @@ -57,6 +58,10 @@ static int checkentry_lsm(struct xt_secmark_target_info *info) return err; } + /* xt_secmark_target_info can't be changed to use lsmblobs because + * it is exposed as an API. Use lsmblob_value() to get the one + * value that got set by security_secctx_to_secid(). */ + info->secid = lsmblob_value(&blob); if (!info->secid) { pr_info_ratelimited("unable to map security context \'%s\'\n", info->secctx); diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 2e8e3f7b2111..8c064342169f 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -882,7 +882,7 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, void *addr; void *mask; u32 addr_len; - u32 secid; + struct lsmblob blob; struct netlbl_audit audit_info; /* Don't allow users to add both IPv4 and IPv6 addresses for a @@ -906,13 +906,18 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, ret_val = security_secctx_to_secid( nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]), nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]), - &secid); + &blob); if (ret_val != 0) return ret_val; + /* netlbl_unlhsh_add will be changed to pass a struct lsmblob * + * instead of a u32 later in this patch set. security_secctx_to_secid() + * will only be setting one entry in the lsmblob struct, so it is + * safe to use lsmblob_value() to get that one value. */ + return netlbl_unlhsh_add(&init_net, - dev_name, addr, mask, addr_len, secid, - &audit_info); + dev_name, addr, mask, addr_len, + lsmblob_value(&blob), &audit_info); } /** @@ -933,7 +938,7 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, void *addr; void *mask; u32 addr_len; - u32 secid; + struct lsmblob blob; struct netlbl_audit audit_info; /* Don't allow users to add both IPv4 and IPv6 addresses for a @@ -955,13 +960,15 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, ret_val = security_secctx_to_secid( nla_data(info->attrs[NLBL_UNLABEL_A_SECCTX]), nla_len(info->attrs[NLBL_UNLABEL_A_SECCTX]), - &secid); + &blob); if (ret_val != 0) return ret_val; + /* security_secctx_to_secid() will only put one secid into the lsmblob + * so it's safe to use lsmblob_value() to get the secid. */ return netlbl_unlhsh_add(&init_net, - NULL, addr, mask, addr_len, secid, - &audit_info); + NULL, addr, mask, addr_len, + lsmblob_value(&blob), &audit_info); } /** diff --git a/security/security.c b/security/security.c index 3a88a90ddba6..eac7c10b8cfa 100644 --- a/security/security.c +++ b/security/security.c @@ -2081,10 +2081,22 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) } EXPORT_SYMBOL(security_secid_to_secctx); -int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) +int security_secctx_to_secid(const char *secdata, u32 seclen, + struct lsmblob *blob) { - *secid = 0; - return call_int_hook(secctx_to_secid, 0, secdata, seclen, secid); + struct security_hook_list *hp; + int rc; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.secctx_to_secid, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.secctx_to_secid(secdata, seclen, + &blob->secid[hp->lsmid->slot]); + if (rc != 0) + return rc; + } + return 0; } EXPORT_SYMBOL(security_secctx_to_secid); @@ -2235,10 +2247,26 @@ int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, optval, optlen, len); } -int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) +int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, + u32 *secid) { - return call_int_hook(socket_getpeersec_dgram, -ENOPROTOOPT, sock, - skb, secid); + struct security_hook_list *hp; + int rc = -ENOPROTOOPT; + + /* + * Only one security module should provide a real hook for + * this. A stub or bypass like is used in BPF should either + * (somehow) leave rc unaltered or return -ENOPROTOOPT. + */ + hlist_for_each_entry(hp, &security_hook_heads.socket_getpeersec_dgram, + list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.socket_getpeersec_dgram(sock, skb, secid); + if (rc != -ENOPROTOOPT) + break; + } + return rc; } EXPORT_SYMBOL(security_socket_getpeersec_dgram); From patchwork Wed Nov 4 23:40:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882577 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 E8CA71130 for ; Wed, 4 Nov 2020 23:49:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ACF842075E for ; Wed, 4 Nov 2020 23:49:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="d9sX9jaQ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387728AbgKDXtT (ORCPT ); Wed, 4 Nov 2020 18:49:19 -0500 Received: from sonic301-38.consmr.mail.ne1.yahoo.com ([66.163.184.207]:36397 "EHLO sonic301-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387698AbgKDXtR (ORCPT ); Wed, 4 Nov 2020 18:49:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533755; bh=2NyewPO53/4iI2Tr/R68jXRbY58jiTgqBTe9D9i5YK0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=d9sX9jaQB/cgQo9ZC0b5xZpK+ThkHBcTMsl70NzsPSswNoTbPh9MNEGi/mRt/NOYwU7vvBvhVMpyC4nvYPXB689v3q6UD2Hp9pQ62EtPfD05VyedOQeEWtAto6PDEdq+B/+buFWZTerN7z8fjj9ZjTf/stGKPeM6CnctyJZplP3w74dcOdV5+2k1odu55aI0xFOCK99cI6dVlf3O3M0b7ogPRtWGpl/wmkuzN5ZWnEzc/8psbjjgg1VtpVeGNvZo+lRvkcoX51tOx4s1DvQ6BCfR6eStQvdStWUysvGEHyKa/J4dRV5J/2gBpubwlNxmwv4c5Nrw4pBTWRLNP+gmGg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533755; bh=WZcAgyNM4+jZY0eGaP3rDPKNbQXXHglG02YFpRngFGD=; h=From:To:Subject:Date; b=PbObaTose9DCjuIBwLQC/cLknzZD2AitFAlPKgHPBtQn67A3WkyLHmkio8PO/sjeYuO/xUGiXz2ecDYjZupXbn1SK1UQkRONLP+YGzp7BFY4AH5UtVzIAMaKl6hCnAiMy8w3piT14orI/cfPVSYTGm2BPmmFu9hhyc2U9Qe0+EnBTm1ansLJO3xvgC8IqOZoiE/80VvxjUt7Q+xKh6an+8IH0mXVQlS3dFXNySLeo60/E8eEW1fUA+nHWEVQdhu59a4f3t4ZJptrhz4GncYUuoLBH1GVxKeK36xsFDoHdcHGDmtfxIwAoIq0/p6jcfSWZ/xJ/O6QmIxaXrskEAlxuw== X-YMail-OSG: hUXPO.MVM1k2KPZzdKAxjIcQSQwPyeIQBlPqV4OqW.bKiRIfpBhEl2WgOQUKeWl wc853OUumGKsKvKw72Ld1UbEGObWN1juRs19DXYMe11XiAuZXJ.zcfaO9aNVbLQ.7K5ostoDxa2v yW1MQ43Gc3AoJfApkPDLlyxW4g5xzvatjSTGk1J_YOVL7A2jU_GFFiO47sS8u0PmSonA3iflBeU3 aNS2NfW5.vi2PbLO_B6WlaUMLINJ0dnvPoM2lQykgapjgcWnB4C9MQDkV9_I4j87KmLJtjiPoTg6 ETGc15mTwU2YRg1AII3uyi7WKfkhvGjeXyrGr5BTG9rYyKh.zrwcUSigP5bl0u9PL2cQoMcOcQqc Czrtp2LJ_YqMNaDvYDUSw_U06Kas3WCnGfxfeBP2csknuzybUG_DlUdLNHfvjt4IxyfkZbniqsSw VguacZD6z3cN0tyZgQzWNVKwNFqGMg2_COCCKjJotF81btl5jT5ui9uHoxMfrz5B_OWJX9XVqdi_ Bs9o2Xq0jwbt1UwrWH2SRj.omqCKWtOcpOe41xenGeX_fWSy5UkEjoHGf1sbMtihryvOAYsEH2p5 xYwrYgISLqffbXS6Aq6sYdVPlkJ.Z35QGcCW2eQEzn4h6NMCzi3naJLZPIePD2YjdiQOETGNQpLA 0t.AqOQMpTDjwsYrpcZPFFa3jKdwq0kbqY6eaY_3ZCkSp9rDeRkwYqMhn.I2ZdoTz08L8ZHCk.5I .a6W8DVB5jWcSkDqWe8ypSsaHCyeSPIYLtryzckbsVp5IBn27YCML9PqO8.wz5y6i7lPLSyaFrIi GsGdSCQEgDDkROnLa0k2rsakdygK59vebmJ3Y1h5VFPS.3a5Z7ixbVMv4_InPuHFvnAJ07tZz_ew K87v9YyV8Hik.4Mk.L7tkIiMorI.ltyoDTBEoeDP3bRoktxUWXL_Ax.6LwO45UcThDC077xQ.95j 4ZneHs7vvSws5KcLr3i1n2nnzI.UNRKV9O7WGIQvqy4jv5Fxp.ogCKFovdaDBsVj0p2Jl2zVxXmG iCwpow14H816pshwqRZgdpcBwkyvbcoQb4oreV2J1SiQzIphI5AIKUi22rM3DoQHH8CZ9M86_ICl d8lCxCBjrwFlRrL9s76oF4NDZt.DdAonFWLrPspdf9p0lt6IgvfWsfAUjyUXviG7_4VU6OTmDVuU pQo40SUpYUf_zF5Riha3yF3SKT7PqJKh3gW1q6esiab7bvJmjjEKDpz66CIKxqFUYxb.._mRXr4y PwcdxsyWCyVuVoDKIcbFV9.UBCqHp9aL6dJ_PjDqzmgjsz.H9v0lrYDVAtVCUyQ6c3h.IAhn_E_R XCPqKVs8a14POLS.QEK1F.KUJc8myUuNeg1Q3MdJ0BUkxwAHIqBiAZ66l.38QQmX11H6PHxEwVz_ WZSHYcA7qcCulzV8ml2fCXzarJPSqRxG0HyWfvv8kSfYQDyjjf4Ua2WGZfOUfhoS5.HFGWZ9JiJ4 8_.9mEwnSsr0D_ILu6N6TRFa2GEIufNEZyF2VkCUIW2UzUQA5We5p8ER9cyoTYnn.1J.8FDSSOW. 7RsWM7U2OyHRwQ5g940eHqpOQBh8C2B6Ju1Zz1gby4fARYPD556ZXIWiknM_suLLanZYJJ3Nofnd 3aVFRmeik4B5bKQWivbaQZnYk0hEmqCmye1D4_gl4nxTjTcyeqKn8EaRlWKfIaOwzeEHISSu_Sfm teV6FcY4CV2cHoCySaQ8IaO51Loqtnn4OjzswAiimKbxSVmgWqzV.uPIelcDmlckW86SbUlPJPof zQNvUAJaUBjWYRvQsOfhoR_a1N64oTBYkaWguZ8h9GxluPdRK2zaOWfm6K9XdEOf1jREWl_bDQ.O xxdw2VgLguUeVHAXDsjugn2c_qHbtggMJhsVxBzByD4wzWsnZ0sMWOI5WeuKvh5EogsgerzxcFUo H_s_yvkCOWrJgScoAS5LvrFNW0pjSDC6g2wIw8o3mQTxA1i_5rWahqo3wfdFQomMh8JO2wWSXfx0 uPWgFJ5u4VsHsXSw7OCHXnI0a2.vAiCtNayifOxwnNgCGWsaiS.iErgpx4iXfMTBtto3IjPuofpf hJ39jjz03EFXIlklpfe_ET7J7UdieqFSpfn.Iv12dIsLdsMDnAuxKPjBrViSJohrTxF2iYCmg57q HFH3NZwJq4wkM7_8_u7PJfXmenPixb.Rx0wpAfigm5RhHxznEsohuLvZxgJRS7AmBoElp32BczlV pIyKb5Y.IA3zlgl5p59NHPzBxFCfcuzQpE2SRxITW5wd4JSskntiiSy5IkYIU7OBBdAOz2x9iWQc DF_eZ.UtMthIkCaCOnM_I6gWEEEsm7G9Q83AUNyYJg3QIXJRjxdJknOscf.F922n6AMGQ2MyoRiR H8gwEB46vrIKrPzW.sK03GXrUVkIQ0rJ6YSsDXtok64pDFDB8UcwpNAP8kf.3uI1BSnxmMGU_IGF bljUjAQfK.Ys6aRyXkBmKFKEp_elgevJbFm1gH0Jq9bielPGzzx9jQhlSxIR9Ia8UeO_ZCJLfzQT .i2Ha7OZleOBkVxbXTh7QNUpa904lctLRtP2Ulp1LJ5tdsO6_PM89rkB.w6P7UewCWUL.bcJWZeZ bClV_EORiTfMxFAj6PU1g9H.No237_pezjArtTUf2KZf0jOrpBskEi4YbgD1I2KMi6LqVO0etK2D ZDuzk9EyiB.OJzGLETDR_uT2L6gjMiF0oXtQlGqT1N0VhkQxEVMt732B1lWYf5hJcwSwrLqidrl. H2MnUcBGCnnvZSr4_4ZZeNx2knysx8JKxfK21Qx5tE9bFPDYwZL.w_xEc3N3SQt.tkhA3p1I4xw8 TF.lFxhpAIIGNQl0PbLU61PrbLndb1_uuagUuyjzsmL0SBr_0bASSpBnQsZNGYNTHlArGnWZiH0w 0jlKXQflNG.GMk4qrF3yyfD50tXmQ_ypWaeNVZ3mgR5sgKswb_a9FujkBR.JtmMKBLMSyu4wlP3B VtO4z8KUJD3nMYQ39d9JfnYckhPGrUeXAiB88ewnV38wFy1sqxIqVGFA2.elw.2ar_FUGmiBLkmu PwRYbS8vrKPQMmIdFkfeorzNBkALKGMdDVDXvBwGOv2tBMWJJftxqIrfV.M0hk3jcOOG1q5Kg5nF 5K8b4iyMT9zBOlOoNGqS8bnnAT.Od4zGJbKhJs7EttUjzQHAPgBAMSTDsBkHD8uti9C_umErGftY UNTHsRCrUnM47UIF.z4O4hlLIwUeadUpa2QBfXtn3gnkDvXQVarX6L1RO6LL52q.N9XwTwUU._6B nzeDIkhMXdubrC62_M9HHQw6zTREjz4YLuAwpg44IEg53NmhQZPOl6004D7Z6TGU7fKjKQ6JfSqp xW8P4D5RlguWXhZWKIakEDWFFoiFKprz_Ct472HjaPKI- Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:49:15 +0000 Received: by smtp424.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 0a1c713e7d1496881f68596c73cc8fa8; Wed, 04 Nov 2020 23:49:11 +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 Subject: [PATCH v22 06/23] LSM: Use lsmblob in security_secid_to_secctx Date: Wed, 4 Nov 2020 15:40:57 -0800 Message-Id: <20201104234114.11346-7-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-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. Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com --- drivers/android/binder.c | 12 +++++++++- include/linux/security.h | 5 +++-- include/net/scm.h | 7 +++++- kernel/audit.c | 20 +++++++++++++++-- kernel/auditsc.c | 28 +++++++++++++++++++---- 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 b5117576792b..55f3fa073c7b 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3088,10 +3088,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_task_getsecid(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 0766725a6b21..fad361bf320e 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -528,7 +528,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); @@ -1350,7 +1350,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 68cee3bc8cfe..4cd6339e513d 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; } @@ -2128,12 +2137,19 @@ 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 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 7dd6b815a9eb..5f9bdd62f78d 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -673,6 +673,13 @@ static int audit_filter_rules(struct task_struct *tsk, security_task_getsecid(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, @@ -690,6 +697,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, @@ -995,6 +1009,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) @@ -1004,7 +1019,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 { @@ -1247,7 +1263,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 { @@ -1397,9 +1416,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 ec6036713e2c..2f089733ada7 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 3d0fd33be018..8627ec7e13fb 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -333,8 +333,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; @@ -647,8 +652,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 46c5557c1fec..54da1a3e8cb1 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 d1d8bca03b4f..a6dbef71fc32 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 8c064342169f..ba74901b89a8 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, @@ -494,8 +500,13 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); if (dev != NULL) 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); @@ -537,6 +548,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); @@ -555,8 +567,13 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); if (dev != NULL) 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); @@ -1082,6 +1099,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, @@ -1136,7 +1154,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 eac7c10b8cfa..ea927a00de18 100644 --- a/security/security.c +++ b/security/security.c @@ -2062,17 +2062,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; } From patchwork Wed Nov 4 23:40:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882625 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 0CB0F921 for ; Wed, 4 Nov 2020 23:50:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D61A920BED for ; Wed, 4 Nov 2020 23:50:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="XzO+qDxn" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733191AbgKDXuZ (ORCPT ); Wed, 4 Nov 2020 18:50:25 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:42141 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733163AbgKDXuY (ORCPT ); Wed, 4 Nov 2020 18:50:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533822; bh=U5bKWCQ1u99Nru5o24TB+6IKzAJnsO7yXV4aGiXz6j8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=XzO+qDxnTgpXNz7m3xq/4gWgOUERuzPqUxB7erjRKnqrmkFYCvciDQdx+C8oqXW+qxRHJSSJwnKymMb9cO/YrKcq2uz5ISDtQ1q3yLtK/HHBdb7o35es5ETZO97m7LWmqHAFK4cEVNL72u/L76RVm1qJm5QEh1d7hXbuyiRrWcr7UH+3UuFJwk5rqNoEgkufcJKj/J+6JRpdFx3JFJDl8RryuRlgq6nWcHCU9n13ZGJx4dOVHY5a/Hjb05THsHj7c6Pi9a8MYO+jeqSMk26EM3DpVHKz2Vs9tKOdlHFsVa5cHIr9YsS6hLRm6fxxRCSeRgx/wY6HSeerVZeKeB0duA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533822; bh=3UhOoslsnfsqfF6hR+s/qCpCPR7QK4U9VBKdUY4f2qv=; h=From:To:Subject:Date; b=kFfrqG4bpt5IsFAsj1/k2BlArDPYiM8wZfzhHA0JJLNs3Dy35gpQD9V7owZIpXtktKt4suyjqYGy+PONgfULfDkCFwB/ls1dfbt3mLLGRAy3qh4melpZp+gKzS3lm9Y1/JPMsGXigVgPAJ1xb96TY+MZYwB7L4FTexzF0aIr9i+5WsI26LjYQsEY4cK5hkE67mdAy0hFao4TJAhywxdwf4hIjOK6cDdgsv/Fal0CHAYDC1FxWi70PsuW1P4lz+gRvDyuqDKgnDFUgisavP0KP/avkGwT5CNnugEaOdVIyUvx5T+w379w0j1TdFe6v4v92gPNUoDJXxdCsjDxiWnkqA== X-YMail-OSG: 09UsMW0VM1kibSLgQpEZrCsrxHqYLRql4MrK3TFzDpxf8VErzeFOWcAtMqEv0u5 N5k2N4sBhOqwFnv2322wlJZ_3BZrOe4oek3zesp2kIil.EaTA7ZqFxz3ZRuut43bHLUjW.4Skulc Fig4dcQRhW3TAav5H_rPVt7XQFot3GUR2.3hJGPHJv85.Gbg2Y3HaeYdPcSToMgsCsnNDFQyMjuZ DJ.OGC29zMfE5xGLyCHDifXmICjpgFfqlhNQHG6Zii1.HUS3gTQL76LNw6xA0JdVSy8owiIJrgnb pgdD5iS6RJqVq2p2HHfiJSNoMpzTpASZJTGWI7vA4UY8lVnQTt5Syekel3nctYQ1NZWb.VFYcJre vK9G245LH5DemRBicpyjD87he.bnfdb167iaLjNJD1zAldibVatUPxRCZXpYiGaxKzGC.vglkIG6 xFQnDKw1_vjEFp9jAfBOq5xFOG3c5dCtslJC6g4z.prsmZUiEeVJy6Mp2qCcrjmC0zea0T_SlTvi fct7FleyKpM_aa5MWLn4ghHr0703v3Pq2BxyByxY3tDcBz18j6Whw6y4pZ7llFdUrSG.gF9XaCv. AxZZG2DZ7KGOmEoCgi1BKPAjquRfeA_FqkICW3dyBdMzL1AlUZQCzuPHD.0pWzOdqpZr2xuivj2y _sMsd0luWyyyrGx0ox_IQmvHU5XdXoo_SSfa0HVjLCJjbjMIxlxjikjt4h5ZZZk6M8fzzdZnLqqx 8iaBSvTU6fMrgTKiUJqVj3pl2.sQRzgYwRCpuUVvoJfAqT1BARqpgggzclZ6ugSiUR1E3e5hksa8 S5xtCkg6Ayz9SYAmM9tk8J0OzdYKoWeyujUAm_ln3p88RqkuPBYNtKjPUQlEdOAa0VbzsANNpiwu lBHwdPAQspiRJhm6toEURkidbAxdXb2B4sdkaxa2Diceefx7VK_VtHigQYSfKvE9V5TUxafjmtgx VpPm3mBS87LXz6otDkemmctaXGNjG.t.dzo5tEH9FIZxd8UoLpC7UIp.gGSPDHEBsTyWV7otn0dW yqI3W6wCFXGrs4Ozabu8qZSLPRgE87JaGZ9gJqQhUA8G8BrrGSNPCB7xoDHf03PUOtFDnzpz_9I2 M3qs6qM1r3oOAbwpLY9871k77om.j_mrG6tmzV533J4zaWyHdvp88V.XpU5ApOYnTIupyitfhB1U 4wzG1SuTgkY5W13qxyE003cLo.ia9Dh9z5xRHZgwtjcUFQWm92nHEPV7cXSKHET39srd5il71pmb ghSv8Lzf563Fb4py6B87HNqi5Ps17JvOpjzcgQFQmL1I3zx7flprOZblpMrmUy2noaPLwS8UXy5s r.1PSuwuRzBeR62Pvf3Izx17U5c0_IRpp7gaMhhdGr.O0fE1BblDfLncl5R.91FpTxv9S7iQzJQw 7GubcWUtNrRJAKFmKarF4OKQgfYFylwx38jtP8zOkl7EZIuDjg36njP4tcE8o7K1x_a7RFlVcLKY Wj103SpUQ1x2tnHVTPx06efQVX3iA0e1AaUyd1U70DRS304az3F4cwKapw6aZua0KmGhlpIuslV_ ODY1xZZbLcBsSixW7pCEQFTziMVQsFZtTL8gyL2k9ODbUQYT2iB2Habh3lroq_0Mbexvjwt.Pslk XNYrx3cBxfJ5.EUMKR0yTNAHaF6ulGTq.vgTCkO_F10Ik2f57qe0ockn0bs2lr6xt.mtCn41qbCg Bz4mjyo246OMh1urtVZzXAhJXlSK6zSod01eTUEuID9mK9SKRcm56cqpQmdJ3aDM9rl3EnkRkQt8 DcjWXe2cwxEcGLz9s03r3EoTp3cOZHg0YYpdxtaIho6WOp3dIxBq3yqghWAV3AZ6UkvJBvmp2dK3 ry.CaHYMIWb1V4ofIfj7AGq_RfkRaWpOZZuTuOpwkvwiTgexoJa8AovNYtIpnaKMpkOZiDN3iwY3 0SpNebhrqHXfXYo1.X43aRphJWVbEboF35_QviPBrcbzcJjVigLubIuYH3dHWjZaz6uzfqGVhneq TdfoIZelcSxzSFEyHInbubO4u7C8yKLte8sXEYV8YViopCGdcxjoi29SVq_QB65EnmW2fjc47gSJ Fr8CJtuNTWJ88lKYkW1E7vJNGY7ptSy2JGMJJopQzLLHspRzrvNzxFw11HEvqa55Z3ncNmNIoXyK FNHqcHb10_3_kB8zTDWpxBIsN62J8XbEf5BbVTTytaDNnsy9mmrIq10ykGzFAytUGrLcFVKLbOo2 0DIhcbRxI71HUbdSyTFTaPjm67kcLmV.MHymfVNDxySW3MjfhIPXbeYCfP8TztKIHesJYsQ5vYQK l92NjM8wCURopm2JglbSO5BL1OtUPur43DyLj9gHLMRxpNqODu.wiO.QCUzGt9wCMOX9zh3tFz11 pOo5hUDcf2RJqJ3FhNqmjDOYltFuj50uN8j2OnuyWDR5KaTbB1U0HpJWjxO7wEQw0sigRpKmuuSo B3OyjNgOWtiQ2F.GBmiRCJ2DopJYjrGJ_SrJHUp2W6OcY0x9vWHAd84GO7ad9NKMsvpcEYvtv4fV 4OpUbNHREkjiqwHd0GOWMMh.tDNo4ZaEsVR1bhF_lEGu4nYp4U4g8hKTvFKwE1lGIKe8ovH3Bj2U TWy04bmtkjKtc77zMLZgmjrWT0HOLh7hoUta8WjIJgXTzTk2_bU8Xh1EVw6GRuKZEqP57ezAZPNQ fQI1jfkaMpJTUORDqoWZrqpIyBnsNu5VCsate8dNybAjagaJEZO9J9IGPYLzJArAFzjTJJolbIdH TeCHuFGPz861sqsDyjsW0XTAmV_1fUz4_d17V71n_VFCEuwNWHLQ6QJzCOG1_28TIb3rB9ecYkaV d56rPr9wNHEFio3aHlNjC3AtL3ciOjoMHEiRI.g6YDTpE8ygkzAkSzi33pEwYdjC42dh6aA.CsS9 BeV_ayzu6ApW5n0c5m1V2RMPWLsZWyiGNow34Sd.295LMILk4MHOUPiWGy8v3atmf3bOqFawXaCh B7MjcrCMM_E4jglOM9G2HIyBpMCWAEMSOPOT8qXpBcssUNKLtp7cRQ14cs_aKrfKldKty0cFPDVf VRtRbYYpTQnLqeiXkcbGJgEXw.Ys4xwm0Ziapg2thXEWcMaWRTZba0D94fjrW.P4ry5CY9XK9i9w NWQ3cUGnxNSGvl8st8tvOnuohb.17UqIHQxb.t9qsJHlA4hXzAi4hWIargicNOqcWXNce0H0wEvx Yv9VjBJgk.C4n3HDnLe7UxjDX3fLLoC67FqhHIUXucZCuoUH3PIlgZqomJ6tUdXIIZBqmT6uBYCI MEyKlPsfwt3KWcvMeDceDfqgrZ2_TFTkbqqARQilV8zQdCdoHAAVh7.afP1cpY6duH0DDtIo- Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:50:22 +0000 Received: by smtp423.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 4a17fb36862a3a05cf4ce3fe352ac738; Wed, 04 Nov 2020 23:50:17 +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 Subject: [PATCH v22 07/23] LSM: Use lsmblob in security_ipc_getsecid Date: Wed, 4 Nov 2020 15:40:58 -0800 Message-Id: <20201104234114.11346-8-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: There may be more than one LSM that provides IPC data for auditing. Change security_ipc_getsecid() to fill in a lsmblob structure instead of the u32 secid. The audit data structure containing the secid will be updated later, so there is a bit of scaffolding here. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: linux-audit@redhat.com --- include/linux/security.h | 7 ++++--- kernel/auditsc.c | 7 ++++++- security/security.c | 12 +++++++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index fad361bf320e..be8db737da74 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -499,7 +499,7 @@ int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5); void security_task_to_inode(struct task_struct *p, struct inode *inode); int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag); -void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid); +void security_ipc_getsecid(struct kern_ipc_perm *ipcp, struct lsmblob *blob); int security_msg_msg_alloc(struct msg_msg *msg); void security_msg_msg_free(struct msg_msg *msg); int security_msg_queue_alloc(struct kern_ipc_perm *msq); @@ -1228,9 +1228,10 @@ static inline int security_ipc_permission(struct kern_ipc_perm *ipcp, return 0; } -static inline void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) +static inline void security_ipc_getsecid(struct kern_ipc_perm *ipcp, + struct lsmblob *blob) { - *secid = 0; + lsmblob_init(blob, 0); } static inline int security_msg_msg_alloc(struct msg_msg *msg) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 5f9bdd62f78d..35d6bd0526a2 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -2341,11 +2341,16 @@ void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat) void __audit_ipc_obj(struct kern_ipc_perm *ipcp) { struct audit_context *context = audit_context(); + struct lsmblob blob; context->ipc.uid = ipcp->uid; context->ipc.gid = ipcp->gid; context->ipc.mode = ipcp->mode; context->ipc.has_perm = 0; - security_ipc_getsecid(ipcp, &context->ipc.osid); + security_ipc_getsecid(ipcp, &blob); + /* context->ipc.osid will be changed to a lsmblob later in + * the patch series. This will allow auditing of all the object + * labels associated with the ipc object. */ + context->ipc.osid = lsmblob_value(&blob); context->type = AUDIT_IPC; } diff --git a/security/security.c b/security/security.c index ea927a00de18..9c1098ecea03 100644 --- a/security/security.c +++ b/security/security.c @@ -1882,10 +1882,16 @@ int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag) return call_int_hook(ipc_permission, 0, ipcp, flag); } -void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) +void security_ipc_getsecid(struct kern_ipc_perm *ipcp, struct lsmblob *blob) { - *secid = 0; - call_void_hook(ipc_getsecid, ipcp, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.ipc_getsecid, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.ipc_getsecid(ipcp, &blob->secid[hp->lsmid->slot]); + } } int security_msg_msg_alloc(struct msg_msg *msg) From patchwork Wed Nov 4 23:40:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882705 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 6D2851130 for ; Wed, 4 Nov 2020 23:55:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2D88C20825 for ; Wed, 4 Nov 2020 23:55:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="i551Wzt3" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731343AbgKDXzF (ORCPT ); Wed, 4 Nov 2020 18:55:05 -0500 Received: from sonic301-38.consmr.mail.ne1.yahoo.com ([66.163.184.207]:46496 "EHLO sonic301-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387531AbgKDXv3 (ORCPT ); Wed, 4 Nov 2020 18:51:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533887; bh=eZeO09DJlcX2wY8AdT21fgnfDkYz/4ihUnMP/xr6IW4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=i551Wzt33ltZfd8lOj0K7F8tISSsfwFLA+MV6ZW3oRBErZn+RKI5gFwGYBOCHMq1y8GPqjOMpqwPS7/XgNpnd9SNzHYFxHlH6U/PcLY7TUD2JczJFJkQiY+dG/9naLRFZ+p3BFbwLDQamE8f5JFSAeZ6X51cHG8ycg7OaGN02FBDqD3uo9XPQLR5mHF+XeorCD/Mw4O0T317cbf1paPCNeq9Vv3Il5BO970kKyQaVIFL1ZWIQzeKdkcXBn41eR/XDpbohqDIEyq2zNkowD85eDARV5qhbwYLFzRlLsgUpR5kIRLXWbILg+v030Ph0BEeGpNaCqihXnCyf4dTbTaQrQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533887; bh=Pz5ZBcP0XdSBWBdSYxf4t3NLqu3W/7Yxa+xzAYcjUq9=; h=From:To:Subject:Date; b=SuMvk9WXeNGevQd447PnvN2YqWxjEzUpZMa/9Z+ajHGhhmbnyGB8MM51RGrPu3Z3MNzY3PmqGHrQAC8/wW2z4xNOxQlpLh2jN+ZzuMOaQNZ0C/1mW0U08qkitk21AT4AJa2FZsBYHVZYETlbkZ+Wl+AoZxSNwBuPLS9my4V+SL77u5Ha4kanHBGIJELlbgegzk2wvba/LG+RkLQHYGSLLyUaszcJFfLGx+8GvMFb18/4LZmNUYBwxYq08iQ2O9+R5ekBnLDs4aGXTNWGfiVCjCycz0L5pht0q9Mz17kfT1DOnIIC1fcZsJXe28cNmibO62fr8g8wh2bm59rIit/TCQ== X-YMail-OSG: JWufGrMVM1nvQtbpG73LNP6MlH08ll8BtZg7sbfpx85QxKbObE0ypmzwwyppB49 g07GIL3aSsv.E.rQzCmv6CisKz7CfzzjmhMceD35jJ8Gu0Mt9zzT0hPz4tSVXMvwvB5u5ldXwUQ6 LV7rxBcg0oQpzdRCzxhJAKHfuqDdaeoVffDJRqRJAbhWUS_3auzSjQOzaQadC6dqOvTWaJjZieoG ZGlxM97smw51PNGFRrqekfwGSOexvEuPkTMtuV0DSYQ64dxNt.AUW6oXi1BsfF6wA0OSbH8wqKoY 5ycrD1tL798OSGaIGuZr70aewIs4QkH9KY3CuP0lyKtPIeU8NDHAcZI6EEJ9ZaZuzSD1jeVlek72 b3HTCShFwNv_oK9SO5_DpyTS27nOqjIXg.ABrXHl2SKQ_czL7QEsv_dAwZSHa46X2f5I4JdiTHlb 7Pr77lr4tLqKYlD_sp8n.LcPMI_C39rFcnkPTHlNxKubaEpYa.REvDfWV7vQ6UHpMP2rZxmjiTRo tnZoyAsQUbKwn_xlGrrzcV8DTuVmzPeOT0VbqLgOCQf0Bwad_XVmCZENBWa6SONtgZX6JJ39mTFd UCil8Pz2hpxYhX6YVbsOe.SrCwQfkHIcUQtc3eYjC4YKs.kxq_tCvSbmTDrgXHNyfYoEspcZcSL5 xOQViMywIBc7QMACoPWwGNmkOF_4M2Nl98BOH61kjpXlD5jKHX8j1XsAR.WUicGEk0I3PY0Okf77 AcoMRnOZV.ALEXfMoLLYyesRpyg94n95gvxmqeIGP3Zh7Erxu0V3dbU3Jw0oA1OL6fsq.kRU5r8s O90LFaQg5lEsLZiZBrqxytP6QexjUjSf.mAxV9KGUHxiGym6e_Tkn3vHOeIrIiKh5WkS6K2n5IcW 9c6CNT3QEJzKXQIgx6N1MRbUafA4co6k3nAiT2mJDLRs4_slUsITGKCgMMsicQBD7CpsHBWJbWVe kc3SeKxtN1S5QNEOfuqyzusNJmzLcV5UmEyYpyJp47wDY9rdn5lmX_FykO8nb6XVQuxVqExX4KZZ ajJs4p6biVO51XqKKY9hhRSM_hWIq6lyvIF9C8foa0Ar8U356yupv8DblMvdZJ7eWOt3mBjyr3A4 dKLbtJLtGiDQ1OiAdpGSx3lB3BzjL5hlREVjAfpO1JdvscGKrgynyWfkuCzlAc_bnVnCc3sX9Evr Ko3MOE.9TXTmE1Tsxr.syMACCV9ITHRGJFMpFLiH8.eR.nmwG3NLuyfoohiTGVC5N610Stu19E1i p4hlN4bKKTldpxVzgeQpWs8gTEWcTZKXm4XOsjy74dU7IhCpmJeg2vY.xBKZD4ah.zYgwIvPeZPB RhjETfoJA_u7MUIrKDwrLst4zch6zTOSz0.LlX3TEpKmkb7eFWmhW48.VNlbn1wb.kzxuoK11OmB aVZ_sVJVe5D_H3hyTJBkvnbYHn71GmsPoq5aU4Js3wjBVlnmSBc2b_3pdZYpxCRpW90TgXG0dL9z bfRukSnGGzQikJZZaxyPy7hWq5xIbvN32.OUskcaPRqZlZTr9py1UmYjhWg9Zc3Ez4dJ3e5q8A80 bnT6stCrdYpF.kT9WWE2zvMq1E42xualJ7LlkVY.lExZlfkb_FvSLhDruPLNka71zf5_TUWo0dFf JaSO1eUm3cj.xDGRFb38pff6Cn_wDutpwjC4zSa0U9Q2LEetY6H4shsWFkk4o8Z1Tc6tb8vD4ly6 ZutEq7ZHbcLeQ2BIky1kmJRz1ch4fQc9vtAoexctP1F9ejdjxZnGVR8NbLYylmizlViwaX8LyOT_ 3mR7rb_NoFskC.hNzsIqbMry_5jeGCj7E7Y_lAYA_X1GfF81ij0tX.mIJK93OJHQSaZhpMPzOPMP 0GOZz0MExNTr.YS8hojxWPvoSdLhYfjmtnRL_fr0Kfw.fXdYmbMuMxQ0oKFTf40p.xa1dj8F_PrM AzoiT464k_SzSnN1iwBbU3BIgr1ERudLraKplKOhO85eQuMOwgEhS6wSZTy.WNqe0YRgHH6YMcvW A8lZ7Hr73irEFjvgSKBNdNyQrsIP3AnaBIjcYgKnlG_vC5UxfP_bwLc2nVBPfBnj7rfXZpvHk09e 2kalcOpPvMEaIL4ZQEP4UisX8V5BbL2XR08z9ytzlzqELGnUQm6H0vpRfWpdUmNeFO1S5.ZQUpPk cDAAiPTsBjh_X60CsQZXOx57KiZQGD0QSk5BUQg0S.1ynfR.RvYRPP8aV7_Dh4CgrsTK8p7g_w9l kixEE8Zu5_1IKtFVMQh46.W1GUhkNrTuJnHdXlUpl5JCNhlLQz_bMzoOzUxTolaMRYZr5sHaRWRc G2OZkAXl7sZ7YzrUyLpf1spJqtG6bP4kmOqrc4bWNy2foRQYydobFJoIE7OS8RfTySeXXEGKKEEm 3DjxjuZ55PF_qcEW2K.IfDPJiKOHx__rREtZouqQRQG34NreiitJWZnTgHMFeLNEqQyLlY_MbVbz TjvLX1ygIPGAhXAGqQQrGbJwCnrque2ICAQzL.GGqXZSA9cjr55.lzgPNoYm4nT6qEqXfPzGOuUz S8ELXU505OAu6HHIF1YB2Ax2vDIUgF53FGCxFvAIyuP8iuHqEoPH4C.fDtJoQz_amwfpqRA65cHw wUuuDp8i4BAXuhr3LPT9em2YzKtyOLfR3C0N9YOM6D89sYS8oF_2Zq5jnno7Lc3KULne333_pakF srcd2Lhu.Ivvqfv_LG9qx_h2xcPRZo1m3woEGObyBtRxaqUzjhgPh4M2m2GWu9Zg5Yc8BHa5Vc3P 5MMVnEZT7QjF9qLou_VfvyzoFtJiizTWkKqpjuzt1G0L1xX_SJiGadD_JthBgsXsz3Wlse_R1wR. GOxY4xaSGzBjCxN7Q_lEpfFMSGHFYgOfmpjEnDOyHlnUG7zAzmx7s3bDQ_S_rHEZIKgy8df2z9Uk ldxvjtcDZ0guSZLRKVi2cb0t1fPml5vNSy8qTj6c4FFWq4FZY9MiAWlRYt0DIr.OC0vnN2ONZDzV wz8HsGXPI4PDCYRKdS0FmOMoyKTCjOdWkYzfXH4J0EtA1txhwGRnImEotASzNNW77odP2gqtGigC P40NRJT8gpuUF0heBFY91cAAjZE9wXZw2tx2HwutHv2Kd2.gJqsS6jhWMyKCT8us5xRnKNtqTa1m R18LuA05b1zjCjTWpzpANj.3s6QoVnmVblvOdvAD4xS6VDwVCGaKfOcPOx5dxq7XEklI7SaJjSaf kkIptLVEfDBkxtZj9zuNyY3pVtZiybzMbfru1L4CXww.gJQuIToWfWxH7_QGAnqSxCeHv1V4W60t d5t0uzAcaMeyApLJRlJTreuIJORgQnMzutgXt6_4HgrTCpce3NDx12bPhfDYRAiUef11EkjWFa2o omEyNuwQ.Pm0NvoV5P16cObJz0orrPsE4eyjEqrEyDERtKqun5gXg3Ke2Xi0ZRndNvaj27CGByBc 3FfCDIkyoaYLhPozPxDDreQNAJcbPAF3YMdt7xQmPH5SAxtEHxQ-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:51:27 +0000 Received: by smtp414.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID aaf521eb30ad00320d4ff2ee1d353ff2; Wed, 04 Nov 2020 23:51:22 +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, linux-integrity@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v22 08/23] LSM: Use lsmblob in security_task_getsecid Date: Wed, 4 Nov 2020 15:40:59 -0800 Message-Id: <20201104234114.11346-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: Change the security_task_getsecid() interface to fill in a lsmblob structure instead of a u32 secid in support of LSM stacking. Audit interfaces will need to collect all possible secids for possible reporting. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: linux-audit@redhat.com Cc: netdev@vger.kernel.org --- drivers/android/binder.c | 12 +----- include/linux/security.h | 7 ++-- kernel/audit.c | 16 +++----- kernel/auditfilter.c | 4 +- kernel/auditsc.c | 25 ++++++------ net/netlabel/netlabel_unlabeled.c | 5 ++- net/netlabel/netlabel_user.h | 6 ++- security/integrity/ima/ima_appraise.c | 10 +++-- security/integrity/ima/ima_main.c | 56 +++++++++++++++------------ security/security.c | 12 ++++-- 10 files changed, 80 insertions(+), 73 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 55f3fa073c7b..08737a07f997 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3087,20 +3087,10 @@ static void binder_transaction(struct binder_proc *proc, t->priority = task_nice(current); if (target_node && target_node->txn_security_ctx) { - u32 secid; struct lsmblob blob; size_t added_size; - security_task_getsecid(proc->tsk, &secid); - /* - * 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); + security_task_getsecid(proc->tsk, &blob); ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); if (ret) { return_error = BR_FAILED_REPLY; diff --git a/include/linux/security.h b/include/linux/security.h index be8db737da74..6b9e3571960d 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -482,7 +482,7 @@ int security_task_fix_setgid(struct cred *new, const struct cred *old, int security_task_setpgid(struct task_struct *p, pid_t pgid); int security_task_getpgid(struct task_struct *p); int security_task_getsid(struct task_struct *p); -void security_task_getsecid(struct task_struct *p, u32 *secid); +void security_task_getsecid(struct task_struct *p, struct lsmblob *blob); int security_task_setnice(struct task_struct *p, int nice); int security_task_setioprio(struct task_struct *p, int ioprio); int security_task_getioprio(struct task_struct *p); @@ -1155,9 +1155,10 @@ static inline int security_task_getsid(struct task_struct *p) return 0; } -static inline void security_task_getsecid(struct task_struct *p, u32 *secid) +static inline void security_task_getsecid(struct task_struct *p, + struct lsmblob *blob) { - *secid = 0; + lsmblob_init(blob, 0); } static inline int security_task_setnice(struct task_struct *p, int nice) diff --git a/kernel/audit.c b/kernel/audit.c index 4cd6339e513d..9e3eec0a9c29 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -2136,19 +2136,12 @@ int audit_log_task_context(struct audit_buffer *ab) char *ctx = NULL; unsigned len; int error; - u32 sid; struct lsmblob blob; - security_task_getsecid(current, &sid); - if (!sid) + security_task_getsecid(current, &blob); + if (!lsmblob_is_set(&blob)) return 0; - /* - * 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) @@ -2356,6 +2349,7 @@ int audit_set_loginuid(kuid_t loginuid) int audit_signal_info(int sig, struct task_struct *t) { kuid_t uid = current_uid(), auid; + struct lsmblob blob; if (auditd_test_task(t) && (sig == SIGTERM || sig == SIGHUP || @@ -2366,7 +2360,9 @@ int audit_signal_info(int sig, struct task_struct *t) audit_sig_uid = auid; else audit_sig_uid = uid; - security_task_getsecid(current, &audit_sig_sid); + security_task_getsecid(current, &blob); + /* scaffolding until audit_sig_sid is converted */ + audit_sig_sid = blob.secid[0]; } return audit_signal_info_syscall(t); diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index e27424216159..9e73a7961665 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1330,7 +1330,6 @@ int audit_filter(int msgtype, unsigned int listtype) for (i = 0; i < e->rule.field_count; i++) { struct audit_field *f = &e->rule.fields[i]; pid_t pid; - u32 sid; struct lsmblob blob; switch (f->type) { @@ -1361,8 +1360,7 @@ int audit_filter(int msgtype, unsigned int listtype) case AUDIT_SUBJ_SEN: case AUDIT_SUBJ_CLR: if (f->lsm_isset) { - security_task_getsecid(current, &sid); - lsmblob_init(&blob, sid); + security_task_getsecid(current, &blob); result = security_audit_rule_match( &blob, f->type, f->op, f->lsm_rules); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 35d6bd0526a2..8916a13406c3 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -473,7 +473,6 @@ static int audit_filter_rules(struct task_struct *tsk, { const struct cred *cred; int i, need_sid = 1; - u32 sid; struct lsmblob blob; unsigned int sessionid; @@ -670,17 +669,9 @@ static int audit_filter_rules(struct task_struct *tsk, logged upon error */ if (f->lsm_isset) { if (need_sid) { - security_task_getsecid(tsk, &sid); + security_task_getsecid(tsk, &blob); 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, @@ -2440,12 +2431,15 @@ int __audit_sockaddr(int len, void *a) void __audit_ptrace(struct task_struct *t) { struct audit_context *context = audit_context(); + struct lsmblob blob; context->target_pid = task_tgid_nr(t); context->target_auid = audit_get_loginuid(t); context->target_uid = task_uid(t); context->target_sessionid = audit_get_sessionid(t); - security_task_getsecid(t, &context->target_sid); + security_task_getsecid(t, &blob); + /* scaffolding - until target_sid is converted */ + context->target_sid = blob.secid[0]; memcpy(context->target_comm, t->comm, TASK_COMM_LEN); } @@ -2461,6 +2455,7 @@ int audit_signal_info_syscall(struct task_struct *t) struct audit_aux_data_pids *axp; struct audit_context *ctx = audit_context(); kuid_t t_uid = task_uid(t); + struct lsmblob blob; if (!audit_signals || audit_dummy_context()) return 0; @@ -2472,7 +2467,9 @@ int audit_signal_info_syscall(struct task_struct *t) ctx->target_auid = audit_get_loginuid(t); ctx->target_uid = t_uid; ctx->target_sessionid = audit_get_sessionid(t); - security_task_getsecid(t, &ctx->target_sid); + security_task_getsecid(t, &blob); + /* scaffolding until target_sid is converted */ + ctx->target_sid = blob.secid[0]; memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); return 0; } @@ -2493,7 +2490,9 @@ int audit_signal_info_syscall(struct task_struct *t) axp->target_auid[axp->pid_count] = audit_get_loginuid(t); axp->target_uid[axp->pid_count] = t_uid; axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); - security_task_getsecid(t, &axp->target_sid[axp->pid_count]); + security_task_getsecid(t, &blob); + /* scaffolding until target_sid is converted */ + axp->target_sid[axp->pid_count] = blob.secid[0]; memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); axp->pid_count++; diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index ba74901b89a8..94071f67e461 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -1557,11 +1557,14 @@ int __init netlbl_unlabel_defconf(void) int ret_val; struct netlbl_dom_map *entry; struct netlbl_audit audit_info; + struct lsmblob blob; /* Only the kernel is allowed to call this function and the only time * it is called is at bootup before the audit subsystem is reporting * messages so don't worry to much about these values. */ - security_task_getsecid(current, &audit_info.secid); + security_task_getsecid(current, &blob); + /* scaffolding until audit_info.secid is converted */ + audit_info.secid = blob.secid[0]; audit_info.loginuid = GLOBAL_ROOT_UID; audit_info.sessionid = 0; diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index 3c67afce64f1..438b5db6c714 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h @@ -34,7 +34,11 @@ static inline void netlbl_netlink_auditinfo(struct sk_buff *skb, struct netlbl_audit *audit_info) { - security_task_getsecid(current, &audit_info->secid); + struct lsmblob blob; + + security_task_getsecid(current, &blob); + /* scaffolding until secid is converted */ + audit_info->secid = blob.secid[0]; audit_info->loginuid = audit_get_loginuid(current); audit_info->sessionid = audit_get_sessionid(current); } diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 3dd8c2e4314e..2a18124af429 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -65,14 +65,16 @@ bool is_ima_appraise_enabled(void) */ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func) { - u32 secid; + struct lsmblob blob; if (!ima_appraise) return 0; - security_task_getsecid(current, &secid); - return ima_match_policy(inode, current_cred(), secid, func, mask, - IMA_APPRAISE | IMA_HASH, NULL, NULL, NULL); + security_task_getsecid(current, &blob); + /* scaffolding the .secid[0] */ + return ima_match_policy(inode, current_cred(), blob.secid[0], func, + mask, IMA_APPRAISE | IMA_HASH, NULL, NULL, + NULL); } static int ima_fix_xattr(struct dentry *dentry, diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 2d1af8899cab..c9f1f6bddab5 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -388,12 +388,13 @@ static int process_measurement(struct file *file, const struct cred *cred, */ int ima_file_mmap(struct file *file, unsigned long prot) { - u32 secid; + struct lsmblob blob; if (file && (prot & PROT_EXEC)) { - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, - 0, MAY_EXEC, MMAP_CHECK); + security_task_getsecid(current, &blob); + /* scaffolding - until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], + NULL, 0, MAY_EXEC, MMAP_CHECK); } return 0; @@ -419,9 +420,9 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) char *pathbuf = NULL; const char *pathname = NULL; struct inode *inode; + struct lsmblob blob; int result = 0; int action; - u32 secid; int pcr; /* Is mprotect making an mmap'ed file executable? */ @@ -429,9 +430,10 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) !(prot & PROT_EXEC) || (vma->vm_flags & VM_EXEC)) return 0; - security_task_getsecid(current, &secid); + security_task_getsecid(current, &blob); inode = file_inode(vma->vm_file); - action = ima_get_action(inode, current_cred(), secid, MAY_EXEC, + /* scaffolding */ + action = ima_get_action(NULL, current_cred(), blob.secid[0], 0, MMAP_CHECK, &pcr, &template, 0); /* Is the mmap'ed file in policy? */ @@ -468,10 +470,12 @@ int ima_bprm_check(struct linux_binprm *bprm) { int ret; u32 secid; + struct lsmblob blob; - security_task_getsecid(current, &secid); - ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0, - MAY_EXEC, BPRM_CHECK); + security_task_getsecid(current, &blob); + /* scaffolding until process_measurement changes */ + ret = process_measurement(bprm->file, current_cred(), blob.secid[0], + NULL, 0, MAY_EXEC, BPRM_CHECK); if (ret) return ret; @@ -492,10 +496,11 @@ int ima_bprm_check(struct linux_binprm *bprm) */ int ima_file_check(struct file *file, int mask) { - u32 secid; + struct lsmblob blob; - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, 0, + security_task_getsecid(current, &blob); + /* scaffolding until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], NULL, 0, mask & (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND), FILE_CHECK); } @@ -629,7 +634,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id, bool contents) { enum ima_hooks func; - u32 secid; + struct lsmblob blob; /* * Do devices using pre-allocated memory run the risk of the @@ -649,8 +654,9 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id, /* Read entire file for all partial reads. */ func = read_idmap[read_id] ?: FILE_CHECK; - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, NULL, + security_task_getsecid(current, &blob); + /* scaffolding - until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], NULL, 0, MAY_READ, func); } @@ -679,7 +685,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, enum kernel_read_file_id read_id) { enum ima_hooks func; - u32 secid; + struct lsmblob blob; /* permit signed certs */ if (!file && read_id == READING_X509_CERTIFICATE) @@ -692,9 +698,10 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, } func = read_idmap[read_id] ?: FILE_CHECK; - security_task_getsecid(current, &secid); - return process_measurement(file, current_cred(), secid, buf, size, - MAY_READ, func); + security_task_getsecid(current, &blob); + /* scaffolding until process_measurement changes */ + return process_measurement(file, current_cred(), blob.secid[0], buf, + size, MAY_READ, func); } /** @@ -809,7 +816,7 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size, } hash = {}; int violation = 0; int action = 0; - u32 secid; + struct lsmblob blob; if (!ima_policy_flag) return; @@ -822,9 +829,10 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size, * buffer measurements. */ if (func) { - security_task_getsecid(current, &secid); - action = ima_get_action(inode, current_cred(), secid, 0, func, - &pcr, &template, keyring); + security_task_getsecid(current, &blob); + /* scaffolding */ + action = ima_get_action(inode, current_cred(), blob.secid[0], + 0, func, &pcr, &template, keyring); if (!(action & IMA_MEASURE)) return; } diff --git a/security/security.c b/security/security.c index 9c1098ecea03..421ff85015da 100644 --- a/security/security.c +++ b/security/security.c @@ -1799,10 +1799,16 @@ int security_task_getsid(struct task_struct *p) return call_int_hook(task_getsid, 0, p); } -void security_task_getsecid(struct task_struct *p, u32 *secid) +void security_task_getsecid(struct task_struct *p, struct lsmblob *blob) { - *secid = 0; - call_void_hook(task_getsecid, p, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.task_getsecid, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.task_getsecid(p, &blob->secid[hp->lsmid->slot]); + } } EXPORT_SYMBOL(security_task_getsecid); From patchwork Wed Nov 4 23:41:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882679 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 F3890174A for ; Wed, 4 Nov 2020 23:52:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C736B20786 for ; Wed, 4 Nov 2020 23:52:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="VIBVQ1FZ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733166AbgKDXwv (ORCPT ); Wed, 4 Nov 2020 18:52:51 -0500 Received: from sonic313-15.consmr.mail.ne1.yahoo.com ([66.163.185.38]:45250 "EHLO sonic313-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387551AbgKDXwe (ORCPT ); Wed, 4 Nov 2020 18:52:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533952; bh=kp4dWfdwZR3/duFNL35a57sdXSJgVd0rWpqs628JXTI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=VIBVQ1FZOHd0wMGLkGOC0lMJNwkD2P7PiGa3dM0M3W3X37JCu4z9l3I7YCL+Nfx/Jj1PPaGoF9oT2mGzYdiWQmrEkgrKfL3pbOJ5M+z75aHeiYvoUnyX76OINW3dGF7njx+AX9FLum5MUb6VQHe/qzjlWFmyx7XfxUiwSF06pcLDJqrBMCg5si1WTX+RMbzy1YthmvWeMlZkG6s6BTLnT8uRuwn5vU78UOm+3r++JiBM2oZn4mEnAuiyVteUz1Oy+Q9JHWUzMT0bc1rd2J8Ybw4pL6qNUpCmiV1C0E3TEsEsaqo/cN2P6uzuYeoxRDpU1H8tta75sGdzbkAQ99crCg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604533952; bh=FWeADDGvhP4tBC30iACHhd1/5pqoUdABTolo3HVOdhp=; h=From:To:Subject:Date; b=i8y972YOmfj9XLyJDenRqT2y2VtHZpepSArqTpMQXu6VAbztWraAQ1whggiP28k8WD6CdykLfptNm8vUGpMeriEwzyJh7uT0wPH+lbXfxWzqkQU8/2Wf5RRRo5ItZ0JiTgEC8mYqppbCwpQguBiU3XZlneVdxNBFG0iTUTQx9SNtHlMw5VZGeplpNGBSAyO4ww1wvSgeFB1bk7uvAOzMAR8tjJgqJvPipAPs9nePwmWdIrM8Riis7PfK681wEIJFmttT4CrTsB40I/SDtWYS5nghUkXX5Fo6ygHY1IQHEsoInUR3i1dUUKVON+rI+AhLykC+sl6/TrJ5vjIpAKmhIA== X-YMail-OSG: atJBtdUVM1kF7O0SSsxxEUWpivmfTLBoOSIlZ_ffK5Mn__OUD7npoIRu.FkftQB HVmOiw4QmJKMmoNVtlhqgs2r12lWc.NbQdwohVsruKxLrLH4lEn27bZCxNnqbyksQ.xW9y5DWNp_ T2NqvfCNqG.FgsvwY4eazHbD1dEGGk0MsVR5Kqy.rQyS381FnJ6xBO_YC.BqLdHooUeq.AiAXCBh EErGVZR4pO68ZqD569blNE1..SyJju2lppqucveRhSdxUEzoCfA4axlbvOE42iywKElt_ikiUXf7 KEcOoa.NNrfKtH4T0yrMhHF7TRbKrJBmRa79fxArKno6ub8pSZzgDnIPHs2_NnoWjePd7b1Db.n6 FAwj4GKSS7SxfjK5lesGflpLyaBZT6yzdXpHSk65dFZsxPMv_P5bfrBIU8w30zqB47FXkryjfQmv TJzMUEUfEkApTMWlydgm3yE8RrJlrY56g.7MPl608JW_8l4XUHb6RU_92SF4Dr3YTJoMo9YxRM56 Rc.swzykmpWeOw9GVPdy7Vvjx_lMXYdrURpXC2Z4vP3liVEqDW_FD9YXZxUXoBtj6zB35hLxKTE. Ki8krITbDuOyndRfYFJVMcyOvAVdiJw1GjmDbzn7.3Fw3sHJEENksa8Q.rXQ.5hp2tjqzhnXk3pf zWAGeXrshzFVYWo1e9XWVL210hWMG9VbH3DYWWDLHRsUTmyVJHPQ.yEYJn_qunoj4IkjXJ4TSR4Z 3gXMcZH1aqvH18RHqe7BXoTnAo1SGIyVoMR6rat2WaRWcuuJGVaGHVXeL7ygEax9Cn8MZWJFM_Ve 0VMDKyi1cMARjbu21J8BgnIF.Zwliuec.Hlqdx922wwQC0GXMeT2vOVFn35XPrLGhHwfbjcei2Jr ifbm_i_EjgQ5qTVjrtaOC92gfY7JrX9gLxSGLKYl4f9ooEHkCItWo4Zg.nIW9Mk7h.qdrEs0eil2 iAr8sGeM3tuHGpBSx.bqYxiVwikH6XcUiBqfqTA9v3.QnA7MsbUVKMJyGVKzfYWqn6htH.4J3Qc1 uNPEVC3_xsJRWRzr8p3N3h.fuX4yLivbSDWOAONi_QNhiW6K80EEaTHFpr.AQKKzW8KNveto3dai uYT0bZ1iD8dlshZBGQc9t9OL2z.RDktHTPeOg_U1afVDG_6ikcnmeKv7.wE1w7F1RoRceH9w9D1C BnZZnXZRfkmBReU5gjmtGxnLs37gUIx2PH4VDhB6VErjRNlAIRV1EStsU.DV.ow6QOE9x2.PPvsa kT6fctTBQvVhe704MKl5qIaPw1kRTj5ZBt04zilYe7_LyokEuwDNavlfDpmemPhm6iF_I9omDYFs HSzXZm89h3LMB9Mh1fZ.1iaVaDblGhAMbQc_lf5YfSl_i2xXD2NFRaDUKFicn0WYXsucq7tUWRHo Mbq._iv.Y2aoy6VsboAPuVe0pF2Xi8EGPDFr0iMdkq_B.1CoAlg5hIdtPlaaTi0oVkRGe8t1rhAL bVJ2tX7D.hN0QzhZri3BT1VBMsjxBl0Eeg_rRe5kv3uTxuj29yPj5ETbQM5Gk36F6wV9BELGPJP8 Db_6o9VK9wUHKJTSi15pcH9cGd.vhKoNKTc8p038qJfk5td3eKiLhg.rLAWCgf2C0SG_ZvJ35ERb ml98TMRZ_7hTV2.eiVkIr6whdXp1rtbZNnrBilSrcJPg.qU0j7V_kwc10JdQ_uYY0gjwz5azTxZX Ns5zcJpN3WUPbIqNAiyZqANIXQ_R8XTwyYQc3BHCgmioHowFDdPut0v.wph8E7Ds92KeSnyDkD_n IYr.KHFdqwnXDC.JvTgqavTH.LJC7Xuqbx0rlIhQMgSw2VBhMlGqeNcvbiEwhvsxSHryD90SXa_L Cg7IA0GLpRzQCv8mXaLbh3ki3WSI6Qp_Tw0YbxRXa8P4nHobV3ZSpzlULvZKkId03zQmCdLJQ.6p b4mq4krJIjBrI02Kn1pEMjGO84Z.xebidf2AtWUCLy1NVTTkyd1G7BnBUirRjPATtG3_6lFrTgbh vm6k5rH9v9rY8ouVgRCAntYQC_8RALSn4yvyqMJmcQKCfP.c6ELxgpfchPLSLXNmp.4U5QCJQpOA j91uv7AvW9soSqbardS5fncBVEwkeiu5Bc2YZd55mTv3bsWANy2yuAnQh93xcqkFEuqIKOOzFvu7 S5yuglyfVSiKH5dCsbu6GPXBgau3agfGt.6YEJWflg2OE7oYVMDsiTQJNa7nT2lEMPtuYMVtXrvt 47SQCWxGFwISKuB5Z7rafKU_W1zRU1m4Y9j1BN.MO4qwroHSoXGd3KfECajaBj6dW8dtb1fBj.Tx 9lHBXHY1h8tYYyUUmj0WarTEl1Jswfj9dn1IcEGGEF87Uz3j.6onR3ApMkl7aSwrxtzKp3j3g0jB sPXvejB8TBO9fo4gMjlLEFIUqRdb_K0W1JB6GvocqAlbzkkDXJw3ZsXqvwNBUjWyM4su1cXi24nn c8bBA.oWhN.wKCJK426.ZKvCwL6xfyCp3JYbJIkqkJFn9a0CecC5bgR1X9S2fwe5AyWls8hYqV3F 5wf_rwhRBVffbSDxOuh3_jguNv3Jh72cdVRcFaEdNNkZC1ljrWifOPNHfri8aOvz1lao86STxQlk Uvkbm_.eTJNE3nF6F20iySwGroR9XrM3jwFwcnX60TLroU7rfGp6_aB2BCG40CZtKBryjr2Ao0MU TiYi63QcnanmY6DACexlOv.7rPFOJSe2d1okvl0sM8UZLwdB3T_5PAhIrr_rGW7MzD.nhW.lXzRV iqf4D93Aun.2UxX0Y_jCoxJ9S.Khl7f90I0UemygdcBw0wNq7ml_.dP8mf75jGjd0hzezJNMcB4J jWyy5Llv3Q8muYJY6uHHBnj_KozLtTYHmS.RpdlaQ0S1_oVRfmmbYE4lvC1pH1j_K_SgbQuu5jCQ yxtmQ49EtGyOzlnUZso5ITjuIWejy6_3.v_FX_vSl_8Uu8ymw.39F7FCq3e0jRIaaZI9Jn8IwTTX RY2gYKOhjPHmIJsoIoe3fKztANyFMOnDFNqInKr60vCIMDWbkrdxULjSh7j9GfHJUEI3GDNlw5oX I.AQMgH5aVARfEeuoDAErMsy1Xio0T3Aup9vM0xlT_vkFU9OqrAfD_JfgUCjHBgKEFs76NxyowND ZwL4A.Qc8W0M_aagzXM3sKuq_aY57Ou7Mt7STyl1uoQRAcO1gEUt6B4Lj5sfgUagaDMlMWucOAD7 ODK6sz1S6nPrIoTMKt4vo2jhi.MN42bXpAkLJp5mRYZ5SJZD9yM3z11l_U2zd9ZZtfZafMc7gEk_ qI5HeTaU7KVa_xfzE.wjhpVWREBLA2SPXVrsMi.fa934nXhsCQ7AUStEHtnRBPHOVRMQKBbfaE45 RMla99idx9ZMb3ERhH2FGzPILmUQknsoQd6rQE4I1_RxPIdmEZ.BTufxeLlJBBpkmG6z7NUsP7aX 0ifVpQ8F8jcqRMQ-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:52:32 +0000 Received: by smtp405.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 3474b28a6b02d5760a35af9bdeaf56de; Wed, 04 Nov 2020 23:52:29 +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, linux-integrity@vger.kernel.org Subject: [PATCH v22 09/23] LSM: Use lsmblob in security_inode_getsecid Date: Wed, 4 Nov 2020 15:41:00 -0800 Message-Id: <20201104234114.11346-10-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: Change the security_inode_getsecid() interface to fill in a lsmblob structure instead of a u32 secid. This allows for its callers to gather data from all registered LSMs. Data is provided for IMA and audit. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: linux-audit@redhat.com --- include/linux/security.h | 7 ++++--- kernel/auditsc.c | 6 +++++- security/integrity/ima/ima_policy.c | 4 +--- security/security.c | 11 +++++++++-- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 6b9e3571960d..a7968dde27c6 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -436,7 +436,7 @@ int security_inode_killpriv(struct dentry *dentry); int security_inode_getsecurity(struct inode *inode, const char *name, void **buffer, bool alloc); int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags); int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size); -void security_inode_getsecid(struct inode *inode, u32 *secid); +void security_inode_getsecid(struct inode *inode, struct lsmblob *blob); int security_inode_copy_up(struct dentry *src, struct cred **new); int security_inode_copy_up_xattr(const char *name); int security_kernfs_init_security(struct kernfs_node *kn_dir, @@ -963,9 +963,10 @@ static inline int security_inode_listsecurity(struct inode *inode, char *buffer, return 0; } -static inline void security_inode_getsecid(struct inode *inode, u32 *secid) +static inline void security_inode_getsecid(struct inode *inode, + struct lsmblob *blob) { - *secid = 0; + lsmblob_init(blob, 0); } static inline int security_inode_copy_up(struct dentry *src, struct cred **new) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 8916a13406c3..b58b0048702a 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1980,13 +1980,17 @@ static void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, struct inode *inode, unsigned int flags) { + struct lsmblob blob; + name->ino = inode->i_ino; name->dev = inode->i_sb->s_dev; name->mode = inode->i_mode; name->uid = inode->i_uid; name->gid = inode->i_gid; name->rdev = inode->i_rdev; - security_inode_getsecid(inode, &name->osid); + security_inode_getsecid(inode, &blob); + /* scaffolding until osid is updated */ + name->osid = blob.secid[0]; if (flags & AUDIT_INODE_NOEVAL) { name->fcap_ver = -1; return; diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 3e47cc9b7400..bbf9fa79740a 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -561,7 +561,6 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, return false; for (i = 0; i < MAX_LSM_RULES; i++) { int rc = 0; - u32 osid; struct lsmblob lsmdata; if (!ima_lsm_isset(rule->lsm[i].rules)) { @@ -574,8 +573,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, case LSM_OBJ_USER: case LSM_OBJ_ROLE: case LSM_OBJ_TYPE: - security_inode_getsecid(inode, &osid); - lsmblob_init(&lsmdata, osid); + security_inode_getsecid(inode, &lsmdata); rc = ima_filter_rule_match(&lsmdata, rule->lsm[i].type, Audit_equal, rule->lsm[i].rules); diff --git a/security/security.c b/security/security.c index 421ff85015da..f3f6caae392f 100644 --- a/security/security.c +++ b/security/security.c @@ -1443,9 +1443,16 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer } EXPORT_SYMBOL(security_inode_listsecurity); -void security_inode_getsecid(struct inode *inode, u32 *secid) +void security_inode_getsecid(struct inode *inode, struct lsmblob *blob) { - call_void_hook(inode_getsecid, inode, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.inode_getsecid, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.inode_getsecid(inode, &blob->secid[hp->lsmid->slot]); + } } int security_inode_copy_up(struct dentry *src, struct cred **new) From patchwork Wed Nov 4 23:41:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882693 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 BEBE1174A for ; Wed, 4 Nov 2020 23:53:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 97D2D20644 for ; Wed, 4 Nov 2020 23:53:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="K/xk7WPr" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728751AbgKDXxp (ORCPT ); Wed, 4 Nov 2020 18:53:45 -0500 Received: from sonic301-38.consmr.mail.ne1.yahoo.com ([66.163.184.207]:40373 "EHLO sonic301-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733029AbgKDXxm (ORCPT ); Wed, 4 Nov 2020 18:53:42 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534020; bh=ociN9rc5MgUa54JEw2DtkHS55iR7GBeupgmmWIRrLO0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=K/xk7WPryeEg1wXQzeD3lxKb4q8JJVR5QA+ua/tFXCPwS+yGlTZuHmZQsIVbRKFqNCAmkpYTNmB0/6mucGyzK9IjpT6H8/hjICamMQL/drJClfp65bk//o389iSWN0RkNH6i/+5fSCndgOgELYgawhLmus2BfF5xL2AvcWPwCBdz+mvpynEPz9/xGbc99jvjo8llPOR+Wtt4aIU1FfoDopUem9fsH2IuCrrWiCTq7msD4L2eZHkCFYMacqHZBsLjFphOx2pG7a+W2ZQoxhGdaYpcSjQPBxIh08r9JXcMe2c/SW4UfI5lBeT2TiwtEShqRe1i0iL9+6jIVPhY1KlLqQ== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534020; bh=M0LMp5BGVBkAGkqRU0Uj/I53D6Bfmwio5eOyHGTy6XK=; h=From:To:Subject:Date; b=LRcaPbHr4kphvzPpz9n50SPLYCVVTZIyeJl2gNf2rGFUZVhQG1SXlCs/9mCIfINeduskOoWGRare8KVWFKLbM5TPcCTuYOW2JZ35N53sxCyz6xbhCb+MhVWwXQnofqTSGQi2jnXzMpRFseqIi5er53xvTzLFt58XV9fa95EmGhYDlrJWDvdhch18/37egqVGhFBcP3UnptQ9uM+3rsYkEvwYYIfvJwdP81KdSk5NKjy6G36BO37S7IrkrYA2YgQ9Y0fEPhgeOvFl5zsqmftFHC4f7VlTbkGSM06vUwPk13oXtAbgQeXyoaqDuZ+NQW4okBD/U4Jo9wCgEE2WTQPb2w== X-YMail-OSG: 5kmfQlUVM1kjxbm0RK9DBE6l5pKbQX.ayIPrEKGyRVHInNE.9Rm.Z2ZDU5w7d_o Ff9dem6eqj_6GlJubkd1aErzHrxikmr55.Kim.qg1L5K1xLvV3LariZvhaZthGO4C9OmsXrlBvZW wdtTs0xXGxrq8kcNbQbZiEf7pn72qRfn922Cip5m4lC93gtiiftoX9DQa_m0IidF0O.zPSDp7NDW Hus9LvD8OT3z4o6g3VjME7hkn_pjgGMUvvxSsFlXFN4VwE2abh5WdGAJDY8QHUl9vXSUDVz6JKML meK8MESJnnompj_H17A7Da_wsA4iqFeF0I17PMQl68lhyolxThj3yJECJ3ggEHv9S0YmPnnGYTwC tltBHjGt0ovktc_i4206QAglWFliATV0PschL7e7TaAr9N2R2JpIxF1UAv.jR_EIsuiLP9sP_Bbd gTFITRuEMslRy89xNyTXelJW1.fbT7PQYAcoBaGcvK8D90Ez46vxQIBCQ1c5AjWgJFS36_OMEG.t ICjDbytdxdScDYvRf.m.Tke86y52NjS5JxsCZdN3gozpA0YVpcWwLJsFr4AXj7bsuPzXrh90MN4O 362vH4HM9gWR1jvpOlP0PAL1pwb7apY.k2d920x9BjkJQ6uMqCW.Pqf1nuBsKKjMMRK9jSr0aWjN 228vn_rtjRxtYhRMHWtfRwVsP00Vi_khlfkLNTOTZGGfJ7q1oCdatIPRcAPakO..5Ufmf70TrQKD zrDQmwbGBQW.Pe48v7xUga0n9doYkLcmYnn_808Igl.rw4i1lLe2636kEX3idq67wTEeQoLXHmlT 22Jx0i8hmVIc9UL5WpN66vu5UTzvmk9Wmvx3GZb6WsEoDBfDTQgWMGEA4WBO581cK7VocNLMsVUW jX1dsKUDgkGCAs_o88bk7Y6CjfpSkcm5.y2ZnzpYGLEA._tMkA3kcg7AKaTNLEwoSfZcLtPNYm9X QLNOiUo_2xiPd3bRPxyL6oXl5oKXAuiL4NLQ0IUgkI4uM81kui8UF2kVBgLOYCZNTk58FvO6mAVt m7LADK_HrOp_6B7u2L47XUAJQ6Fnmhn447h8zgdwH.hY5H5UBnmILrzk7NkR52jRBjq.juwQLMXE 8tyocVSKuFEGoF.6HG7sqT6eLydHazTIDCXw_bo4ZE34_JaztwWMvSA2truQ4SwS81Jpn4J2HPze bgFDAOvTVNeF8h54gj8XZXu0Ewp1HP8tq2MM9rQEawqYjxI4XNeBMZc6RSSyRmsen0iGkyVkJ.3p Ht34n8gvB9Sichxz5PQw2w4UwsuaqmMsbSe_1eJo8h1wzcc6iClrCOPK463SOiv0id_9KFMAOJH5 iJ91Vd.u5w.qTINRgjwnOSqmpA05oB2b18xce02_7g8ScAwQm79IuvMKWU7MdUwvUDtqJTx8WS3Y 8gNCt2Lo_WGZtIwI_NJGRb2aq0XumaFzm0vnKM_m95G4isgzB2_bFteMo8jv2iyhsfSsvORxdzCB bMhVNAQdAVgic3RglUyDbdvkaxrhhXb94sVmZpg1weHCSkr7cVS_w2epeF6V.fpn..0._PktowK2 N2p36sf8.IMXzAGAOzKqMzR_zCw0jxVN46du4IsdDu8m5V1_5QPAYDl4BAobM0Npk82tJQjuNSzj R_eVtv__CjOh6d0BLFEATSk9xRt__9qyfhXDy7lyvpmSb9nITMjx7ysca838ZYU9Jd7XDfA0KvUk wrNtkKHJ3aufpAI4S8HZYdR6pMZIMtUt774n9aZBJVTzoz6EopQD1WXqjOqG2ENH_LOAomzXqem. lwlIiu7pKLDG6pujKwddYIhzMmEv1AjBjZ3v0QstrK3MBMNZFGMvOIyptshX9nTuD7.WLOed2yIA o1B1.DAJRDp0cSC6OoxEVVXVQ9VFs_aa1aBI2C.ogvmrFHgmCuJQnZVzxIxJZj8jPvQgK7IHwP3I Lmelr7FF3M5TAX6ogdQJAI7sMH9Od_4YIIQpFtqjDwm4XdUXJZ0BGGJvdB8gGGCH9M.vvu9Qhmc_ 63eoJVW0xyEGLhYq4pTH07ZTE3k.AVmGgIXgKAUBWlzP1B._7i93NXfLznvfTbSOQrQ941jxvF_h _HdkgKhDPjjCfbyoWqivg4mvehSIHSLV480VAf0tP0jPDMQIXOcwtqcAwSDt1E1_JnUc2TYrxdmo BC5.G1XqP.XltCot2YmWFl3aJ31yCH5nYw64HnWSRaQXpkRx6OOZ7bGuQCfa5XR3EIYvUMKC.zPQ yH7q352DTwshAyBwnV9769oBTWRfcVjAW495B9t5UuxSqA99tB1nVfg7Tili5gGTe.egOInLju7Q vZNMmYK5OGlRQWVOqqANp2wn0Hxxiftg9ye1310.TIEPX76ZESUVmXRgpvp.goXvhgzQRzNvOg3L .sSSVsPNz6_eqN_W0NjbA.CL_N7A1s.FUIGe9DPQ1SL6wipt15jKvo8SyPRASv1GecMPXt4zZkn2 CYqG8NcQECLfTIHyg3r8Hwr_OW34LeCOvt7EWkK9FOXn_IbtGika8uGn.vW8t8EHRD62IrfqF81_ 581hgKEX3346QJz.4qO5fzJZszd57jcDgoJogmI0PMim2XOuOkF2H9PBYBtysEHkkAQl86dpQ6XO USqJtjqAFreMhiHofejBuPb3oqY3Qg5JkHgcgYYZ2wkpel0Bx5tJWL44aKEiPsHBcsultw1MsN.z BqzC9aPhaPcI.5j5zo2fYQq5THgiTF2EaCHbE91eF_qin.t4G41.HZhOlOjHKmuWY0vNn2uud63H DcoopBy7AhWzdpmENE4abL9GCs3JZoOCZ22gD6PRzV3lO5vFXuZ5fS4nC1qviEH.J1Ywo_Rq8sJx AYSv6p.XVCojDC73.5..ii6wHYN5uSFF5Oy.qWWCm.aQZP_5UX4GNsEb1ZAuHU7P15mXIZy.Jvem vY3p2KlvheT3fDS4WaImZVDGyruVkJfLc6gIUt0gzLt2Rd2kYgNv2b5izOFoFb26WQl2ZEQFe3GW l7ai3fFHARRsGol07q8qQ3EiG4QUVW8S_zzce41TePe0BATeAXkfbMUDuKPgM4OobWyGIqQcrSS1 LwuRVoj1cr9EWUeKTnpbVGEHxvZepj6OQTGWToYMf1fFlp5Lb1yT1YAT5SGhEkE9lEKRPCjSGzT2 r5fzOfPZQQ19fzEmaY7QjSOX9rCNa7mI_nvaRXZovXcAgCboc3L72CbLX6x4uTQOv5AJuLxlfB15 PZY_t63atLpmTLrsjagpu792eUneX.rdXK.exjGmdTNp9dPhqLD913fS0bSvU2Px9m1b5uNi0Atj 26dXckv449jqx9j6WIWdZcqjeLVmE1sGt.wDzPiwW0mLNI9OHnqsLLva1OcW_wwBM.8mJSN0Y3Ye 8YjwvYalYWxI5NxHIfO2f_Jq9hb1jOhclbQN.ipuXRNpZrBCMVbO8aRv.fzO.FzesrkT_YEmC9tp lnwLrET8HU8OFbIHMY_w2 Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:53:40 +0000 Received: by smtp418.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID f73babc1cd8e7bf5e99016dd2688bf1a; Wed, 04 Nov 2020 23:53:37 +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, linux-integrity@vger.kernel.org Subject: [PATCH v22 10/23] LSM: Use lsmblob in security_cred_getsecid Date: Wed, 4 Nov 2020 15:41:01 -0800 Message-Id: <20201104234114.11346-11-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: Change the security_cred_getsecid() interface to fill in a lsmblob instead of a u32 secid. The associated data elements in the audit sub-system are changed from a secid to a lsmblob to accommodate multiple possible LSM audit users. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: linux-audit@redhat.com --- include/linux/security.h | 2 +- kernel/audit.c | 25 +++++++---------------- kernel/audit.h | 3 ++- kernel/auditsc.c | 33 +++++++++++-------------------- security/integrity/ima/ima_main.c | 8 ++++---- security/security.c | 12 ++++++++--- 6 files changed, 35 insertions(+), 48 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index a7968dde27c6..dacd64d2d141 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -463,7 +463,7 @@ int security_cred_alloc_blank(struct cred *cred, gfp_t gfp); void security_cred_free(struct cred *cred); int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp); void security_transfer_creds(struct cred *new, const struct cred *old); -void security_cred_getsecid(const struct cred *c, u32 *secid); +void security_cred_getsecid(const struct cred *c, struct lsmblob *blob); int security_kernel_act_as(struct cred *new, struct lsmblob *blob); int security_kernel_create_files_as(struct cred *new, struct inode *inode); int security_kernel_module_request(char *kmod_name); diff --git a/kernel/audit.c b/kernel/audit.c index 9e3eec0a9c29..1f987ac23e90 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -125,7 +125,7 @@ static u32 audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME; /* The identity of the user shutting down the audit system. */ static kuid_t audit_sig_uid = INVALID_UID; static pid_t audit_sig_pid = -1; -static u32 audit_sig_sid; +struct lsmblob audit_sig_lsm; /* Records can be lost in several ways: 0) [suppressed in audit_alloc] @@ -1441,29 +1441,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } case AUDIT_SIGNAL_INFO: len = 0; - if (audit_sig_sid) { - 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 (lsmblob_is_set(&audit_sig_lsm)) { + err = security_secid_to_secctx(&audit_sig_lsm, &ctx, + &len); if (err) return err; } sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); if (!sig_data) { - if (audit_sig_sid) + if (lsmblob_is_set(&audit_sig_lsm)) security_release_secctx(ctx, len); return -ENOMEM; } sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid); sig_data->pid = audit_sig_pid; - if (audit_sig_sid) { + if (lsmblob_is_set(&audit_sig_lsm)) { memcpy(sig_data->ctx, ctx, len); security_release_secctx(ctx, len); } @@ -2349,7 +2341,6 @@ int audit_set_loginuid(kuid_t loginuid) int audit_signal_info(int sig, struct task_struct *t) { kuid_t uid = current_uid(), auid; - struct lsmblob blob; if (auditd_test_task(t) && (sig == SIGTERM || sig == SIGHUP || @@ -2360,9 +2351,7 @@ int audit_signal_info(int sig, struct task_struct *t) audit_sig_uid = auid; else audit_sig_uid = uid; - security_task_getsecid(current, &blob); - /* scaffolding until audit_sig_sid is converted */ - audit_sig_sid = blob.secid[0]; + security_task_getsecid(current, &audit_sig_lsm); } return audit_signal_info_syscall(t); diff --git a/kernel/audit.h b/kernel/audit.h index 3b9c0945225a..ce41886807bb 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -134,7 +135,7 @@ struct audit_context { kuid_t target_auid; kuid_t target_uid; unsigned int target_sessionid; - u32 target_sid; + struct lsmblob target_lsm; char target_comm[TASK_COMM_LEN]; struct audit_tree_refs *trees, *first_trees; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index b58b0048702a..b15222181700 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -113,7 +113,7 @@ struct audit_aux_data_pids { kuid_t target_auid[AUDIT_AUX_PIDS]; kuid_t target_uid[AUDIT_AUX_PIDS]; unsigned int target_sessionid[AUDIT_AUX_PIDS]; - u32 target_sid[AUDIT_AUX_PIDS]; + struct lsmblob target_lsm[AUDIT_AUX_PIDS]; char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN]; int pid_count; }; @@ -993,14 +993,14 @@ static inline void audit_free_context(struct audit_context *context) } static int audit_log_pid_context(struct audit_context *context, pid_t pid, - kuid_t auid, kuid_t uid, unsigned int sessionid, - u32 sid, char *comm) + kuid_t auid, kuid_t uid, + unsigned int sessionid, + struct lsmblob *blob, char *comm) { struct audit_buffer *ab; char *ctx = NULL; u32 len; int rc = 0; - struct lsmblob blob; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); if (!ab) @@ -1009,9 +1009,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, from_kuid(&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid); - if (sid) { - lsmblob_init(&blob, sid); - if (security_secid_to_secctx(&blob, &ctx, &len)) { + if (lsmblob_is_set(blob)) { + if (security_secid_to_secctx(blob, &ctx, &len)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { @@ -1582,7 +1581,7 @@ static void audit_log_exit(void) axs->target_auid[i], axs->target_uid[i], axs->target_sessionid[i], - axs->target_sid[i], + &axs->target_lsm[i], axs->target_comm[i])) call_panic = 1; } @@ -1591,7 +1590,7 @@ static void audit_log_exit(void) audit_log_pid_context(context, context->target_pid, context->target_auid, context->target_uid, context->target_sessionid, - context->target_sid, context->target_comm)) + &context->target_lsm, context->target_comm)) call_panic = 1; if (context->pwd.dentry && context->pwd.mnt) { @@ -1769,7 +1768,7 @@ void __audit_syscall_exit(int success, long return_code) context->aux = NULL; context->aux_pids = NULL; context->target_pid = 0; - context->target_sid = 0; + lsmblob_init(&context->target_lsm, 0); context->sockaddr_len = 0; context->type = 0; context->fds[0] = -1; @@ -2435,15 +2434,12 @@ int __audit_sockaddr(int len, void *a) void __audit_ptrace(struct task_struct *t) { struct audit_context *context = audit_context(); - struct lsmblob blob; context->target_pid = task_tgid_nr(t); context->target_auid = audit_get_loginuid(t); context->target_uid = task_uid(t); context->target_sessionid = audit_get_sessionid(t); - security_task_getsecid(t, &blob); - /* scaffolding - until target_sid is converted */ - context->target_sid = blob.secid[0]; + security_task_getsecid(t, &context->target_lsm); memcpy(context->target_comm, t->comm, TASK_COMM_LEN); } @@ -2459,7 +2455,6 @@ int audit_signal_info_syscall(struct task_struct *t) struct audit_aux_data_pids *axp; struct audit_context *ctx = audit_context(); kuid_t t_uid = task_uid(t); - struct lsmblob blob; if (!audit_signals || audit_dummy_context()) return 0; @@ -2471,9 +2466,7 @@ int audit_signal_info_syscall(struct task_struct *t) ctx->target_auid = audit_get_loginuid(t); ctx->target_uid = t_uid; ctx->target_sessionid = audit_get_sessionid(t); - security_task_getsecid(t, &blob); - /* scaffolding until target_sid is converted */ - ctx->target_sid = blob.secid[0]; + security_task_getsecid(t, &ctx->target_lsm); memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); return 0; } @@ -2494,9 +2487,7 @@ int audit_signal_info_syscall(struct task_struct *t) axp->target_auid[axp->pid_count] = audit_get_loginuid(t); axp->target_uid[axp->pid_count] = t_uid; axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); - security_task_getsecid(t, &blob); - /* scaffolding until target_sid is converted */ - axp->target_sid[axp->pid_count] = blob.secid[0]; + security_task_getsecid(t, &axp->target_lsm[axp->pid_count]); memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); axp->pid_count++; diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index c9f1f6bddab5..e2fd092a1023 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -469,7 +469,6 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) int ima_bprm_check(struct linux_binprm *bprm) { int ret; - u32 secid; struct lsmblob blob; security_task_getsecid(current, &blob); @@ -479,9 +478,10 @@ int ima_bprm_check(struct linux_binprm *bprm) if (ret) return ret; - security_cred_getsecid(bprm->cred, &secid); - return process_measurement(bprm->file, bprm->cred, secid, NULL, 0, - MAY_EXEC, CREDS_CHECK); + security_cred_getsecid(bprm->cred, &blob); + /* scaffolding until process_measurement changes */ + return process_measurement(bprm->file, bprm->cred, blob.secid[0], + NULL, 0, MAY_EXEC, CREDS_CHECK); } /** diff --git a/security/security.c b/security/security.c index f3f6caae392f..78aeb2ae7010 100644 --- a/security/security.c +++ b/security/security.c @@ -1693,10 +1693,16 @@ void security_transfer_creds(struct cred *new, const struct cred *old) call_void_hook(cred_transfer, new, old); } -void security_cred_getsecid(const struct cred *c, u32 *secid) +void security_cred_getsecid(const struct cred *c, struct lsmblob *blob) { - *secid = 0; - call_void_hook(cred_getsecid, c, secid); + struct security_hook_list *hp; + + lsmblob_init(blob, 0); + hlist_for_each_entry(hp, &security_hook_heads.cred_getsecid, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + hp->hook.cred_getsecid(c, &blob->secid[hp->lsmid->slot]); + } } EXPORT_SYMBOL(security_cred_getsecid); From patchwork Wed Nov 4 23:41:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882701 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 9FC0A174A for ; Wed, 4 Nov 2020 23:54:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8050021527 for ; Wed, 4 Nov 2020 23:54:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="gZ5+/46s" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733029AbgKDXyw (ORCPT ); Wed, 4 Nov 2020 18:54:52 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:45783 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732924AbgKDXyw (ORCPT ); Wed, 4 Nov 2020 18:54:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534090; bh=sn233g3yrLDkG9XqXk4WNuW+QliBdnrF8a2qtcNu7yk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=gZ5+/46spdEGuTi8ylPlhzD07w1eizRwkYzNMp+iztY3nHxiqSRfsS/S+LAFxN94jaUBsh9OYHzfqE385m5U9pc0nPPpFXyZqVK16TBUR7W9ynhtc9NLbI4kLRU2YL0HJyZWoVeobhlc+2amuJ/3vr3LK5i24SJb/xf9XvplnblVuEvHuBAbbVGu05tlJ61CX1eMvGcXgXMVrQqFcmm2FRX/bloqY4vn0rQvd7oWxivrq/RULcwl69E5XPcaF39uRn7AzyWVKNlzBAKa9y36k2qD7iCUBNUAZmg5FRoNUbwDAhYeU1579kZdOqHnHZNHZexXu2ua0KGg70HgZ7xWTg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534090; bh=s3V36KpnPAW1Bwo67ozixpI+w0bHihZxyxPIYOTYzkC=; h=From:To:Subject:Date; b=Ho6wnZ0vA3yf0guDO3vr7g7OMiLY4lQC/IS673qU7c+oNN8Ho1k/IcxF+xIxvRUGQtavreKG1GfkpVTKHeFNOamKO5Iq/5zqBRoactY7u78yDrvn21qqGIm2l/XJhmGdog2W53Vq76puxaqrb6NC1UPAJggvdZ+moepgbmNbJkZM2L1F6SeUslMGEobg5WUUN3wIAQ9V6L0EjlpkbmNQSNjP/11mZIV3j9Nr+fD/NSuHF48d6DNoywaYbETNiMP/n5bEo5XrPHiTXvSbeprm7RuWH9VqtiH1hOnWv3MbU+yTX1R8OI7uRnW7FEbMY6RsWCIbf6nvbFIBpQxIY2f98A== X-YMail-OSG: ini5vyoVM1m3arVDwkwLnamoxeTYcJyjidv9qPMdL5qkvaaLMY6PFI8yGNSX4td tZfETGuR57_cBBAJzWluGQnxhMBlOzy7VKYNnxjheK1.OriKHaD19MklCjPydBtoq1BzGAB9mhIl JHQNmGH9rOjyWaeLU4CH.T7xhwpnBvtMUZIHVvtlLHO6ntwfmSJmqfUX19GyoOfZ2WZtos0Gt9Lm GXNERMYWlNB3Ul2oUal0jXt4RAreWPPwf70SfXQm5f0mdVp_HIqgC5wBo8nQ6oY285sqKN2uhDBM hOLmIPQwDIOvze9CiKnu6foHgjj30o_rCv5vUWaxf_Fvqr.dPIcUeGa9omyDAc1cmC_Ohe7FZc5G pYYGViKR2AyrnQ6LosgAeKAytwcf9oeIr1uVxMIgEagEnEZaRNdmfHR55gUMRgO3nOxHmUSN4.E_ xS_K.rxWt58NpFmRHp3PBnJeEKWbMZIz.Tk1E2XY1YiiTSjag7j2PpzcDQaW2.qNPwP5rimu4_Ad e7HC.yI2YGCTIeem7UwGr7ga3BVRp6KUKm8sZTqIyQFZZEchygMf6b8_TIoWsLSACfc7bx9aZfwJ .1E54OBUM5pQtg4rp4rwfcAFYOpPmbRaS.andGwegwXOn29d7p2WDLpYLFYEbO_IDF3d0_vrJLe_ Q4gEB_FzpjTRm92pQ5KcX1M5XoBWxsmwRw5dXhZ2eYoL1EUAQ8sB7F8v7Rtd.oounYp3PqIa4jXM Hyp0RQquVNt.uNZDy1XTZoPpPeBmP6lyCdWSAaUSo871D4IxMpFnwHN8mR_GGcgPWvQpXiwN6lwL tfpkdngmdMcEtGZAZBNwWmsh8895qgL6eizkI1ySL12EWkBJFuKOaboyqoRmVXeSyX3TybJTcmSz RN9kTl01NN8NLt1QBd9Zm55piV85LBEdP2vwVYrfHHZpgTHfpVdcI9Vx.dD6Ghi9HdaEHACA66qU MulEeV6rC59Xu47PgBzEZwd5e4kW3IrRnKHQB0xV.wm5sF_FWNRjwrfjipTW.NAxrnvq7S1ZDmfG PLhTjzPXxyDQe7PAJsusy3nhpXS63HP1heRKOVVsGrGwVbKPmDLUyD1mlBk.1TVbwWrJ.adjoy0n h8xn1fezJ5oEAOzQfpKuJJUQ555r1L7wvU9Z8uScpHIrtf2FcJYlpFsrPyAGiODvyxRDRcxbBW81 037hwmsKXKHyvef8Spe1IDNirZh6FbS616u2osWlDQLQRej0ACE1fsfTAibmCzqJJoXktD6Hhk_3 IS0HxGdHI9T3XcB87v1HtTPiKiYLvNqRMYLbpKhLeB_S.jhPvB71QUIm.f3abnJ57b__i99rIi4Z D8BHvStjVIhYCllZZs8RQXzU_kPi.G5lImEBbfQhLDXqQ3uIbxtA8snPqPYiofQQQKGkKyD8CBqU m6rod4iKdT321fmDBco9bAVHIiKjLeuMzUt8a8aUcW7.6pD8j2zri_mzc19St8V_D6TtJ.OeLPD7 v78njuE1l4TTMp0LiNCf3zQt87v._ifURJIQa9lRZVlRsS0wO0XieKqvXaJAoIFTwUJnLR6evXGl pVxQ_908bHhUFCqjl325hdeLztrNj62OjrKQWvIL730pEBNYxFT3vXMoCFIBLu4i9unqhQsN5kSX BPi__rcQH2zGQNJJuaE65ZwFGuG3g8nvLSXVFg_aJxdsUJaz3WxoUB2z9DK0kjZ8xBMcxBIhxtaE aeYtgXBVZwOpvkBYQt3avilEm1dX4JLmd5m4wn4QWZngkCw0B8i3ILzr0hhxVF7CSKyODKGGe_mi knu1a5D0PAGtrJZl1fZpHOuZrsWnPzqiHkZ1T_rxyHvs5njbO_wDMGv5o_nXRoYMoghOzqJqKy9S HoRSaSqVuauZe4Id19rbG99re5Z6Dg1edfUc49eTylXE.u8OlvAHzGkpHMtViwW2ESo5vz_CFyoB eKOVAM5Rks.iYsAUEPEWZrQaga40eo59UnJbIOWPADnRham0vYJC.U_VlI6QvaZmnOYHMP3JDwpP Xmu75pglZb8Bp9Gh8CMf0Nwrct7rJuD7Lsf4ndCvdxNJssyzPqFmacyqfEbHoqt.EPnXdyg8TKZe THZmVrpn9NFy9aOFqC5pN6nHr8cIFrhQcKe2hjHOfND3ZNw1y9WDsCbSvdAvaAklVmrRGHEpjbPy DfOpOgnztIHDrEMaq1_Ab6nKK5Q6WVywovxtaUl5Xg_0q5X0MlMiNDMBHbfyh0FCi1EXgUbJEA28 ijU2VRuCuWftYHupkkpisd4.EqzTIxOOWJtLQ2AYk2xV_c3VkkoyJxzmfgQ9OmHxtrbXj1gTsXO_ 8y62wlz2otQhuv3LrPUrqesPkUbPkTBIgN_3O2TULUenwsi.haLBApbvVK34La98U8uC1.hO3u4u 2Cw9mUhCvPMxXTnSN9yo89dvkWTKVWEnNXt1.M6ZawYr_sbUWkK.Uo5ZnZKJaA57TswMFU9eLxjE IoRwzF0ajSqVJePSDrC7tSbomUsUCkAwNFrZ9qW0LbJdjw1nFii5Yr9sW0IX8n0zg2tM_WOQRU0F W9U7mlKcj8AsHMvVIEBVTTxm.iLgq_3ATDBKUNKWCR2qq.KjigOGRK7C2v_OtpffTrVpO.YqCVFm VxPh4g.DcF87iYW9POI6n7.VV4GiddkkA0JVvA6jUYPd_itK87AayREMEQEt_mq7DmrjjjI2Yma_ nU8vMpv3nsdCBdiuLYNyx9T8CG3EEfo6QAnQwZ7uVYDNY4a1leOVa04Fc0oHzfSzUUdIgbvFjeim CUJSmx8C_Z5_bP.M8.Nt6u8BYid1kUTfu2S9K_R7aG3aSa3GLBk7zBTXJgnUTmsL90EQF5beIgZ_ z2Ihr1VYOpaK5Ip3INZf2bHxFvwUx2qWY2Le8nek_bW2cRyG66twa5m0cjsoqe3_jXAysA82I6aT vBUNrDF38R3Dx.3rNjZuSqE9wJGfsHJ0d7GzOW1877YlDlxn2TEnRDevHos0pBhe2IO05nzqxJlJ njsviZ_iWx3sARnJob2sdOx3YWCVMAYzxxGvkbyU8BeT2shN3cdnJ84oebZxSkChl9_jLnlkJZ7w DnbSdSAJg3eO3psx9vfEv2mY6GkiKWwkgiUKyffSUZX.PJzmwlG0v3liwa16u4pSq.8bLgE_zSUO req9UmGc9QoGUL8YXkEL6aRQ4prrkUhcUpxYWSlPjO9leIeFlx8R4EdtgTvWypwEwgBdlQDeem9H fFY9rIEHg.4aIqOr77V_YDFJnppKsSlXbRPzHQzX5IeS4UactK3MjjQueFDOaVJTFlVKyXlzQ783 o0RVbCo2PhDyoJI23FPvXWE2S40.45a6b1O5nWHwD5CJnVz9151UEUGmNcgyRMyQ1IMcx.KZK7Mo 8EN6wOq0RuzcOiYvYGFIeBTdEffEfXThAOdQsBMOaLdER8hCvb2zac_IVuVe0dQN6dlWFIGuEsZV 9vyhgmugiqIL.XxnuwBRSS1t.9yRL__K6SmvdEA-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:54:50 +0000 Received: by smtp406.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 68f40420d8ea732223d2145b31b3510b; Wed, 04 Nov 2020 23:54:45 +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, linux-integrity@vger.kernel.org Subject: [PATCH v22 11/23] IMA: Change internal interfaces to use lsmblobs Date: Wed, 4 Nov 2020 15:41:02 -0800 Message-Id: <20201104234114.11346-12-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: The IMA interfaces ima_get_action() and ima_match_policy() call LSM functions that use lsmblobs. Change the IMA functions to pass the lsmblob to be compatible with the LSM functions. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org --- security/integrity/ima/ima.h | 11 ++++---- security/integrity/ima/ima_api.c | 10 +++---- security/integrity/ima/ima_appraise.c | 6 ++--- security/integrity/ima/ima_main.c | 38 +++++++++++---------------- security/integrity/ima/ima_policy.c | 16 +++++------ 5 files changed, 36 insertions(+), 45 deletions(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index d7fe1d5ee8c9..81b00d07490f 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -252,9 +252,9 @@ static inline void ima_process_queued_keys(void) {} #endif /* CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS */ /* LIM API function definitions */ -int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid, - int mask, enum ima_hooks func, int *pcr, - struct ima_template_desc **template_desc, +int ima_get_action(struct inode *inode, const struct cred *cred, + struct lsmblob *blob, int mask, enum ima_hooks func, + int *pcr, struct ima_template_desc **template_desc, const char *keyring); int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func); int ima_collect_measurement(struct integrity_iint_cache *iint, @@ -280,8 +280,9 @@ void ima_free_template_entry(struct ima_template_entry *entry); const char *ima_d_path(const struct path *path, char **pathbuf, char *filename); /* IMA policy related functions */ -int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid, - enum ima_hooks func, int mask, int flags, int *pcr, +int ima_match_policy(struct inode *inode, const struct cred *cred, + struct lsmblob *blob, enum ima_hooks func, int mask, + int flags, int *pcr, struct ima_template_desc **template_desc, const char *keyring); void ima_init_policy(void); diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index 4f39fb93f278..e83fa1c32843 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -164,7 +164,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename, * ima_get_action - appraise & measure decision based on policy. * @inode: pointer to the inode associated with the object being validated * @cred: pointer to credentials structure to validate - * @secid: secid of the task being validated + * @blob: LSM data of the task being validated * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXEC, * MAY_APPEND) * @func: caller identifier @@ -183,16 +183,16 @@ void ima_add_violation(struct file *file, const unsigned char *filename, * Returns IMA_MEASURE, IMA_APPRAISE mask. * */ -int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid, - int mask, enum ima_hooks func, int *pcr, - struct ima_template_desc **template_desc, +int ima_get_action(struct inode *inode, const struct cred *cred, + struct lsmblob *blob, int mask, enum ima_hooks func, + int *pcr, struct ima_template_desc **template_desc, const char *keyring) { int flags = IMA_MEASURE | IMA_AUDIT | IMA_APPRAISE | IMA_HASH; flags &= ima_policy_flag; - return ima_match_policy(inode, cred, secid, func, mask, flags, pcr, + return ima_match_policy(inode, cred, blob, func, mask, flags, pcr, template_desc, keyring); } diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 2a18124af429..7c4e43399269 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -71,10 +71,8 @@ int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func) return 0; security_task_getsecid(current, &blob); - /* scaffolding the .secid[0] */ - return ima_match_policy(inode, current_cred(), blob.secid[0], func, - mask, IMA_APPRAISE | IMA_HASH, NULL, NULL, - NULL); + return ima_match_policy(inode, current_cred(), &blob, func, mask, + IMA_APPRAISE | IMA_HASH, NULL, NULL, NULL); } static int ima_fix_xattr(struct dentry *dentry, diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index e2fd092a1023..39ca17586c6c 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -194,8 +194,8 @@ void ima_file_free(struct file *file) } static int process_measurement(struct file *file, const struct cred *cred, - u32 secid, char *buf, loff_t size, int mask, - enum ima_hooks func) + struct lsmblob *blob, char *buf, loff_t size, + int mask, enum ima_hooks func) { struct inode *inode = file_inode(file); struct integrity_iint_cache *iint = NULL; @@ -218,7 +218,7 @@ static int process_measurement(struct file *file, const struct cred *cred, * bitmask based on the appraise/audit/measurement policy. * Included is the appraise submask. */ - action = ima_get_action(inode, cred, secid, mask, func, &pcr, + action = ima_get_action(inode, cred, blob, mask, func, &pcr, &template_desc, NULL); violation_check = ((func == FILE_CHECK || func == MMAP_CHECK) && (ima_policy_flag & IMA_MEASURE)); @@ -392,8 +392,7 @@ int ima_file_mmap(struct file *file, unsigned long prot) if (file && (prot & PROT_EXEC)) { security_task_getsecid(current, &blob); - /* scaffolding - until process_measurement changes */ - return process_measurement(file, current_cred(), blob.secid[0], + return process_measurement(file, current_cred(), &blob, NULL, 0, MAY_EXEC, MMAP_CHECK); } @@ -432,8 +431,7 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) security_task_getsecid(current, &blob); inode = file_inode(vma->vm_file); - /* scaffolding */ - action = ima_get_action(NULL, current_cred(), blob.secid[0], 0, + action = ima_get_action(NULL, current_cred(), &blob, 0, MMAP_CHECK, &pcr, &template, 0); /* Is the mmap'ed file in policy? */ @@ -472,16 +470,14 @@ int ima_bprm_check(struct linux_binprm *bprm) struct lsmblob blob; security_task_getsecid(current, &blob); - /* scaffolding until process_measurement changes */ - ret = process_measurement(bprm->file, current_cred(), blob.secid[0], - NULL, 0, MAY_EXEC, BPRM_CHECK); + ret = process_measurement(bprm->file, current_cred(), &blob, NULL, 0, + MAY_EXEC, BPRM_CHECK); if (ret) return ret; security_cred_getsecid(bprm->cred, &blob); - /* scaffolding until process_measurement changes */ - return process_measurement(bprm->file, bprm->cred, blob.secid[0], - NULL, 0, MAY_EXEC, CREDS_CHECK); + return process_measurement(bprm->file, bprm->cred, &blob, NULL, 0, + MAY_EXEC, CREDS_CHECK); } /** @@ -499,8 +495,7 @@ int ima_file_check(struct file *file, int mask) struct lsmblob blob; security_task_getsecid(current, &blob); - /* scaffolding until process_measurement changes */ - return process_measurement(file, current_cred(), blob.secid[0], NULL, 0, + return process_measurement(file, current_cred(), &blob, NULL, 0, mask & (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND), FILE_CHECK); } @@ -655,8 +650,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id, /* Read entire file for all partial reads. */ func = read_idmap[read_id] ?: FILE_CHECK; security_task_getsecid(current, &blob); - /* scaffolding - until process_measurement changes */ - return process_measurement(file, current_cred(), blob.secid[0], NULL, + return process_measurement(file, current_cred(), &blob, NULL, 0, MAY_READ, func); } @@ -699,9 +693,8 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, func = read_idmap[read_id] ?: FILE_CHECK; security_task_getsecid(current, &blob); - /* scaffolding until process_measurement changes */ - return process_measurement(file, current_cred(), blob.secid[0], buf, - size, MAY_READ, func); + return process_measurement(file, current_cred(), &blob, buf, size, + MAY_READ, func); } /** @@ -830,9 +823,8 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size, */ if (func) { security_task_getsecid(current, &blob); - /* scaffolding */ - action = ima_get_action(inode, current_cred(), blob.secid[0], - 0, func, &pcr, &template, keyring); + action = ima_get_action(inode, current_cred(), &blob, 0, func, + &pcr, &template, keyring); if (!(action & IMA_MEASURE)) return; } diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index bbf9fa79740a..a95eb37937dd 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -508,7 +508,7 @@ static bool ima_match_keyring(struct ima_rule_entry *rule, * @rule: a pointer to a rule * @inode: a pointer to an inode * @cred: a pointer to a credentials structure for user validation - * @secid: the secid of the task to be validated + * @blob: the lsm data of the task to be validated * @func: LIM hook identifier * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) * @keyring: keyring name to check in policy for KEY_CHECK func @@ -516,7 +516,7 @@ static bool ima_match_keyring(struct ima_rule_entry *rule, * Returns true on rule match, false on failure. */ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, - const struct cred *cred, u32 secid, + const struct cred *cred, struct lsmblob *blob, enum ima_hooks func, int mask, const char *keyring) { @@ -581,8 +581,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, case LSM_SUBJ_USER: case LSM_SUBJ_ROLE: case LSM_SUBJ_TYPE: - lsmblob_init(&lsmdata, secid); - rc = ima_filter_rule_match(&lsmdata, rule->lsm[i].type, + rc = ima_filter_rule_match(blob, rule->lsm[i].type, Audit_equal, rule->lsm[i].rules); default: @@ -624,7 +623,7 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func) * @inode: pointer to an inode for which the policy decision is being made * @cred: pointer to a credentials structure for which the policy decision is * being made - * @secid: LSM secid of the task to be validated + * @blob: LSM data of the task to be validated * @func: IMA hook identifier * @mask: requested action (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) * @pcr: set the pcr to extend @@ -639,8 +638,9 @@ static int get_subaction(struct ima_rule_entry *rule, enum ima_hooks func) * list when walking it. Reads are many orders of magnitude more numerous * than writes so ima_match_policy() is classical RCU candidate. */ -int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid, - enum ima_hooks func, int mask, int flags, int *pcr, +int ima_match_policy(struct inode *inode, const struct cred *cred, + struct lsmblob *blob, enum ima_hooks func, int mask, + int flags, int *pcr, struct ima_template_desc **template_desc, const char *keyring) { @@ -656,7 +656,7 @@ int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid, if (!(entry->action & actmask)) continue; - if (!ima_match_rules(entry, inode, cred, secid, func, mask, + if (!ima_match_rules(entry, inode, cred, blob, func, mask, keyring)) continue; From patchwork Wed Nov 4 23:41:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882713 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 458F61130 for ; Wed, 4 Nov 2020 23:56:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2123A20786 for ; Wed, 4 Nov 2020 23:56:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="AUwLlcAU" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733264AbgKDX4r (ORCPT ); Wed, 4 Nov 2020 18:56:47 -0500 Received: from sonic313-15.consmr.mail.ne1.yahoo.com ([66.163.185.38]:38450 "EHLO sonic313-15.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733230AbgKDX4A (ORCPT ); Wed, 4 Nov 2020 18:56:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534159; bh=N6iORuVgdJrnPiBRwx/E1Rjlds9E5M3v9taI9rMKSHk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=AUwLlcAUU4dYbYzjs6ZmxVAC3bnbOkT+qHZQ/8snbXf8nO43a1nIbeYWZhHKNIEvdDcjcvMnNLcSl3E+GrzF/zrDaLoyr5SZq9GI572oVeE+UlEFnqHcxvMdyG9stJvaweo28bVkmRdbRbWusGO1UrSzG4RekOaOuSbiS4wovBkem6UKU8Oj9L8CsdpGn+xx7UX4xGarak1FMxTI5+UlFZZTJCZwN1fiyznlPckOltptKOsz3SqZDzHdTW2blxhBNZY1bNiDnWD3ebdymXpARoj8Z17Pm2qgNSCUdOlrkE+I5WjX5pF0hyMQsId0bCv2762SS5dzB/mQIGk7osbOAg== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534159; bh=b1eOB3fuV9PbLUiKiWgjCLkmmpjaBZ/rAJV87FIEy8a=; h=From:To:Subject:Date; b=Dwc0a1bEBBuYOb2zH1cwP+g4Nkw6GYTWUA5locVoQpu9x3kwwPm7LF1QWfYnDLEcuTSYA+gp2bJUdXSrDfNA6jKBlfjNlOiLEbhz6eMWYu9YAX5hwcjBqdfmfTzqqBmaE9z2FFxYntLtNKmtkx+V/OWFvSHoRd32i6kuuqz4sPMnA6qi2OrfbCCoAdQFfvAI5HNtfrhX4di4yZxFRPoTzqWtJrr7/gqdePAx9Rfsi17e2NXLxDtJkBuj4T2ASB/JGj4suAB/j96HFfyNW4+WFYP/6kYI567TYifYUiW+xjGW4k11k6XA7Xk7adwIFx1Dm8Rp7MzpXHjO4AzrTz8QGQ== X-YMail-OSG: SSL.yVoVM1njgWDgdrACv2KhMgEk4kdJFFamRTErETTasLWdag2myXk4ZSaqInh whu_0Of3cDrv8lfo81wqRyZ4iaN4OPLCK9TNLtH5HFvuqPodkzcJ_6j_7FVfRozmJr8I0jf0cez9 RaqVNfE.dJ0KTk93SdsP5TvtIzJOgj5UQKp9nXnepVjwNxuodW2Tx_V1HLks2by9LwIRGo9KhhHu ijsDbWmlZ1ssPfEjO3aUaXH1m8kWapdBpUNEWRBmr6yK7DkpQ9brG3xrrpaWbjLyUkkPcpHtU7xJ A_M_wI4dwDQe8eO5hvyDs7bhqHQkyNGTqwYxoVbEtxIosRavypSNO132c2C7IPBiTHkr5l5BbpFt zAk0mla9kjbeYZnyB2i5pDWIOr_ncPjgoqsveW5RiIjTEYCduNAUftD7rTSmr.kO4awxd92PCA0f 0.JUKeOLcVWi28a.19PW.q4o3.iAmEWhzWz9dO4YC1tomJ7L3D22igTsXQT7ogxNGA.aBrde.MnL Ul__nYpcJd9NlQp5Vd0egxcrNdVTAIOoODJZVexFl8eIEopw1_9ytbOxQM7ifJ1ScDS5u8msbrOv 7Rv4kLoVMxnFymNcK2PymDm6YwFBQq0hvXpNCfrs4mYDCPSn29ZcLu_04Uxd9DJy1.1TdFefk.9p Vpw06fkgSfM._M4gdCmuwmYhWBg7J8eE3_gqekTkaY2zkl6_Y6P08JQ7Ob0e1NlAOsIph6fEtyEA Zm6GikeVbntXSGcCSMPIcje5DlRDVCoauDt5d.4qoQ5NnAom.o4LjlRkGZi4knrn9JsH0BKtRr92 ANwWr97Avuw4_qiSZHC.aa8Ms0o301iB9ji_69Nh79tbHe0voGdsXjFYmzGvL3VVLH6rk4UU7o0j mU8FMR6DrjGIAcqzKnUU.XyiQySS_y8xE6kbF474DJmzJjYlUqmLZFFwMPRloIZUCDP7V_wGDdnS pDc5NcZQWk921jdHpaH0ZpX.6f7sdgvxjqhYh96OrFLdryopF_Lm4_VDrw69s9ihYAnZaudh2LGg NfMVu56V8kTUap2iiM9e5BoyIgACGiRaEMgQ4FhwZglGFD5J9lfU5YMzIVhXrtlyKBwpKfCW8Rtp pPxTIUDbe0gAUMZ.mXMhoE1.1cx.2.s1RccA1e.AOghw2c1e7yCUN5W4JbMX9Pw_wCn8RyiBhLRP ZULMZ3kxr_3oDgugVx.8PmIRvmI6WB0XD_rckMdAbEc6RjkaBPCxNFr.dSpcwpfERjN2mUK0yoTj Y21WFH.2Dvyz258UqQOcOEDXmGcujHjdvx405.wqWPeis6SJYt7LmWnxvATvDoHgOtwAqMuIcebt 7UYcwqGO0rDvEUuS7Eo5Pqz4bLuEkdcuRlZUTPx4j0H83XNJzw4Un.mFyrURe2cfiTHCsCJ93yvG 0KWpJ60dwcFiOR6AwPM8AlgaY91D.2oOOy8qsE9F.VTFlt_pGHBQZ5z37xRl9tBPx_gkDVE1S5wZ TT3nl5I8P4HDtmV6pFcYiJhv0rZQkSalaLCm_1.wmUwbDxhwDOD6GUM5hqouDAW2gpooPkCszuS0 xvZObMHHer0S9uBMFRbQYQalqfdJC7cn3nRpDyaNC_H7kYYqH5jYr486veuJIGBwrr_qgV5NRJw6 kqXZ6mPBcJWsYvYFndI0pMYZDAmYEXYwZe6wdEkVzigY1c3H3Bjc9NAsc9eEGgVjBx6XpbGGZW.D dvXdmGuNWvf3c69Zv1s_R3QN7LjvJfmLdChoylBUYQkJAPf4q3I04Reutg.7hCPEYmN81Oxn2pWc EpiTWAoVCmKGV5qfJDjmxzhNhG7p.w3iijm2j28jCWXO6vCav5Qpj03KeJtE9iSVTLZYLYL5RpPx 48hDDR8bksclt2unv8UcstSBYCrivdlg5Y9nDdXfo_tfy8r2BaU7uRQDXDmf451Rfc_5yMd.D9Lp ubypx3J60FGRqr0peiAvtJqfdudrotC8E1j9QgFrpdYoAJRYRlPFHDGz2IW8VW8u9CJN3W4LsgvU PQv8FmkSfRjCfUx1l.nMhnICvOa0H0bvYyyN68bfSF3StGEnS2IK9wfL2M5oQSonQw__zBleyZsF WvyBCjsKQKNuJyHz6RhvlVtP5pMI9YGq9Azb3OtfTn9qBEnO7eBccnh2WlGCNMAlaXhGkbPOBs_7 nqEd3EVJC.VdzZrOYZLyOow84yoadFXdJqO7lQYIf0efMRAJ4d90rdVXOp9mApw.YeVle_1GK59A QULvWODHkQDrJefAeNV8I6QGE640tK9EuC52SDcqdXqpchWopW2hXpwD4GdgVnvmfk3wMzrl2kWJ VKxbOv3pTIkN7bf9BcO1NwtP9sJjSo6mdl5SabP0F3RVtFifzyt.NIUK0wfBuVmtNlQqdGJyB8UG Lsf3FkVgHlsicKkwg669X84Xnc2M8BpuZTuSVylmB9sf2ezwI28vm.qlihh8q8lwibI.WOQhRtK. 5gu9.t_GQJwf_7GrMyQZD.NkNmJfKXz49oyAtZdst.pL2Is9.oakdjFb9A4I2JkF7ussi5Y_BgYH 1ds_ae_bhEmgvRF5_fPQRR74Fud9rpkTsAjg36k8Bj8FzzuAYDTEcC_kr29Cg.2TLCRTzJvwYdS4 gGvzxlmsGEA4fkqK5UK2vScTps4mbk6jnjRaBIeixcWlKJ9gHl2C0gX06FJZq08eoRwSHOB1UVnY KN_71.Nl.A5WiK2TprgHDcX.AJKhqeERrU_aPeULZ9xrlhf6OEm7Z21j1s41Y6JB.Z7lH5zKLNd1 9Pk6aX3nd6sJ_MGL39m8fGocWFE96PuX2NSDR3UtcjT9FlMHKIMbsWPPS5SAMPvq5jso0l8f713M ZbsNyem38WtdyIfrmXWM_aasZGKeKAXZw3wyDOOJzMFSy9cyp000P.UpPCuT7TB58H39l4MBoHx4 mluW1U9VnfN9k.pWIOrssuDn4OW6CpGvbp6fZyoj.bWaT51GtRFZdQW6IosIv9QF_xxX5XxxxG82 Q5.WVfMvjI.BW3f0IM0N70X2VZvvsXfL9xW7u8icEMLDkv5BbwA6iAXejdoKTgdY9RQPi8DH0FPq _EuXYiQDWIFBsl5OHM_ku5JzvUSalugli_82kFf.kRPE1kzD5n_6uBcvVCcHsuAF12Dpxqb.VYIr .H3sGtB9oUj35qG3Zqok1waWSbx1xVbVpyRYXpCg411h28iF7V9Gr0CTv00d78S_Tr2_UQySMBvx PzSPRREib5Nl4Z9h6Lbn2j4H72x1s4GL_gAj12OqphS6IFNieNONdticxIdoIrCEBy0MzSdppmnT JmXnyRTtdZj51RUqLx2.yY_tU8HxPukSJnFqjKRKKeoOs1S37x32.iIMPRmOENghhQ1l3CfRYl5P WKW73s0QuiBTCmvhsgB4pKT8eJnzeGOKZD4Hs_FoTtUWPI3W3kz0ojmBW7h7WBXONJr4eXoZFaAQ - Received: from sonic.gate.mail.ne1.yahoo.com by sonic313.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:55:59 +0000 Received: by smtp422.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 4ee3430ab44837f61159983ac4fba4ec; Wed, 04 Nov 2020 23:55:52 +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, linux-api@vger.kernel.org Subject: [PATCH v22 12/23] LSM: Specify which LSM to display Date: Wed, 4 Nov 2020 15:41:03 -0800 Message-Id: <20201104234114.11346-13-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: Create a new entry "display" in the procfs attr directory for controlling which LSM security information is displayed for a process. A process can only read or write its own display value. The name of an active LSM that supplies hooks for human readable data may be written to "display" to set the value. The name of the LSM currently in use can be read from "display". At this point there can only be one LSM capable of display active. A helper function lsm_task_display() is provided to get the display slot for a task_struct. Setting the "display" requires that all security modules using setprocattr hooks allow the action. Each security module is responsible for defining its policy. AppArmor hook provided by John Johansen SELinux hook provided by Stephen Smalley Reviewed-by: Kees Cook Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: linux-api@vger.kernel.org --- fs/proc/base.c | 1 + include/linux/lsm_hooks.h | 17 +++ security/apparmor/include/apparmor.h | 3 +- security/apparmor/lsm.c | 32 +++++ security/security.c | 169 ++++++++++++++++++++++++--- security/selinux/hooks.c | 11 ++ security/selinux/include/classmap.h | 2 +- security/smack/smack_lsm.c | 7 ++ 8 files changed, 223 insertions(+), 19 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 0f707003dda5..7432f24f0132 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2806,6 +2806,7 @@ static const struct pid_entry attr_dir_stuff[] = { ATTR(NULL, "fscreate", 0666), ATTR(NULL, "keycreate", 0666), ATTR(NULL, "sockcreate", 0666), + ATTR(NULL, "display", 0666), #ifdef CONFIG_SECURITY_SMACK DIR("smack", 0555, proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops), diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index fe9203f15993..c2f5adef0ad7 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1660,4 +1660,21 @@ static inline void security_delete_hooks(struct security_hook_list *hooks, extern int lsm_inode_alloc(struct inode *inode); +/** + * lsm_task_display - the "display" LSM for this task + * @task: The task to report on + * + * Returns the task's display LSM slot. + */ +static inline int lsm_task_display(struct task_struct *task) +{ +#ifdef CONFIG_SECURITY + int *display = task->security; + + if (display) + return *display; +#endif + return LSMBLOB_INVALID; +} + #endif /* ! __LINUX_LSM_HOOKS_H */ diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h index 1fbabdb565a8..b1622fcb4394 100644 --- a/security/apparmor/include/apparmor.h +++ b/security/apparmor/include/apparmor.h @@ -28,8 +28,9 @@ #define AA_CLASS_SIGNAL 10 #define AA_CLASS_NET 14 #define AA_CLASS_LABEL 16 +#define AA_CLASS_DISPLAY_LSM 17 -#define AA_CLASS_LAST AA_CLASS_LABEL +#define AA_CLASS_LAST AA_CLASS_DISPLAY_LSM /* Control parameters settable through module/boot flags */ extern enum audit_mode aa_g_audit; diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 432915c1d427..31a6f11890f1 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -612,6 +612,25 @@ static int apparmor_getprocattr(struct task_struct *task, char *name, return error; } + +static int profile_display_lsm(struct aa_profile *profile, + struct common_audit_data *sa) +{ + struct aa_perms perms = { }; + unsigned int state; + + state = PROFILE_MEDIATES(profile, AA_CLASS_DISPLAY_LSM); + if (state) { + aa_compute_perms(profile->policy.dfa, state, &perms); + aa_apply_modes_to_perms(profile, &perms); + aad(sa)->label = &profile->label; + + return aa_check_perms(profile, &perms, AA_MAY_WRITE, sa, NULL); + } + + return 0; +} + static int apparmor_setprocattr(const char *name, void *value, size_t size) { @@ -623,6 +642,19 @@ static int apparmor_setprocattr(const char *name, void *value, if (size == 0) return -EINVAL; + /* LSM infrastructure does actual setting of display if allowed */ + if (!strcmp(name, "display")) { + struct aa_profile *profile; + struct aa_label *label; + + aad(&sa)->info = "set display lsm"; + label = begin_current_label_crit_section(); + error = fn_for_each_confined(label, profile, + profile_display_lsm(profile, &sa)); + end_current_label_crit_section(label); + return error; + } + /* AppArmor requires that the buffer must be null terminated atm */ if (args[size - 1] != '\0') { /* null terminate */ diff --git a/security/security.c b/security/security.c index 78aeb2ae7010..f9d9f68d40cf 100644 --- a/security/security.c +++ b/security/security.c @@ -76,7 +76,16 @@ static struct kmem_cache *lsm_file_cache; static struct kmem_cache *lsm_inode_cache; char *lsm_names; -static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init; + +/* + * The task blob includes the "display" slot used for + * chosing which module presents contexts. + * Using a long to avoid potential alignment issues with + * module assigned task blobs. + */ +static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init = { + .lbs_task = sizeof(long), +}; /* Boot-time LSM user choice */ static __initdata const char *chosen_lsm_order; @@ -471,8 +480,10 @@ static int lsm_append(const char *new, char **result) /* * Current index to use while initializing the lsmblob secid list. + * Pointers to the LSM id structures for local use. */ static int lsm_slot __lsm_ro_after_init; +static struct lsm_id *lsm_slotlist[LSMBLOB_ENTRIES]; /** * security_add_hooks - Add a modules hooks to the hook lists. @@ -492,6 +503,7 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count, if (lsmid->slot == LSMBLOB_NEEDED) { if (lsm_slot >= LSMBLOB_ENTRIES) panic("%s Too many LSMs registered.\n", __func__); + lsm_slotlist[lsm_slot] = lsmid; lsmid->slot = lsm_slot++; init_debug("%s assigned lsmblob slot %d\n", lsmid->lsm, lsmid->slot); @@ -621,6 +633,8 @@ int lsm_inode_alloc(struct inode *inode) */ static int lsm_task_alloc(struct task_struct *task) { + int *display; + if (blob_sizes.lbs_task == 0) { task->security = NULL; return 0; @@ -629,6 +643,15 @@ static int lsm_task_alloc(struct task_struct *task) task->security = kzalloc(blob_sizes.lbs_task, GFP_KERNEL); if (task->security == NULL) return -ENOMEM; + + /* + * The start of the task blob contains the "display" LSM slot number. + * Start with it set to the invalid slot number, indicating that the + * default first registered LSM be displayed. + */ + display = task->security; + *display = LSMBLOB_INVALID; + return 0; } @@ -1629,14 +1652,26 @@ int security_file_open(struct file *file) int security_task_alloc(struct task_struct *task, unsigned long clone_flags) { + int *odisplay = current->security; + int *ndisplay; int rc = lsm_task_alloc(task); - if (rc) + if (unlikely(rc)) return rc; + rc = call_int_hook(task_alloc, 0, task, clone_flags); - if (unlikely(rc)) + if (unlikely(rc)) { security_task_free(task); - return rc; + return rc; + } + + if (odisplay) { + ndisplay = task->security; + if (ndisplay) + *ndisplay = *odisplay; + } + + return 0; } void security_task_free(struct task_struct *task) @@ -2054,23 +2089,110 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name, char **value) { struct security_hook_list *hp; + int display = lsm_task_display(current); + int slot = 0; + + if (!strcmp(name, "display")) { + /* + * lsm_slot will be 0 if there are no displaying modules. + */ + if (lsm_slot == 0) + return -EINVAL; + + /* + * Only allow getting the current process' display. + * There are too few reasons to get another process' + * display and too many LSM policy issues. + */ + if (current != p) + return -EINVAL; + + display = lsm_task_display(p); + if (display != LSMBLOB_INVALID) + slot = display; + *value = kstrdup(lsm_slotlist[slot]->lsm, GFP_KERNEL); + if (*value) + return strlen(*value); + return -ENOMEM; + } hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) { if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm)) continue; + if (lsm == NULL && display != LSMBLOB_INVALID && + display != hp->lsmid->slot) + continue; return hp->hook.getprocattr(p, name, value); } return LSM_RET_DEFAULT(getprocattr); } +/** + * security_setprocattr - Set process attributes via /proc + * @lsm: name of module involved, or NULL + * @name: name of the attribute + * @value: value to set the attribute to + * @size: size of the value + * + * Set the process attribute for the specified security module + * to the specified value. Note that this can only be used to set + * the process attributes for the current, or "self" process. + * The /proc code has already done this check. + * + * Returns 0 on success, an appropriate code otherwise. + */ int security_setprocattr(const char *lsm, const char *name, void *value, size_t size) { struct security_hook_list *hp; + char *termed; + char *copy; + int *display = current->security; + int rc = -EINVAL; + int slot = 0; + + if (!strcmp(name, "display")) { + /* + * Change the "display" value only if all the security + * modules that support setting a procattr allow it. + * It is assumed that all such security modules will be + * cooperative. + */ + if (size == 0) + return -EINVAL; + + hlist_for_each_entry(hp, &security_hook_heads.setprocattr, + list) { + rc = hp->hook.setprocattr(name, value, size); + if (rc < 0) + return rc; + } + + rc = -EINVAL; + + copy = kmemdup_nul(value, size, GFP_KERNEL); + if (copy == NULL) + return -ENOMEM; + + termed = strsep(©, " \n"); + + for (slot = 0; slot < lsm_slot; slot++) + if (!strcmp(termed, lsm_slotlist[slot]->lsm)) { + *display = lsm_slotlist[slot]->slot; + rc = size; + break; + } + + kfree(termed); + return rc; + } hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) { if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm)) continue; + if (lsm == NULL && *display != LSMBLOB_INVALID && + *display != hp->lsmid->slot) + continue; return hp->hook.setprocattr(name, value, size); } return LSM_RET_DEFAULT(setprocattr); @@ -2090,15 +2212,15 @@ EXPORT_SYMBOL(security_ismaclabel); int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) { struct security_hook_list *hp; - int rc; + int display = lsm_task_display(current); 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 != LSM_RET_DEFAULT(secid_to_secctx)) - return rc; + if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) + return hp->hook.secid_to_secctx( + blob->secid[hp->lsmid->slot], + secdata, seclen); } return LSM_RET_DEFAULT(secid_to_secctx); @@ -2109,16 +2231,15 @@ int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob) { struct security_hook_list *hp; - int rc; + int display = lsm_task_display(current); lsmblob_init(blob, 0); hlist_for_each_entry(hp, &security_hook_heads.secctx_to_secid, list) { if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) continue; - rc = hp->hook.secctx_to_secid(secdata, seclen, - &blob->secid[hp->lsmid->slot]); - if (rc != 0) - return rc; + if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) + return hp->hook.secctx_to_secid(secdata, seclen, + &blob->secid[hp->lsmid->slot]); } return 0; } @@ -2126,7 +2247,14 @@ EXPORT_SYMBOL(security_secctx_to_secid); void security_release_secctx(char *secdata, u32 seclen) { - call_void_hook(release_secctx, secdata, seclen); + struct security_hook_list *hp; + int display = lsm_task_display(current); + + hlist_for_each_entry(hp, &security_hook_heads.release_secctx, list) + if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) { + hp->hook.release_secctx(secdata, seclen); + return; + } } EXPORT_SYMBOL(security_release_secctx); @@ -2267,8 +2395,15 @@ EXPORT_SYMBOL(security_sock_rcv_skb); int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, int __user *optlen, unsigned len) { - return call_int_hook(socket_getpeersec_stream, -ENOPROTOOPT, sock, - optval, optlen, len); + int display = lsm_task_display(current); + struct security_hook_list *hp; + + hlist_for_each_entry(hp, &security_hook_heads.socket_getpeersec_stream, + list) + if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) + return hp->hook.socket_getpeersec_stream(sock, optval, + optlen, len); + return -ENOPROTOOPT; } int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 52a50d7ca534..9bfc1eea02de 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6334,6 +6334,17 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) /* * Basic control over ability to set these attributes at all. */ + + /* + * For setting display, we only perform a permission check; + * the actual update to the display value is handled by the + * LSM framework. + */ + if (!strcmp(name, "display")) + return avc_has_perm(&selinux_state, + mysid, mysid, SECCLASS_PROCESS2, + PROCESS2__SETDISPLAY, NULL); + if (!strcmp(name, "exec")) error = avc_has_perm(&selinux_state, mysid, mysid, SECCLASS_PROCESS, diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index 40cebde62856..1858aa47b32a 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -53,7 +53,7 @@ struct security_class_mapping secclass_map[] = { "execmem", "execstack", "execheap", "setkeycreate", "setsockcreate", "getrlimit", NULL } }, { "process2", - { "nnp_transition", "nosuid_transition", NULL } }, + { "nnp_transition", "nosuid_transition", "setdisplay", NULL } }, { "system", { "ipc_info", "syslog_read", "syslog_mod", "syslog_console", "module_request", "module_load", NULL } }, diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index f96be93d1a75..bd03020b3cad 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3509,6 +3509,13 @@ static int smack_setprocattr(const char *name, void *value, size_t size) struct smack_known_list_elem *sklep; int rc; + /* + * Allow the /proc/.../attr/current and SO_PEERSEC "display" + * to be reset at will. + */ + if (strcmp(name, "display") == 0) + return 0; + if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel)) return -EPERM; From patchwork Wed Nov 4 23:41:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882725 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 4A06B174A for ; Wed, 4 Nov 2020 23:58:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 25C9A206CA for ; Wed, 4 Nov 2020 23:58:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="TacPj9Ap" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730179AbgKDX6s (ORCPT ); Wed, 4 Nov 2020 18:58:48 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:33162 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732678AbgKDX5E (ORCPT ); Wed, 4 Nov 2020 18:57:04 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534221; bh=NjD1+KtwElZe56/UGI6PApTnqSE+EEj9ZLVXzNuLfBA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=TacPj9ApVH+EUYrhvYkRyDwcUoWB4r/z2ezYwS6ns2zJCM31poZV0t16JAdi7acv5+NjGXcrpeA9zsRxq3TpupV4ttsa70JjKi5GoMCEJr1j7nxfdhCHEK5CDfUSf+A9mQTyTiI4uDivH/1FjB9ytosqLd87gDAvD8+vlPTO+jdZY1PC4PreHY/91Bq6KK+buM3q9BOWxFqj/19Mqy4a1eVKvIupMr1HRO9BKvF3tEwN8nWw2vGNqdm02GGAtOVlIBIBlJEd20c/B5jKNxHd6wW0OQOEXKECLFYwzF2EFcRiBD12aXVYUfnbVhGvWYIiLoNNkAiy2fpPtoMWtS/LmA== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534221; bh=MdJFTVIwice8z6Qr31BjcYfd6OGiITBBohbEvul5xSK=; h=From:To:Subject:Date; b=VVYOH1ZuV8Gp39UyFQ6qxlimGlRLRprmQqFmICJm6iNTkQDDHmFP7o3D3ZeGi/TlQYYIDd+TpPEBkKL5bbfswmWQ8+LvDKd+TFjD83+Ldm/39oUJ7ybf1mAxayLPnWm7u13mcyL10cYJhZfyjUFG9mG/XxfUkboYBypUVxqiFdlOnSp+OMX3ybK584VqRgT5+j8L8YvyhEe01IFLVV7WNXC0QF3yuhX+Y7UkwcrxfbeOZIPg+2oZ3e2XNY5rCwA2Ww2+A0pCkhuBLYZkFVrDtJAp85A9nKsJJunROkb+wM9fIORKCpjM7rus2fIZCjnlwPJS/PixIftnlKF2SR0sPw== X-YMail-OSG: agIkQ8MVM1l.5pnlaHlRT3CENiUjgSNFPp7zfOkfh7jR.V.U6WTOMPzOL2kcuNX 6QzRoCOkBw5.jmYRuNqTTzgTMFl8RQ.v2bVN4cvF3ZscpUpxPTQjMgMt7wuw8Mp7LmIGMSCql_af kSvc2Wivk_2KN1sNG15GpHINxpvz3Kl.7DB2GTUkCKdJO7H92mw0wDnh8PgfTeL2aH9NB8JQy7A6 i.E.XrsYDZyrUyOC2JVqAZvOoM6DC7IGvUmGcQrYUHqomOzm3Opy247mEsk3pWRSKNLI_wDgydzC 7fs3UbYlsPXdi3uiVl.6d6_9NRozvMrUs0wIIul.v97a9m1fEaWOr.Ao2iwYuDLVNWdWUVCCY9dH qJ3vNbvttso5yaFnA1dl6xVl1n.TSGbsbXNe0D404uTFksALT3Wwwj2sU9r7teMWJDLKqsHeo7Ww wJFnKiO8bB6SnX7LOZrgacP_paYWpNRikGHz3vKA6NBpc3xwJ_gACd._olB79Z0WFtvihL6jHCAl sM89EStGS0_G4nAMBJWcHHaSt7GrlLuzTImBJ4KuRfHwPbfYDRCOtWA2z6_FEkNf8059MwNMNUGR XwzKCuFDMtBRWYhNSPk7mMraH88fr9mcB3Yt6T9HwpbkL2dMBE6B38NHx.Y.wXQGCkeGSFafdBEW XaRjZtkhpQiVsnTEC.se2A0nrXGUnCauxCOgkVkjrzKfCy95CLtusrK5BSTvvqL0PV9wSNrDPD8p 9vsQAOO3cpwJ3ncAKcF2XTEYcBwW8xx8OWJ5JBO66ZJ7WTqe1FxMAn.NIeBM11wpSYFBurcjR6RK DLUFVNdBD20Ifqmh2wyDGGBzXoB7UerohXg8lveyLkL2EzVwqMgroA12E_7R2vpGsHa7nrGhoo2u bBN0MfJdmhuKnyuf8lWOV2iXufSSDrIXxdasRmR7zF5kiC2LqgwxRrs9YxEDlFVNDtlmN5zlcPxL vvqSAC1uT0yESOF39WALZ2icDu7ASvOY2BphlqqYaujDSFfzO7fUmDWfH.4lF5sIQjbPUIWbfQn0 NOIOdjkKdvzufMV.cXEzx2ECQCOdrREGTiy6DuiwFIDP_DXnM_azSBQjU8EHUSx31Q_CBWe9AF8l 9tDIPlIrX8bnUuFxJvKsntcM7epFWMoSziPyPZjb5Q13wENKldgiTP2Tf_LM5yMb9w5CNH8eITgF qXIFjoSJob17B9jGAL5VJKyXmbf0r7YjQGipbS9qX9HVVpXI_AN8U5yhwzQCCagRv0alpp3wz6OA M22vMa.daiR9K.cKEBz7p6BT4vzZra7MiSKLqqc67xY27irdhWCS5vvXn_jZYyvuzxakF334dX36 MttX8lDMEBsCOXXnOmvM5GahQTQ_ygvnAyR3w8y6JVWNQD2SgXSisOYnLAiEM9QH0FapxSpIxxw9 Ce3tzp_ihzsUyz79T_02l.NlDsDj1besOPF3Tfq3xGHIOH92AUtx5lPUob9hWwZmOXrbX09XJLLq Aw3aFml2PrybJe.vFhrg6Afh7LPi_ybX5I_wqZOncaT7F0.Whsv_nhpzzzVL_eyLgjXqQBaN6Cc_ 5UMduR9bnwEZqisRE7vQdTXOYaTfgzyUJdas.lMd6QrT2LL9FKpbAwXx9QKxKzbpcLW2i4x2N.l1 SnX17VG6bIhdjzsh0W1QAzerx.DRaZkpjTT8ukiC0GYxzjLKOzWOfdvclXcz0g9puzqHtJ.rodmE E8GKh9GkWSL_dsRpvPMoGyp6sqtR_WYqYImTFaCodGrR9cGdKHwbkndXja_Yeue792pr06.9gY2l nHi9jqeh6HigDaLaLoIdEeqjhgeDrWtI7e4Xdsy.ABHz0kTa6vel9kOTmYoQfSMX1SqrPTG30gHN LyhF8HBlbgqJO0pwjSFH_kyvRmxHtLowALkhjunoTZJE1nnTTlCIHfyC8Zm0_zJIUA1PrhDI4Kl9 GJdoy9Vot3QTwprJkwQ28r6JWFB.dLH_t5lVVMChdMR4.FwZglwuaEkZjTS3_Q.y3fIu2YiwZqoZ HJ1_wiHFoAKqukHgVJceA7P7XZixDRyM6Vl5cPdkmw.gHCs70iRYuy6TyIVXxVMwuqVdjHXW_7AJ 8c2paT7AjYxwa6ED..8ovYJO.p4mk7jxlb_VQmwYRwqK5o07f_Cfok9BKAe2yVX8uoY2XBOenRXF 1kBSYdZQn1bIhWzFsb_AfmCBllvU9jos96GF5vXP63Q4qJVVTTDMQ2k06DXqHLJHDPWt6aX3Xa12 x3u.KB3Idv5Jr3ZdfRzFo4iWao2JeoSUDVDp.pDxIVGQbESBcr40Fa20uuffCQ.C8uYCsdhCYOCc 2.3bXTxYsrVYk3qsqPC4CICDYP2A_R2LTQos_9hartcEAo6J6CWfhgCE05U4luG4w5QVbQrD7zfe Bq0V_n1HVkf3vJsFVb5IRFJDKkx7._tXrO5XfMo4VEO5xCLaj5I6l0jgafonHH_Mg2dwGmPvK5om I6xYK.hZ8oPs7nzjePHjZGH9wSEK6ELBXqeB_E98zroysZYA5DLn7ldPa0hO9gc9u3M08ysauuUm gc5dKaAxwkPriU8c9_8H0wJ7NvTju1Xkjd6utJ1AWlobHN8b9Z2ioDUhGQOHv5lmPu2dmXvv0uiv A5usJbFLH84Kgt8or2R7Sag.daz2U1NAZN_0FqbzfgsM0etii7WH2pabodH67CtT0CBOx.0z4BuH X8PjspK_ahjaAeEeV3R9ItcuQR03Ws3..1l3cP7YJJeQBRzq8D_XdKqK2WkenqObPhVfNAz1GGyk LeaKFS60MXC5tQVZkz6cmUNtYbD_HDtZzZR6zokq10cvx5b3WpyRNgVvLYRwXHKQEPO24KOwfQsy 9KYqltzQCN5h7dpXbsK6amfbTR1X4O594.jJYCz6PM3k97D2NC20mPbPcERNpsVpd1dN3PW5ixAG yWvwoX_TofDzcU4Ss26bki2hANGA8iA3fIaE4d9GzlUGJGoU_BQXg8RthLshSASQuZ.Cb1tYKnZr 3_OS2dYeXADbGCsXaKviBxKPGwKmppRYe2Noj6zizn_4ESmnxm5e1S1Wme3OLiVoZeRpSZygJ5JU Cs.lv1TUn0WRh9eUlukui5bD.Ugj4IoW5MtcuA7JKXOUTcNOmHfhqmIttpsdFkaOw54.aa_Rv82g pABt3WTVFL_toqPY2ZxRFTcomQ9ENkRTlDDpczChCe8UI2Tchk7dSfW.VEaN3XsKamRaCP9E5sWK HTfGJYB3slNA0ufc6Ov8z08H9NRroPZsGE5PHNtaMogcPRDplZ0wyhOSStaaLF6NlKd4ub0WQseX CyIXGzLDxD3xmBb9ktnJFbrFX.04I63BQ3_Wnflg7_D6FSk5Rvvu3HZ.01y6wEGkRQ6pPCi4EZlx 8iF4Xf4jiR1Yzqk9VsftyLabO8sco2gOyjyugGOXzwKT2W7BTfv8GoVu0gd1ApC7u2mBTHV27DWL LiwZ3i5PkTpp7.b93r9MKo2hE3Od.PkeFWLzpYtwNYWLUUfhfRg8kVurQ2OFAgRegFw-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:57:01 +0000 Received: by smtp404.mail.ne1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID d10307ef7e6d7a3eff163ccc4c899d4e; Wed, 04 Nov 2020 23:56:59 +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, linux-integrity@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v22 13/23] LSM: Ensure the correct LSM context releaser Date: Wed, 4 Nov 2020 15:41:04 -0800 Message-Id: <20201104234114.11346-14-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: Add a new lsmcontext data structure to hold all the information about a "security context", including the string, its size and which LSM allocated the string. The allocation information is necessary because LSMs have different policies regarding the lifecycle of these strings. SELinux allocates and destroys them on each use, whereas Smack provides a pointer to an entry in a list that never goes away. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com --- drivers/android/binder.c | 10 ++++--- fs/ceph/xattr.c | 6 ++++- fs/nfs/nfs4proc.c | 8 ++++-- fs/nfsd/nfs4xdr.c | 7 +++-- include/linux/security.h | 35 +++++++++++++++++++++++-- include/net/scm.h | 5 +++- kernel/audit.c | 14 +++++++--- kernel/auditsc.c | 12 ++++++--- net/ipv4/ip_sockglue.c | 4 ++- net/netfilter/nf_conntrack_netlink.c | 4 ++- net/netfilter/nf_conntrack_standalone.c | 4 ++- net/netfilter/nfnetlink_queue.c | 13 ++++++--- net/netlabel/netlabel_unlabeled.c | 19 +++++++++++--- net/netlabel/netlabel_user.c | 4 ++- security/security.c | 11 ++++---- 15 files changed, 121 insertions(+), 35 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 08737a07f997..05266b064c38 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2838,6 +2838,7 @@ static void binder_transaction(struct binder_proc *proc, int t_debug_id = atomic_inc_return(&binder_last_id); char *secctx = NULL; u32 secctx_sz = 0; + struct lsmcontext scaff; /* scaffolding */ e = binder_transaction_log_add(&binder_transaction_log); e->debug_id = t_debug_id; @@ -3140,7 +3141,8 @@ static void binder_transaction(struct binder_proc *proc, t->security_ctx = 0; WARN_ON(1); } - security_release_secctx(secctx, secctx_sz); + lsmcontext_init(&scaff, secctx, secctx_sz, 0); + security_release_secctx(&scaff); secctx = NULL; } t->buffer->debug_id = t->debug_id; @@ -3473,8 +3475,10 @@ static void binder_transaction(struct binder_proc *proc, binder_alloc_free_buf(&target_proc->alloc, t->buffer); err_binder_alloc_buf_failed: err_bad_extra_size: - if (secctx) - security_release_secctx(secctx, secctx_sz); + if (secctx) { + lsmcontext_init(&scaff, secctx, secctx_sz, 0); + security_release_secctx(&scaff); + } err_get_secctx_failed: kfree(tcomplete); binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 197cb1234341..5dfd08357dc3 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1273,12 +1273,16 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode, void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx) { +#ifdef CONFIG_CEPH_FS_SECURITY_LABEL + struct lsmcontext scaff; /* scaffolding */ +#endif #ifdef CONFIG_CEPH_FS_POSIX_ACL posix_acl_release(as_ctx->acl); posix_acl_release(as_ctx->default_acl); #endif #ifdef CONFIG_CEPH_FS_SECURITY_LABEL - security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen); + lsmcontext_init(&scaff, as_ctx->sec_ctx, as_ctx->sec_ctxlen, 0); + security_release_secctx(&scaff); #endif if (as_ctx->pagelist) ceph_pagelist_release(as_ctx->pagelist); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 9e0ca9b2b210..4b03a3e596e9 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -139,8 +139,12 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry, static inline void nfs4_label_release_security(struct nfs4_label *label) { - if (label) - security_release_secctx(label->label, label->len); + struct lsmcontext scaff; /* scaffolding */ + + if (label) { + lsmcontext_init(&scaff, label->label, label->len, 0); + security_release_secctx(&scaff); + } } static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label) { diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 833a2c64dfe8..4ae7e156ea87 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2717,6 +2717,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, int err; struct nfs4_acl *acl = NULL; #ifdef CONFIG_NFSD_V4_SECURITY_LABEL + struct lsmcontext scaff; /* scaffolding */ void *context = NULL; int contextlen; #endif @@ -3228,8 +3229,10 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, out: #ifdef CONFIG_NFSD_V4_SECURITY_LABEL - if (context) - security_release_secctx(context, contextlen); + if (context) { + lsmcontext_init(&scaff, context, contextlen, 0); /*scaffolding*/ + security_release_secctx(&scaff); + } #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ kfree(acl); if (tempfh) { diff --git a/include/linux/security.h b/include/linux/security.h index dacd64d2d141..4ed7a0790cc5 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -132,6 +132,37 @@ enum lockdown_reason { extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1]; +/* + * A "security context" is the text representation of + * the information used by LSMs. + * This structure contains the string, its length, and which LSM + * it is useful for. + */ +struct lsmcontext { + char *context; /* Provided by the module */ + u32 len; + int slot; /* Identifies the module */ +}; + +/** + * lsmcontext_init - initialize an lsmcontext structure. + * @cp: Pointer to the context to initialize + * @context: Initial context, or NULL + * @size: Size of context, or 0 + * @slot: Which LSM provided the context + * + * Fill in the lsmcontext from the provided information. + * This is a scaffolding function that will be removed when + * lsmcontext integration is complete. + */ +static inline void lsmcontext_init(struct lsmcontext *cp, char *context, + u32 size, int slot) +{ + cp->slot = slot; + cp->context = context; + cp->len = size; +} + /* * Data exported by the security modules * @@ -531,7 +562,7 @@ int security_ismaclabel(const char *name); 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); +void security_release_secctx(struct lsmcontext *cp); void security_inode_invalidate_secctx(struct inode *inode); int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); @@ -1366,7 +1397,7 @@ static inline int security_secctx_to_secid(const char *secdata, return -EOPNOTSUPP; } -static inline void security_release_secctx(char *secdata, u32 seclen) +static inline void security_release_secctx(struct lsmcontext *cp) { } diff --git a/include/net/scm.h b/include/net/scm.h index 23a35ff1b3f2..f273c4d777ec 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -92,6 +92,7 @@ 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 lsmcontext context; struct lsmblob lb; char *secdata; u32 seclen; @@ -106,7 +107,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); - security_release_secctx(secdata, seclen); + /*scaffolding*/ + lsmcontext_init(&context, secdata, seclen, 0); + security_release_secctx(&context); } } } diff --git a/kernel/audit.c b/kernel/audit.c index 1f987ac23e90..8867df3de920 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1192,6 +1192,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) struct audit_sig_info *sig_data; char *ctx = NULL; u32 len; + struct lsmcontext scaff; /* scaffolding */ err = audit_netlink_ok(skb, msg_type); if (err) @@ -1449,15 +1450,18 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) } sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); if (!sig_data) { - if (lsmblob_is_set(&audit_sig_lsm)) - security_release_secctx(ctx, len); + if (lsmblob_is_set(&audit_sig_lsm)) { + lsmcontext_init(&scaff, ctx, len, 0); + security_release_secctx(&scaff); + } return -ENOMEM; } sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid); sig_data->pid = audit_sig_pid; if (lsmblob_is_set(&audit_sig_lsm)) { memcpy(sig_data->ctx, ctx, len); - security_release_secctx(ctx, len); + lsmcontext_init(&scaff, ctx, len, 0); + security_release_secctx(&scaff); } audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, sig_data, sizeof(*sig_data) + len); @@ -2129,6 +2133,7 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; struct lsmblob blob; + struct lsmcontext scaff; /* scaffolding */ security_task_getsecid(current, &blob); if (!lsmblob_is_set(&blob)) @@ -2142,7 +2147,8 @@ int audit_log_task_context(struct audit_buffer *ab) } audit_log_format(ab, " subj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&scaff, ctx, len, 0); + security_release_secctx(&scaff); return 0; error_path: diff --git a/kernel/auditsc.c b/kernel/auditsc.c index b15222181700..2b06171bedeb 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -998,6 +998,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, struct lsmblob *blob, char *comm) { struct audit_buffer *ab; + struct lsmcontext lsmcxt; char *ctx = NULL; u32 len; int rc = 0; @@ -1015,7 +1016,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, rc = 1; } else { audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&lsmcxt, ctx, len, 0); /*scaffolding*/ + security_release_secctx(&lsmcxt); } } audit_log_format(ab, " ocomm="); @@ -1228,6 +1230,7 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) static void show_special(struct audit_context *context, int *call_panic) { + struct lsmcontext lsmcxt; struct audit_buffer *ab; int i; @@ -1261,7 +1264,8 @@ static void show_special(struct audit_context *context, int *call_panic) *call_panic = 1; } else { audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&lsmcxt, ctx, len, 0); + security_release_secctx(&lsmcxt); } } if (context->ipc.has_perm) { @@ -1407,6 +1411,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, char *ctx = NULL; u32 len; struct lsmblob blob; + struct lsmcontext lsmcxt; lsmblob_init(&blob, n->osid); if (security_secid_to_secctx(&blob, &ctx, &len)) { @@ -1415,7 +1420,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, *call_panic = 2; } else { audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); + lsmcontext_init(&lsmcxt, ctx, len, 0); /* scaffolding */ + security_release_secctx(&lsmcxt); } } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 2f089733ada7..a7e4c1b34b6c 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 lsmcontext context; struct lsmblob lb; char *secdata; u32 seclen, secid; @@ -145,7 +146,8 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) return; put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata); - security_release_secctx(secdata, seclen); + lsmcontext_init(&context, secdata, seclen, 0); /* scaffolding */ + security_release_secctx(&context); } static void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb) diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 8627ec7e13fb..5d2784461798 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -334,6 +334,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) int len, ret; char *secctx; struct lsmblob blob; + struct lsmcontext context; /* lsmblob_init() puts ct->secmark into all of the secids in blob. * security_secid_to_secctx() will know which security module @@ -354,7 +355,8 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) ret = 0; nla_put_failure: - security_release_secctx(secctx, len); + lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ + security_release_secctx(&context); return ret; } #else diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 54da1a3e8cb1..e2bdc851a477 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -176,6 +176,7 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) u32 len; char *secctx; struct lsmblob blob; + struct lsmcontext context; lsmblob_init(&blob, ct->secmark); ret = security_secid_to_secctx(&blob, &secctx, &len); @@ -184,7 +185,8 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) seq_printf(s, "secctx=%s ", secctx); - security_release_secctx(secctx, len); + lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ + security_release_secctx(&context); } #else static inline void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index a6dbef71fc32..dcc31cb7f287 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -398,6 +398,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, enum ip_conntrack_info ctinfo; struct nfnl_ct_hook *nfnl_ct; bool csum_verify; + struct lsmcontext scaff; /* scaffolding */ char *secdata = NULL; u32 seclen = 0; @@ -628,8 +629,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } nlh->nlmsg_len = skb->len; - if (seclen) - security_release_secctx(secdata, seclen); + if (seclen) { + lsmcontext_init(&scaff, secdata, seclen, 0); + security_release_secctx(&scaff); + } return skb; nla_put_failure: @@ -637,8 +640,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, kfree_skb(skb); net_err_ratelimited("nf_queue: error creating packet message\n"); nlmsg_failure: - if (seclen) - security_release_secctx(secdata, seclen); + if (seclen) { + lsmcontext_init(&scaff, secdata, seclen, 0); + security_release_secctx(&scaff); + } return NULL; } diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 94071f67e461..3e06efe29cfa 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -374,6 +374,7 @@ int netlbl_unlhsh_add(struct net *net, struct net_device *dev; struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; + struct lsmcontext context; char *secctx = NULL; u32 secctx_len; struct lsmblob blob; @@ -447,7 +448,9 @@ int netlbl_unlhsh_add(struct net *net, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); audit_log_end(audit_buf); @@ -478,6 +481,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct netlbl_unlhsh_addr4 *entry; struct audit_buffer *audit_buf; struct net_device *dev; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -509,7 +513,9 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); audit_log_end(audit_buf); @@ -546,6 +552,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct netlbl_unlhsh_addr6 *entry; struct audit_buffer *audit_buf; struct net_device *dev; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -576,7 +583,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); - security_release_secctx(secctx, secctx_len); + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); audit_log_end(audit_buf); @@ -1095,6 +1103,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, int ret_val = -ENOMEM; struct netlbl_unlhsh_walk_arg *cb_arg = arg; struct net_device *dev; + struct lsmcontext context; void *data; u32 secid; char *secctx; @@ -1165,7 +1174,9 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, NLBL_UNLABEL_A_SECCTX, secctx_len, secctx); - security_release_secctx(secctx, secctx_len); + /* scaffolding */ + lsmcontext_init(&context, secctx, secctx_len, 0); + security_release_secctx(&context); if (ret_val != 0) goto list_cb_failure; diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 893301ae0131..ef139d8ae7cd 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -84,6 +84,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, struct netlbl_audit *audit_info) { struct audit_buffer *audit_buf; + struct lsmcontext context; char *secctx; u32 secctx_len; struct lsmblob blob; @@ -103,7 +104,8 @@ struct audit_buffer *netlbl_audit_start_common(int type, if (audit_info->secid != 0 && security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " subj=%s", secctx); - security_release_secctx(secctx, secctx_len); + lsmcontext_init(&context, secctx, secctx_len, 0);/*scaffolding*/ + security_release_secctx(&context); } return audit_buf; diff --git a/security/security.c b/security/security.c index f9d9f68d40cf..9107ca5a6af3 100644 --- a/security/security.c +++ b/security/security.c @@ -2245,16 +2245,17 @@ int security_secctx_to_secid(const char *secdata, u32 seclen, } EXPORT_SYMBOL(security_secctx_to_secid); -void security_release_secctx(char *secdata, u32 seclen) +void security_release_secctx(struct lsmcontext *cp) { struct security_hook_list *hp; - int display = lsm_task_display(current); hlist_for_each_entry(hp, &security_hook_heads.release_secctx, list) - if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) { - hp->hook.release_secctx(secdata, seclen); - return; + if (cp->slot == hp->lsmid->slot) { + hp->hook.release_secctx(cp->context, cp->len); + break; } + + memset(cp, 0, sizeof(*cp)); } EXPORT_SYMBOL(security_release_secctx); From patchwork Wed Nov 4 23:41:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11882719 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 EE480174A for ; Wed, 4 Nov 2020 23:58:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BE5A1206CA for ; Wed, 4 Nov 2020 23:58:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="aZ4zBTGZ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732768AbgKDX6e (ORCPT ); Wed, 4 Nov 2020 18:58:34 -0500 Received: from sonic301-38.consmr.mail.ne1.yahoo.com ([66.163.184.207]:39209 "EHLO sonic301-38.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387693AbgKDX6N (ORCPT ); Wed, 4 Nov 2020 18:58:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534290; bh=RhDyTRIUUvKNSYKelEuTITA9CN5VF/9jr5GLz/2ip2o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=aZ4zBTGZgg1m3MMEBn6o0upk7HTkMhInWaMHPB+kHOjIgv+XIZnzTUhTY0+7UIfEUVq09wZCD/bmNK0epbiPsyXzruUVvkSbhfOrrpiyVqW9dX2WSCJQtt2Vn/KQd5ZW3c1TJ183OuECbqEWfpcHs1TjnJCexWcVjxWaVyFqeIYq7in8jPjVzY9prmPPVLrL6GGPyE2JM8PZoT/SNG30EkzMyWJEK99Li0VtQ15q1s1zmbMxA8eyMXLHzvSS9ihLjsqvU12YCiLWVBtMHwnC5l41R8XH9+iAU7TIzKZpmWGXfoHqpZ6O24wgW3Ata5paXH228ECk2Qa/3ChmmAYxXw== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1604534290; bh=lQGd0BcZGYtqgVxtWlSl6QnZLTOX4pQdSmJHCOFdylJ=; h=From:To:Subject:Date; b=MjIkUvkisdvf6IRzIOTFAmza/+jvwGUe1OkEYF2bjw66S5FHSnN/W6ouwhZt0w95x1iYiH3d+izAv4bLPovjmDPqaGqGDduEgff0ox8497jAFhrS7rtHhUc/AYMSgRRN+gTPCOr6ITnPBYrPbIhAw1xDV+H/4bHIg4rBFAKya9VyLCrTGtNoy9gBVIhIDvGzH+UBveUS6pYSbqoKMGRRvxdRLUk9Hr9iz1kMjS8EJcaF2nJxgX9PK+QiGOlgJVdzsOhk4l/pOASGgHBS2WJN4pGc0nT0VVpurpjKgxx/zKGISJKDFSkcmho2l8pV8Jh5id8hv/Tij8ub3aXqAuzEpA== X-YMail-OSG: cCaCev4VM1kK3p1bU1FRbahaBTqsJF3jB62BO6Pqq8rltXYqiG4LKxSiSCXcF45 6iyEol7HM5meV3ZzApteiC3IxnKClQcUQ0muEIN54Qlrg0Ce0Pcdj08l.boonZUy6SA9onOcDOFI MnOXcMvyW9rm6v0BUnPJ1PF95Tha7y1.di0rXwyAnv_MWjRAdwNzHRnzALlzzBLIm482bHu7QXEQ BVbY3DmvqAgMuYHxJpPhZyAM81fag_d1_eiq3Kam9lhJjKbquGTEwi1hc4.3PxxoH1CPzrSXJv94 2PUv2uMg_7w2QEbxeb58Iig5NQw3SFaAa.nJmYu_efqAWYkYZ5YNokHoMZQhhXqHGCsJAtHoNnHx U1rprwjGUgMYtpOPuZrSPKqfHKomXYHQIV29sRBgzRzQR32gF7oFEfxJL_6TVQsCQB8Glwcz9nMI ZO5hL9cFNwxVez4B7aKtNtIJEfEPrgBfEGL.QXUyxmCZd3BIRFtYgJHVLnAmGYLGNyfm8qrlx0Ve mz0_gcxIKpB_ht4enYj.TEjUyp507HPw4SSAgY7YXgGobedT2oa5MeUWKscOM3QtPIM6zEwAUhN4 oTczL1akAC5l1bBXMKyoYhT3m.1gw3jKtmshGVE.vv7FgLFo2Tap2cmvAXCFYSS6L_TXJgaOCTXV sw__LppMFKd1vcwrtw5QrwxcJUBdoShvCZWf7QkxKvFxwXx5SyzRqDSvZFDGEspTDiNk0sVbb6GX 9Kz_B7Svku7_ks7WdNhJcpRsyw.4QGgmEbbazKULoOadV5qMxOBET37uiIgJgnY7Sf1zbdVPxrwy hot3LvvoW2gXWKNtrOZaTuDLLzSzRFZtY0F4jh_tA6S1Bbb041I6cAUO0FR0Vl.21iMxDPTTBznk VaWNkRON.stc5cBkqEnzThDT4eijz__W6eyMnrlXghYScY6.h.tBLH10xrSLo45eWj3x4KAwYE6w NDUSh2sWpARo0Sx8xSf.ajz3ikxQhuy4GpezP1X_MpSuDcmSY2_3lg_aHnI_fP8o0UiVjHPhfBNL VHMNfZFlo9.zn2tAXjicionIRxtNh_NmpnA_F74pETmVIjUSqi5YHvsbSpXVVYPOtC7c7x7SIPjM Ofn0Zytg3NPx9T5.FigvCxQPfpRfYCR0KJ7aZWKgtE3I3AuWMIg0AO2y7xRbEvxr4vNYHRLoUjBj .ILsG7Dn2dB3uxYGoWsP35N9VBfxulTAnJ9fzzO5lQvB5NEZ5iCeIeGhCvS2d6iDx.vbn.xplZD1 I.JfKECYEHDLGtMAg1PwJ479drG2mg3pdJDN357ZhetmQdi2PMKyrPmY07qPEBrQeECLCQ_NwJ8I dtp304mlOKjER9EABPJdTBrMeoCytoRdUKhxtKdSS7X8eH75Jtd5rIUxBVnyzn7rigtXp5xVj3Sb t.XMIiLO27mPZCPJx8wTc_kdfH35NzynMXrH8NtKNPKo5p_uayTBglWEgYRHsw4C3DnjoJdUa0E_ YErK5lRzf5fN.d6XmJHqbAf2e1VxwXSw9KIBOzKjPawTM3eKqCOOX6fYgb3Q_DwNIbcM9pSjgbJh kIAp_IiWxuuZbslN_JcGkCXFQLIirg7psbghvJ1wpaGB4VQFs9jD4VxbUPquTldrUPBtZM3HyNVR nZbIzlg0AvcvFYxUZgD281hY_1SLJqbK46XoHief5w1v0rjFAgIyABmEZLv0.NfPsmBt.Zoe0Byt axB4Q.bPssl8aIRvqjHOowBz1W0sR6XdcjChON1NtNBA.pj6SczKT56w5ZKLKhlAAiCjPENwDJIn agLDHHR.Exm4kdQha2TDl4oJpGkRo7aK.NhsjvqksOVpuUYImDfDqvbfOTnabZB5G1kEoamDPnXs bqU4caLbWyBkeOSqWv6S0gUv4qIX70xpOabM46SFjHwZPXAtj5iBpbUyqGdw.itzIrSL3aq2w3Hk j_0czHsxqhYKjVJfCvgOp5lJcbWSbFWNKZAbDb7g4v0Ntsep5tSX9Yl9cQ32_lv8B73Zdo_K78IC JRwV5xhAZzYjI1cjXI1z3YxVsx2Ny58ckAtXlSS9fZzZZo4n71GuCsKburapExAYE1V6FlSl8Wfk viid8oXx13SIQGWAsUym7q4w8BoszKnarloctl2hI7ujf7W4lLNs.scF_9dLGOoDT8Cz1KbmrSEh Cc0gUj4dNV6ED4Xm2YyaCbGxKz6YXuStn3nFy_QYD7iP3IX.IpTp1nq1.J3eNgZxFjQj4WHk4Aoq pk1WBmSNRHnDx0BelrAns_H9BDt7TUYYyt2p9yeiJ0G_.OGu07t5mk0pMXLHvIVhh7dQIkxnlRlV aTrdqZQz5K_4h.A01ydBbH078c4ZEnuqznDp_HIRYkFu74MKyYapUazt5oHK8f4RDJ0UmpAbrPpR 8NhPV.sQpMlqIvKMl2r7jxgK9nMSHoltbUcdMceQZZubFZAGulIUvBeyQsdT4Uq_N74aONfizum3 wn13mCFfZ1dPTmc_txCz7.7XMZLK9zqFZ8hnzGNbTalcTewuUsOFZxxqxYje57slegadZe9HVZFe WnSrvrYbZThoJLkbqzfDI0twv.Ks_lGbIi4Ie49HhPydSWE3gn.xY5hxB6qqmzj8wV7cvuhVi6lw QfJ5vntsaDNc2lvzUYBZpg7NOfXiuosnfVdrq3lqmIGCK2G8pGrgZSk5oHbx84SUi_tpArTw15ND G8GEd.fa39EzFZWORM6MnoEFJTyMSwPpcRHbk43PlqwOtXxAthwBaBwuhIxLXDPgGBCreopbxjj6 lSy7_MKEcdtSbebhzdG2FE9_aCla8hJwVJD5eTPmlebHftlsIo4lDwNmkWUSqPK.DKfYyJIV7LP9 wLwM2zEJkvYlVpAA71mTS4PlddRW1ZcV99nRt3EGAHaQXFItg6lZASNaFY9cCqSyOoiS2o9rxZYP BsfPlvDhtzKn9OmK4L_Gg4k8DLefFDav5.8JdpEy_OjLydXo9miOEFFqEH82XWMwuzzzjCSJmCfj 0e5h.fuZXm0U5jMqMNYT6Ms4CtHyj3QPjPi3tLmxwjho5arvSwCFb8.8nKZQeJOQhWlHlWtVfGxZ 3nFZzP340jHNsvJeIPmh_cvK88h29eNTU.QjRTwk1ESjbWqFXF3NKL3LQuFbd1C8eAOFpmTTRqaP FGVuGaf9_6xct6r__LzTJDInvazqyWy0Nw3YDua0V24P_BpqHuuFiDDod9ud7cGsR.2OtimTNWdU 1MLpvJtkRBFfAryhUXYd6mzAVR.7sfDUregHEMuSVc9erNtwghXLBWr8Q77_GJPMR29ckign0zQ4 tuI2dtvDwu2ccCQgs5cnPr6IHBuqmH62Hx.Brrehry59ZvZ7GAFx5bpfR2XSaOylG7A52WilYhky cxrQQ4_qo9Gml9NcNXUrR33l3uWuW94BJ3M4UyywP6fN9DMHRp6ZNNUpJ7ypE Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.ne1.yahoo.com with HTTP; Wed, 4 Nov 2020 23:58:10 +0000 Received: by smtp421.mail.bf1.yahoo.com (VZM Hermes SMTP Server) with ESMTPA ID 747a85aac485fd10d2f221e176742fa9; Wed, 04 Nov 2020 23:58:06 +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 Subject: [PATCH v22 14/23] LSM: Use lsmcontext in security_secid_to_secctx Date: Wed, 4 Nov 2020 15:41:05 -0800 Message-Id: <20201104234114.11346-15-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20201104234114.11346-1-casey@schaufler-ca.com> References: <20201104234114.11346-1-casey@schaufler-ca.com> MIME-Version: 1.0 Precedence: bulk List-ID: Replace the (secctx,seclen) pointer pair with a single lsmcontext pointer to allow return of the LSM identifier along with the context and context length. This allows security_release_secctx() to know how to release the context. Callers have been modified to use or save the returned data from the new structure. Reviewed-by: Kees Cook Acked-by: Stephen Smalley Acked-by: Paul Moore Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com --- drivers/android/binder.c | 26 +++++++--------- include/linux/security.h | 4 +-- include/net/scm.h | 9 ++---- kernel/audit.c | 39 +++++++++++------------- kernel/auditsc.c | 31 +++++++------------ net/ipv4/ip_sockglue.c | 8 ++--- net/netfilter/nf_conntrack_netlink.c | 18 +++++------ net/netfilter/nf_conntrack_standalone.c | 7 ++--- net/netfilter/nfnetlink_queue.c | 5 +++- net/netlabel/netlabel_unlabeled.c | 40 ++++++++----------------- net/netlabel/netlabel_user.c | 7 ++--- security/security.c | 10 +++++-- 12 files changed, 81 insertions(+), 123 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 05266b064c38..a75ffcd0270a 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2836,9 +2836,7 @@ static void binder_transaction(struct binder_proc *proc, binder_size_t last_fixup_min_off = 0; struct binder_context *context = proc->context; int t_debug_id = atomic_inc_return(&binder_last_id); - char *secctx = NULL; - u32 secctx_sz = 0; - struct lsmcontext scaff; /* scaffolding */ + struct lsmcontext lsmctx = { }; e = binder_transaction_log_add(&binder_transaction_log); e->debug_id = t_debug_id; @@ -3092,14 +3090,14 @@ static void binder_transaction(struct binder_proc *proc, size_t added_size; security_task_getsecid(proc->tsk, &blob); - ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); + ret = security_secid_to_secctx(&blob, &lsmctx); if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; return_error_line = __LINE__; goto err_get_secctx_failed; } - added_size = ALIGN(secctx_sz, sizeof(u64)); + added_size = ALIGN(lsmctx.len, sizeof(u64)); extra_buffers_size += added_size; if (extra_buffers_size < added_size) { /* integer overflow of extra_buffers_size */ @@ -3126,24 +3124,22 @@ static void binder_transaction(struct binder_proc *proc, t->buffer = NULL; goto err_binder_alloc_buf_failed; } - if (secctx) { + if (lsmctx.context) { int err; size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) + ALIGN(tr->offsets_size, sizeof(void *)) + ALIGN(extra_buffers_size, sizeof(void *)) - - ALIGN(secctx_sz, sizeof(u64)); + ALIGN(lsmctx.len, sizeof(u64)); t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset; err = binder_alloc_copy_to_buffer(&target_proc->alloc, t->buffer, buf_offset, - secctx, secctx_sz); + lsmctx.context, lsmctx.len); if (err) { t->security_ctx = 0; WARN_ON(1); } - lsmcontext_init(&scaff, secctx, secctx_sz, 0); - security_release_secctx(&scaff); - secctx = NULL; + security_release_secctx(&lsmctx); } t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; @@ -3199,7 +3195,7 @@ static void binder_transaction(struct binder_proc *proc, off_end_offset = off_start_offset + tr->offsets_size; sg_buf_offset = ALIGN(off_end_offset, sizeof(void *)); sg_buf_end_offset = sg_buf_offset + extra_buffers_size - - ALIGN(secctx_sz, sizeof(u64)); + ALIGN(lsmctx.len, sizeof(u64)); off_min = 0; for (buffer_offset = off_start_offset; buffer_offset < off_end_offset; buffer_offset += sizeof(binder_size_t)) { @@ -3475,10 +3471,8 @@ static void binder_transaction(struct binder_proc *proc, binder_alloc_free_buf(&target_proc->alloc, t->buffer); err_binder_alloc_buf_failed: err_bad_extra_size: - if (secctx) { - lsmcontext_init(&scaff, secctx, secctx_sz, 0); - security_release_secctx(&scaff); - } + if (lsmctx.context) + security_release_secctx(&lsmctx); err_get_secctx_failed: kfree(tcomplete); binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); diff --git a/include/linux/security.h b/include/linux/security.h index 4ed7a0790cc5..c86c9870b352 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -559,7 +559,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(struct lsmblob *blob, char **secdata, u32 *seclen); +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); void security_release_secctx(struct lsmcontext *cp); @@ -1385,7 +1385,7 @@ static inline int security_ismaclabel(const char *name) } static inline int security_secid_to_secctx(struct lsmblob *blob, - char **secdata, u32 *seclen) + struct lsmcontext *cp) { return -EOPNOTSUPP; } diff --git a/include/net/scm.h b/include/net/scm.h index f273c4d777ec..b77a52f93389 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -94,8 +94,6 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc { struct lsmcontext context; struct lsmblob lb; - char *secdata; - u32 seclen; int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { @@ -103,12 +101,11 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc * and the infrastructure will know which it is. */ lsmblob_init(&lb, scm->secid); - err = security_secid_to_secctx(&lb, &secdata, &seclen); + err = security_secid_to_secctx(&lb, &context); if (!err) { - put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); - /*scaffolding*/ - lsmcontext_init(&context, secdata, seclen, 0); + put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, context.len, + context.context); security_release_secctx(&context); } } diff --git a/kernel/audit.c b/kernel/audit.c index 8867df3de920..4e219d1c1781 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1190,9 +1190,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) struct audit_buffer *ab; u16 msg_type = nlh->nlmsg_type; struct audit_sig_info *sig_data; - char *ctx = NULL; - u32 len; - struct lsmcontext scaff; /* scaffolding */ err = audit_netlink_ok(skb, msg_type); if (err) @@ -1440,33 +1437,34 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) kfree(new); break; } - case AUDIT_SIGNAL_INFO: - len = 0; + case AUDIT_SIGNAL_INFO: { + struct lsmcontext context = { }; + int len = 0; + if (lsmblob_is_set(&audit_sig_lsm)) { - err = security_secid_to_secctx(&audit_sig_lsm, &ctx, - &len); + err = security_secid_to_secctx(&audit_sig_lsm, + &context); if (err) return err; } - sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); + sig_data = kmalloc(sizeof(*sig_data) + context.len, GFP_KERNEL); if (!sig_data) { - if (lsmblob_is_set(&audit_sig_lsm)) { - lsmcontext_init(&scaff, ctx, len, 0); - security_release_secctx(&scaff); - } + if (lsmblob_is_set(&audit_sig_lsm)) + security_release_secctx(&context); return -ENOMEM; } sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid); sig_data->pid = audit_sig_pid; if (lsmblob_is_set(&audit_sig_lsm)) { - memcpy(sig_data->ctx, ctx, len); - lsmcontext_init(&scaff, ctx, len, 0); - security_release_secctx(&scaff); + len = context.len; + memcpy(sig_data->ctx, context.context, len); + security_release_secctx(&context); } audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, sig_data, sizeof(*sig_data) + len); kfree(sig_data); break; + } case AUDIT_TTY_GET: { struct audit_tty_status s; unsigned int t; @@ -2129,26 +2127,23 @@ void audit_log_key(struct audit_buffer *ab, char *key) int audit_log_task_context(struct audit_buffer *ab) { - char *ctx = NULL; - unsigned len; int error; struct lsmblob blob; - struct lsmcontext scaff; /* scaffolding */ + struct lsmcontext context; security_task_getsecid(current, &blob); if (!lsmblob_is_set(&blob)) return 0; - error = security_secid_to_secctx(&blob, &ctx, &len); + error = security_secid_to_secctx(&blob, &context); if (error) { if (error != -EINVAL) goto error_path; return 0; } - audit_log_format(ab, " subj=%s", ctx); - lsmcontext_init(&scaff, ctx, len, 0); - security_release_secctx(&scaff); + audit_log_format(ab, " subj=%s", context.context); + security_release_secctx(&context); return 0; error_path: diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 2b06171bedeb..4af5861bcb9a 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -998,9 +998,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, struct lsmblob *blob, char *comm) { struct audit_buffer *ab; - struct lsmcontext lsmcxt; - char *ctx = NULL; - u32 len; + struct lsmcontext lsmctx; int rc = 0; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); @@ -1011,13 +1009,12 @@ 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 (lsmblob_is_set(blob)) { - if (security_secid_to_secctx(blob, &ctx, &len)) { + if (security_secid_to_secctx(blob, &lsmctx)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { - audit_log_format(ab, " obj=%s", ctx); - lsmcontext_init(&lsmcxt, ctx, len, 0); /*scaffolding*/ - security_release_secctx(&lsmcxt); + audit_log_format(ab, " obj=%s", lsmctx.context); + security_release_secctx(&lsmctx); } } audit_log_format(ab, " ocomm="); @@ -1230,7 +1227,6 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) static void show_special(struct audit_context *context, int *call_panic) { - struct lsmcontext lsmcxt; struct audit_buffer *ab; int i; @@ -1254,17 +1250,15 @@ static void show_special(struct audit_context *context, int *call_panic) from_kgid(&init_user_ns, context->ipc.gid), context->ipc.mode); if (osid) { - char *ctx = NULL; - u32 len; + struct lsmcontext lsmcxt; struct lsmblob blob; lsmblob_init(&blob, osid); - if (security_secid_to_secctx(&blob, &ctx, &len)) { + if (security_secid_to_secctx(&blob, &lsmcxt)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { - audit_log_format(ab, " obj=%s", ctx); - lsmcontext_init(&lsmcxt, ctx, len, 0); + audit_log_format(ab, " obj=%s", lsmcxt.context); security_release_secctx(&lsmcxt); } } @@ -1408,20 +1402,17 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, MAJOR(n->rdev), MINOR(n->rdev)); if (n->osid != 0) { - char *ctx = NULL; - u32 len; struct lsmblob blob; - struct lsmcontext lsmcxt; + struct lsmcontext lsmctx; lsmblob_init(&blob, n->osid); - if (security_secid_to_secctx(&blob, &ctx, &len)) { + if (security_secid_to_secctx(&blob, &lsmctx)) { audit_log_format(ab, " osid=%u", n->osid); if (call_panic) *call_panic = 2; } else { - audit_log_format(ab, " obj=%s", ctx); - lsmcontext_init(&lsmcxt, ctx, len, 0); /* scaffolding */ - security_release_secctx(&lsmcxt); + audit_log_format(ab, " obj=%s", lsmctx.context); + security_release_secctx(&lsmctx); } } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index a7e4c1b34b6c..ae073b642fa7 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -132,8 +132,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { struct lsmcontext context; struct lsmblob lb; - char *secdata; - u32 seclen, secid; + u32 secid; int err; err = security_socket_getpeersec_dgram(NULL, skb, &secid); @@ -141,12 +140,11 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) return; lsmblob_init(&lb, secid); - err = security_secid_to_secctx(&lb, &secdata, &seclen); + err = security_secid_to_secctx(&lb, &context); if (err) return; - put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata); - lsmcontext_init(&context, secdata, seclen, 0); /* scaffolding */ + put_cmsg(msg, SOL_IP, SCM_SECURITY, context.len, context.context); security_release_secctx(&context); } diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 5d2784461798..e6fdcd87ab3e 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -331,8 +331,7 @@ static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct) static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) { struct nlattr *nest_secctx; - int len, ret; - char *secctx; + int ret; struct lsmblob blob; struct lsmcontext context; @@ -340,7 +339,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) * 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); + ret = security_secid_to_secctx(&blob, &context); if (ret) return 0; @@ -349,13 +348,12 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) if (!nest_secctx) goto nla_put_failure; - if (nla_put_string(skb, CTA_SECCTX_NAME, secctx)) + if (nla_put_string(skb, CTA_SECCTX_NAME, context.context)) goto nla_put_failure; nla_nest_end(skb, nest_secctx); ret = 0; nla_put_failure: - lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ security_release_secctx(&context); return ret; } @@ -655,15 +653,15 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) #ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret; struct lsmblob blob; + struct lsmcontext context; - /* 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); + ret = security_secid_to_secctx(&blob, &context); if (ret) return 0; + len = context.len; + security_release_secctx(&context); + return nla_total_size(0) /* CTA_SECCTX */ + nla_total_size(sizeof(char) * len); /* CTA_SECCTX_NAME */ #else diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index e2bdc851a477..c6112960fc73 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -173,19 +173,16 @@ static void ct_seq_stop(struct seq_file *s, void *v) static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) { int ret; - u32 len; - char *secctx; struct lsmblob blob; struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &secctx, &len); + ret = security_secid_to_secctx(&blob, &context); if (ret) return; - seq_printf(s, "secctx=%s ", secctx); + seq_printf(s, "secctx=%s ", context.context); - lsmcontext_init(&context, secctx, len, 0); /* scaffolding */ security_release_secctx(&context); } #else diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index dcc31cb7f287..84be5a49a157 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -306,6 +306,7 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) struct lsmblob blob; + struct lsmcontext context = { }; if (!skb || !sk_fullsock(skb->sk)) return 0; @@ -317,10 +318,12 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) * 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); + security_secid_to_secctx(&blob, &context); + *secdata = context.context; } read_unlock_bh(&skb->sk->sk_callback_lock); + seclen = context.len; #endif return seclen; } diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 3e06efe29cfa..7d426ca1aff6 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -375,8 +375,6 @@ int netlbl_unlhsh_add(struct net *net, struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; struct lsmcontext context; - char *secctx = NULL; - u32 secctx_len; struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && @@ -444,12 +442,9 @@ int netlbl_unlhsh_add(struct net *net, * 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); - /* scaffolding */ - lsmcontext_init(&context, secctx, secctx_len, 0); + if (security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", + context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); @@ -482,8 +477,6 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - char *secctx; - u32 secctx_len; struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); @@ -510,11 +503,9 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, if (entry != NULL) lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, - &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - /* scaffolding */ - lsmcontext_init(&context, secctx, secctx_len, 0); + security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", + context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); @@ -553,8 +544,6 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - char *secctx; - u32 secctx_len; struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); @@ -580,10 +569,9 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, if (entry != NULL) lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, - &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " sec_obj=%s", secctx); - lsmcontext_init(&context, secctx, secctx_len, 0); + security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " sec_obj=%s", + context.context); security_release_secctx(&context); } audit_log_format(audit_buf, " res=%u", entry != NULL ? 1 : 0); @@ -1106,8 +1094,6 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, struct lsmcontext context; void *data; u32 secid; - char *secctx; - u32 secctx_len; struct lsmblob blob; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, @@ -1167,15 +1153,13 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, * 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); + ret_val = security_secid_to_secctx(&blob, &context); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, NLBL_UNLABEL_A_SECCTX, - secctx_len, - secctx); - /* scaffolding */ - lsmcontext_init(&context, secctx, secctx_len, 0); + context.len, + context.context); security_release_secctx(&context); if (ret_val != 0) goto list_cb_failure; diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index ef139d8ae7cd..951ba0639d20 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -85,8 +85,6 @@ struct audit_buffer *netlbl_audit_start_common(int type, { struct audit_buffer *audit_buf; struct lsmcontext context; - char *secctx; - u32 secctx_len; struct lsmblob blob; if (audit_enabled == AUDIT_OFF) @@ -102,9 +100,8 @@ struct audit_buffer *netlbl_audit_start_common(int type, lsmblob_init(&blob, audit_info->secid); if (audit_info->secid != 0 && - security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " subj=%s", secctx); - lsmcontext_init(&context, secctx, secctx_len, 0);/*scaffolding*/ + security_secid_to_secctx(&blob, &context) == 0) { + audit_log_format(audit_buf, " subj=%s", context.context); security_release_secctx(&context); } diff --git a/security/security.c b/security/security.c index 9107ca5a6af3..007f23797de1 100644 --- a/security/security.c +++ b/security/security.c @@ -2209,18 +2209,22 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp) { struct security_hook_list *hp; int display = lsm_task_display(current); + memset(cp, 0, sizeof(*cp)); + 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; - if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) + if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) { + cp->slot = hp->lsmid->slot; return hp->hook.secid_to_secctx( blob->secid[hp->lsmid->slot], - secdata, seclen); + &cp->context, &cp->len); + } } return LSM_RET_DEFAULT(secid_to_secctx);