From patchwork Fri Feb 14 23:41:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11383543 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 9281917F0 for ; Fri, 14 Feb 2020 23:42:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6860124650 for ; Fri, 14 Feb 2020 23:42:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="cG8e8W1e" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727935AbgBNXmT (ORCPT ); Fri, 14 Feb 2020 18:42:19 -0500 Received: from sonic310-31.consmr.mail.ne1.yahoo.com ([66.163.186.212]:37349 "EHLO sonic310-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727860AbgBNXmS (ORCPT ); Fri, 14 Feb 2020 18:42:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723733; bh=Tl3BVk0P2ymCN7v2fxClfbZkF85tMn5jH45DgsMa3mk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=cG8e8W1eFDF6bq/jQcaCwFiYDaFshG5ApOGzPr20a16/umirjbJsj1J7ngaBSJ5hGaj9DgdUDJ47itsG3IG4ualJX4VciPO5lpk+/hqehdUQfsDwyxN5eyBuZpahSrLYIH8f0uB+uypBqACiPa+Tmp8TsGSgQYP9Tp9yQl2mbmzG7HLHkcOZEke1+zztH61i0woeXP6Ws0E9aEF6vH2r+3B83o+aNXkkx60WSkVHKcaWrXHJFPVg+vPpCbgzou0fB1rK/ZernZZ3gdyeeCGAUNYxJTXXwyaexDAMz7qv72i9kSdNgrVOauDK6hgvwek9lZiW84oDRZHPqSJQ4J9MlA== X-YMail-OSG: 1fTINeIVM1kba.a1CoFXi2IJ4B0a7bbalATKtMV73At02sJNET5j22JBsdCVhG_ kherXjM_kVJTUVQ4mysCALTnz4aYAU2NYNyJw28bHt0L6WxQ2l9l3iJ6R6YFNVtkQdRk.8C98vxI 83xWpI9X7vO83N6g43scHDR2.LLAtzLTOrXgVWFjJtOA2Z.S.CymozoZlLkIEuGl5j1aNZL8p.yA 5QmjJ1PQBapVqXiMXfR1W41jRt5NaA0cMU8MLfyLC43CGHhRCUfSZjlU0Rq50MH0HtVAzOVVfiJs Mp8H5G5ajh1CAenby6QCqSiOQ6snBzc3sE38Bhcl0dj0D1ad7_P1s_mnkW_Y3opAY_pJQ_qD1umc 4oWTVg.qmcDYHjCk2prqy.TlCV52NWeEog2q_I02mmURh.AG0aJHdSS2xBE3k40ls.suIVB6GkEw VM1K9dZhVcPrLNXA824vMidG32Z.9PNKuTzOkbij29z.pXttOE63qsa43W.vh4TdD70OSRI9Osfj XL9rpzr_9irSi8zPsIEmnbNbeWhitAmkj8GKRf.GkPUPxfqkwCGUjIeJApHGyU7ZNitICnroeKkB yDvFw2EnGjwj9h6CmApRSFMRRKkL5idqXB6ZJ5JbQdIfegzXoGZaRZpvs23gMukO31KQE6_B.DLB oKzpPrBipbmxsdAcCZ51cIW66JZ7S82ZLagcUzxW9CbY_6qvY7OKVWWLuSXxtawsqLdP7lXgv7xw neTKHARASQi.I.f6jq027RMztiHHUZPlttxHnnGL0cLY8yMagQL0ooIh6N9v4fj7Sz7D7GA.8syB PGP_Ji5IiulspiM_G3YOiYKxM7WMySId3fayUXu0ttxJddpNA5g0uyQ0zVdG40fcsNeLt_Xtxpnr wBMIBYV82RMZqfAt5OEkMAfxH_8G74QXWWhi70fF_bwVeIt0SLymM_JM3Ibozgox8H6wlN3Ln1xH iUPo7QQzK0Cbsj4pVHFvlU8nybX.iyvc39RWNCJ.NpkW2wGeTYqOey2Nx6HtxmVwoh8.VdRy6CWw b4Quj7HgcYK4W3JakUcEfbXaZE8vl_7cIagzoy.W0ycvbk33L4p4uqm1R5GeJQ4C0SZWyfgKkpug I3Bo8JfA2yfZ45Ktnf.1UEHANjQZ.smIlAGvxSLasYrszxm4MjJbookJvE732vZRiH_yPFTAp5N5 kEHUc2SdMW9tkFxSilJj7sE_cTc7KC6tX5zG55Fk_NDOJblC1Dwb7nclOz5jrkryVkgIB8gTVJUb _w36gj.NwRs8oNrVpCB2.VG9gg2a_KhNXy35IKRRjuQms_rpchY3yaRr1zK65XNLoBx2z.b5jDaO wF0RoNvqM_PLfsMBeyS4UCvq0bh_6ETqN6dBMUcdjVLMhVcKqOOTlr.faX68udSUZoiNPmVjtVaZ 8dp7mVhfBjNx6SFQE9u623i7kIbpuIQcJ0A-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:42:13 +0000 Received: by smtp428.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 4657fbe77e4c20ee04927285b6183fa3; Fri, 14 Feb 2020 23:42:07 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 01/23] LSM: Infrastructure management of the sock security Date: Fri, 14 Feb 2020 15:41:41 -0800 Message-Id: <20200214234203.7086-2-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 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. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler Acked-by: Paul Moore --- 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 | 64 ++++++++++++------------- security/smack/smack_netfilter.c | 8 ++-- 10 files changed, 144 insertions(+), 120 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 20d8cf194fb7..c2b1af29a8f0 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2095,6 +2095,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 b621ad74f54a..61b24f4eb355 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); new->label = aa_get_label(ctx->label); new->peer = aa_get_label(ctx->peer); @@ -853,7 +835,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); @@ -1038,7 +1020,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; @@ -1051,7 +1033,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; @@ -1135,7 +1117,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(); @@ -1145,7 +1127,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; @@ -1162,6 +1144,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 = { @@ -1198,7 +1181,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), @@ -1749,7 +1731,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 565bc9b67276..4ee63826c116 100644 --- a/security/security.c +++ b/security/security.c @@ -28,6 +28,7 @@ #include #include #include +#include #define MAX_LSM_EVM_XATTR 2 @@ -201,6 +202,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); } @@ -336,6 +338,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); /* @@ -654,6 +657,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 @@ -2098,12 +2123,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 4b6991e178d3..de64cfba91f0 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4461,7 +4461,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,}; @@ -4518,7 +4518,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 */ @@ -4534,8 +4534,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; @@ -4550,7 +4550,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; @@ -4685,7 +4685,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); @@ -4864,9 +4864,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; @@ -4898,8 +4898,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,}; @@ -4941,7 +4941,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,}; @@ -4974,7 +4974,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; @@ -5042,13 +5042,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 || @@ -5108,34 +5110,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; @@ -5149,7 +5144,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; } @@ -5159,7 +5154,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) @@ -5174,7 +5169,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; @@ -5325,8 +5320,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. @@ -5343,7 +5338,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; @@ -5364,7 +5359,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; @@ -5381,7 +5376,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)) @@ -5465,7 +5460,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 @@ -5609,7 +5604,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; @@ -5648,7 +5643,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; @@ -5740,7 +5735,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 @@ -5769,7 +5764,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; } @@ -5832,7 +5827,7 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) int err = 0; u32 perm; struct nlmsghdr *nlh; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (skb->len < NLMSG_HDRLEN) { err = -EINVAL; @@ -6805,6 +6800,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 62529f382942..2836540f9577 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -372,6 +372,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 8c61d175e195..f6c2ec5b60b7 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -1450,7 +1450,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; @@ -1832,7 +1832,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 @@ -2239,11 +2239,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. @@ -2257,11 +2253,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 @@ -2270,7 +2265,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) { @@ -2283,9 +2277,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 @@ -2403,7 +2396,7 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip) static int smack_netlabel(struct sock *sk, int labeled) { struct smack_known *skp; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); int rc = 0; /* @@ -2448,7 +2441,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) int rc; int sk_lbl; 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(); @@ -2524,7 +2517,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; @@ -2612,7 +2605,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; @@ -2706,7 +2699,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; @@ -2754,7 +2747,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; } @@ -2779,8 +2772,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; @@ -2845,7 +2838,7 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, #ifdef 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); @@ -3577,9 +3570,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 @@ -3625,8 +3618,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; @@ -3663,7 +3656,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; @@ -3836,7 +3829,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { struct netlbl_lsm_secattr secattr; - 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; @@ -3957,7 +3950,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; @@ -4007,7 +4000,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: @@ -4020,7 +4013,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, * Translate what netlabel gave us. */ if (sock != NULL && sock->sk != NULL) - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); netlbl_secattr_init(&secattr); rc = netlbl_skbuff_getattr(skb, family, &secattr); if (rc == 0) { @@ -4058,7 +4051,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() */ @@ -4078,7 +4071,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 netlbl_lsm_secattr secattr; struct sockaddr_in addr; struct iphdr *hdr; @@ -4177,7 +4170,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) { @@ -4581,6 +4574,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 = { @@ -4690,7 +4684,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 Fri Feb 14 23:41:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11383551 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 F2889159A for ; Fri, 14 Feb 2020 23:42:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B3772222C4 for ; Fri, 14 Feb 2020 23:42:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="TZNOfK1G" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728285AbgBNXme (ORCPT ); Fri, 14 Feb 2020 18:42:34 -0500 Received: from sonic308-16.consmr.mail.ne1.yahoo.com ([66.163.187.39]:34254 "EHLO sonic308-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728293AbgBNXmd (ORCPT ); Fri, 14 Feb 2020 18:42:33 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723750; bh=yHIgJ+K0cNodLTVb6C/KOzn67uZ7jYTuGPVy1dQ2KjY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=TZNOfK1Gy68+tUoIaUrSySNcrWWMKljlGhiTK2QmHi+pJeMis6srdAZD55yZN0MdTkvzwJ4F6jDrwseQzYGrGcjwoz/sHp2Jy2y4KHtGz8KI1jopYpu+dfuAIxSeXbpgzq5we4EAubEFrMp+/te7+lJeL9FpCF4r93wH/d8sUwsW9fa6MlENRTFYIl/0NalVhcYqD4Tlc/XTNX6gHVYvW8TpJTKC4zmw53uL/V0aoAPzMfYYf7urXyb6jTBPO+yxRjH2VFzK52430bM3sLkzpvjOuQhwN4qhi8E5YrD/dGcTd2gJ0ZKszMhYpHUS3d1oT/cf9zG1qW2PcGZIDU2IOQ== X-YMail-OSG: CjruIa8VM1kR1230GeF51qEMD.9nJ1yYnYzivmrOegZsAaL8ZtvZrHaoYGGucIF K8MuSLsbn3mmg0LRIOndwqPr_csZ2dLdDSDdKMVneTQ84XMyXDi0bFaqrqLB0pg2mA6EGXkd9MOJ Lpe_rR6WFy2urulRNR2qvXnzQMZ5z60hlHuGCtx1uAz2OLjM7g4EDoDhfill1MqZx7XWCGNgSxZ7 jJ8apYZRr36SRIzbohjMM7YUDaqdC6Ynb9sFkStJM8OYpH9myIbOr.PEkLb4mKN4VDxEkUm5tWyc Mn6IMfL3kGsZYjlrP2PbM9P.uRYT6L11b6CoYVqZvCIeVG6cVcZx.hBvMovpa6bL6jg4fi3StsXG AeVCH5zY0J5ghkw_hKLODMFcUM_BwfKQ8a1VR9wsXpE1cDc.mUJYAvEXylQy5wryl_u.KpTVCwNP qLja33agtweKcN7uFaKsQtDf0iH.h8Za7xSBjk2XtobugWXcJo5DZ6wOsfrjJpauuKpAsXt2USHd R0TBfq7egYbScA1UTJ_MxXbly_x4bt.A3mHYsS1OmdhJSvcc6TYYJQq6.qYxbs6IpSRnGxdbGh.b .GMWdfKhYla4sjRwtB9X.jfjSh5MWExDx0lgVgg5pJ4j7LPlvdpy7VgBonejFXroQArr9ubQ74ni Xh4GW8CNa2Z0f3bDuWfrNQhkP3WHfN6UGkpNKtRLesRYqSJY5DoKlzIp0qmZW.C.YA2V5PJJysFN bHkTGyVMMpGiaKGWqKXq_EeD2OIouEsJKiWBpQTdaIu3PvGxw1zVQfg2.eJvJnYXjtNkMpnz4eCL 3YJwc1eec7j_QNx0H.9eqOQuhKVvFGK8eztqgHBXRhvfd41Hn.k8kAyDEY0hjfOjxBKfYKi_ayyO z3cQnI.5ajE6cvCJTAFaVUwIi_0SDcc9dFwtgDCcdy8P1KrlheckfLGZDQYKsOgTshqepQ1ET2ny vJgycNpPdYudZyRsJGTZvTt3GDNnoFoq4zvCUvCwATQ0C9TRskb9XGN.N_qyYDnawkMdvq7C6yWH wA4v4YV7VSq9SfQbfkplDsdyOLN0XbvZIwiHnb2DFfaEjvQdH3MHNKppz0xp.zyfzx.nVmvShhIF eeiIykfEQtNdsCHTEKrfNrexHZW_bSkbqpDjC_5g1y7vePoO5124Ml5x27rZDryAvHI8nvgy.Ltq DEhuVwiAW1EITiomvLzLRSwfcx4tsMgcgVCccy6qmOchiSnAHy503XE2YSRmkXdYb4yLtupdxh3m qs4r_eAzywCKGMuibeMeM8VByYu_crz6rbYM8ve6cW_DDDqygtpB6JPaQuuxMoBPMarx2q6s03mN NcrYPh.UzU0br52sW6nfFu.Q5Gd0gyZB71Ol7CQ1K0raFd9613O3YaNyzchAyX_JEQTPgiJ9ECnJ iHy4ujlQ97H.1pC9V0SS_osVlqUIxu4Y01VUmzyaXzjgdoDG.tOqnJDe_ Received: from sonic.gate.mail.ne1.yahoo.com by sonic308.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:42:30 +0000 Received: by smtp423.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID aa3498465e4a622537bda8a87dcaca06; Fri, 14 Feb 2020 23:42:26 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 02/23] LSM: Create and manage the lsmblob data structure. Date: Fri, 14 Feb 2020 15:41:42 -0800 Message-Id: <20200214234203.7086-3-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 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. Signed-off-by: Casey Schaufler Acked-by: Stephen Smalley --- include/linux/audit.h | 4 +- include/linux/lsm_hooks.h | 12 ++++- include/linux/security.h | 66 ++++++++++++++++++++++++-- kernel/auditfilter.c | 27 ++++++----- kernel/auditsc.c | 12 ++--- security/apparmor/lsm.c | 7 ++- security/commoncap.c | 7 ++- security/integrity/ima/ima_policy.c | 34 +++++++++----- 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 ++- 16 files changed, 238 insertions(+), 56 deletions(-) diff --git a/include/linux/audit.h b/include/linux/audit.h index f9ceae57ca8d..8e1c759fd1ff 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -11,6 +11,7 @@ #include #include +#include #include #define AUDIT_INO_UNSET ((unsigned long)-1) @@ -64,8 +65,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 c2b1af29a8f0..7eb808cde051 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2077,6 +2077,14 @@ struct security_hook_heads { #endif } __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. @@ -2085,7 +2093,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; /* @@ -2114,7 +2122,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 64b19f050343..8c2751763c52 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -130,6 +130,64 @@ 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)) + +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); @@ -1781,8 +1839,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 @@ -1798,12 +1856,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 b0126e9c0743..3a44abf4fced 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); } } @@ -517,7 +517,7 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, entry->rule.buflen += f->val; 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) { @@ -528,8 +528,10 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, if (err) { kfree(str); goto exit_free; - } else + } else { + f->lsm_isset = true; f->lsm_str = str; + } break; case AUDIT_WATCH: str = audit_unpack_string(&bufp, &remain, f->val); @@ -767,7 +769,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) @@ -781,9 +783,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) { @@ -835,7 +837,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) { @@ -1353,10 +1355,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: @@ -1383,7 +1386,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; @@ -1415,7 +1418,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 @@ -1430,7 +1433,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 4effe01ebbe2..0c239c29a9d5 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -638,14 +638,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: @@ -655,21 +655,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; } @@ -680,7 +680,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 61b24f4eb355..146d75e5e021 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1147,6 +1147,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), @@ -1847,7 +1852,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/commoncap.c b/security/commoncap.c index f4ee0ae106b2..9dcfd2a0e891 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -1339,6 +1339,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), @@ -1363,7 +1368,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 453427048999..624ed1a34842 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -75,7 +75,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]; void *args_p; /* audit value */ int type; /* audit type */ } lsm[MAX_LSM_RULES]; @@ -84,6 +84,16 @@ struct ima_rule_entry { struct ima_template_desc *template; }; +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 @@ -258,9 +268,11 @@ __setup("ima_appraise_tcb", default_appraise_policy_setup); static void ima_lsm_free_rule(struct ima_rule_entry *entry) { int i; + int r; for (i = 0; i < MAX_LSM_RULES; i++) { - kfree(entry->lsm[i].rule); + for (r = 0; r < LSMBLOB_ENTRIES; r++) + kfree(entry->lsm[i].rules[r]); kfree(entry->lsm[i].args_p); } kfree(entry); @@ -295,8 +307,8 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) security_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); + if (!ima_lsm_isset(nentry->lsm[i].rules)) pr_warn("rule for LSM \'%s\' is undefined\n", (char *)entry->lsm[i].args_p); } @@ -465,7 +477,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 @@ -479,7 +491,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, rc = security_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: @@ -487,7 +499,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, rc = security_filter_rule_match(secid, rule->lsm[i].type, Audit_equal, - rule->lsm[i].rule); + rule->lsm[i].rules); default: break; } @@ -872,7 +884,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); @@ -883,8 +895,8 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, result = security_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); + if (!ima_lsm_isset(entry->lsm[lsm_rule].rules)) { pr_warn("rule for LSM \'%s\' is undefined\n", (char *)entry->lsm[lsm_rule].args_p); @@ -1585,7 +1597,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 ee5cb944f4ad..86317e78899f 100644 --- a/security/loadpin/loadpin.c +++ b/security/loadpin/loadpin.c @@ -180,6 +180,11 @@ static int loadpin_load_data(enum kernel_load_data_id id) return loadpin_read_file(NULL, (enum kernel_read_file_id) id); } +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), @@ -227,7 +232,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 5a952617a0eb..924292f7bfcd 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 7760019ad35d..950dfb7f931e 100644 --- a/security/safesetid/lsm.c +++ b/security/safesetid/lsm.c @@ -149,6 +149,11 @@ static int safesetid_task_fix_setuid(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(capable, safesetid_security_capable) @@ -157,7 +162,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 4ee63826c116..67c8116d8711 100644 --- a/security/security.c +++ b/security/security.c @@ -340,6 +340,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 @@ -467,21 +468,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 __initdata; + /** * 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); } @@ -490,7 +506,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__); } } @@ -1938,7 +1954,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); } @@ -1951,7 +1967,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); } @@ -2415,7 +2431,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) @@ -2423,14 +2456,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 de64cfba91f0..22b882867dd2 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6864,6 +6864,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, @@ -7171,7 +7176,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 f6c2ec5b60b7..12e01d450dd4 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4577,6 +4577,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), @@ -4775,7 +4780,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 716c92ec941a..f1968e80f06d 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c @@ -529,6 +529,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. @@ -581,7 +586,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 94dc346370b1..0f0cf7136929 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 Fri Feb 14 23:41:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11383547 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 2097E159A for ; Fri, 14 Feb 2020 23:42:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 00373222C4 for ; Fri, 14 Feb 2020 23:42:32 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="JyfA6KAT" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727649AbgBNXmc (ORCPT ); Fri, 14 Feb 2020 18:42:32 -0500 Received: from sonic314-27.consmr.mail.ne1.yahoo.com ([66.163.189.153]:44088 "EHLO sonic314-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728285AbgBNXmc (ORCPT ); Fri, 14 Feb 2020 18:42:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723750; bh=mdZK51sBu8gaQ8wZdlOHgByPRBos6L+Jf4Sp+s8QzAc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=JyfA6KATbos1z1K+nB6nbK2QTf4nBcMtzenOauSt6QyBse2c2k4kkFJdyGVDkpnXHtScJrOEjUVBdN2Yoc7XoYw5+KensBEzQSw+HviBeTQYcFLaZszxokNn8EA5uFk5imcqMbBJGx0AfXR1TWhkYgQIAfbs4IuHi/L/6jV7U7FKKbzlMyD1JOGLMPg5Wep85p353YWv80Zf3lDqg6+4xOTNNWJUhMEJoHFvkuqrTXk7kF+Nio438zhGuj7GDjQpP6QeytjLgWbwzvgWQtZ9CP89DL+KrGwARmR0mRKi+FsWyf1doDhEmJBAtKTB62PRlqN1NYnOI+L0NDoeVvkauA== X-YMail-OSG: ObZUG6IVM1nx5CZa8wAmiWyPqaT8n1U16_OyWYCtjEAJS_1SUAMv8RuosHudSVX TAuSHWPpuWnZrTbHz71A180DeXLI52dWtF6IMyMupJkpL6sh7RjsCqBX_FgIXWBiRvclhNvVuuSI 4C0V9d2mExBB1V0hgRjdT1MS9dzzOFZluOUzRE.U0e7Ka5pFilQyQOrRUVECKv_gX_NFfq5hHuGM kFZFfbiw8CtWPPXeBnwfYsmArHdXfH9ECb1ahojWaNKon_V.kLA12rFX4rdepM8EGNKKxH2chmcK Wdkt.1pVHoDlVWV7dxek6_VjTI0gQeEATHgI.5M0peUBW6SoaYVZ6p5QwcJ6awUSyu0t7nC7r9N5 R7uzuvdqpcjtqP1Gd.CWwcWGaqk31McerMHsJrlKwRTUJ78RSBIpmyz4_HzPqY79weWVbBIWrqHu x0sC0dhIMkqveXZauFgpcHEajd84ntNv8nq9xaVxKCTiqEZP.rwoaTlEv15sAab3WUX0WjotFLzT aZX_T5NLodFbkDvz_IuI0xWKGzWXT8.9SwC2qtfBPA3t8R.mSmDe7apzF6XYcNaIrpclZ6Yc2Yj. .soemoyeojSvYeHr_1ePEsDuiQKyhUCPR64EmR0uzlRWKBGRiNwA3BdGL_sOhX2CVSz4tecQXYD_ .SnBHaKyZUqXsStODWERwY_auhokr05upGjThMxwVUkzAJTbSQgSCEyPD..pdE4eakxgaa3ErpA. P0t7zWrRsZj276HxOGhdJE.emJbWZs_Vnz4GJ.vWOng4SvDfRMOxN4_D_Jav7YBJWY6L6rCjvGft 1dl2j1f3FaKG.q18hnpb1KVs9k1gZ4Grs84AXLdFWYmb56RWQxKlItmX5AmBZ9gaaUx0Q3KewUQe bkayTtRcqjBlxuJ0I81_hlXhVCLKosb3lhuAVIOVKJ7O6HFwO46SnypCiw.eQkdCxMoqKiT.iucG bdZ.ARsZMOruOZs2M5JCHLISG69Vwpns9SmykbnBRH6wIdIy1uDc8CXvueU24F6c1ILqcT02wcwc iBH_b7jMSlgKHMQmqFu9_3q5DC6VDOs57sTxv0qZw9JEeYTsVHYU_P1VSnyGX9_iONR4e3uuOf00 2mXvWGvqd81p3J6AqJ0wIVQlI.hqRRL.JBiezDM14UtX4THlxtOv0KRDWE9ySXC_VDEmPnF804pn DwIR36zUkiubVlOwuuzrxaS0j.QO1is1ZmaohGMaqxZgWVvCgRmYumdqpkq.4WfDTe_971jl4CCE LgMmBgPsch6fDbSyyKuCt1qwxFvLxNUps_UfHkSGt8Ov_4JvnmXo9sKogwWFdwCBLfhwfVSjC2Kf vPGNou_NSUkSURj5PlCBxXjuHwqJKC3XIG00wdUZnL5.aeVWLfgWZrS81HSccEk6.gXQn3G3j3RN TAxyLGAy8yLeVoy0K6CR69ohX_wc8zvQa3zvUTMI.5ixX2n1YGYzjmDaiEMNsogzk Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:42:30 +0000 Received: by smtp423.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID aa3498465e4a622537bda8a87dcaca06; Fri, 14 Feb 2020 23:42: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, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 03/23] LSM: Use lsmblob in security_audit_rule_match Date: Fri, 14 Feb 2020 15:41:43 -0800 Message-Id: <20200214234203.7086-4-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 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. In some cases this requires a temporary conversion using lsmblob_init() that will go away when other interfaces get converted. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley 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 | 8 +++++--- 6 files changed, 30 insertions(+), 16 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 8c2751763c52..9d83c6832bae 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1839,7 +1839,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 @@ -1855,8 +1856,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 3a44abf4fced..509eb21eff7f 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1327,6 +1327,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: @@ -1357,8 +1358,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 0c239c29a9d5..ef2f5e7eec7b 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -445,6 +445,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); @@ -643,7 +644,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); } @@ -658,15 +661,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)) { @@ -678,7 +683,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 64317d95363e..f9e3ca96fa52 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -408,8 +408,8 @@ static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr, return -EINVAL; } -static inline int security_filter_rule_match(u32 secid, u32 field, u32 op, - void *lsmrule) +static inline int security_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 624ed1a34842..ad48b7b60cff 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -476,6 +476,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 blob; if (!ima_lsm_isset(rule->lsm[i].rules)) { if (!rule->lsm[i].args_p) @@ -488,7 +489,8 @@ 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 = security_filter_rule_match(osid, + lsmblob_init(&blob, osid); + rc = security_filter_rule_match(&blob, rule->lsm[i].type, Audit_equal, rule->lsm[i].rules); @@ -496,7 +498,8 @@ 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: - rc = security_filter_rule_match(secid, + lsmblob_init(&blob, secid); + rc = security_filter_rule_match(&blob, rule->lsm[i].type, Audit_equal, rule->lsm[i].rules); diff --git a/security/security.c b/security/security.c index 67c8116d8711..b3fab8fdbb57 100644 --- a/security/security.c +++ b/security/security.c @@ -471,7 +471,7 @@ static int lsm_append(const char *new, char **result) /* * Current index to use while initializing the lsmblob secid list. */ -static int lsm_slot __initdata; +static int lsm_slot __lsm_ro_after_init; /** * security_add_hooks - Add a modules hooks to the hook lists. @@ -2467,7 +2467,8 @@ void security_audit_rule_free(void **lsmrule) } } -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; @@ -2475,7 +2476,8 @@ 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, + rc = hp->hook.audit_rule_match(blob->secid[hp->lsmid->slot], + field, op, &lsmrule[hp->lsmid->slot]); if (rc) return rc; From patchwork Fri Feb 14 23:41:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11383553 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 02BD0139A for ; Fri, 14 Feb 2020 23:42:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D622A24650 for ; Fri, 14 Feb 2020 23:42:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="QVEvKZcN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728293AbgBNXmt (ORCPT ); Fri, 14 Feb 2020 18:42:49 -0500 Received: from sonic310-31.consmr.mail.ne1.yahoo.com ([66.163.186.212]:41268 "EHLO sonic310-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728126AbgBNXmt (ORCPT ); Fri, 14 Feb 2020 18:42:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723768; bh=T54rQV8CSCnr4XkKEc2qRlTsrM4kuFgwmoKr+LgYOmg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=QVEvKZcNlGDcVURdM4V3Y6Vw4se6Id6v9hsDF7E2zIURbVeiK5g9PYnzY8YQViI5zqSlRriJ2G15kA9SNfl/pEZBMJvnjSkkSruS270HQh70nTCi6CpdogFL1lebAPeUzICtsddCJNeg3TXKSPpUZxazpZIAf1ME0c/Wf2AZL4+mFo4BgCZagdHWv3F77H0+UFU/0HneY6tAQ+7VDYOgBWE5C3paUxBxKomOVOdnxPwFbyD5v7tyHJXqMvRJVBNfK0iTggHgAZ1wg3moKRRSFtAaWcXgdDHpnnmTUXkerA5d/HEsVNseYRVR6cLEeUlXIjwQx3EwfoU+v2oav0z/xw== X-YMail-OSG: I5nkZT4VM1lHhfqfpX__2DrS2BG1gbuH_heEHSTrcDiciLCbOARPbsOcjF7qopT eFRM4nnyrX6yDPUxoRPmDADmERyL_zaYwkeklex3GPsMvClh4y9Oyie6ey1GuissSw.y14Bf3.VG SvgX2o8cuEZ9Le4jGk9CoasTCB.rdgXfX6Hbjolydhh.VDnYxc6Cbu1kyb.3ktCDY.Tp0HzRJjyo iY1fXkei2iHPfHzM_rr1aACwds1s.l22xcPPYiKFUfQsLWw.For39F5iKF3aYHQ2lgxeZ.TOUL0A slBypPqdzQ9s3D5HgKgKYjAWoCfwDEAATIhPZooaiHKo.ffmm02pmT53p_WGLKM0lmQUslWzn2_R UW19DFkMYz34H7NTOa8BL8T5M4dqxuobIx_uTtiTyMLJn1PN23nqSz345wamDpA3DriOPo7sn5Y8 qbRL_ulezhpmwHCZjCzPdKocBlEdh3qVFCNZTjD_yfwjPAt7g6JSx_AzbZXZHDTpq3BDSIk1B2mX fJHWT9VL1ikO6JYAmwZqVOExS5wR1N6AoLuzOaCLf_lKO5D6EV6zZgPHLYde.PihNJ8ad4wrtkGG T_g1Mq_JO0PXZ__NzpnWwqBjnNIsdUeBx0qF2CDg8zA71c.P5xuk6aZDOu21L3mGWwvZ.Byej2nk i4DikE62TMyvBo7Q1FUhHnWiDsHrk3yA0bPYVkTZryuM5Oz3wiiMq7bo9ENsDdQfhEKh40kA.lVO soudV_3XfB0QeOJAScHBKQ1vC8JXPOJj8Cg_eslMaj7oEhy5HNuRw8fxEgpyRs3RoIP6tcbQJKrq wCa4pT64NwzocnjglGJp47zgMGFm_Ej0QB83MHipZPzbCi6oWSmZjiQSLfr35VlgYjVdSiqEEejn g6rh92fWR9Bvf8JA_lxqAbn6.rdVrGY21olOV5KbTD.gGujKW4O9iWTklz6id8yPceyj0X926kiE 2f5LWAYFoACllI2WIfDw7fAeBXZ40.3.hXY4ZN7xcoY_ewcGf31ee_QuN54G3p3TL.lOjKuSlquZ u8LkqPEVGpflVKUR6Yg_QVXsJfqHl3qkugbyM1kTs7RQvsLi4hHqT9AwqHYnP3pfjlcE.H0tQNXD pb2oZusamAwsGSqRILpi9L2kP4HVOkWFvg9zSAJ16YeecXbxWazUxnUNaBRTLzVEDJ1iZi46YDZC YfLKga5XKCk7eXVLMsa9rF73YebzHVmwDvfjzY5iuO3S1Jt_7vlNMI.CffnAAo3kA1pwrK4J_sZh BXf3nXzuHagaqIIO8uyKIl7J2wIqFmU97tNuMKrO7gGJg97HUwM5qWyh4qH7cvpQlAqn3QsjZ.qP v77aAKchSb7kE4WPgZFEAmm9mP8UQ8SGQuqu2tO9qQ77jEps3g2kBTyfLBzCgstWtHAzDyawEphx dOADd0p7M9Fj8nuzbbRjoiZfoRUCeMMGFEjrfJWfb_8GyFHu_DS8fLCrAzqIA3Q-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:42:48 +0000 Received: by smtp404.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID b292bb0fd345409316b9003c09784b73; Fri, 14 Feb 2020 23:42:47 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 04/23] LSM: Use lsmblob in security_kernel_act_as Date: Fri, 14 Feb 2020 15:41:44 -0800 Message-Id: <20200214234203.7086-5-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 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. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley 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 9d83c6832bae..1bfaf9ece13e 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -439,7 +439,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); @@ -1045,7 +1045,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 809a985b1793..fae63c0a1b36 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -732,14 +732,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); @@ -755,6 +755,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; @@ -762,7 +763,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 b3fab8fdbb57..914aecd89822 100644 --- a/security/security.c +++ b/security/security.c @@ -1647,9 +1647,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 Fri Feb 14 23:41:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11383557 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 DDA3B159A for ; Fri, 14 Feb 2020 23:42:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B376724650 for ; Fri, 14 Feb 2020 23:42:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="aHfthvdh" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728292AbgBNXmz (ORCPT ); Fri, 14 Feb 2020 18:42:55 -0500 Received: from sonic310-31.consmr.mail.ne1.yahoo.com ([66.163.186.212]:39611 "EHLO sonic310-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728093AbgBNXmz (ORCPT ); Fri, 14 Feb 2020 18:42:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723773; bh=GV4fsCtl9Zu3zO8p52d7tePzz4dql89E4KeJ6OVte2s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=aHfthvdhxBCEpghpEwVICH77e5AmGG6th09NF51eT0SmqRHRA9KY4vBYhgtslKvXtv+6NfFFjhI5ab0hkhCmUcLk4q/XBycSvW8mcfHJGIyIAs/29cGAEQcLnstunkeVpxrwKOD+IkMgE3/aY2EpObJUMpXpn7gM4FQnFqQsKVfoyK4/vcDLzBCmoWU2GGMnpwF1oml2GmiJyR1LNdG4voeLmRrAa3NN7HwPfb3a06eD8bTp9eehqEYpj6CWa7ZvSUEx8KGQVmvC9/scmO4VaeyGN4lxC7I2H06oPbbcZg4+FbYrUNxcOfy6XX0Tr+lfVNY0abdHXa2AalYtSuLo8A== X-YMail-OSG: 34W5cikVM1kIV8pzdR9IKr2KZpCedlWAjIT0YnpOOMWH6uX.p4b9COqBiZr6vKs s4cudLTqHJaVVQ8y2mJhCNl2_5F6hhvuYJiW.nSgesQmHv7LKLT_YSR_G5YRRcl1kSzpw8eW3_E. Bv.Q.1zkC_VkP4ieQv9ZlNButA4CHVTPIS_.t3zNiKc8E2rfCqutEUY6uYaMs18xfT51XKsTZ3Xg Bn3coRmor09FzASuqVkyUN3Ze8imqIAGNXW2o02Lrd_5SIpxBXckBsSI4d_lvyaBnq3szoawwSvg so.Qar0ms24oyv9162sNPpLFrn24nJjvhq6sBU3Y37mH32JHvN5PgKeycoflby6YCAqU7tsSof6L TkxX8DIR2pxJ_bBiuNRIJmwuni2RYsYzZ.N757txfkMIrUyIfhiPVulgg82p4HwYcpdlvQW1hr5Z uRJm2LsOcB.6PLF3jCEXdlgPhfYOzsEvAjjI_j1NBdKB7947F8qmVoPzly3kBvkG3L4qFm3.tNJf xLYZlUkG0_rthjWp.9LGZTiQDbT7q2idB2gRV2KZjuvKF1Iapn9PZTWGzQVue6_R.UARgQ2nke2p D7ZYp91epcIhRd0gUe6zmyDZmB8I.TbCHZb9EeSpyWfTInRAagp.PZmBTlQRIXbQOhwQ3UWEqmLD traEJLf9OIuTTfng5l4d8a6dcNj.JKIIC37IKBq9YbZgRXxY3GTDgaIE3ypHQI8HH5PGVEuuOyc5 Qk4r4zvi2chGhQW76BymngUt0lHsO3s_g3Cth5BJSeYa2_UdBUQSyFd7FEG9PUEh7WtV3T99jWhK vmbwr.Gu_kO0O_HMEY0z.T71_3A1yZX5oO4HuOtOeuprdcUTCBKex9RxWASncck8kDu69XbtQoaQ p.e4S0DwuXGyjz0DqW8qaRhNSOQIMEDuijaP91FdqTZodEtqAVREgN_YtN7uetV1rjQbO0llaCjI LLp6N3yLksmqevaTrZVqgDLPMYouxjze3Z.hYVRpz9mT52W.dje6auKQwy4_JLEaRv.6sNoDQBKT Xgibt_NUTgFsI_DT6j8VMWNEcM55oJS49zX3rPb2pIY0VqGblfAtc5xDsUdLWOB9inNu9BDzpwzn 6Jpu1LczOuAzR5wBI9n3eNecg2EuGCQFD02oSm9IW3JbJwucfxfnwst7jYpYmZGestZvbBWMvv2B 0cpGDo6Xg7m.5c2uh0qJScRdBv_RsHQpX6kpn9F1fQc2vXzuipYr60OVQvpp9.BhIgxgu4HFtx3r Q7wetZzxwUAXA_5uMM_74.jlpvEjqu2tFY_qGsuqGEYwBdLSgEHMSy53X9X9XUsOhl2zdc1JuSpy yFBvGyQf1LCV4DCZMaZPLYy.AHKMAL_KqwTxoANFTq7GOR.yIUl0cJvOJZ..uJs46cIot6GnO8bV Hy5acV9Kdn3_rtCIblgXPIa6W_ylUknXELWzWCj_M5hSy3D2fEHRSRO3s9e45bVYqPaoj Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:42:53 +0000 Received: by smtp404.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID b292bb0fd345409316b9003c09784b73; Fri, 14 Feb 2020 23:42:48 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 05/23] net: Prepare UDS for security module stacking Date: Fri, 14 Feb 2020 15:41:45 -0800 Message-Id: <20200214234203.7086-6-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change the data used in UDS SO_PEERSEC processing from a secid to a more general struct lsmblob. Update the security_socket_getpeersec_dgram() interface to use the lsmblob. There is a small amount of scaffolding code that will come out when the security_secid_to_secctx() code is brought in line with the lsmblob. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler cc: netdev@vger.kernel.org --- include/linux/security.h | 7 +++++-- include/net/af_unix.h | 2 +- include/net/scm.h | 8 +++++--- net/ipv4/ip_sockglue.c | 8 +++++--- net/unix/af_unix.c | 6 +++--- security/security.c | 18 +++++++++++++++--- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 1bfaf9ece13e..2ad58e2900e7 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1358,7 +1358,8 @@ int security_socket_shutdown(struct socket *sock, int how); int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb); int security_socket_getpeersec_stream(struct socket *sock, char __user *optval, int __user *optlen, unsigned 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, + struct lsmblob *blob); int security_sk_alloc(struct sock *sk, int family, gfp_t priority); void security_sk_free(struct sock *sk); void security_sk_clone(const struct sock *sk, struct sock *newsk); @@ -1496,7 +1497,9 @@ static inline int security_socket_getpeersec_stream(struct socket *sock, char __ return -ENOPROTOOPT; } -static inline int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) +static inline int security_socket_getpeersec_dgram(struct socket *sock, + struct sk_buff *skb, + struct lsmblob *blob) { return -ENOPROTOOPT; } diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 17e10fba2152..59af08ca802f 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -36,7 +36,7 @@ struct unix_skb_parms { kgid_t gid; struct scm_fp_list *fp; /* Passed files */ #ifdef CONFIG_SECURITY_NETWORK - u32 secid; /* Security ID */ + struct lsmblob lsmblob; /* Security LSM data */ #endif u32 consumed; } __randomize_layout; diff --git a/include/net/scm.h b/include/net/scm.h index 1ce365f4c256..e2e71c4bf9d0 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -33,7 +33,7 @@ struct scm_cookie { struct scm_fp_list *fp; /* Passed files */ struct scm_creds creds; /* Skb credentials */ #ifdef CONFIG_SECURITY_NETWORK - u32 secid; /* Passed security ID */ + struct lsmblob lsmblob; /* Passed LSM data */ #endif }; @@ -46,7 +46,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl); #ifdef CONFIG_SECURITY_NETWORK static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm) { - security_socket_getpeersec_dgram(sock, NULL, &scm->secid); + security_socket_getpeersec_dgram(sock, NULL, &scm->lsmblob); } #else static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm) @@ -97,7 +97,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - err = security_secid_to_secctx(scm->secid, &secdata, &seclen); + /* Scaffolding - it has to be element 0 for now */ + err = security_secid_to_secctx(scm->lsmblob.secid[0], + &secdata, &seclen); if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index aa3fd61818c4..6cf57d5ac899 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -130,15 +130,17 @@ 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; + u32 seclen; int err; - err = security_socket_getpeersec_dgram(NULL, skb, &secid); + err = security_socket_getpeersec_dgram(NULL, skb, &lb); if (err) return; - err = security_secid_to_secctx(secid, &secdata, &seclen); + /* Scaffolding - it has to be element 0 */ + err = security_secid_to_secctx(lb.secid[0], &secdata, &seclen); if (err) return; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 62c12cb5763e..5bed7361ec4c 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -138,17 +138,17 @@ static struct hlist_head *unix_sockets_unbound(void *addr) #ifdef CONFIG_SECURITY_NETWORK static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) { - UNIXCB(skb).secid = scm->secid; + UNIXCB(skb).lsmblob = scm->lsmblob; } static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) { - scm->secid = UNIXCB(skb).secid; + scm->lsmblob = UNIXCB(skb).lsmblob; } static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb) { - return (scm->secid == UNIXCB(skb).secid); + return lsmblob_equal(&scm->lsmblob, &(UNIXCB(skb).lsmblob)); } #else static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) diff --git a/security/security.c b/security/security.c index 914aecd89822..2fa826000889 100644 --- a/security/security.c +++ b/security/security.c @@ -2140,10 +2140,22 @@ 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, + struct lsmblob *blob) { - return call_int_hook(socket_getpeersec_dgram, -ENOPROTOOPT, sock, - skb, secid); + struct security_hook_list *hp; + int rc = -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, + &blob->secid[hp->lsmid->slot]); + if (rc != 0) + break; + } + return rc; } EXPORT_SYMBOL(security_socket_getpeersec_dgram); From patchwork Fri Feb 14 23:41:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11383561 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 C3339159A for ; Fri, 14 Feb 2020 23:43:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 985C8222C4 for ; Fri, 14 Feb 2020 23:43:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="IhOX9xWd" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728306AbgBNXnM (ORCPT ); Fri, 14 Feb 2020 18:43:12 -0500 Received: from sonic314-27.consmr.mail.ne1.yahoo.com ([66.163.189.153]:41062 "EHLO sonic314-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727932AbgBNXnM (ORCPT ); Fri, 14 Feb 2020 18:43:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723790; bh=Nz2BsKw0RpJ+BAc7gr0ehY/W5OLzgpZJmHP+xz0cFr0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=IhOX9xWd24TCqA/HHOtLxvnRAD68THAmvSHZvtQqxCtm+hQ0m886tmLvkBwOXNuzeB+5GrxYG3igoXJ3+mLPoJ3/hniqWMW38NKRuSJN19qtEcKr7lrZMgT416q9Kjb0IoxDNU7wvKz1j/v+MzEvszYJKFaJGtZYVPmB84OlXIXH2lkHRPvXgzk2w9Ttwo0PS45CZel7H/dRUxcvAirhkWSr0/0paZ/ziFE43+DOyrRaoUXSHDvGsPbLrSBD4srF70vI5WKDIXaBseGK+DU3knr2SQQwS8GyMLtlo0d5MXweLwzaMAb6rA9LSbeK77syo+KITkR/Ye6PXCg+Q40aww== X-YMail-OSG: xepI7cQVM1n4INpAvz0NqHYQICesSd8USJhNASysUef8trulMfsR9i0ONf5CQoP BjjyRU4UQYiJg9i.ZqQEVdkTiYn.koXXohaNgGrjiS0xUoz2VA5GuA4r5QWOtCTC5aD2tfyoWFjU sMAfkgiGmj7i68nQlXGYSI58i809gYjzJVYTr01w4e1JMbhidZRlPhIJ4bs565ueeZH8PVqfGsv6 cPqVXKFfLSpzzfR3FRsSclOSttQ2GnwFOc5b_MpTsG6iPEG.JCnkz35nB3PFG03tXOriC0YQJMz_ VGQIg8mJ5w7MxEuISt_SqwNhUkbqEXifYzo17WrTo1Kgk8Qxim.1RF2jrYOvfizOg3I8PMtnoEDd 9Go85M91Qr_5c3l3ZcNNGeZsJI_B2aUdP7.sGQ0g5UolWjOt5r5X88D1k9GYC7vooeeHq3GAxQTd Jqh6zZUUTR18BCApsGXZF2LS5O1DA.qRi.casyNSs7g7KG2cQdsC9SsCXpofkvLs1Fo2n3OZ813n fwv2JhPsJR7GXTO7yAmxF6B.4sR8vFGBO6M1H27ichwoZGwPYqaYaxbd0YExexPn7Kkv2d15AYEm PWsH3YbPS5McdgGgQwNwAB661ZuLMCZ2xWgGAUSkxbAC4VKO0ItLqDYG44N5IYkrCY_u6.ZmS9vp In8uPb1LcvxdfseXkxkzT0Noe80c.AauqIa2dREKEWyS26KSd94kZIMilkeUafPs7xLp.TbIWWxr w5EgNWbH9gIPM2BLJhlfu7z84Dws.QrCl7dz4NCqrFRrhRGoHvEoc73xGelfrFHVlB8b47w.9ACn 84WVHBwhLSLXxG0LLGDi4xWXdPdArJS3.2mKx_8Vp_Vp9Dp3kdeZMShKQECTrOpq35ibvWCJlPPq rgcWNshoNm9t0ijKnbvZhi0MYWZrHvUBRP12JiWATtsloa4ec2lqrnuDSYoO42KNBjceMsWg6YYL h4CgggELXyEy6DsWjv4UaECwuXDURA4ARD6rIoB.SZGbUGPqEfwyxhIf7bHOnvsdVCL6mgwNbw02 MBjDUj_FyBdkJOGaMX8jWJ0CZTyXkZOXc8jduvqKSRv.fYDlKdxJeIYY6n6VPErkNI2ydQBXuXl0 jXOYs._JCgPr0WtMXPoo_3CPhrKJZWKY33mwTdXbx0uXrZCMo6U9ZRwPoJN.OWmycYELtlaPuHnN K_5Ouyx6.ratJCm84qpH3jUI9GfYtdNGDAicpnaFv5QuvlJ.ep9mFFHv4AwSbbf1kCRg.IhUBAHO S_3goA_UmxWS.XN3w_U_XWoLkF339LLjHaBWgNfQ5FV5LLrq1SXGZuh2L_J5qzXcJ4B5AmniwhSs W5N_rhPgZM9r6jdh_efMM2QywoxfIxf8_IeZb3dyKbkLXD0HlcfZfN4bpkIg2Lanc91p8nF5xceD vtG4_AMefUfl0fWSs.r.QjjIKwTPYZEP8zDLawVe5cLxKNotIjoih6Lat38O8Cu4D Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:43:10 +0000 Received: by smtp421.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 034a07a14f1305e890adf12d8ef35b61; Fri, 14 Feb 2020 23:43:05 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 06/23] Use lsmblob in security_secctx_to_secid Date: Fri, 14 Feb 2020 15:41:46 -0800 Message-Id: <20200214234203.7086-7-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change security_secctx_to_secid() to fill in a lsmblob instead of a u32 secid. Multiple LSMs may be able to interpret the string, and this allows for setting whichever secid is appropriate. In some cases there is scaffolding where other interfaces have yet to be converted. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler --- include/linux/security.h | 5 +++-- kernel/cred.c | 4 +--- net/netfilter/nft_meta.c | 12 +++++++----- net/netfilter/xt_SECMARK.c | 5 ++++- net/netlabel/netlabel_unlabeled.c | 14 ++++++++------ security/security.c | 18 +++++++++++++++--- 6 files changed, 38 insertions(+), 20 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 2ad58e2900e7..65adcffafee9 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -498,7 +498,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); @@ -1304,7 +1305,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 fae63c0a1b36..e654a5a84408 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -756,14 +756,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 951b6e87ed5d..e12125b85035 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -811,21 +811,23 @@ 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); + /* Using le[0] is scaffolding */ + err = security_secmark_relabel_packet(blob.secid[0]); if (err) return err; - priv->secid = tmp_secid; + /* Using le[0] is scaffolding */ + priv->secid = blob.secid[0]; return 0; } diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index 2317721f3ecb..2d68416b4552 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c @@ -45,13 +45,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", @@ -59,6 +60,8 @@ static int checkentry_lsm(struct xt_secmark_target_info *info) return err; } + /* scaffolding during the transition */ + info->secid = blob.secid[0]; 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 d2e4ab8d1cb1..7a5a87f15736 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -881,7 +881,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 @@ -905,12 +905,13 @@ 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; + /* scaffolding with the [0] */ return netlbl_unlhsh_add(&init_net, - dev_name, addr, mask, addr_len, secid, + dev_name, addr, mask, addr_len, blob.secid[0], &audit_info); } @@ -932,7 +933,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 @@ -954,12 +955,13 @@ 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; + /* scaffolding with the [0] */ return netlbl_unlhsh_add(&init_net, - NULL, addr, mask, addr_len, secid, + NULL, addr, mask, addr_len, blob.secid[0], &audit_info); } diff --git a/security/security.c b/security/security.c index 2fa826000889..e0f9287483aa 100644 --- a/security/security.c +++ b/security/security.c @@ -2002,10 +2002,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); From patchwork Fri Feb 14 23:41:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11383567 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 9892D139A for ; Fri, 14 Feb 2020 23:43:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6409524649 for ; Fri, 14 Feb 2020 23:43:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="Kv70HIUO" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727998AbgBNXnO (ORCPT ); Fri, 14 Feb 2020 18:43:14 -0500 Received: from sonic308-16.consmr.mail.ne1.yahoo.com ([66.163.187.39]:46019 "EHLO sonic308-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728176AbgBNXnN (ORCPT ); Fri, 14 Feb 2020 18:43:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723790; bh=pJrAQQDy16N+C5H2badS//vd/Z5Dh3P9pJ/xvpazbLs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=Kv70HIUO6EIfNmpJLiWvuv/5pQPIB8LW0ewWanBECCpds3Ihc7yV99POGt1wz0OXC9apQ/lEbtupRXWswm0Y0iM5jgjwpSLx6ioPe7++Zw5hADARdjYNt/yA8vHOKS396EfTe7ydaD+QlgRFrTbzsRVUECWW8xiQLjyY1bO1dtJxbXCI7UVnSvG3WT1mAfNVeFuVNxeYHRngWwocAbf8lvLNLBe/UntqXyvGmAb/GcP9UgV2ug/iLsS/h7EiSFmd/eQ4i9+EWqlV0F94gPSa1Bda8TLdlzkFSnY2ruT6hb8OmlXTIQQvwnizvLfOHJZpmRs7j8pReFJuFaSs5k0Mow== X-YMail-OSG: v.qx020VM1ndcT9evCZW6MIPoXusuQETtP4l4_qsLhtpP6LRClL2.mrB8A3qDUO Df9NQY5mtQfRXKs.wLsb8Hta.RCicegQ5O5XfaKlvyi4xMF8qFjTLVPnNVEIFGN3ER5yt9CRNAcW LlRtAznR37YEsvU_8LaUv97y4_5ccoyfCh.nSyBzGUOny0DB4YbAgVVIPj80bj6RjQppWC6_EyWV ZeAZMjxUGyIYCy3UuYcFTNw8oGDR0dxTxHMQlzUsUl5qD._qubmEVUdRULkhVQCmbZoJ74q7UdZ_ c8X9RFyzxwljtlya6I5yZknNNljBmilFmdiMZUNM79lmAstnGUn0BEhL.ePidtWW15rkVaYp8oFp WWxD1HkAZxAyPWv3hNYBmRXqhugGXOH2E0znh4gnUaPw39kdQemzQ0FWGRWdrzt0w7p0KpoAEaOY IhKPIsMdYedltwOfxxlye6L1bJsM1PzEur8Ml4ML8geXDAyGvfB2ELK_OUIAzxVQutZSLlD.vyCt eyTsQBE1tl3OOf4ltOUkr7rnirF6AH8D9AFAt76T6tThnRqejyPnzNv2Q_AqCul4sBFeIh5L6nkc 9VjkuN3xUkSiNHIpGvbhQQ6HjEND72DZY8cl08MvjH17iUOlCmY7xaHfI2OcLgMLtRa6FOrfOVK8 OtbNIGlEEXmbzl7iIrXPdDH.i.S4NPECZPqezh0_q.iw6gKBOOvtd7hcQ6fU8m7oFyGWBslxv2W2 4jIlvG_FsFR7Wofm18vinLV0sB4_KbCWZeB6puNhmDK8eZa9m5QFmey6AU_NeC9iSSSNYzmFjCB6 3E1JkSRIrTpPwEH0HotsK.QmyAnq33opK.aUZj4vDSahEFhIWLrHjPtnZisrN1O_DlMoo1tg9YW7 sTr8.pqDMZAar9QbDR1nXHMvViG1QzKr4RzDb25Bnu50cweAMa5iCnYqyCr_t_Tv9es3Vs4CtR4x uDpxxrcCde96RJ5vWtNBM1Y33Vp9OcQVtnFktnLSogz4RWZv0FbMNtXRspI0gldfG2hBmxyGrqKP aRIJ3YSjmZbXAO.WqGrFFgwIbsBymHfXqSkRHg08jfuqTwjEZIIsMtFWZ9oAjqVh9EPytk4Orenx OYzHJgdccYI.olB99YNFxruasr04b1AOZOmMU9bxGBmQyhcXLINu8m_q_3gFjQUuc4ObryXzCZ8y qdJKnLGCK1eeh4KM3Unqt5NCiUBnpeM8yYIoZ7.gHkKRi0zKd2EyAHL27XKhWQ67QGau6mc5BX6P 9vmelvdV5kaqhd8wgWdlMDqOczAtJ2EWhhhgnAXs5vEY0j2o.jlcWO.9pZKiIMTbOmHaAMWoJGdr eB20qj_q70WylREUDh8UfENLBMqiJFiNt8zTfZB2FScNRttRwHNBg21OjdbR527yhrQd6ZF1hsDX HF6UCWOOi_iMRxs4LJGvGY.LH.TLowROem9wveMFHIB4FfOtaID8U6vNJzEypxScK0bE- Received: from sonic.gate.mail.ne1.yahoo.com by sonic308.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:43:10 +0000 Received: by smtp421.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 034a07a14f1305e890adf12d8ef35b61; Fri, 14 Feb 2020 23:43:07 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 07/23] LSM: Use lsmblob in security_secid_to_secctx Date: Fri, 14 Feb 2020 15:41:47 -0800 Message-Id: <20200214234203.7086-8-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change security_secid_to_secctx() to take a lsmblob as input instead of a u32 secid. It will then call the LSM hooks using the lsmblob element allocated for that module. The callers have been updated as well. This allows for the possibility that more than one module may be called upon to translate a secid to a string, as can occur in the audit code. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler cc: netdev@vger.kernel.org --- drivers/android/binder.c | 4 +++- include/linux/security.h | 5 +++-- include/net/scm.h | 5 ++--- kernel/audit.c | 9 +++++++-- kernel/auditsc.c | 14 ++++++++++---- net/ipv4/ip_sockglue.c | 3 +-- net/netfilter/nf_conntrack_netlink.c | 8 ++++++-- net/netfilter/nf_conntrack_standalone.c | 4 +++- net/netfilter/nfnetlink_queue.c | 8 ++++++-- net/netlabel/netlabel_unlabeled.c | 18 ++++++++++++++---- net/netlabel/netlabel_user.c | 6 +++--- security/security.c | 16 +++++++++++++--- 12 files changed, 71 insertions(+), 29 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index a6b2082c24f8..a9d9b69d5596 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3107,10 +3107,12 @@ static void binder_transaction(struct binder_proc *proc, if (target_node && target_node->txn_security_ctx) { u32 secid; + struct lsmblob blob; size_t added_size; security_task_getsecid(proc->tsk, &secid); - ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); + lsmblob_init(&blob, secid); + ret = security_secid_to_secctx(&blob, &secctx, &secctx_sz); if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; diff --git a/include/linux/security.h b/include/linux/security.h index 65adcffafee9..fdcba6e8d242 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -497,7 +497,7 @@ int security_setprocattr(const char *lsm, const char *name, void *value, size_t size); int security_netlink_send(struct sock *sk, struct sk_buff *skb); int security_ismaclabel(const char *name); -int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); +int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); void security_release_secctx(char *secdata, u32 seclen); @@ -1298,7 +1298,8 @@ static inline int security_ismaclabel(const char *name) return 0; } -static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +static inline int security_secid_to_secctx(struct lsmblob *blob, + char **secdata, u32 *seclen) { return -EOPNOTSUPP; } diff --git a/include/net/scm.h b/include/net/scm.h index e2e71c4bf9d0..31ae605fcc0a 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -97,9 +97,8 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - /* Scaffolding - it has to be element 0 for now */ - err = security_secid_to_secctx(scm->lsmblob.secid[0], - &secdata, &seclen); + err = security_secid_to_secctx(&scm->lsmblob, &secdata, + &seclen); if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); diff --git a/kernel/audit.c b/kernel/audit.c index 17b0d523afb3..0fdd51d03598 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1418,7 +1418,10 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) case AUDIT_SIGNAL_INFO: len = 0; if (audit_sig_sid) { - err = security_secid_to_secctx(audit_sig_sid, &ctx, &len); + struct lsmblob blob; + + lsmblob_init(&blob, audit_sig_sid); + err = security_secid_to_secctx(&blob, &ctx, &len); if (err) return err; } @@ -2061,12 +2064,14 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; u32 sid; + struct lsmblob blob; security_task_getsecid(current, &sid); if (!sid) return 0; - error = security_secid_to_secctx(sid, &ctx, &len); + lsmblob_init(&blob, sid); + error = security_secid_to_secctx(&blob, &ctx, &len); if (error) { if (error != -EINVAL) goto error_path; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index ef2f5e7eec7b..d6723c225c7e 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -966,6 +966,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, char *ctx = NULL; u32 len; int rc = 0; + struct lsmblob blob; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); if (!ab) @@ -975,7 +976,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, from_kuid(&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid); if (sid) { - if (security_secid_to_secctx(sid, &ctx, &len)) { + lsmblob_init(&blob, sid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { @@ -1218,7 +1220,10 @@ static void show_special(struct audit_context *context, int *call_panic) if (osid) { char *ctx = NULL; u32 len; - if (security_secid_to_secctx(osid, &ctx, &len)) { + struct lsmblob blob; + + lsmblob_init(&blob, osid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { @@ -1368,9 +1373,10 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, if (n->osid != 0) { char *ctx = NULL; u32 len; + struct lsmblob blob; - if (security_secid_to_secctx( - n->osid, &ctx, &len)) { + lsmblob_init(&blob, n->osid); + if (security_secid_to_secctx(&blob, &ctx, &len)) { audit_log_format(ab, " osid=%u", n->osid); if (call_panic) *call_panic = 2; diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 6cf57d5ac899..1ca97d0cb4a9 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -139,8 +139,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) if (err) return; - /* Scaffolding - it has to be element 0 */ - err = security_secid_to_secctx(lb.secid[0], &secdata, &seclen); + err = security_secid_to_secctx(&lb, &secdata, &seclen); if (err) return; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 6a1c8f1f6171..68c74c28eae9 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -331,8 +331,10 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) struct nlattr *nest_secctx; int len, ret; char *secctx; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, &secctx, &len); + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, &secctx, &len); if (ret) return 0; @@ -643,8 +645,10 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) { #ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, NULL, &len); + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, NULL, &len); if (ret) return 0; diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 410809c669e1..183a85412155 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -175,8 +175,10 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) int ret; u32 len; char *secctx; + struct lsmblob blob; - ret = security_secid_to_secctx(ct->secmark, &secctx, &len); + lsmblob_init(&blob, ct->secmark); + ret = security_secid_to_secctx(&blob, &secctx, &len); if (ret) return; diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 76535fd9278c..b7b296fe0c0b 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -305,13 +305,17 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) { u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) + struct lsmblob blob; + if (!skb || !sk_fullsock(skb->sk)) return 0; read_lock_bh(&skb->sk->sk_callback_lock); - if (skb->secmark) - security_secid_to_secctx(skb->secmark, secdata, &seclen); + if (skb->secmark) { + lsmblob_init(&blob, skb->secmark); + security_secid_to_secctx(&blob, secdata, &seclen); + } read_unlock_bh(&skb->sk->sk_callback_lock); #endif diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 7a5a87f15736..0cda17cb44a0 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -375,6 +375,7 @@ int netlbl_unlhsh_add(struct net *net, struct audit_buffer *audit_buf = NULL; char *secctx = NULL; u32 secctx_len; + struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && addr_len != sizeof(struct in6_addr)) @@ -437,7 +438,8 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - if (security_secid_to_secctx(secid, + lsmblob_init(&blob, secid); + if (security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); @@ -474,6 +476,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct net_device *dev; char *secctx; u32 secctx_len; + struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, @@ -493,8 +496,10 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); if (dev != NULL) dev_put(dev); + if (entry != NULL) + lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(entry->secid, + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); security_release_secctx(secctx, secctx_len); @@ -536,6 +541,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct net_device *dev; char *secctx; u32 secctx_len; + struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); @@ -554,8 +560,10 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); if (dev != NULL) dev_put(dev); + if (entry != NULL) + lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(entry->secid, + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); security_release_secctx(secctx, secctx_len); @@ -1076,6 +1084,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, u32 secid; char *secctx; u32 secctx_len; + struct lsmblob blob; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family, @@ -1130,7 +1139,8 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, secid = addr6->secid; } - ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len); + lsmblob_init(&blob, secid); + ret_val = security_secid_to_secctx(&blob, &secctx, &secctx_len); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 3ed4fea2a2de..893301ae0131 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -86,6 +86,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, struct audit_buffer *audit_buf; char *secctx; u32 secctx_len; + struct lsmblob blob; if (audit_enabled == AUDIT_OFF) return NULL; @@ -98,10 +99,9 @@ struct audit_buffer *netlbl_audit_start_common(int type, from_kuid(&init_user_ns, audit_info->loginuid), audit_info->sessionid); + lsmblob_init(&blob, audit_info->secid); if (audit_info->secid != 0 && - security_secid_to_secctx(audit_info->secid, - &secctx, - &secctx_len) == 0) { + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " subj=%s", secctx); security_release_secctx(secctx, secctx_len); } diff --git a/security/security.c b/security/security.c index e0f9287483aa..dae86629a2f6 100644 --- a/security/security.c +++ b/security/security.c @@ -1995,10 +1995,20 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) { - return call_int_hook(secid_to_secctx, -EOPNOTSUPP, secid, secdata, - seclen); + struct security_hook_list *hp; + int rc; + + hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.secid_to_secctx(blob->secid[hp->lsmid->slot], + secdata, seclen); + if (rc != 0) + return rc; + } + return 0; } EXPORT_SYMBOL(security_secid_to_secctx); From patchwork Fri Feb 14 23:41:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11383569 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 477C5159A for ; Fri, 14 Feb 2020 23:43:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1D92224649 for ; Fri, 14 Feb 2020 23:43:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="T9/Zv8aL" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728363AbgBNXn3 (ORCPT ); Fri, 14 Feb 2020 18:43:29 -0500 Received: from sonic310-31.consmr.mail.ne1.yahoo.com ([66.163.186.212]:39642 "EHLO sonic310-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728033AbgBNXn3 (ORCPT ); Fri, 14 Feb 2020 18:43:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723808; bh=N0JMRKHo4PzCnQoum1C1molfIvuCl39NYAfI87+Gfsw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=T9/Zv8aL1npMIkLC+Umc3b13TB+LYFPT8cnRihFh7T27v2WjY810HG5Wcwz5ZMLMY21bDT4ttdLuN21QngI5y4e5rDLxKT2dFb1lzIeDTAl0EdiQyOnHeRdZxI6SiGMSVFlVXzzpW5iORp7xqZoVBX9q5MrkEN/NJ5Y4g6Jjkxk1eGDJyGRNhPCuKj+GSbzvDTH6KtsVA8dn8Tu/U3ifUq8WZsO3IF8AqDMn30GqS8OU1RvqE43QKlCmJXZ9mo83fLh3W+PEhuXyRpY7klLlQc8rvdHGPn98IfNA1z0dn817G3aFa/6BurRMK2iEA155KQREZKtBWEamgDCzyWLb7w== X-YMail-OSG: 7kbMmwAVM1lEvyOvy35W0vd00VCWJ0nZxiJqeTUW0N72tfgWuReglwyineaywAf 2vW4UISV2cshCnNVOX3cTNadLWqF_nOZ.Pm0PvxZEVeq7gHcX4vdXp2SoGnzUcjDVTWsirKy3q3m q2fbSK1uASGXmr6HqRwYZGUp789_7tyYdYOFF_roAffKh1ALYzFEVRlrK.wEzBmO2CBwpYNM2eHQ wOIxJVls.cNPPF9dyAmIgAOTAzjVTVgDBqU7hkgMCPiQd5HNigawPbQIsJvq.QQZgQ9Xtz7aRakS iw.NPFezxkiiinEVrttzj3ADlfMO9teYVu0nMSOCjGsOHuFAnW2BCl4O01_ZWwJYHQQrBLMUyPsG TPPVJsEtAGvpxxd0CESPgkrnkjrHWt_WRGp3aGMkRUei1Kql.v2iv6JfLKYxx6fa8dmD34_FhuJV ZRnwL85Bu0D_hLGPq1kRsuEF3UX2209EYzrfc.97jyMloa8C7ff4eHj5E2Zd8z9pup8JQ15ZKyHo Ni61SFdAF93ferfLH6GU4LtTeaIUtHDSfU_zPRiFGW3BGSwy1fnrPVNhkLif_d7RNDxlD5vu.Uge 5fPR1690q.eVoJgR512npqpDidrTB.pLu0thwoo3Wq3DQ_ifTdeob9ZzCIrPnucvmikN7q.zUG2U 4SzIfLxwoK_RUSSEYMzeVjrMSWgVqYO_nni0CtMtRhOQJsuR0ajExkUEFJmeYD5Y6s1jRfIVYO8i ssxhJJfBTfLF4Q4tOuEs3vSt0OjU53RkzU7Eu3S_1dWGWdvhiBbk8J5sFfJTQCCjYvOxhlaD7iJ9 wlfVIVtAQBxhhjQ2h7iHo1L5wGlG8KOisLUfCNGCNwwhF9dQA1RHFZCSe7qcvyEiFcKNdZEV5yRU QgfVaTIhh5XBJzPo39eFPzqhFBOuPIOD1e7ipVtg6i7l.LAd4RW.qpYixnVbutgVtoUUxMZjFqC_ GhJnk86ednq7v4LKptx9NbNMd75lWsqi0cK19bA59csPf4IVgz2zXHus4FW81PDR9jcpyus8wvvq LeAa_L6OUQ7vk3DkEkPp6FduX1FSOtb8m6dzKRgE6kpht0a8JErtFmr8xPzS8F0nQj1jOsVz10wK Le8cl5ZicBfKenjFuKB9rzwqDHHnazA1fl5dC5Wd27R4kEs7o7P.aFM8zXnvdhQ2D6hwQjUhAURY F.cKTCtROCMqgQIjzSS1dliy5WitqG2RPBuRfsvJqNpBg1FxcvCh7AvJW5ucCzvo0GP_0TD8Auq0 dvLza7fs1Pp5jgn9S6DxxnorbmNu8x.EcU22ilx2IFdNhLIUKAhwnvIAVcPluwswFgNZMhcTKBNT uBEiFbwxtgUE.9rd4rQbYdxn2QZE5rd6fFLT98sGV5bpBPkAsA7swAyH0mSz._IEQxTLFAbhLeT3 DqVY4vgRGnhsO2uCWCtVF20Y_yM5zU27X..tKPT8aldC.6EtgwSrwTy9QK_ZxOxnp2N8- Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:43:28 +0000 Received: by smtp411.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 1b596ec9113447dd0b17d9e01e17ce29; Fri, 14 Feb 2020 23:43:27 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 08/23] LSM: Use lsmblob in security_ipc_getsecid Date: Fri, 14 Feb 2020 15:41:48 -0800 Message-Id: <20200214234203.7086-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 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 Signed-off-by: Casey Schaufler --- include/linux/security.h | 7 ++++--- kernel/auditsc.c | 5 ++++- security/security.c | 12 +++++++++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index fdcba6e8d242..3ceea6c51bed 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -468,7 +468,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); @@ -1176,9 +1176,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 d6723c225c7e..032cdb603ac0 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -2285,11 +2285,14 @@ 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); + /* scaffolding on the [0] - change "osid" to a lsmblob */ + context->ipc.osid = blob.secid[0]; context->type = AUDIT_IPC; } diff --git a/security/security.c b/security/security.c index dae86629a2f6..9d67db68f6f2 100644 --- a/security/security.c +++ b/security/security.c @@ -1815,10 +1815,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 Fri Feb 14 23:41:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11383575 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 48E6217F0 for ; Fri, 14 Feb 2020 23:43:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 28879222C4 for ; Fri, 14 Feb 2020 23:43:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="TOHugdpe" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728068AbgBNXnh (ORCPT ); Fri, 14 Feb 2020 18:43:37 -0500 Received: from sonic314-27.consmr.mail.ne1.yahoo.com ([66.163.189.153]:39692 "EHLO sonic314-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728365AbgBNXnh (ORCPT ); Fri, 14 Feb 2020 18:43:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723815; bh=I0OzVIRzpJnd3KCmF7mgLgegupqx8ZAhm+uAmwgUltM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=TOHugdpenJZh81YQWLIW15xGKlRV+my0S0pCBHX/rbS/HxldN5Omv19zl4KLW2BwQlIAAe6UUbb8T+LlV/VgYt09dXLDiY/+9x9xRVxiz+mVNPtoN6Sd1l4q0XiGlRabd6kJ8vuxDIfkW86p4dQBZhm01nFZhRnOX31PfUPnzuKZPUjAIvU4kXc/EitRxjL5vqS9jTQKN/zymmgKYUH5UeyxhI3w+vZwhIy4K9v+LYZwlYeOrbS/+MpEyU+d37py91+i+F+BYuJSbALAqqzJNVrlU34sVB5UsmC6t3fvXoNqwUHAxNksnsRrA4o/WOSb1nI1uW0g8PvqR8lgVL1tIQ== X-YMail-OSG: 7OP6UPIVM1m1SQsFq.JXEf1P12tFaRUAIoCVZkM.gWqbgJh8cdKwGMkklveb9Rg wgHGHIY9XrXB0wPavM3PPpdDvA20FJxbuLp7D6IjYZJ1gvXhdAS4m0pKXg91GpjHqQjQ986HeNmG s.vNIqEUPnwSnqoX58vnSYiZtRwVlegw1cuno8RO2DhsAAP75O64PKNI8xPyDNDMn7nq9H.YMDSI 5c11RcE_rs2vBAyntAnzEiMjii7itAIPUR0zFW9HfAY7Sufx7NekqxEPDxfMJNqBTk6ZqsnWrsrn u6EvsYGuXH1vxNUp96Jpy4tniuyEYs3h1.d6ZqS5dOrhmf6g_mjgjF3cuC5XwCXwL7aGYfhBHRde HTdjXQBg2Nkts0slzVSeV4bCEb84Wgm4fNIvV0Y10qqaN0w4BnroV2xdWVtAi2EvhzmAsANNqrBt h9Reh2hss2yNTOzk9sXxG9Q5y950R.Edcp5DZh983r89TS65KsD4Gfm3Y4.ShYUZG7aPDhdDlzhi DMxH0q2sBCtRMn0blsxYsVc6es_gzo5SxQrY11ctMXiJhCQ0uU1rk91MXc0Z.gZFZFrPmfCdqP7u dlnfqVzfwBb_ztnCVq_EmujMvBkHg4ZSB8s_f19M4nlmKZMrXdtCMoObtJEdG3qB6fnpqI5emwdj w5gbdstFzGFMNqNM63tc.b_jNG3JE__hamBU9YLntM0I5F4DIvRDSmkHaayJ7pS65EgIHElmzfg1 oueaU7v8BWdQ_9je07GXAmLlI0ij_6u5Mq0rk6SW18yGxvyUnwK96TGEb.Atu54W_XjimG1cCZ9F UT0Nzi2.8VLET2cjLBAega0sWelhlpQgfyvN1Wn2CEKnql_xwQLgKGFQNwxWq3ea4QFxMiL_vv62 UUI3lG_FTJwHPKxHulTtlQClNHa4xlkSGRClKGE3pCN9vNvkrFP62b_JiEm3enMZWFKmcsgjHIPR F2z2rtRHIvFvXlKz.qxK0U0UALAK3O.rzfgz_GWPmz5SPfI9MkwmWOKRwv0x7W4BYODFP2EP3jUW UZcLuMROyFWxH52pLWVnPZCQ_KbVDpS2wz3yR.UKBTRV6H4s6hXFwIkY3o7MFYrazaDUT_e1cP2v xXmxHPyVrwfcWvh6vx6ZbibxEiCR.dEImv_G_xPFgdOlMg8ooAgPYPUcyT6p4gw_jTYW2aPlFf0n j7GGav7FzY0Kb_UnHIxb0cVmsSyUyAGRFLFX27CmFQ75FkYML6qjykoPSViPXxdHr2uFMgzMGwuC _mthO.4EO7pPTPQv5vsirGkkLNUXQkVhuWZbZmKAK9shNu0M2jW6VWxtYOYk4gLrhhJyNQC8rPAq CvlO7YX6xdAzuHM8CdDmdXSKLXq7T1bDpyPOYbQ6oL6IC3Olmot3GzcyGCMaQCmUns.GEPPnI74x rGk3qSbCjdiOr.Pl5Ms4C19MOtOS6oNhGWMCh2cTFg8136rxgGuFM4Q6PXXRDHNOd85UHLg-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:43:35 +0000 Received: by smtp411.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 1b596ec9113447dd0b17d9e01e17ce29; Fri, 14 Feb 2020 23:43:30 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 09/23] LSM: Use lsmblob in security_task_getsecid Date: Fri, 14 Feb 2020 15:41:49 -0800 Message-Id: <20200214234203.7086-10-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 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 Signed-off-by: Casey Schaufler cc: linux-integrity@vger.kernel.org --- drivers/android/binder.c | 4 +-- include/linux/security.h | 7 +++-- kernel/audit.c | 11 +++---- kernel/auditfilter.c | 4 +-- kernel/auditsc.c | 18 ++++++++---- 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 | 42 +++++++++++++++------------ security/security.c | 12 ++++++-- 10 files changed, 72 insertions(+), 47 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index a9d9b69d5596..b133f0af5151 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3106,12 +3106,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); - 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 3ceea6c51bed..b5ffb2286bcf 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -451,7 +451,7 @@ int security_task_fix_setuid(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); @@ -1103,9 +1103,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 0fdd51d03598..d7d51ad5d234 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -2063,14 +2063,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(&blob, sid); error = security_secid_to_secctx(&blob, &ctx, &len); if (error) { if (error != -EINVAL) @@ -2278,6 +2276,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 || @@ -2288,7 +2287,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 509eb21eff7f..c9a46b78b932 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1326,7 +1326,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) { @@ -1357,8 +1356,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 032cdb603ac0..3e5ccb7a46d1 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -444,7 +444,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; @@ -641,10 +640,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(&blob, sid); result = security_audit_rule_match(&blob, f->type, f->op, @@ -2382,12 +2380,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); } @@ -2403,6 +2404,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; @@ -2414,7 +2416,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; } @@ -2435,7 +2439,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 0cda17cb44a0..e279b81d9545 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -1539,11 +1539,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 a9649b04b9f1..3dfb573c7171 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -48,14 +48,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 9fe949c6a530..1f50f68a6f5b 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -384,12 +384,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; @@ -412,10 +413,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; @@ -436,10 +439,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); } @@ -597,7 +601,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; if (!file && read_id == READING_FIRMWARE) { if ((ima_appraise & IMA_APPRAISE_FIRMWARE) && @@ -619,9 +623,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); } /** @@ -703,7 +708,7 @@ void process_buffer_measurement(const void *buf, int size, } hash = {}; int violation = 0; int action = 0; - u32 secid; + struct lsmblob blob; if (!ima_policy_flag) return; @@ -716,9 +721,10 @@ void process_buffer_measurement(const void *buf, int size, * buffer measurements. */ if (func) { - security_task_getsecid(current, &secid); - action = ima_get_action(NULL, current_cred(), secid, 0, func, - &pcr, &template, keyring); + security_task_getsecid(current, &blob); + /* scaffolding */ + action = ima_get_action(NULL, 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 9d67db68f6f2..85cdd24abcd6 100644 --- a/security/security.c +++ b/security/security.c @@ -1732,10 +1732,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 Fri Feb 14 23:41:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11383577 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 94CC2159A for ; Fri, 14 Feb 2020 23:43:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6352D222C4 for ; Fri, 14 Feb 2020 23:43:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="q5HqUqDN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728264AbgBNXnz (ORCPT ); Fri, 14 Feb 2020 18:43:55 -0500 Received: from sonic310-31.consmr.mail.ne1.yahoo.com ([66.163.186.212]:36699 "EHLO sonic310-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727979AbgBNXnz (ORCPT ); Fri, 14 Feb 2020 18:43:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723833; bh=u6fnRIvxVpCx3zktmvDIcWNsrnFJMt9iY6RLJaZIX6E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=q5HqUqDNbK6cz6Wlo2XbDZ3Ox/xArDa/Z559sTIrmls8mkHu7QFap1jNoc9nkDc1EJya2b9k/H29MtdYgTgpDgoabGKdsyOCycgR7chRrToKhRh7wJjNLlJr5CWm82uKmPxSAAzr7YPKeshqodfTth0MG1wR3rzP6tqm+RNKaf6lHQehAlic19ncMrllmSptJO0ztQJnxodKBP0qa8FIZgRLDOwweTCTXuPQQnimpuSVH3RxAZ/Wmw8Y6mV9WtEVaCGy0nY/GKN/EIAv+Xz1UdYM88X0O2TOAqZzD2VGw+K9xy+MbnNgh30XgNx0rq75MJ2lLQ8H3keC3Lg2uUkSTQ== X-YMail-OSG: .3DRc4IVM1mi1c3bGpIAHaW3iGLb_5ugykLV93EwDabrjxmyMYxq725Tyzw8DtQ eZXURHjjQeqnRw.vlTZYXBxpsKjKPnlNpWGVQjecwhuvcT9clSgZRexbWM6ft.MdFa_uherGZSoV 2e7IlmaeIPjQWFs2hztcCw_GPumsE.ckJsThig3nPagFDbth4tN.Xq39Iac8uECrK0zsP.hBMuyR ijCzN_mBQRMuJg.Gn3MjrRWbish0DsnEov1tDSMhNOVRihNXj9EChxoh9IiNt5xx7q70oj2zzDTg 6GgpKmiuKJrkdycetxxHV3BaFFOTzQv2z2fc0CrJLgRklDvLEZzYwsJ.ZJsPQnkbArl0kT1HvYX_ 8hhirc27C5Dr6KZaN4RyU2HtdQHvraHIQJdgWniQUYfmBmUetbn9VjPVzLiBdb_t.UrVWA2RMtj3 5mrRZRiNdJeyTyG45GcznWx2sl5wnvsPkIUhH5LuO3JvKdivXAkGcGN3WOjS.St50KzDphvBFcBt T2JjQ6Z9eW7x4PS5XF6yT5EPrLcoSVrYZbA3GuV_2JctvP1y3yGR2H08H6ePpVuMpHm6h5J2DhPL UGr0l74iKNOouhi5VwnMXJD9mY90platm4mBABF4jrNIUQuijPcvZA4zyyLq5x6xuGKkdMFTPqH0 jyNhXijqT7WfKJpEU2h0eR4DT8Pcs7rE6DdV6b9Kw6caj5m6IJL2m9MmgU7QXwW_bkJNPIV4YlX9 W2YeV_BVz9KNw48gZeOYJAUzmbo1ncjqaMZ1Q5k6Uvz8QU4qGotiJMdTiyRgRSuur_huU.hOXyb9 coMWK7l_Rm9bhAFYfnpunCZ9BeNWIxuymPR30ctb4y2HaWJ5dxJ9mj6GyPhc08Yn6ln8fpOAFesb yIZ38wPwC9IF2UI.OOSzjGQvTllTm2Ft2U0IxxVvTJQTvThmG0V6jioRtdzKcEt5lO0B6dIVHeIw 5hYq4JbuPiNM_BuJsMnteZLKxh0HQxJQrzqN.D2aQC4PCYwX81LPUdTw7zmhZd_s7weMQpPuqsKE 7EYRP5MbvKWcYSMhCGhiegeY0fTHBSypKF1juAt2ak4OHda.WJ1Y8rIefwJkWqfrviOpDxNHFKYJ KbVtDNUDk92WpSvzUF1WxHJIO83SvUUPsBPPuBkSz5460WwmgFRpTWpoIalAx4HC2C92vff_FHgs 2kayar97DXu.Y9L6KqhUAKzYcycPVHpOSA7ggNmpmZ0Tr41eQ1y4ZaKUXYJZmhJSTviITaNGsVul Q9P0n.G6pp_n4RtGXZwkl__ZXwORJljbipcsvR2qbw7AgVX5dj9008_2bhBTISGIOeW6NnKzHxY. _pcccu.MFliqv.jjvCiXT0BGKy_OwvpTOvAhhNlyFi7IIPgKUbM2rNRH4J1KkBvhQ6b4Sq5z8Tos GgelXt.sJ_67rKRWqYVRSS75RZY2PFfD4tdjGQmTwNwfFoX2njWRg8_Yfke7BDWb68fVYM.Xgfis - Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:43:53 +0000 Received: by smtp429.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 57fdd4c7e447fc43d9116acb36d9c5de; Fri, 14 Feb 2020 23:43:48 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 10/23] LSM: Use lsmblob in security_inode_getsecid Date: Fri, 14 Feb 2020 15:41:50 -0800 Message-Id: <20200214234203.7086-11-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 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 Signed-off-by: Casey Schaufler Acked-by: Stephen Smalley cc: linux-integrity@vger.kernel.org --- 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 b5ffb2286bcf..62e095c34bcf 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -411,7 +411,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, @@ -926,9 +926,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 3e5ccb7a46d1..b55e66c2451d 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1931,13 +1931,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 ad48b7b60cff..5c3270050dd8 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -475,7 +475,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 blob; if (!ima_lsm_isset(rule->lsm[i].rules)) { @@ -488,8 +487,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(&blob, osid); + security_inode_getsecid(inode, &blob); rc = security_filter_rule_match(&blob, rule->lsm[i].type, Audit_equal, diff --git a/security/security.c b/security/security.c index 85cdd24abcd6..116800662a0f 100644 --- a/security/security.c +++ b/security/security.c @@ -1418,9 +1418,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 Fri Feb 14 23:41:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11383583 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 6F40F17F0 for ; Fri, 14 Feb 2020 23:43:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 444F324649 for ; Fri, 14 Feb 2020 23:43:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="c9gcD11S" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728365AbgBNXn6 (ORCPT ); Fri, 14 Feb 2020 18:43:58 -0500 Received: from sonic308-16.consmr.mail.ne1.yahoo.com ([66.163.187.39]:42765 "EHLO sonic308-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728176AbgBNXn5 (ORCPT ); Fri, 14 Feb 2020 18:43:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723835; bh=DQ7wZIZU+MspA5KjkAuPAbFCVlWr5ctpeELSa/CfUkk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=c9gcD11SscrAGAJ8odCuT+e8vxbqSnGiAHvJl7NGI2rbhFkby2tZ5eHo2nHSJglKsyxqxnY4+m7My2GWpEvb7g3tJ8pZCK5QY/DhY1scFfox7Z2TMbeS/bQeZWOYuzeAvyGCnq38P5fltuX+cAT5LEuC0Av8bz4lB2MngOukdQJPl+cjk8GD0toQhXpf9SgaS2mRkyfKnwq5I5jMZfwMzGEtD2SySCXD9w1oHSUrWDHCjBxdMvByEPee4labn2t+jBqjCvEdFgXQ44zudV461jnW5daq7dYch1yOyyAkv12HkFMfuE30Orq0z+MUkYYNeiHPVdifxnL1Y51Dhubq4Q== X-YMail-OSG: .nGRZe4VM1l2zQuVRAY9zeuXaRJB5rTO7EcBKJhx89CKn_rFPca4XB0Z2J2DL_1 q5OKDEuS8CtfvVMUo.ramDq9xyp.yEOOrdE4uOST0sOn0D9Bl7LhXhhtjDjDRM2uY.MULQ2oUwtG Ay0_3mqdBEsqbKN00pEJaVtGMkzIcj3eVj0kv2acRrskMksn5HFm2ncYwrfgVzXybIrWdAkTQ6iE WdadNYHeFPBKXxb6Pe.Am9qLYToJ3EdQyS9e5ZybIBMWeScaDeuwIITEvLe9Q8ETxt5bFL9kHLuQ 8MQR1THkvZIh0Lu3DbbKFW6Imb3oSzmq16Fzs6cbE8y7bLS8Z7la69RRXF1X_GROHdHbP.Q4Qjc_ jPvxzkoBVkWzvGsZNQoU7exymTxnIA.29l3i1VnVCDnthiZohBbD7HD.RXrnV0RfHY6EQnUhWXAR UxLDYThh4Pz3lqHQCx.1bV.EI6M3EdFjCPt2PcgfBQ4Hs6mGRwnVz3fiehiHqpfOLItKr41QbtUO CbVIh7O5Rr_47sosT4h9q13uYn7ljjImGWxlz6he_zqrB_pOasgWkXu4OPTiTA6RGyBlEfyivWlH eSH4lYL5.r10oWL6gp60l7pjo7nKNm4rdIT2f8bGnLSkbXFbHj8q2xWVlD9XMnPZbuNK9_EiYzGM JS1l47XYJ9ZWRMGDUTPu5.g6p7d5dFsEAMIqd3XC7ELTaQoM1iC_6.x22ZvtWJQtwO5VI5W.XGhx OLJSlqJjc0Glt04K6TIbQoiKEFjCbN6Y2zt9U3FDtIuHfPIarHtGVqZcGmXnP60MsxbGhtsWW7so _6U9aKop7H_wQqKVIWWnqSPHJb5rwHXsfm5qcoqaxfWUTbSAHacRtod7LU_QVGkAmYGu2Dq1TuXB I1CIMmMD4YulevoQHZ.WQQg2942b4TDDkZQ.hEuXvca.xIhx4pzeS.d9aHDl3f_Jb354juHb9sYS Ikuf26uQxUfmlo3.0AyjRO2OHr37OzHFXfhWBIiJX_ff_0bof_6TbKa7kLf7yVKsfTORcEtPmUAa Qd8Lr7eHwCxKNp2HznKqc6FrPnF9eyWUrlyn2Kz9rk9V043LzsKcEYXkNH6u9RiKlDbh3CKU5KWH EwaMAdORU50X1kY6kiRa7bcu8CFq8S5qJHrfwJxWU_reHRAxXqv8Na2lQ3liZer7.nn9sBahJmpu h3zjc2qgvquklRIvQ1TxGk78i8DeAOZhzwAGdYInxYRZJCkCrj1GFctB_uzibGiG.uClhB075e.p n7kUiK2hMmTncwX7ze5STZQbjgLEB9W2rHgaCDnNVtC88ivsXQP1X7v_yyj5QUY1pyblX47vXpBA nG3qFRKeq8P50SdthXPEo9GbW9u0imEoMQl1BCjvJ1ILe0Mt780fqHlMCJMA0RxM7Z89yLrx8WpR 94u_JmxlkJSXmcAn0jkBEjcT_TsxH_6atk_FRC0LnbHN6hCt03I6RhFnPDqnFPL4n6_umLQ-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic308.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:43:55 +0000 Received: by smtp429.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 57fdd4c7e447fc43d9116acb36d9c5de; Fri, 14 Feb 2020 23:43:50 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 11/23] LSM: Use lsmblob in security_cred_getsecid Date: Fri, 14 Feb 2020 15:41:51 -0800 Message-Id: <20200214234203.7086-12-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 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 Signed-off-by: Casey Schaufler cc: linux-integrity@vger.kernel.org --- include/linux/security.h | 2 +- kernel/audit.c | 19 +++++++----------- kernel/audit.h | 5 +++-- kernel/auditsc.c | 33 +++++++++++-------------------- security/integrity/ima/ima_main.c | 8 ++++---- security/security.c | 12 ++++++++--- 6 files changed, 36 insertions(+), 43 deletions(-) diff --git a/include/linux/security.h b/include/linux/security.h index 62e095c34bcf..92a783f5ae1f 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -438,7 +438,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 d7d51ad5d234..1bc0e1264115 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. */ kuid_t audit_sig_uid = INVALID_UID; pid_t audit_sig_pid = -1; -u32 audit_sig_sid = 0; +struct lsmblob audit_sig_lsm; /* Records can be lost in several ways: 0) [suppressed in audit_alloc] @@ -1417,23 +1417,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(&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); } @@ -2276,7 +2274,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 || @@ -2287,9 +2284,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 6fb7160412d4..f65f516913c6 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; @@ -329,7 +330,7 @@ extern char *audit_unpack_string(void **bufp, size_t *remain, size_t len); extern pid_t audit_sig_pid; extern kuid_t audit_sig_uid; -extern u32 audit_sig_sid; +extern struct lsmblob audit_sig_lsm; extern int audit_filter(int msgtype, unsigned int listtype); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index b55e66c2451d..d52ae228ad3d 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -112,7 +112,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; }; @@ -957,14 +957,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) @@ -973,9 +973,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 { @@ -1546,7 +1545,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; } @@ -1555,7 +1554,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) { @@ -1733,7 +1732,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; @@ -2384,15 +2383,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); } @@ -2408,7 +2404,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; @@ -2420,9 +2415,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; } @@ -2443,9 +2436,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 1f50f68a6f5b..8ad399ea7883 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -412,7 +412,6 @@ int ima_file_mmap(struct file *file, unsigned long prot) int ima_bprm_check(struct linux_binprm *bprm) { int ret; - u32 secid; struct lsmblob blob; security_task_getsecid(current, &blob); @@ -422,9 +421,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 116800662a0f..2218abab789a 100644 --- a/security/security.c +++ b/security/security.c @@ -1647,10 +1647,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 Fri Feb 14 23:41: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: 11383585 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 D0A28139A for ; Fri, 14 Feb 2020 23:44:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A70E024649 for ; Fri, 14 Feb 2020 23:44:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="V3e77f8d" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728370AbgBNXoM (ORCPT ); Fri, 14 Feb 2020 18:44:12 -0500 Received: from sonic308-16.consmr.mail.ne1.yahoo.com ([66.163.187.39]:40676 "EHLO sonic308-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728367AbgBNXoM (ORCPT ); Fri, 14 Feb 2020 18:44:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723850; bh=wd3sllg0H7uMaKBl871meRxv+kRV4h9UPqy+g1Oo7nQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=V3e77f8dMHXq0niLBJQ9mNO8t74JXRVtpPO8HPSFkJYUHLhWn8Id8/rOrnw2o4pCjbWv54uKJ1O3wW03bNna2t8BmrqnaiL1KPnIYLsaEMTU7QIbkK6uE6s4HbyiXTkleNbJvI++R9wWx80p6gjjfbvRIKHQN4RHHwM++DnmBo7FCfxaIutuQnHT4kqzidbm/MgaEQ5qkFwSv0F4jVeh5M5urftx6+2sxKRB97Tj6zO4dkqAYV2kyQzaYDMdG3bQtMiSWzow4Hb24tpZUF0UdEkpO/JXYy7M4Ne8P8P0Pt76OixrDBxATXF0Ws867Je8PiDNJI5WFGh/6uaMXRi5dg== X-YMail-OSG: E6JHWNYVM1mmFLfXr7OLfvCMQEeNDk0Ee3n6RU9vpATUI2v3tdPMm_RsQ1qSkcc DL98iksVThRPPHyF1PL9P7Csr6xtF8ogjtdBwbDBBDHNzW7KVmpAEVFFbKPsLUBZEZjs_5r.eGoH DJgxAJQJUDH0U3lKAHZYHI2pLcaJQmjMHKW2OPYEdFVuFVAWTnXGwyZ65DP_uo8oBg1ibAO7Nq_w B_RNJAlho2eO7DN40oP5LpaiYR.PqYplnMR8zM21eg8nRJuVrfiO95rdRviMP_sLbISBnQL2j7sa I2G_d.x196EEKooMGbOTUgkHaXbO_sH4DDws2ippYym.SnRUUBjj9lgOKn11sTdOhj4Hoh6xv9mC KbRj7QSacLgtRrI6yR9y14tmm9bmPsEiEUVIVPb3Mzu4k9XnzvgjBKUeBDoTOsPdJ3iJRqrJzh3l 0c1UynuaIb7cG4GCViyF4nnEpVWZ5qTOl0EZw2r8TVCvPFbR4VJCOVfUJV.XNCRWkJY0N5BEQ0ik r.bnuZjpfFto28HNC_4gB2eRplgh8M4zEEAki.t05oOjWjWQZ08rlmf7DsJrcCFGdcQXUUb44b54 QGTcpZgyRuUjyyadWh44YMCq6IZ2RASqh0nid1_kwvdOHHRYwTytc6l32o5QBO0TXx.CWOvdExjz uV04dgjFx2fTL7EK6fQckz9VxHoqOz1IpH7ewVRxBCWECjrE30Te03eiMPr.nj9FLJ8pbM54F29R NRh09EmV1iRre6wH5wqWKb2HxQ9FgDfNGcK4dRSlfHvwjLP.D9kywmbpyeLq7l4eQJNLW9vazq9H gdsWBVAADTbZYTD3jhXm0VROOPXt8wEjMaTKDC_7HX4mKndmzKm73bAQDD6E0PX95KhDJ7v4C5Y7 BiYMxyGwySt6KV2CgnOcRDefVyHIzaAFz6.chDe6CXkxGqmft.6D0PKuMVqTdQRtpVeW5YmcKWWy ID0C0DAwFD6hkIaowTNqgO1KYWsTmKx9ZzUYmXJVyumNFlsOlQYrW4QvYUgqRQUww.V5wC2jJX9. iHiWSJdNJ3LBpmfywMwd6ywCLGUbSVNHNZOsAgaFOoNgK_L6TIR5BiR9hCHSzYb2OwWtU8uGbP_a JNmGbnVwV2NUir8Eg4HR2ML5Tv3chgiuMAS3uQiBgJT3.VERZtgfyXB2w9qq.3n2YFP5f35MTHG9 D23Ow6.mpVoNm77PpMwYJcMYUU3hZ.f1XqB9GIWVd1EOms1O7wNYr4drcEN6QexJPG6zoe21Z62p eotEUiqPkQQDmp4EhdVtBWivg425Z.R6FFA_1md5dUaG9fkTA1.fUi0cY9fNqarGMnkp3HJY5e39 i4u.3x5Cb4KZI8w1qHDTrDRsNbOTRzxkbDMZyeLn2heMALFNnlPDUULaGIFfYP68mth5Qs56wD94 brILoSZcteqWCQIkhsn9RNyAJ6ztd9gmplOhnnLBFrF06dA8rmNYAOXGQBw.xiVg8nlQCsQ-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic308.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:44:10 +0000 Received: by smtp427.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID cb3a62f0a1530c83edfb2fd8c399384b; Fri, 14 Feb 2020 23:44:09 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 12/23] IMA: Change internal interfaces to use lsmblobs Date: Fri, 14 Feb 2020 15:41:52 -0800 Message-Id: <20200214234203.7086-13-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 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 | 32 +++++++++++---------------- security/integrity/ima/ima_policy.c | 12 +++++----- 5 files changed, 32 insertions(+), 39 deletions(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index f9e3ca96fa52..a85aa57d28c5 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -230,9 +230,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, @@ -258,8 +258,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 f6bc00914aa5..b481bbc2e55f 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -163,7 +163,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename, * ima_get_action - appraise & measure decision based on policy. * @inode: pointer to inode to measure * @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 @@ -182,16 +182,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 3dfb573c7171..bf66e3e6f398 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -54,10 +54,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 8ad399ea7883..a6348dca299c 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -190,8 +190,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; @@ -214,7 +214,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)); @@ -388,8 +388,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); } @@ -415,16 +414,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); } /** @@ -442,8 +439,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); } @@ -624,9 +620,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); } /** @@ -722,9 +717,8 @@ void process_buffer_measurement(const void *buf, int size, */ if (func) { security_task_getsecid(current, &blob); - /* scaffolding */ - action = ima_get_action(NULL, current_cred(), blob.secid[0], 0, - func, &pcr, &template, keyring); + action = ima_get_action(NULL, 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 5c3270050dd8..5ff6218a9c4a 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -426,7 +426,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) { @@ -496,7 +496,6 @@ 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(&blob, secid); rc = security_filter_rule_match(&blob, rule->lsm[i].type, Audit_equal, @@ -540,7 +539,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 @@ -555,8 +554,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) { @@ -572,7 +572,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 Fri Feb 14 23:41: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: 11383589 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 C79B0139A for ; Fri, 14 Feb 2020 23:44:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 91C4024649 for ; Fri, 14 Feb 2020 23:44:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="bhBnXW6P" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728378AbgBNXoS (ORCPT ); Fri, 14 Feb 2020 18:44:18 -0500 Received: from sonic314-27.consmr.mail.ne1.yahoo.com ([66.163.189.153]:36122 "EHLO sonic314-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728176AbgBNXoS (ORCPT ); Fri, 14 Feb 2020 18:44:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723855; bh=Yognqs0uaU0CcJGK22af100kJpc21EI8ynuOxYSuPbg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=bhBnXW6PRxY/+zriqWEM9tsvz1kaGY/yU1qDOkVLKlkUO8gZ+ty2KvhB0ebuzUeskuha7ZbQzK4tXwgILiUTz5jy13nVCBqeYtHXToxIzJfcl2pdr1OBPOvHmA/0RpiLW2pVzZTIn+JSxsFc2rgGklz4Xf9yxBvThvu1D9lgAGTssnm0frc9Vt1DW5/2xeocM/EWxLI3EvLuCLNA/YhGfdPINJxr9F8i6PxvigF2/jE+8TRG/ucVAUliWcBq4BfIEDV6HJ5gN9PIc+vtL4qt7EsIHUVy1zChMDaY6CIWNxAwLMFMqYKM7RoNR9Xu7q4k4burKMgiB1l0YHEeV4AmBg== X-YMail-OSG: 46W63oEVM1lU5VPxt_QsbkB4D3qwl10Hd1h2ad09dsM9Z35oNhs3.A53EZVLx3T gRS7YCesHNl02deHo9iVfI71vtoRmAfllVjHlVpu4g2E5w5o4wPY683OCnwwGbyiFidsv.QPsbC2 LmvkJ7zGfbjHs80nMfIjc0c.9zc2x8UH0w_Hc7RcerXpJ.wCRpVuGk3DHRhrbVCsWv6OzFY8e.i5 9GH4khbQRSMTtWVYyJQW8ftHQbhGBt5WoMTjtkNcuaq9ffW3gwD2SCQz_4G2qYqYoW_xiTgqSZm7 62esS2OLSeOPpDL3BBBkvFZ1Nuoc2pinto9k7Q.z7HZZWTz9PCAQ8qbvahdYc60oG0CrTjXCvePi hVodafO3xq.qWs7kwIvmqjwfSDEkVHfYfARjEt8sZqQzC37GlEcrZbCuL6UiWx06lqURnims6dj2 ah8CSg3MSRGs.thUjB3Ia2Q.ghW5Z.Z4PLlGbdDda6KRfmYn1V6SlKkthAXMGLguZGG1yUB7IRfA iam5DyKoI95UUFIeIzmvpEu1U.HFL9QAK.sqlPIX.uAMOam7GGySxgG2HCQMRFMu212ZvtDFktCP A41Ja2fZ7MUktcgaxSXhByzXruPbDYL7wZ_P4ktb.TCTzI46cjUENwO.wHZnd65mERnMJpd3BXuD 1ODLb3QB6z_6fWVa5AySboMdm2HJu_7evPJ3MXtpide3LxLG13JoMlkhtG3eom.0kf1YvZYCLi0A DL0DPshDEb0sXyozWRN52j8BJtnqBBxi02a0KcAhZaEL80ENAegOz_LdxrXYO_yk.kFDl2PdBbuW UDeHTg.vU7lyMzCNOLMB5eIH5w2.UBy02LFKnfgqX9n.YsG1hmqO4S9scnrl9RKsPnuHqz8BdA.c Z8Kh9uXIrYzw2j78wKkHO4u1oR4xRfIN9cFnOaG3FO9dttD_xaD7KLMSG08xvQGCI00McwWcjuG5 Xkno7Ytazk1q1O4Xeh7oa3uFTOtz3h3iz5wv1.h10LfDRWCMSpAO66kED8XGR04IHNVskCK4WVxT c1K4tRH4D4w5NuPWOckduryarm2.6JtRANKlwkMqCp6ceNKj59K1Co4XFoBmfclOWJ59Bi5lA3TM 0em3pfI6_JghdwGz8EEcSaxNUyLnnpTNdu6bvhUhL6Lybq4K1zum1nYpDBr_zZOXYYubJ6TxObdI VN0fGD4A5ClaboDy8fBEsX6zr_.BP7cEb53k.4CVuKPpoAHBzwG8ZX3SwOSjWIZq7m3sYGoH36WH QwYfF9NDTgskB7LwH0oZ7Mtmy6r3yLmdGyRmuAg8KbE.5baXVL4aP1_wdfkp.dvDrs28Rye8ZKpV vjjOT6X5PWwnWJY5utjrKyVlLpNkincSBAutNErvIHAmCxJNlpH8tRNwMDaQNlyGoWLUyecU.Ezi 2EUM59Ftk_MVFyWo.ZYjC1095Tob1VKBAwY6XvIu3jpTufsPGeJLK4njEGGeTYabDzAGVNPlX6O0 - Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:44:15 +0000 Received: by smtp427.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID cb3a62f0a1530c83edfb2fd8c399384b; Fri, 14 Feb 2020 23:44: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, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 13/23] LSM: Specify which LSM to display Date: Fri, 14 Feb 2020 15:41:53 -0800 Message-Id: <20200214234203.7086-14-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 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 Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler Acked-by: Paul Moore --- fs/proc/base.c | 1 + include/linux/lsm_hooks.h | 15 +++ security/apparmor/include/apparmor.h | 3 +- security/apparmor/lsm.c | 32 +++++ security/security.c | 167 ++++++++++++++++++++++++--- security/selinux/hooks.c | 11 ++ security/selinux/include/classmap.h | 2 +- security/smack/smack_lsm.c | 7 ++ 8 files changed, 219 insertions(+), 19 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index c7c64272b0fa..505331ab7a14 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2743,6 +2743,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 7eb808cde051..2bf82e1cf347 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2186,4 +2186,19 @@ 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) +{ + int *display = task->security; + + if (display) + return *display; + 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 146d75e5e021..16b992235c11 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 2218abab789a..475929e3e1e4 100644 --- a/security/security.c +++ b/security/security.c @@ -75,7 +75,14 @@ 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. + */ +static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init = { + .lbs_task = sizeof(int), +}; /* Boot-time LSM user choice */ static __initdata const char *chosen_lsm_order; @@ -470,8 +477,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. @@ -491,6 +500,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); @@ -620,6 +630,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; @@ -628,6 +640,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; } @@ -1583,14 +1604,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) @@ -1987,23 +2020,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 -EINVAL; } +/** + * 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(copy); + 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 -EINVAL; @@ -2023,15 +2143,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 != 0) - return rc; + if (display == LSMBLOB_INVALID || display == hp->lsmid->slot) + return hp->hook.secid_to_secctx( + blob->secid[hp->lsmid->slot], + secdata, seclen); } return 0; } @@ -2041,16 +2161,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; } @@ -2058,7 +2177,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); @@ -2183,8 +2309,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 22b882867dd2..a12cc8959f6c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6299,6 +6299,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 986f3ac14282..ba36a55b5ea4 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -52,7 +52,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 12e01d450dd4..00a304861657 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3510,6 +3510,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 Fri Feb 14 23:41: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: 11383593 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 D278B139A for ; Fri, 14 Feb 2020 23:44:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9F89424649 for ; Fri, 14 Feb 2020 23:44:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="lsqSh6XW" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728324AbgBNXod (ORCPT ); Fri, 14 Feb 2020 18:44:33 -0500 Received: from sonic314-27.consmr.mail.ne1.yahoo.com ([66.163.189.153]:45656 "EHLO sonic314-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728327AbgBNXod (ORCPT ); Fri, 14 Feb 2020 18:44:33 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723870; bh=D0Qj4Fi3Yn2og2y8Aah3Mmk6yXVxJK0NZJ8J1wqf/Vw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=lsqSh6XWuE60BUGfLwTfOM9SHOV6dFvb/Sl3eFwl6TMgapj+hsFSIEKm3wA6i/JXsgjdPKldrq6I4OnFUPvy8yNFkYHKpQ6pM2bUxWnMdFjJm9MiE0cI0NqvUA50z+K9ukIwJldMhH0QCRCmhUa7NASVjqePkZUBMga/xReVyePmBB7rWZeozLL3hGsHbgwTcix6rfd99jrMhHgWaxzkGxSp5vVhIbRNubD+CDLAsdBF/t487+KnDUX4Fd1ypHcwIJs9pWAfzg0LEDaNaBHz10tWpIimAGfjCn/peKRDyDrgJIpOSAha+zy4tVKq7TG35SnWeCXc4X74E4idPiBRtA== X-YMail-OSG: Y5yQ75QVM1lojq1VCN66Buw8ir2ir4qH0_KZxFNis9x4hV608lWv1GQ9Gu.Ghvc YWiP2rfxOLDSx.YWLgthL1ni1fMKKArBmq285updxzHgSERsqiEbxiVxoHtExnRDKDn4ICxLV2aR TQeWDgu3LZk72eCLcOlTf2E_MpvNnimDeWJAWh1PPta5qVY7X66_aqupMLjBntT0okFqqpWyaC7e JIFYzERUSUgSQujDjBRLCjR5jLs8DeTrHwjVX5Qkh5c9L9YsavpFyvXftF8nNDYEdDH31TxRK3D6 8a4qm9EHYmbuCcPoTgmxvhPlCsiY6V2ZH93fyxVI.ex6atGU49bZobpWQqSiDVuWlY3gKMfWChsq j4WhDU8ZAqI.O9D1M0BNvw0_cMxIfX0wOz.L4VBci2DwMY4QTqaxzrMa6QOslwrkLvlRME4AI3VI buC5CE4KMEURHZ0RIb0mpgifX.4Puz1xSSH9uRFLjL1tl0l1MdhoDiMaFUWxQq0VXSNBOruHAGep x90mN_BlchoArvjMJYTFBVAnmmMar22IDUdYmU3URLSYoez4sKk.4jTPrOvEW8RJFTLBxg3f39.b cQqv1i_1m_FnYLIHJu_A4dmt8IHFSvbwXayw6MuFkixKpl7VXgpKntCCI06ob02Tc7dSZygr7EDr oNtpUzsFBgMGWohmmqyVT4XI5n0AE80cVg.NpBoIMZwjjplD5mPiI5iYe8SdJ8DPuW1.0O5MkH_d Ap3AgpR0B7jVh7.Cg_xqFu4h_7Fv9YPc8qftmEeOBJxDunQoVQckTzFZxRa_gnWsfcPFfyNBdf4D i142AT8kVty2VSBULQEhJtl7ZOOcdYbynrP04AdWiGuuIyJMrP_xXLdUHeIqzNX8emz0_6c11F6M 7cmvcuonVxx3pfoUXq7_QzimNDwRZzDSpa03TIOozY8nKF_CGxalTfjHT6nYG7mR9.FIOOs40ig0 NCYV.XLm5vI2YgIRE7b2OC9sztfT..QUrM3C7B8rM86lylJseTyHKYFbLu7QsONnbbAesq3Mf0i. yGQNaKxu4eodFRyXsWVzrpA5gLVU5hBtj.U6Qoiu5Mk4fPyhKwKmZRINUC.ijkAq6f_VrDa0yjbF 2FMT9St_vbP_LBXJBD9Rb19HlA7d_.4ydQTU_0Sh6_6CdggR6VlJOno4vkP0M4xwKIR6BRpOowjM 95tEy4zs9b8C7giDFir1CTcyEGDYitdBUYateA06DjF5md0kH_mJfopyPlg6f_qTf_Sb2BQyDcok _9V29TKnH.uFS_pMbVpKRHHh3Hi3MGtnh0cF.ImDPEthreCONF6wLWJXxC_ZtypRgqyrBVM3T.Gm kmRJ97Ug6maeMofBcVPuKEhoxZXEK5XY5aaJK3HYGNDpEbK9t2.IlHwMMq1zKTQMn03mqLUcdLSE x_9KcyqY_zz9xOHIICazFnvZj1ICYiGGUoIbjRFMJiKtT1d7rQCFdpUkN.JLyl41qqQ8- Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:44:30 +0000 Received: by smtp432.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 816e8b9ade56f3dd6ac23052507c8812; Fri, 14 Feb 2020 23:44:28 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 14/23] LSM: Ensure the correct LSM context releaser Date: Fri, 14 Feb 2020 15:41:54 -0800 Message-Id: <20200214234203.7086-15-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 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 --- 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 b133f0af5151..a11e38d0cd0a 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2863,6 +2863,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; @@ -3159,7 +3160,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; @@ -3492,8 +3494,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 7b8a070a782d..9bf41894e3e1 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1272,12 +1272,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 95d07a3dc5d1..01cddbc7c7c0 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -130,8 +130,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 9761512674a0..df308b1b37fa 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2496,6 +2496,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 @@ -2998,8 +2999,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 92a783f5ae1f..80b24a034799 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -130,6 +130,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 * @@ -500,7 +531,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); @@ -1314,7 +1345,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 31ae605fcc0a..30ba801c91bd 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; char *secdata; u32 seclen; int err; @@ -102,7 +103,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 1bc0e1264115..ed2d8d7c6943 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1181,6 +1181,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) @@ -1425,15 +1426,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); @@ -2062,6 +2066,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)) @@ -2075,7 +2080,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 d52ae228ad3d..75bd9710790d 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -962,6 +962,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; @@ -979,7 +980,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="); @@ -1192,6 +1194,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; @@ -1225,7 +1228,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) { @@ -1371,6 +1375,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)) { @@ -1379,7 +1384,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 1ca97d0cb4a9..96d56a30ecca 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; @@ -144,7 +145,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 68c74c28eae9..3d18d6e2a7dd 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -332,6 +332,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(&blob, ct->secmark); ret = security_secid_to_secctx(&blob, &secctx, &len); @@ -349,7 +350,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 183a85412155..8601fcb99f7a 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 b7b296fe0c0b..8611974322b3 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -395,6 +395,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, enum ip_conntrack_info uninitialized_var(ctinfo); struct nfnl_ct_hook *nfnl_ct; bool csum_verify; + struct lsmcontext scaff; /* scaffolding */ char *secdata = NULL; u32 seclen = 0; @@ -625,8 +626,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: @@ -634,8 +637,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 e279b81d9545..288c005b44c7 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -373,6 +373,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; @@ -443,7 +444,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); @@ -474,6 +477,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; @@ -502,7 +506,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); @@ -539,6 +545,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; @@ -566,7 +573,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); @@ -1080,6 +1088,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; @@ -1147,7 +1156,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 475929e3e1e4..3a65f4ac476e 100644 --- a/security/security.c +++ b/security/security.c @@ -2175,16 +2175,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 Fri Feb 14 23:41: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: 11383597 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 BBF72159A for ; Fri, 14 Feb 2020 23:44:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7E24624649 for ; Fri, 14 Feb 2020 23:44:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="oK8H43uA" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728234AbgBNXok (ORCPT ); Fri, 14 Feb 2020 18:44:40 -0500 Received: from sonic314-27.consmr.mail.ne1.yahoo.com ([66.163.189.153]:44778 "EHLO sonic314-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728335AbgBNXok (ORCPT ); Fri, 14 Feb 2020 18:44:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723875; bh=Ds4E4SEkIQeFkdGzqLaIYhEci8/0xzXvL0Tm5493TLs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=oK8H43uAlbAbgqkc2yKgcT9eKoDVJIZZwy9SLWIaQdLadCiAbhrWh5xrHzfD3NuyAYtqJCnvjw0hzJJzDYrFmrAqrnUdD3moqZSJBGIC5lKAjwIt0Z1N6OxMdn16xu3VHLJAUyImM7+oQqyIyUQIOqecZhFa6x1fMuGrt8fM7BaAAaveJn5Em7xTwB4VnIRsU7Hl2rruwjcXXvN4prwUdEjd6upY7sKCN/9ZRI/2HHMkUk+kw6JYfoMEE0whnos/bbyLKIlUq+7ft2mX3+l0Pgk3EaWZumpLRdIXbomsD7pje78MMGIa70fUUinGvrPLqaxx7UjkimTkY2neCabsLg== X-YMail-OSG: Ai_YSWAVM1lEDJX2jGdt1Mvk8kGHp5r7Za1Gku5yY8WuSfAY3vy59NKwTrD50Rw aZeRqlYL_UF7n1IEluqOF6ZCptOLi.8vQ2r5S3.4VxwJpYrgItkbayaJEENPQHx3nDIpI9T6Nm_W NEzNAOGYtA4Ci_ovG_sOiua6qm6cYtgGUNhIQWvaqL47cxokmcCzbNfn_sgj_2nZIl23rtWNUNTx Fc4ZKO.aT6My4aI2SiV2UOmt.o21hc6w7vKUaaDsob2IvXC.aBHOLbpk32UOeSsVnm4P_OZ8pNPb ayWuqbzth0leDDwbMV0CjZHhcUQpXpTARXIeC3lZQMLbCshL34A_UifBcTQkFARCrI8uUHiQcNeC bg31EHQv0Hm2DvwVnFW6shE1sVwEiyQo2tqCXeO2NKJCwlfLUqeHZ42eYmr3OWS4lSfLwa2bWfaa BlEXPs4K9IJqiSLiBkhfOWq1U_R8.AlUaaIYZkFRbbEErSbE569HkqGc2ukqzVmgqC.pbhfslG0l K4qwXFZve7qPuMR8TewP3KIZmLLWQH8ENJaEk7SRW8GPmTvavY4jNdVBwzsQ99m13WHzb8.bhtZq rVmL6xtlOhY4oiX1x_k0wf6KCb4.OOGIbyaDiNyVJRSap60S3fXSIbUpRZASwLyKpxRAH0lz4OCB Rmxk8nT61iQn3N_Q2vfC3DEuO8J_XqqJAUbcoBStK8pfRRTlTly9TJAXdm8kE7rJsj3nYozUzGu7 zpIrhYYTay2rCmycS9l_kqSdAo0V4kJ0sFxkmq1zkZoxARVi6ULY2X.QyBrf6tOnYBd6JT6IZWm. 6T0ymjWdUsrU5K5k1oHrx0EwEBOlW54HS1ua8Fv3WGCsNtpXA1HH9fn3c.bPxkVR8eJ82oaUfTuE Q7aSOvRG.MoiPmTaZTO7Z3bb8q3hzThRYrv65mfn.EhPEAGjzKgrQH.HGeIZPd46rxZyL_M8dzUt NNrUgkaJZ7dV74.WmxRkw7Kj7nVfcpzxPUYh1o4eabbzuux4CC__5q5SHCB1z.eSPdWjNsCwI2to rQH24wRlgcnpMxgdbVYJ9aqqfiXRtTnWFDMGP__uoTVxMIUjc6.C0atHElE7saaISthjWTaRDccy KCriLNzIW1ntry0OFhWYFkoosMnc.NUspDxgC7Q4xx6prlBT3ehSwfYG2MAT0sf8H1YGMt9P6_1P Hng2gBA5rLrgfVBrYEH6C7UDDmh_A4K49efh7z02iqO99JAR9SotLTHLSf.7ODZ86iMUTGwlM6Bk x.tY9GM0e6Hm.NFWwj_XtG.FMB_yxgkHboyMhUsgo2NkCLHOOESZpVaPOsfGxlZn2W4mqsaHs1bS eBxtAuQfwHlkcaC2VgNemn_Q3LV4KVSnXRP0Htdd4OVOW5oDVJDBzLawdL6Adt1U.HaRSFrir.fQ 1BEQkRutbb3Pqhnnib9HcTAtWAA4D1BKIVLLBq2ljgk8V0KCac3cnlNihx_3VlTmu_w-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:44:35 +0000 Received: by smtp432.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 816e8b9ade56f3dd6ac23052507c8812; Fri, 14 Feb 2020 23:44:30 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 15/23] LSM: Use lsmcontext in security_secid_to_secctx Date: Fri, 14 Feb 2020 15:41:55 -0800 Message-Id: <20200214234203.7086-16-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 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. Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org --- drivers/android/binder.c | 26 +++++++--------- include/linux/security.h | 4 +-- include/net/scm.h | 10 ++----- kernel/audit.c | 35 ++++++++-------------- kernel/auditsc.c | 31 +++++++------------ net/ipv4/ip_sockglue.c | 7 ++--- net/netfilter/nf_conntrack_netlink.c | 14 +++++---- 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, 76 insertions(+), 120 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index a11e38d0cd0a..fb7a473f4270 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2861,9 +2861,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; @@ -3111,14 +3109,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 */ @@ -3145,24 +3143,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; @@ -3218,7 +3214,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)) { @@ -3494,10 +3490,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 80b24a034799..ba7fc88f7858 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(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); @@ -1333,7 +1333,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 30ba801c91bd..4a6ad8caf423 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -93,18 +93,14 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) { struct lsmcontext context; - char *secdata; - u32 seclen; int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - err = security_secid_to_secctx(&scm->lsmblob, &secdata, - &seclen); + err = security_secid_to_secctx(&scm->lsmblob, &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 ed2d8d7c6943..a25097cfe623 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1179,9 +1179,7 @@ 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 */ + struct lsmcontext context = { }; err = audit_netlink_ok(skb, msg_type); if (err) @@ -1417,30 +1415,26 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) break; } case AUDIT_SIGNAL_INFO: - 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); + memcpy(sig_data->ctx, context.context, context.len); + security_release_secctx(&context); } audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0, - sig_data, sizeof(*sig_data) + len); + sig_data, sizeof(*sig_data) + context.len); kfree(sig_data); break; case AUDIT_TTY_GET: { @@ -2062,26 +2056,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 75bd9710790d..f71d8f7521be 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -962,9 +962,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); @@ -975,13 +973,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="); @@ -1194,7 +1191,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; @@ -1218,17 +1214,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); } } @@ -1372,20 +1366,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 96d56a30ecca..27af7a6b8780 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -132,20 +132,17 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { struct lsmcontext context; struct lsmblob lb; - char *secdata; - u32 seclen; int err; err = security_socket_getpeersec_dgram(NULL, skb, &lb); if (err) return; - 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 3d18d6e2a7dd..e2e6d4bf4ac3 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -329,13 +329,12 @@ 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; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &secctx, &len); + ret = security_secid_to_secctx(&blob, &context); if (ret) return 0; @@ -344,13 +343,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; } @@ -648,12 +646,16 @@ 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(&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 8601fcb99f7a..8969754d7fe9 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 8611974322b3..7e91f3c10b29 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; @@ -314,10 +315,12 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) if (skb->secmark) { 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 288c005b44c7..c03fe9a4f7b9 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -374,8 +374,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) && @@ -440,12 +438,9 @@ int netlbl_unlhsh_add(struct net *net, rcu_read_unlock(); if (audit_buf != NULL) { 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); @@ -478,8 +473,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); @@ -503,11 +496,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); @@ -546,8 +537,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); @@ -570,10 +559,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); @@ -1091,8 +1079,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, @@ -1149,15 +1135,13 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, } 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 3a65f4ac476e..e2e5277185e0 100644 --- a/security/security.c +++ b/security/security.c @@ -2140,18 +2140,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 0; } From patchwork Fri Feb 14 23:41: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: 11383607 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 5D8EB186E for ; Fri, 14 Feb 2020 23:44:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3D9A7222C4 for ; Fri, 14 Feb 2020 23:44:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="tsRg9v8g" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728310AbgBNXoz (ORCPT ); Fri, 14 Feb 2020 18:44:55 -0500 Received: from sonic310-31.consmr.mail.ne1.yahoo.com ([66.163.186.212]:44524 "EHLO sonic310-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728271AbgBNXoz (ORCPT ); Fri, 14 Feb 2020 18:44:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723893; bh=/JTyJIIxOgLtTQY9hB7CangNajKOxP2qi4YQSMHVAHI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=tsRg9v8gx636c/m8Tdkh0H4jPpVw0IGcl4qvN0CvpSbGKp0Qy2VwmOxgZrkVNqF9v0ELI7LOytngNtoF/aENUbWe38SvixZmHkqQx4OCPQoeoItxuHs2gkhBxQ5jlFlY5o1uotwLqXfB8HtuJp3tudGnYUa7AoykGnIJNxqJQxtMzdFdc6w/NsVzsvogCg8j329eob99YLZD6JRmt6cpT5UD65R5yUkJ1gY4TXZ9rDH+GBilDOozu57MmHkGMf5Oh3D9Dzv2LVhWCpKc6+rRs0IQ8iie+a8/rg/TfvYNLrtJ6w5FMJTlwOxiO7QydUjJvcjT3fIZOhOR6huhNMkrtw== X-YMail-OSG: J2v3oGEVM1ljvcf.dxmzkgqDMIiG6ndpcQ9jp1yn4Cp12lamVp6bIg.WUpbv5YW cDbq8nXsM1w6Z_W.M8sxEp72pW51lJTxJ7HgQxk0VaiZqYDaKDInV3pWUiyhG732d_KvlDFZSbtq fh_7lcgQk8VwnHGxa1cLomPIU5qXHt.qCI_fykqleSi3V0xs40.940NqGNMnXPIyPgedIYFTRJVy gRXYJv_KI1nJ7F2_iyuO7PCoWoYHYh5O1nwMObIB3Bt_fYmuJ_7G7_HLLbkdiqEGql7TYmj.KJAx RCT1GMXjDJ7DBkODauIRFaueXg0lixXP2SXp7typJTV5_Me092lFL0tg.5pKRVOVoV02Y.hAs0As Qo8h.AHxd1LrCXZQXVTk26QINdGn7QWHZhoEBSdcwtPtNjbxqKLr.ljj._d.MO0HbtS2_jGG.7XJ QnQY.5.s5MBqKaZLKaWgicKzcMYWT2NynD2yC_wqLS1NsaLbdivkly.QeNAZuYlGZpjdO8TUCSgV SzvLsUOemcrkUVSrO8cRjdJo8Au8wp9zBoxkwrJwahIYvbD4GAOOhXZEX6KrWAddBqOEKvFkzoaV baDDJ8OPbYez0WCi1r4jemWFh4Uo5stfwtxCXq66VVdKWEL_Q5ABgnMHbbU6B2CbABExO8gQrPce ic1LeEiuimRdZlXyKyHmDNZsu5eVmqoPk8F5PAgx5M1jp.H5Glr2Z6hnirXgD06CiSE5PDE99kiv moktMGjPfhzuS8aeRJRxrwAsYZgYZeDT82UmXY3UscrXJ_EXUM5jF.395QtmI664H1VFN6aUR2Um mNoWxCvso0x4aBI_24MmfMIKcMTYgXpLhC4xRvUa7sQJNH4aA4dI16QuZXJNs8V5wipSQVY6yqEA DFH_KCYqSgtqvr9x6e9LPkfzasgYj1sU0yp4UvjOUuxeuvGu_KPFVUEMjV3iA6_.vq5pi7AFoqzf JmhwoOFrxrMt.Q.BnjMTlwMpG.ZOCguMtXxEegWPuDaBBVWnwE8hkwOPNLoMoGJKDZXB80KFtgsm ZColjWtCos7nNZ3lCoMlxFAvxP8CvW7JhiBdUjRI.QVgkFu_Yya7cWx4sYRdStfvEf7xF9_WhnAs WB2C4yfxCT8H8a8nUmqfTSXNOljdFwplAMIqynB81kl5GL33tHwTqmpFFUUnA5ioQ4dYtd2YftPL tFcNAjcrjtc_VdwuNjvPyeMpTACYNZBXr1TNbgWAU82H3F6KaphKt_M0_7fus0Dgzm2Auj8ajWPp qTBDOKre8Nl70kaZ5S_OaGu_TWC51INZHaSk_cNyJJmFaba6H.eQ2gS6k7EwUiqAdQcvrFB7O_1a Bb8Cvi0CS6L3h_YXr05EL8RfXzx21TiY8mj03GQYYEXnOAzS3Fb5YqbzmW0pVswl4.2ms20ZsVUx gB2vEfpqcpxJ6RzDMgZb8D.v_dywPjjxi4DsC07s99ZD.7GSoykXqDftk2Hjp Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:44:53 +0000 Received: by smtp407.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 768a909794458cd16a286f5d22121ebc; Fri, 14 Feb 2020 23:44:48 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 16/23] LSM: Use lsmcontext in security_inode_getsecctx Date: Fri, 14 Feb 2020 15:41:56 -0800 Message-Id: <20200214234203.7086-17-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change the security_inode_getsecctx() interface to fill a lsmcontext structure instead of data and length pointers. This provides the information about which LSM created the context so that security_release_secctx() can use the correct hook. Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler --- fs/nfsd/nfs4xdr.c | 23 +++++++++-------------- include/linux/security.h | 5 +++-- security/security.c | 13 +++++++++++-- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index df308b1b37fa..ac8eb77d0053 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2379,11 +2379,11 @@ nfsd4_encode_layout_types(struct xdr_stream *xdr, u32 layout_types) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL static inline __be32 nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp, - void *context, int len) + struct lsmcontext *context) { __be32 *p; - p = xdr_reserve_space(xdr, len + 4 + 4 + 4); + p = xdr_reserve_space(xdr, context->len + 4 + 4 + 4); if (!p) return nfserr_resource; @@ -2393,13 +2393,13 @@ nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp, */ *p++ = cpu_to_be32(0); /* lfs */ *p++ = cpu_to_be32(0); /* pi */ - p = xdr_encode_opaque(p, context, len); + p = xdr_encode_opaque(p, context->context, context->len); return 0; } #else static inline __be32 nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp, - void *context, int len) + struct lsmcontext *context) { return 0; } #endif @@ -2496,9 +2496,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; + struct lsmcontext context = { }; #endif bool contextsupport = false; struct nfsd4_compoundres *resp = rqstp->rq_resp; @@ -2556,7 +2554,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { if (exp->ex_flags & NFSEXP_SECURITY_LABEL) err = security_inode_getsecctx(d_inode(dentry), - &context, &contextlen); + &context); else err = -EOPNOTSUPP; contextsupport = (err == 0); @@ -2986,8 +2984,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, #ifdef CONFIG_NFSD_V4_SECURITY_LABEL if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) { - status = nfsd4_encode_security_label(xdr, rqstp, context, - contextlen); + status = nfsd4_encode_security_label(xdr, rqstp, &context); if (status) goto out; } @@ -2999,10 +2996,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, out: #ifdef CONFIG_NFSD_V4_SECURITY_LABEL - if (context) { - lsmcontext_init(&scaff, context, contextlen, 0); /*scaffolding*/ - security_release_secctx(&scaff); - } + if (context.context) + security_release_secctx(&context); #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ kfree(acl); if (tempfh) { diff --git a/include/linux/security.h b/include/linux/security.h index ba7fc88f7858..690f8d6495e5 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -535,7 +535,7 @@ 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); -int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); +int security_inode_getsecctx(struct inode *inode, struct lsmcontext *cp); int security_locked_down(enum lockdown_reason what); #else /* CONFIG_SECURITY */ @@ -1361,7 +1361,8 @@ static inline int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 { return -EOPNOTSUPP; } -static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) +static inline int security_inode_getsecctx(struct inode *inode, + struct lsmcontext *cp) { return -EOPNOTSUPP; } diff --git a/security/security.c b/security/security.c index e2e5277185e0..d663406cba86 100644 --- a/security/security.c +++ b/security/security.c @@ -2211,9 +2211,18 @@ int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) } EXPORT_SYMBOL(security_inode_setsecctx); -int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) +int security_inode_getsecctx(struct inode *inode, struct lsmcontext *cp) { - return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, ctx, ctxlen); + struct security_hook_list *hp; + + memset(cp, 0, sizeof(*cp)); + + hlist_for_each_entry(hp, &security_hook_heads.inode_getsecctx, list) { + cp->slot = hp->lsmid->slot; + return hp->hook.inode_getsecctx(inode, (void **)&cp->context, + &cp->len); + } + return -EOPNOTSUPP; } EXPORT_SYMBOL(security_inode_getsecctx); From patchwork Fri Feb 14 23:41: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: 11383603 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 C0F49139A for ; Fri, 14 Feb 2020 23:44:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A099A24649 for ; Fri, 14 Feb 2020 23:44:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="K6m4erOA" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728238AbgBNXoz (ORCPT ); Fri, 14 Feb 2020 18:44:55 -0500 Received: from sonic310-31.consmr.mail.ne1.yahoo.com ([66.163.186.212]:45743 "EHLO sonic310-31.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728236AbgBNXoz (ORCPT ); Fri, 14 Feb 2020 18:44:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723893; bh=7uEuOMRa05eNQvWzZSvo8zwgKED7of4sujRisHV1bww=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=K6m4erOA5A8mu4pizTCC6e9Ifp5dzyHObxl+yU5ZnJBi6IlvbkvF1eAC6A+nc0CObw8Q6mjWgigXJStti1otHDQgL21vtkv18nU82Mp2aDwBraKGH8XZF7sOElgLJhWWKAApa6lcF70jC3IAVY0CmH84rOl9u/rThehwp/juYYWmsdCgOZLFJNLkkOfWZCY4fnXjf7mTSyfOImKMPG7uLR3elYhfa55k4JupYmxlSllIAcPgvoxi5fV/MZG/Jk3M5vLEcr2oAExeYM7OpmaOQoNOixlsgk05ViEYtadw+KYg89YR4iWJnnw/TCqdpKvrQksa2J0fwShCLjBeFs1vrA== X-YMail-OSG: dmBevWwVM1maW2qwnizCRZdPncSaCxYxxmiwaePZTFQuz7nwWYky7n3TClXS_w4 2J12NitrF_wLFRJ8q5_sZO5MlIQH_BzRUCsT9o3soKyRl7Bi2oAT4hVYyb1rvkKfUFiFNvEuDl_9 QAxOG1NMZ5yBUjcHw_b1YQfHKSSLZhVADSiNR9lyPgIY0U1mIx6.4tkGjCFlOVwpMuJ7kz3NTCoV vP6XNeUlkMlbVo9Y8jnho.s_we0.goJmoYhxEXohkZP93ECuXD3TuAMOPocYsbTxSBhXrNzjn0vb b4molKJsNllPfXmJhGY4dtIA_E7w_woo3KB8Q24OMOWl_EKdI3Tcq_UCteNRCtXaMFM.hIasXK9T VVSFYIW_I_LtQk49AA5nNHENfYm4kKf_aVr59HPz_3IUmXq3s4Xn_M.LJpIY3YEB3PkFbf.tZrdK V_7koKcUGcLlLOXzOJyzCbQ9Up3PhTt..X7Bibhu4Vlzx93CE_zvJDuKn6E9U0UGWwq0.kGf0fgr y9ZBXUvECJ2tEq7M2PZC9NfhiPbCGxCp9JdWxSuf1rHjmrifb6v64CfnIpuN1aHEMRhXtXm0vgoq 3tYqw.34mzutKpcOMK5QVl7DAZ4G8fla2RyoOAPcMHRM60cRRU9lTv7U9iFao67P0m5WdPuOezdk NJobgAFSAZFgw.rfssWgypnCDCI82Gk3FU1RpQNC_RotnH564uPMN.EwangVRPkLlmEksyCmKCNv F0ODeQX4Ilqdrq0Xml6HlCaVIIogpXJwHDvHcw2j3wrR7.5pgrJVcgg9FuxUKY54H7D8e81T8SP. nKWWwxmuhQimWMcLIddmKhyXAvnn92DB4kvPUreaNXkR9IHabigR1RWdS.Xatp5b3X_0sKgmb6M. zm8alYKQylRJdkC865cDspd3AcmAD2QfQFKfcXRlT1TzYDrZQmoijfkc3AjN1Q1VT3iFSmY9VLa1 og6pvgE9bt_HidIjtBtq8Vl1m7CpMgX4BfGO0bIkzxe3x5a6FprZilb7qOrZS22.ApQOHB6qmt0_ dZp39QKFLsrleDtl5cXH6rmsUM2KEPtqzmhhUiaBB7bHNKsdjCgtIKQPJBD8i.ok4Zl4jx4jfFk8 MSvDXdnORyy7EyPDjyoPX2De3vWMCdztk7Os9yr5LPJG6OSbUVzr_B272cUQ2BUPRersdkUAalTD w_1KfnTthXV86X2sIimTuRiLR.U.HElQ5didSGr0dG3c.TsSfSPAEmPntTj4K7gXzWnUDwzqHikP sA3.A4tYYRy2yrO1ofTyYKmGdY3SFAKSl_isYPhDSkCETWWiq5gQxmasCiUbA7lh4VzFnmzH9uhB tNvD9vGwf.k3KBsuMh8w7kUFnMtb6k05hhi5qgKtc7Ium7fGXTKqGYlt43_Hi_233wdjk_8Kydr0 VfLCc8YUCIiJUlaVV4amPerX83HqqM6NOd4fqIdr4S.AWDEegjMcnzNMTm8Yvw4DT5AlQI14zve0 - Received: from sonic.gate.mail.ne1.yahoo.com by sonic310.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:44:53 +0000 Received: by smtp407.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 768a909794458cd16a286f5d22121ebc; Fri, 14 Feb 2020 23:44:50 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 17/23] LSM: security_secid_to_secctx in netlink netfilter Date: Fri, 14 Feb 2020 15:41:57 -0800 Message-Id: <20200214234203.7086-18-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Change netlink netfilter interfaces to use lsmcontext pointers, and remove scaffolding. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler cc: netdev@vger.kernel.org --- net/netfilter/nfnetlink_queue.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 7e91f3c10b29..e0512e91fed9 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -301,12 +301,10 @@ static int nfqnl_put_sk_uidgid(struct sk_buff *skb, struct sock *sk) return -1; } -static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) +static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext *context) { - u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) struct lsmblob blob; - struct lsmcontext context = { }; if (!skb || !sk_fullsock(skb->sk)) return 0; @@ -314,15 +312,16 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) read_lock_bh(&skb->sk->sk_callback_lock); if (skb->secmark) { + /* Any LSM might be looking for the secmark */ lsmblob_init(&blob, skb->secmark); - security_secid_to_secctx(&blob, &context); - *secdata = context.context; + security_secid_to_secctx(&blob, context); } read_unlock_bh(&skb->sk->sk_callback_lock); - seclen = context.len; + return context->len; +#else + return 0; #endif - return seclen; } static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry) @@ -398,8 +397,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, enum ip_conntrack_info uninitialized_var(ctinfo); struct nfnl_ct_hook *nfnl_ct; bool csum_verify; - struct lsmcontext scaff; /* scaffolding */ - char *secdata = NULL; + struct lsmcontext context = { }; u32 seclen = 0; size = nlmsg_total_size(sizeof(struct nfgenmsg)) @@ -466,7 +464,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } if ((queue->flags & NFQA_CFG_F_SECCTX) && entskb->sk) { - seclen = nfqnl_get_sk_secctx(entskb, &secdata); + seclen = nfqnl_get_sk_secctx(entskb, &context); if (seclen) size += nla_total_size(seclen); } @@ -601,7 +599,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, nfqnl_put_sk_uidgid(skb, entskb->sk) < 0) goto nla_put_failure; - if (seclen && nla_put(skb, NFQA_SECCTX, seclen, secdata)) + if (seclen && nla_put(skb, NFQA_SECCTX, context.len, context.context)) goto nla_put_failure; if (ct && nfnl_ct->build(skb, ct, ctinfo, NFQA_CT, NFQA_CT_INFO) < 0) @@ -629,10 +627,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } nlh->nlmsg_len = skb->len; - if (seclen) { - lsmcontext_init(&scaff, secdata, seclen, 0); - security_release_secctx(&scaff); - } + if (seclen) + security_release_secctx(&context); return skb; nla_put_failure: @@ -640,10 +636,8 @@ 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) { - lsmcontext_init(&scaff, secdata, seclen, 0); - security_release_secctx(&scaff); - } + if (seclen) + security_release_secctx(&context); return NULL; } From patchwork Fri Feb 14 23:41: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: 11383611 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 C447F159A for ; Fri, 14 Feb 2020 23:45:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9137624649 for ; Fri, 14 Feb 2020 23:45:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="D1qXS8fM" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728333AbgBNXpQ (ORCPT ); Fri, 14 Feb 2020 18:45:16 -0500 Received: from sonic308-16.consmr.mail.ne1.yahoo.com ([66.163.187.39]:40003 "EHLO sonic308-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728271AbgBNXpQ (ORCPT ); Fri, 14 Feb 2020 18:45:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723910; bh=l4jgH3lkCwQRd70jBIMCOTlJPoT5xEqpVMifJF75GDg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=D1qXS8fM1SrKP4soqo/+Neh6pRpBoS7x7FkrNVQZLri+c+N409rqvWRsjB4UU/4XdKs7v9jSxdWc4j1D78SsTyC4sftLW2OEQSZpIN2PMFXjpO81Fy/aAftlFrfUQdcI5NmjyIU31X3Uo1FUQpVDjZmCuih7W8F5PNDG5K73ue6cyLmai9xjvj2EsOmz6QO6yHheu8nIUA/THfQNn+Gn2z/77X6U0vi6mO9RJV+hkFIw/+03Dx989P90zc2aF+tJkd/+ozhsfXF9IMjhhrR6fmXGSgzlZIUK7nX2o4aevhn1h1wFtWUYuwrm3BrDjbR9KNKrgbXCNWjrTtlFJdZygQ== X-YMail-OSG: k51uKbsVM1kkmm1tVltrlHcUac8QAJBdwsWNxYevNJrnV8IuZDniwXkVyzYmJQc VFZXWqctmPH_EZ6Xym2qIsLpBwP0XpgMFsLswSxMscFMMK1oNnqJi_1rpUB27xlktuNVUiBAl2u1 YgaBfLK17nQLc6ZDXf3gEg_yRjRfpcnAJQE8cVrhKxPW1GnIQfNf92TiM4_t3WDzQbSKYuNdMnpc gUHZvlUAblg8HIzbV26RV.J7iWQ.oIQ44BF8TYIwFu8HFsPKA0TChnKl6FbFo_XpC9K.KhePSMcf TYC3tfevrP8Yt2UaWZ.2t00ekXFScQE0gaE.jyDGsOr0Skv4p2194w9fKFytC3qjHjt8R2xvw5TW Vu_nFBGTgX5HyKy2t0fswbuX5vm73dpgC58_hQJpLy29cCI7UFFUuPiqtks3NQz2tilSaxtgCKOW kFN0XQiczfPR7NBcKgbWArgORbpE_qZULgjyixeqi2I6SJ3uFLUgYR9DnEwtQvTf3Ia3NBRYJNbq 1HuohweYSzvkPQ7_JJocwi6XhKeS8VyzkydJc.3n4v3mVIF0d5byNQYgZ16WkGCxSIVy8HN7r2Gx 73wELKvUDreOX9Q2FL0160FMXmEr.T6co0jNwXif92L74UKfZmVHdkiSzPq4q9VD9y83LoN59_dd HnWRq75wUB68nc84eQcSkN.vug61MYjRx..5_NAZUj4HDEwvk0YS6wSKJr0V7cnzTjfTHah4eX5Y Qv7iivFgccBd9sfPrrvD8rtGmjEesTLSFHTiUfRoz7MU2pdas_wGGA3eSWKoHBijYryGLRNYNI_B VubMXRC0XGTgtBTKgJA.Mmr6diEyUnmgI9PY3LVSnfWQUrTju12nBISrO.HAVy5laF8P2HDlqxSM I52L2m6iNg39JES_pWucBzWvWbv4nJI5d7Z9nfOfdIWJ93oAzvn3FBz8pGrRAiN52VaSISgtRCzQ XXjw.mtkYPxqnykWoW_O2MTs1k_kHylpPSdxcEbBiM1eifzqZO2EOsB8pYRz8ESicrz1sF3q5ak0 qw375vugVxqGvyKVMS1xjFi7s5ntXkurWtTFeo8cg1tNS5gYhu9BHSA87.dbXDlin_ED8ypPDOZB KbNc.enHtuwRY_dd8QuLK9_3NYzVVsCjwBSePtZAKOFSLZAEUW2_5fKbhhtat9KC3.0fVj6uPWUN bPGNCitfFdMPL_onZhRp2EsN7Ahgi42ebGdwVfoYP.mo_iWlyEB6u2YyNYugjawrEtJFRrpyYGiM rR4eYhEM2ImDCM4x2vvjVuClrO10di1abbGl72NEMLRksvqw73gRvkvNkKMWG0LKAAzx88uinhup 6FT65pEqL2hAtk1G.yVqyYnUMqzmRiNYKs3Uh_dvr_FeY.pnOloOiLEjX8KkTvd21YNB_opi0ITF vB3KFQRisQnaWmFitWdCxRpoG5cF8L4YmEij26lOcnvQA4r.1HHHScf1DsNKGwQmnpMmkDmE- Received: from sonic.gate.mail.ne1.yahoo.com by sonic308.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:45:10 +0000 Received: by smtp429.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 46059d1118a3773b16a774c9ae68d67b; Fri, 14 Feb 2020 23:45:08 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 18/23] NET: Store LSM netlabel data in a lsmblob Date: Fri, 14 Feb 2020 15:41:58 -0800 Message-Id: <20200214234203.7086-19-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Netlabel uses LSM interfaces requiring an lsmblob and the internal storage is used to pass information between these interfaces, so change the internal data from a secid to a lsmblob. Update the netlabel interfaces and their callers to accommodate the change. This requires that the modules using netlabel use the lsm_id.slot to access the correct secid when using netlabel. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler --- include/net/netlabel.h | 8 ++-- net/ipv4/cipso_ipv4.c | 23 +++++++----- net/netlabel/netlabel_kapi.c | 6 +-- net/netlabel/netlabel_unlabeled.c | 57 +++++++++++------------------ net/netlabel/netlabel_unlabeled.h | 2 +- security/selinux/hooks.c | 2 +- security/selinux/include/security.h | 1 + security/selinux/netlabel.c | 2 +- security/selinux/ss/services.c | 4 +- security/smack/smack.h | 1 + security/smack/smack_lsm.c | 5 ++- security/smack/smackfs.c | 10 +++-- 12 files changed, 59 insertions(+), 62 deletions(-) diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 43ae50337685..73fc25b4042b 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h @@ -166,7 +166,7 @@ struct netlbl_lsm_catmap { * @attr.mls: MLS sensitivity label * @attr.mls.cat: MLS category bitmap * @attr.mls.lvl: MLS sensitivity level - * @attr.secid: LSM specific secid token + * @attr.lsmblob: LSM specific data * * Description: * This structure is used to pass security attributes between NetLabel and the @@ -201,7 +201,7 @@ struct netlbl_lsm_secattr { struct netlbl_lsm_catmap *cat; u32 lvl; } mls; - u32 secid; + struct lsmblob lsmblob; } attr; }; @@ -415,7 +415,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info); int netlbl_cfg_unlbl_static_del(struct net *net, const char *dev_name, @@ -523,7 +523,7 @@ static inline int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { return -ENOSYS; diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 376882215919..adb9dffc3952 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -106,15 +106,17 @@ int cipso_v4_rbm_strictvalid = 1; /* Base length of the local tag (non-standard tag). * Tag definition (may change between kernel versions) * - * 0 8 16 24 32 - * +----------+----------+----------+----------+ - * | 10000000 | 00000110 | 32-bit secid value | - * +----------+----------+----------+----------+ - * | in (host byte order)| - * +----------+----------+ - * + * 0 8 16 16 + sizeof(struct lsmblob) + * +----------+----------+---------------------+ + * | 10000000 | 00000110 | LSM blob data | + * +----------+----------+---------------------+ + * + * All secid and flag fields are in host byte order. + * The lsmblob structure size varies depending on which + * Linux security modules are built in the kernel. + * The data is opaque. */ -#define CIPSO_V4_TAG_LOC_BLEN 6 +#define CIPSO_V4_TAG_LOC_BLEN (2 + sizeof(struct lsmblob)) /* * Helper Functions @@ -1467,7 +1469,8 @@ static int cipso_v4_gentag_loc(const struct cipso_v4_doi *doi_def, buffer[0] = CIPSO_V4_TAG_LOCAL; buffer[1] = CIPSO_V4_TAG_LOC_BLEN; - *(u32 *)&buffer[2] = secattr->attr.secid; + memcpy(&buffer[2], &secattr->attr.lsmblob, + sizeof(secattr->attr.lsmblob)); return CIPSO_V4_TAG_LOC_BLEN; } @@ -1487,7 +1490,7 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def, const unsigned char *tag, struct netlbl_lsm_secattr *secattr) { - secattr->attr.secid = *(u32 *)&tag[2]; + memcpy(&secattr->attr.lsmblob, &tag[2], sizeof(secattr->attr.lsmblob)); secattr->flags |= NETLBL_SECATTR_SECID; return 0; diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 409a3ae47ce2..f2ebd43a7992 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c @@ -196,7 +196,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, * @addr: IP address in network byte order (struct in[6]_addr) * @mask: address mask in network byte order (struct in[6]_addr) * @family: address family - * @secid: LSM secid value for the entry + * @lsmblob: LSM data value for the entry * @audit_info: NetLabel audit information * * Description: @@ -210,7 +210,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, const void *addr, const void *mask, u16 family, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { u32 addr_len; @@ -230,7 +230,7 @@ int netlbl_cfg_unlbl_static_add(struct net *net, return netlbl_unlhsh_add(net, dev_name, addr, mask, addr_len, - secid, audit_info); + lsmblob, audit_info); } /** diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index c03fe9a4f7b9..3b0f07b59436 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -66,7 +66,7 @@ struct netlbl_unlhsh_tbl { #define netlbl_unlhsh_addr4_entry(iter) \ container_of(iter, struct netlbl_unlhsh_addr4, list) struct netlbl_unlhsh_addr4 { - u32 secid; + struct lsmblob lsmblob; struct netlbl_af4list list; struct rcu_head rcu; @@ -74,7 +74,7 @@ struct netlbl_unlhsh_addr4 { #define netlbl_unlhsh_addr6_entry(iter) \ container_of(iter, struct netlbl_unlhsh_addr6, list) struct netlbl_unlhsh_addr6 { - u32 secid; + struct lsmblob lsmblob; struct netlbl_af6list list; struct rcu_head rcu; @@ -219,7 +219,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) * @iface: the associated interface entry * @addr: IPv4 address in network byte order * @mask: IPv4 address mask in network byte order - * @secid: LSM secid value for entry + * @lsmblob: LSM data value for entry * * Description: * Add a new address entry into the unlabeled connection hash table using the @@ -230,7 +230,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, const struct in_addr *addr, const struct in_addr *mask, - u32 secid) + struct lsmblob *lsmblob) { int ret_val; struct netlbl_unlhsh_addr4 *entry; @@ -242,7 +242,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, entry->list.addr = addr->s_addr & mask->s_addr; entry->list.mask = mask->s_addr; entry->list.valid = 1; - entry->secid = secid; + entry->lsmblob = *lsmblob; spin_lock(&netlbl_unlhsh_lock); ret_val = netlbl_af4list_add(&entry->list, &iface->addr4_list); @@ -259,7 +259,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, * @iface: the associated interface entry * @addr: IPv6 address in network byte order * @mask: IPv6 address mask in network byte order - * @secid: LSM secid value for entry + * @lsmblob: LSM data value for entry * * Description: * Add a new address entry into the unlabeled connection hash table using the @@ -270,7 +270,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, const struct in6_addr *addr, const struct in6_addr *mask, - u32 secid) + struct lsmblob *lsmblob) { int ret_val; struct netlbl_unlhsh_addr6 *entry; @@ -286,7 +286,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; entry->list.mask = *mask; entry->list.valid = 1; - entry->secid = secid; + entry->lsmblob = *lsmblob; spin_lock(&netlbl_unlhsh_lock); ret_val = netlbl_af6list_add(&entry->list, &iface->addr6_list); @@ -365,7 +365,7 @@ int netlbl_unlhsh_add(struct net *net, const void *addr, const void *mask, u32 addr_len, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info) { int ret_val; @@ -374,7 +374,6 @@ int netlbl_unlhsh_add(struct net *net, struct netlbl_unlhsh_iface *iface; struct audit_buffer *audit_buf = NULL; struct lsmcontext context; - struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && addr_len != sizeof(struct in6_addr)) @@ -407,7 +406,7 @@ int netlbl_unlhsh_add(struct net *net, const struct in_addr *addr4 = addr; const struct in_addr *mask4 = mask; - ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid); + ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, lsmblob); if (audit_buf != NULL) netlbl_af4list_audit_addr(audit_buf, 1, dev_name, @@ -420,7 +419,7 @@ int netlbl_unlhsh_add(struct net *net, const struct in6_addr *addr6 = addr; const struct in6_addr *mask6 = mask; - ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid); + ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, lsmblob); if (audit_buf != NULL) netlbl_af6list_audit_addr(audit_buf, 1, dev_name, @@ -437,8 +436,7 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - lsmblob_init(&blob, secid); - if (security_secid_to_secctx(&blob, &context) == 0) { + if (security_secid_to_secctx(lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -473,7 +471,6 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, @@ -493,10 +490,8 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); if (dev != NULL) dev_put(dev); - if (entry != NULL) - lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -537,7 +532,6 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct audit_buffer *audit_buf; struct net_device *dev; struct lsmcontext context; - struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); @@ -556,10 +550,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); if (dev != NULL) dev_put(dev); - if (entry != NULL) - lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(&blob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -913,9 +905,8 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, if (ret_val != 0) return ret_val; - /* scaffolding with the [0] */ return netlbl_unlhsh_add(&init_net, - dev_name, addr, mask, addr_len, blob.secid[0], + dev_name, addr, mask, addr_len, &blob, &audit_info); } @@ -963,10 +954,8 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, if (ret_val != 0) return ret_val; - /* scaffolding with the [0] */ return netlbl_unlhsh_add(&init_net, - NULL, addr, mask, addr_len, blob.secid[0], - &audit_info); + NULL, addr, mask, addr_len, &blob, &audit_info); } /** @@ -1078,8 +1067,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, struct net_device *dev; struct lsmcontext context; void *data; - u32 secid; - struct lsmblob blob; + struct lsmblob *lsmb; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family, @@ -1117,7 +1105,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, if (ret_val != 0) goto list_cb_failure; - secid = addr4->secid; + lsmb = (struct lsmblob *)&addr4->lsmblob; } else { ret_val = nla_put_in6_addr(cb_arg->skb, NLBL_UNLABEL_A_IPV6ADDR, @@ -1131,11 +1119,10 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, if (ret_val != 0) goto list_cb_failure; - secid = addr6->secid; + lsmb = (struct lsmblob *)&addr6->lsmblob; } - lsmblob_init(&blob, secid); - ret_val = security_secid_to_secctx(&blob, &context); + ret_val = security_secid_to_secctx(lsmb, &context); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, @@ -1487,7 +1474,7 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, &iface->addr4_list); if (addr4 == NULL) goto unlabel_getattr_nolabel; - secattr->attr.secid = netlbl_unlhsh_addr4_entry(addr4)->secid; + secattr->attr.lsmblob = netlbl_unlhsh_addr4_entry(addr4)->lsmblob; break; } #if IS_ENABLED(CONFIG_IPV6) @@ -1500,7 +1487,7 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, &iface->addr6_list); if (addr6 == NULL) goto unlabel_getattr_nolabel; - secattr->attr.secid = netlbl_unlhsh_addr6_entry(addr6)->secid; + secattr->attr.lsmblob = netlbl_unlhsh_addr6_entry(addr6)->lsmblob; break; } #endif /* IPv6 */ diff --git a/net/netlabel/netlabel_unlabeled.h b/net/netlabel/netlabel_unlabeled.h index 058e3a285d56..168920780994 100644 --- a/net/netlabel/netlabel_unlabeled.h +++ b/net/netlabel/netlabel_unlabeled.h @@ -211,7 +211,7 @@ int netlbl_unlhsh_add(struct net *net, const void *addr, const void *mask, u32 addr_len, - u32 secid, + struct lsmblob *lsmblob, struct netlbl_audit *audit_info); int netlbl_unlhsh_remove(struct net *net, const char *dev_name, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index a12cc8959f6c..4618e2d0c032 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6875,7 +6875,7 @@ static int selinux_perf_event_write(struct perf_event *event) } #endif -static struct lsm_id selinux_lsmid __lsm_ro_after_init = { +struct lsm_id selinux_lsmid __lsm_ro_after_init = { .lsm = "selinux", .slot = LSMBLOB_NEEDED }; diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index a39f9565d80b..8300e565ddf3 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -70,6 +70,7 @@ struct netlbl_lsm_secattr; extern int selinux_enabled_boot; +extern struct lsm_id selinux_lsmid; /* Policy capabilities */ enum { diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 6a94b31b5472..d8d7603ab14e 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -108,7 +108,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr( return NULL; if ((secattr->flags & NETLBL_SECATTR_SECID) && - (secattr->attr.secid == sid)) + (secattr->attr.lsmblob.secid[selinux_lsmid.slot] == sid)) return secattr; return NULL; diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 216ce602a2b5..8972269a8e3e 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -3673,7 +3673,7 @@ int security_netlbl_secattr_to_sid(struct selinux_state *state, if (secattr->flags & NETLBL_SECATTR_CACHE) *sid = *(u32 *)secattr->cache->data; else if (secattr->flags & NETLBL_SECATTR_SECID) - *sid = secattr->attr.secid; + *sid = secattr->attr.lsmblob.secid[selinux_lsmid.slot]; else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { rc = -EIDRM; ctx = sidtab_search(sidtab, SECINITSID_NETMSG); @@ -3746,7 +3746,7 @@ int security_netlbl_sid_to_secattr(struct selinux_state *state, if (secattr->domain == NULL) goto out; - secattr->attr.secid = sid; + secattr->attr.lsmblob.secid[selinux_lsmid.slot] = sid; secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; mls_export_netlbl_lvl(policydb, ctx, secattr); rc = mls_export_netlbl_cat(policydb, ctx, secattr); diff --git a/security/smack/smack.h b/security/smack/smack.h index 2836540f9577..6e76b6b33063 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -316,6 +316,7 @@ void smk_destroy_label_list(struct list_head *list); * Shared data. */ extern int smack_enabled; +extern struct lsm_id smack_lsmid; extern int smack_cipso_direct; extern int smack_cipso_mapped; extern struct smack_known *smack_net_ambient; diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 00a304861657..5bee05bd7a42 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3767,7 +3767,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, /* * Looks like a fallback, which gives us a secid. */ - return smack_from_secid(sap->attr.secid); + return smack_from_secid( + sap->attr.lsmblob.secid[smack_lsmid.slot]); /* * Without guidance regarding the smack value * for the packet fall back on the network @@ -4584,7 +4585,7 @@ 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 = { +struct lsm_id smack_lsmid __lsm_ro_after_init = { .lsm = "smack", .slot = LSMBLOB_NEEDED }; diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index e3e05c04dbd1..d10e9c96717e 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -1122,6 +1122,7 @@ static void smk_net4addr_insert(struct smk_net4addr *new) static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { + struct lsmblob lsmblob; struct smk_net4addr *snp; struct sockaddr_in newname; char *smack; @@ -1253,10 +1254,13 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, * this host so that incoming packets get labeled. * but only if we didn't get the special CIPSO option */ - if (rc == 0 && skp != NULL) + if (rc == 0 && skp != NULL) { + lsmblob_init(&lsmblob, 0); + lsmblob.secid[smack_lsmid.slot] = snp->smk_label->smk_secid; rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, - &snp->smk_host, &snp->smk_mask, PF_INET, - snp->smk_label->smk_secid, &audit_info); + &snp->smk_host, &snp->smk_mask, PF_INET, &lsmblob, + &audit_info); + } if (rc == 0) rc = count; From patchwork Fri Feb 14 23:41: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: 11383613 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 8396392A for ; Fri, 14 Feb 2020 23:45:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6475A24649 for ; Fri, 14 Feb 2020 23:45:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="VNdxTC2H" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728380AbgBNXpR (ORCPT ); Fri, 14 Feb 2020 18:45:17 -0500 Received: from sonic314-27.consmr.mail.ne1.yahoo.com ([66.163.189.153]:35692 "EHLO sonic314-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728389AbgBNXpQ (ORCPT ); Fri, 14 Feb 2020 18:45:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723916; bh=B4wbGcaiLwb5+EB9+xkZV8Fh0rr1qZuc/k0LHtXJsBw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=VNdxTC2Hsz+fvHtT5yMYgzDT5wFIUdObwxEO2QxFAYsYr30oVzDaId89l0ZiiL26O6wMOLPA+FadqMSBHaYcoulRwvyrTPvdsKyDFzUV4xnhibpGGaHfZxxRKybhH4iS5ZYL0VJKSv/8aIEOlNT1ls4afdFRk6JrG9Pj/eTrEWhIs7CHOOHkBczKoz9kFJas0qyU8MRJ3YPYSkuSh9TdEFBscP/gutR7MXmRLVbzZ71ByxPyoKPNnhr6n+uAqDiiqq/M3oaP/vIYW7vxfef7hzBvnqfjKteYPqZNoFXbSnFsLyIieJrtaq4CYOUyNazq13Y37h8CZHVDFsL2VrJrcA== X-YMail-OSG: SFrpa0gVM1nNnUx9KgrMQ.Shq80JlKa8hV4Io1xpdOG9dHgg4Sdnyi47bCwTGQd 89q8FPgsO2isDI4v_SLXcDwPHR5KUGd6PYtqnN_X7gxQROEZS6SkTfFRTfXqHdvrunCr07w7oNWb axPQc3RmBjfN3QSrYe_HdkQAaB.PpHTX37lI1JDyJcZSFNDfJqFihPoQN65Qt4in45fyL7u8tjlS ehIglk1pjECwA_VdQIJUV1VlZSD1PldYO1MYiMbJcfPjMthohJRGsSMYCcdIqOp2rynIQguB6VTK 4QeRsKko5KiQelLcX8mkFr4GEMA8_QeT_uWSTEsRArKw2G4Q.m45nuRw16Wcx1isAVi1nQbBAJQO Wr.Iv.iOpOlV57_zanG4YPLwrjLpqc1.yPJw73Lqp8JMLG1hV7Zej__URhuXezM8Z_e8SGXZVeEC dSbRPJFhjeIIgPiQhb4chBd2vVF7i7YapXOVNqbSSnKWLOgb8vMbS.ir0AQo7r_Yce7L0uq4o8lH u7hiVmIf_urOtkzPdeZG0AY6VeyuvWUzBJokfdnODWk9MUyjHmP7zqCmCplDlVfe2CXn6qJyji0h qa_vVYImUr4feGHoXsTUPEDYfBsi_8CTL94QPL1iL.4kc_IMJFbYFW7vXTgNnwMNoVzD73cEZtsG GYOR9fh_TCfteOZduk45.DxLuM7rzHJ1mN04cM9cYFOG2_CzKBay4jRZCxGh.iGwefXyUlOCMTwz GLOOu4z6RBli4VVpb5CI5enqpuwciCzruO1Khqnih0I_xEdvmhNlDuEdqYhkldZF7dZj8uNZkMvO bxAal0xstYEhICAJO8ek2.485PF4kdYNVTa.tlhl73OkCEyIRT7FZJXdk2Cycqa6SgpT9jASRL3d 3qcsJHO9rBQLcV9EJcpCfnRTSBdfo3kBhvxbixveJOxzK00Goz_YvkbAzVzUgWqY1wVK.R_sSe5v CuUbXuevIAdcFHUdCbNCV1HWOuix2NkppIO_Ltjsw1g7rWfR_yNccrf_Vhbe8Pau2bC3i87IGMQC AQ0x6r_TTkLzuHu3nW98qW7Z7mTCaBgB4ifrpnD3Ki.l80gOSO._Fhlm0kn4QMXXfc6Uyenshnt. 81KczZ5z2AOLjHfmGF8TbQHCu0o76wiSGsHaJvAymeDkYuN_80kmULSVEFZiEIFQdAmN7UdXPgzk OPuKe3cz721uI85CCwH5SxrgsZVyiPkBg4My3YjvrOgIVQTNeZquNmq5fahacD2.gS4I1w3Xphqh _5vK_vhCG3N4BlztkGtFOFhF_.DNCPQhiIeMaMUgypCJlfB5U3kPn3TOf9Qhf2BPTXgMRJcGyLYL oKTFFCncQpH1SCgnjhmxmNPR6BGUx3viJtGizCChrPW8EpeE87UCNVml._uzdX9k_OcsrbjYPk1y 2PWaNumlaEeGPOY_Z5VNwX.NCsABP6SucNVYXYlRcRpU4m2GjDJbEUw-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:45:16 +0000 Received: by smtp429.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 46059d1118a3773b16a774c9ae68d67b; Fri, 14 Feb 2020 23:45: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, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 19/23] LSM: Verify LSM display sanity in binder Date: Fri, 14 Feb 2020 15:41:59 -0800 Message-Id: <20200214234203.7086-20-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Verify that the tasks on the ends of a binder transaction use the same "display" security module. This prevents confusion of security "contexts". Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler --- security/security.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/security/security.c b/security/security.c index d663406cba86..d6600bb81829 100644 --- a/security/security.c +++ b/security/security.c @@ -769,9 +769,38 @@ int security_binder_set_context_mgr(struct task_struct *mgr) return call_int_hook(binder_set_context_mgr, 0, mgr); } +/** + * security_binder_transaction - Binder driver transaction check + * @from: source of the transaction + * @to: destination of the transaction + * + * Verify that the tasks have the same LSM "display", then + * call the security module hooks. + * + * Returns -EINVAL if the displays don't match, or the + * result of the security module checks. + */ int security_binder_transaction(struct task_struct *from, struct task_struct *to) { + int from_display = lsm_task_display(from); + int to_display = lsm_task_display(to); + + /* + * If the display is LSMBLOB_INVALID the first module that has + * an entry is used. This will be in the 0 slot. + * + * This is currently only required if the server has requested + * peer contexts, but it would be unwieldly to have too much of + * the binder driver detail here. + */ + if (from_display == LSMBLOB_INVALID) + from_display = 0; + if (to_display == LSMBLOB_INVALID) + to_display = 0; + if (from_display != to_display) + return -EINVAL; + return call_int_hook(binder_transaction, 0, from, to); } From patchwork Fri Feb 14 23:42: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: 11383617 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 C31DC159A for ; Fri, 14 Feb 2020 23:45:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 865E324649 for ; Fri, 14 Feb 2020 23:45:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="t8zfAWqM" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728396AbgBNXpf (ORCPT ); Fri, 14 Feb 2020 18:45:35 -0500 Received: from sonic314-27.consmr.mail.ne1.yahoo.com ([66.163.189.153]:34075 "EHLO sonic314-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728271AbgBNXpf (ORCPT ); Fri, 14 Feb 2020 18:45:35 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723931; bh=wYO2CcQl2Kf9WovEcrBX6XimRlXSfK+Qih9jcWSahZw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=t8zfAWqMns7NVsI0Ap7x+58dp0mJ9wyqrx1QLixIj7TB0at5Js36O6clHiBMsMZaQRoYUzU0bdA5/Xqkb5T5lcGK6QKP2yy7PUfoSKkx2AOhMlZ+/NHsQ/ELMdgG2rdCWrFgf3zUm2/lf/5nZLNKVP7KArlvrf7fSg/jNCUathOzW4n0mKCNUHBhllwrjQHPHQgYH5ft6RVMeQ6dXNmIOPl72MLL1e4uSTLT+dj1xzbaCUJfCgERupiIoIVcC9zZp/ST/jgw/cgN1Bn/yOzr/YWWLjko9lrgq+SWg9kVVjEuUMoNbiyZr2yOXkqDJKFOtrrSmIdUy+lb3GG48tz+Fg== X-YMail-OSG: Vu6S7.MVM1m33B14V1p1qPIRhHnNjDlC7tfvUuyY66kgK0dbtBDSTEpKW1R3k4b 04klffko5ZZtBjb9ENrLVLTxSZ0Clq5JXbzAwM4J8V0NOOg8LnPH7LDK4GwMgnyY4gF3LnLzPv5X 4yRaBzMH2LCyiq3.ujON.0EFpO.FMXYv2idKgxfdMmxkyW4AwEy09DWNPlwlKJVkODQ2yTIqsCd6 cfGkuhY8Lb4C5nGSwJ5wA6cZkbrvoCiHDibej8WBoc04RviQY.R78xePTc7JxFMAylBZty8QERoh r8iskDzUj1UK2_CNsrtDtxdCRm_5Cawz9tnyMTeFYsPSLyCBkKTB.DIeWdjvtvZieJtrs36y9WeX 5ktOapfVbFeqb26zMHkfsP2fL7aQERx6ZJ6Mi57OrO0YbygMbAFzMq.zgeTBQhHtM1SiYHj_DxQo KHmf.Js4oOQQXW9c8zbvE4IcthqqbOdXCuu4mkwMWQ0vjl3ZALCIZFRO6J0qt1wt8wt9znImCUZj tDeMvToXiU17KTLPQBsMRwq2DMMQ4sFF6irYYRTzJjD_KDZZFjqLJTNNQ8f8omtXzQTAnUX6F6wT 83vTcE2EM432MwqTrufTyZ7KO_YfNZrX8KRsAGI2.DC27rIHK20LPuBfZXOr3yGEcj9ZxgzWq8Ff I9Uyt4xB043.ckAinNSpigvts7yBQvo7Uia2TrIkSTaO.SWGNaUn_WLtG3pP4.jIPfu9KcbVOzBz _BZO7Bw6QRijVfC.q8K67JAQtqOLdKuQ2P0R_8s6oHYjxsGDfjKHKJeM4TyPaXGJVTROZCGt_K4k vP797tp3GrfxO4G7Y9iiCOtki4q2zfeH6eGd6p1In4bQ49ohOg1PTO5g_posTm0KRwg6S9Hn2Iw9 PgktzObBwEEy.Yhz143M7UqNcBDEJ7ZOfYIC1SDlSLFYGAXtlh4gJ5CAHwxsmEoYgFy8uEcV6Dhb Yn_gvzKCP4arKNML.Kh_WH2gjDRU9.5uHU2F7ZcJLoszlc.t7djkJb.6w2CNstL8ox2MIXVGUjEl DCIpc6.QAIQncp_ViX.VtopcPhrX7LKb.AHxNFGft1vRSIyjqwCcQiN9lKz4kBE3CSQoPHXeezpU sDuBWcaaxe9LEMPvP0DRJGr5nY3miFCU7GCGqySYVNihJPZcf.GH67GrjgeZSr7G5WcZM6YurnYn PzHCG9PS9HZPXTOteZvsHEgx6R3Ij_W3qCKdJqqR_iTTb1K.0ZT2l5DqOiDaNTfN8GRcocRe2DkC NgIYu4YXkREcGnt6RKBq6W5g_J5DcdpJE3J.6g7akCYpNI9nmeOWLixBpAv945dLFQlSVkDljEMd tqyN.b23i82kCG5I5tniKaPxZnsXts0r3KgzMdigVyPC2bIhb8BnTp.QhvXkxTx1HkHCG9Jz2ykp HZWq1yiHFvwu2B4CcYBYNGjFS9D8lii0O0Ho- Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:45:31 +0000 Received: by smtp419.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID ce63e428e13fa705f0ae101fe46b87ce; Fri, 14 Feb 2020 23:45:30 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 20/23] Audit: Add subj_LSM fields when necessary Date: Fri, 14 Feb 2020 15:42:00 -0800 Message-Id: <20200214234203.7086-21-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Add record entries to identify subject data for all of the security modules when there is more than one. Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler Cc: netdev@vger.kernel.org Cc: linux-audit@redhat.com --- drivers/android/binder.c | 2 +- include/linux/audit.h | 1 + include/linux/security.h | 9 ++++- include/net/scm.h | 3 +- kernel/audit.c | 40 ++++++++++++++++++- kernel/audit_fsnotify.c | 1 + kernel/auditfilter.c | 1 + kernel/auditsc.c | 10 +++-- net/ipv4/ip_sockglue.c | 2 +- net/netfilter/nf_conntrack_netlink.c | 4 +- net/netfilter/nf_conntrack_standalone.c | 2 +- net/netfilter/nfnetlink_queue.c | 2 +- net/netlabel/netlabel_unlabeled.c | 11 ++++-- net/netlabel/netlabel_user.c | 2 +- net/xfrm/xfrm_policy.c | 2 + net/xfrm/xfrm_state.c | 2 + security/integrity/ima/ima_api.c | 1 + security/integrity/integrity_audit.c | 1 + security/security.c | 51 +++++++++++++++++++++++-- 19 files changed, 124 insertions(+), 23 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index fb7a473f4270..ee6cd2106dea 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3109,7 +3109,7 @@ static void binder_transaction(struct binder_proc *proc, size_t added_size; security_task_getsecid(proc->tsk, &blob); - ret = security_secid_to_secctx(&blob, &lsmctx); + ret = security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_DISPLAY); if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; diff --git a/include/linux/audit.h b/include/linux/audit.h index 8e1c759fd1ff..d4213c471801 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -163,6 +163,7 @@ extern void audit_log_path_denied(int type, extern void audit_log_lost(const char *message); extern int audit_log_task_context(struct audit_buffer *ab); +extern void audit_log_task_lsms(struct audit_buffer *ab); extern void audit_log_task_info(struct audit_buffer *ab); extern int audit_update_lsm_rules(void); diff --git a/include/linux/security.h b/include/linux/security.h index 690f8d6495e5..26b598a843dd 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -178,6 +178,8 @@ struct lsmblob { #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 */ +#define LSMBLOB_DISPLAY -4 /* Use the "display" slot */ +#define LSMBLOB_FIRST -5 /* Use the default "display" slot */ /** * lsmblob_init - initialize an lsmblob structure. @@ -219,6 +221,8 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, struct lsmblob *blobb) return !memcmp(bloba, blobb, sizeof(*bloba)); } +const char *security_lsm_slot_name(int slot); + /* These functions are in security/commoncap.c */ extern int cap_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); @@ -528,7 +532,8 @@ 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, struct lsmcontext *cp); +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp, + int display); int security_secctx_to_secid(const char *secdata, u32 seclen, struct lsmblob *blob); void security_release_secctx(struct lsmcontext *cp); @@ -1333,7 +1338,7 @@ static inline int security_ismaclabel(const char *name) } static inline int security_secid_to_secctx(struct lsmblob *blob, - struct lsmcontext *cp) + struct lsmcontext *cp, int display) { return -EOPNOTSUPP; } diff --git a/include/net/scm.h b/include/net/scm.h index 4a6ad8caf423..8b5a4737e1b8 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -96,7 +96,8 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc int err; if (test_bit(SOCK_PASSSEC, &sock->flags)) { - err = security_secid_to_secctx(&scm->lsmblob, &context); + err = security_secid_to_secctx(&scm->lsmblob, &context, + LSMBLOB_DISPLAY); if (!err) { put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, diff --git a/kernel/audit.c b/kernel/audit.c index a25097cfe623..c3a1d8d2d33c 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -393,6 +393,7 @@ static int audit_log_config_change(char *function_name, u32 new, u32 old, if (rc) allow_changes = 0; /* Something weird, deny request */ audit_log_format(ab, " res=%d", allow_changes); + audit_log_task_lsms(ab); audit_log_end(ab); return rc; } @@ -1098,6 +1099,7 @@ static void audit_log_feature_change(int which, u32 old_feature, u32 new_feature audit_log_format(ab, " feature=%s old=%u new=%u old_lock=%u new_lock=%u res=%d", audit_feature_names[which], !!old_feature, !!new_feature, !!old_lock, !!new_lock, res); + audit_log_task_lsms(ab); audit_log_end(ab); } @@ -1347,6 +1349,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) size--; audit_log_n_untrustedstring(ab, data, size); } + audit_log_task_lsms(ab); audit_log_end(ab); } break; @@ -1361,6 +1364,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) msg_type == AUDIT_ADD_RULE ? "add_rule" : "remove_rule", audit_enabled); + audit_log_task_lsms(ab); audit_log_end(ab); return -EPERM; } @@ -1374,6 +1378,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) audit_log_common_recv_msg(audit_context(), &ab, AUDIT_CONFIG_CHANGE); audit_log_format(ab, " op=trim res=1"); + audit_log_task_lsms(ab); audit_log_end(ab); break; case AUDIT_MAKE_EQUIV: { @@ -1409,6 +1414,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) audit_log_format(ab, " new="); audit_log_untrustedstring(ab, new); audit_log_format(ab, " res=%d", !err); + audit_log_task_lsms(ab); audit_log_end(ab); kfree(old); kfree(new); @@ -1417,7 +1423,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) case AUDIT_SIGNAL_INFO: if (lsmblob_is_set(&audit_sig_lsm)) { err = security_secid_to_secctx(&audit_sig_lsm, - &context); + &context, LSMBLOB_FIRST); if (err) return err; } @@ -1476,6 +1482,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) " old-log_passwd=%d new-log_passwd=%d res=%d", old.enabled, s.enabled, old.log_passwd, s.log_passwd, !err); + audit_log_task_lsms(ab); audit_log_end(ab); break; } @@ -2054,6 +2061,33 @@ void audit_log_key(struct audit_buffer *ab, char *key) audit_log_format(ab, "(null)"); } +void audit_log_task_lsms(struct audit_buffer *ab) +{ + int i; + const char *lsm; + struct lsmblob blob; + struct lsmcontext context; + + /* + * Don't do anything unless there is more than one LSM + * with a security context to report. + */ + if (security_lsm_slot_name(1) == NULL) + return; + + security_task_getsecid(current, &blob); + + for (i = 0; i < LSMBLOB_ENTRIES; i++) { + lsm = security_lsm_slot_name(i); + if (lsm == NULL) + break; + if (security_secid_to_secctx(&blob, &context, i)) + continue; + audit_log_format(ab, " subj_%s=%s", lsm, context.context); + security_release_secctx(&context); + } +} + int audit_log_task_context(struct audit_buffer *ab) { int error; @@ -2064,7 +2098,7 @@ int audit_log_task_context(struct audit_buffer *ab) if (!lsmblob_is_set(&blob)) return 0; - error = security_secid_to_secctx(&blob, &context); + error = security_secid_to_secctx(&blob, &context, LSMBLOB_FIRST); if (error) { if (error != -EINVAL) goto error_path; @@ -2172,6 +2206,7 @@ void audit_log_path_denied(int type, const char *operation) audit_log_format(ab, "op=%s", operation); audit_log_task_info(ab); audit_log_format(ab, " res=0"); + audit_log_task_lsms(ab); audit_log_end(ab); } @@ -2222,6 +2257,7 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, oldloginuid, loginuid, tty ? tty_name(tty) : "(none)", oldsessionid, sessionid, !rc); audit_put_tty(tty); + audit_log_task_lsms(ab); audit_log_end(ab); } diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c index f0d243318452..7f8c4b1a2884 100644 --- a/kernel/audit_fsnotify.c +++ b/kernel/audit_fsnotify.c @@ -126,6 +126,7 @@ static void audit_mark_log_rule_change(struct audit_fsnotify_mark *audit_mark, c audit_log_untrustedstring(ab, audit_mark->path); audit_log_key(ab, rule->filterkey); audit_log_format(ab, " list=%d res=1", rule->listnr); + audit_log_task_lsms(ab); audit_log_end(ab); } diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index c9a46b78b932..cd19dd995120 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1105,6 +1105,7 @@ static void audit_log_rule_change(char *action, struct audit_krule *rule, int re audit_log_format(ab, " op=%s", action); audit_log_key(ab, rule->filterkey); audit_log_format(ab, " list=%d res=%d", rule->listnr, res); + audit_log_task_lsms(ab); audit_log_end(ab); } diff --git a/kernel/auditsc.c b/kernel/auditsc.c index f71d8f7521be..68ae5fa843c1 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -973,7 +973,7 @@ 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, &lsmctx)) { + if (security_secid_to_secctx(blob, &lsmctx, LSMBLOB_FIRST)) { audit_log_format(ab, " obj=(none)"); rc = 1; } else { @@ -1218,7 +1218,8 @@ static void show_special(struct audit_context *context, int *call_panic) struct lsmblob blob; lsmblob_init(&blob, osid); - if (security_secid_to_secctx(&blob, &lsmcxt)) { + if (security_secid_to_secctx(&blob, &lsmcxt, + LSMBLOB_FIRST)) { audit_log_format(ab, " osid=%u", osid); *call_panic = 1; } else { @@ -1370,7 +1371,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, struct lsmcontext lsmctx; lsmblob_init(&blob, n->osid); - if (security_secid_to_secctx(&blob, &lsmctx)) { + if (security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_FIRST)) { audit_log_format(ab, " osid=%u", n->osid); if (call_panic) *call_panic = 2; @@ -1479,6 +1480,7 @@ static void audit_log_exit(void) audit_log_task_info(ab); audit_log_key(ab, context->filterkey); + audit_log_task_lsms(ab); audit_log_end(ab); for (aux = context->aux; aux; aux = aux->next) { @@ -2602,6 +2604,7 @@ void audit_core_dumps(long signr) return; audit_log_task(ab); audit_log_format(ab, " sig=%ld res=1", signr); + audit_log_task_lsms(ab); audit_log_end(ab); } @@ -2628,6 +2631,7 @@ void audit_seccomp(unsigned long syscall, long signr, int code) audit_log_format(ab, " sig=%ld arch=%x syscall=%ld compat=%d ip=0x%lx code=0x%x", signr, syscall_get_arch(current), syscall, in_compat_syscall(), KSTK_EIP(current), code); + audit_log_task_lsms(ab); audit_log_end(ab); } diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 27af7a6b8780..10b418029cdd 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -138,7 +138,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) if (err) return; - err = security_secid_to_secctx(&lb, &context); + err = security_secid_to_secctx(&lb, &context, LSMBLOB_DISPLAY); if (err) return; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index e2e6d4bf4ac3..210aa5a84a08 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -334,7 +334,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &context); + ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY); if (ret) return 0; @@ -649,7 +649,7 @@ static inline int ctnetlink_secctx_size(const struct nf_conn *ct) struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &context); + ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY); if (ret) return 0; diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 8969754d7fe9..0ff2b8300c28 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -177,7 +177,7 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct) struct lsmcontext context; lsmblob_init(&blob, ct->secmark); - ret = security_secid_to_secctx(&blob, &context); + ret = security_secid_to_secctx(&blob, &context, LSMBLOB_DISPLAY); if (ret) return; diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index e0512e91fed9..89db320f8109 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -314,7 +314,7 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, struct lsmcontext *context) if (skb->secmark) { /* Any LSM might be looking for the secmark */ lsmblob_init(&blob, skb->secmark); - security_secid_to_secctx(&blob, context); + security_secid_to_secctx(&blob, context, LSMBLOB_DISPLAY); } read_unlock_bh(&skb->sk->sk_callback_lock); diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 3b0f07b59436..60a7665de0e3 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -436,7 +436,8 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - if (security_secid_to_secctx(lsmblob, &context) == 0) { + if (security_secid_to_secctx(lsmblob, &context, + LSMBLOB_FIRST) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -491,7 +492,8 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, if (dev != NULL) dev_put(dev); if (entry != NULL && - security_secid_to_secctx(&entry->lsmblob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context, + LSMBLOB_FIRST) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -551,7 +553,8 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, if (dev != NULL) dev_put(dev); if (entry != NULL && - security_secid_to_secctx(&entry->lsmblob, &context) == 0) { + security_secid_to_secctx(&entry->lsmblob, &context, + LSMBLOB_FIRST) == 0) { audit_log_format(audit_buf, " sec_obj=%s", context.context); security_release_secctx(&context); @@ -1122,7 +1125,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, lsmb = (struct lsmblob *)&addr6->lsmblob; } - ret_val = security_secid_to_secctx(lsmb, &context); + ret_val = security_secid_to_secctx(lsmb, &context, LSMBLOB_FIRST); 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 951ba0639d20..1941877fd16f 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -100,7 +100,7 @@ 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, &context) == 0) { + security_secid_to_secctx(&blob, &context, LSMBLOB_FIRST) == 0) { audit_log_format(audit_buf, " subj=%s", context.context); security_release_secctx(&context); } diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index dbda08ec566e..173397c215d5 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -4213,6 +4213,7 @@ void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid) xfrm_audit_helper_usrinfo(task_valid, audit_buf); audit_log_format(audit_buf, " res=%u", result); xfrm_audit_common_policyinfo(xp, audit_buf); + audit_log_task_lsms(audit_buf); audit_log_end(audit_buf); } EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); @@ -4228,6 +4229,7 @@ void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, xfrm_audit_helper_usrinfo(task_valid, audit_buf); audit_log_format(audit_buf, " res=%u", result); xfrm_audit_common_policyinfo(xp, audit_buf); + audit_log_task_lsms(audit_buf); audit_log_end(audit_buf); } EXPORT_SYMBOL_GPL(xfrm_audit_policy_delete); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 170d6e7f31d3..77f07e684429 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2645,6 +2645,7 @@ void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid) xfrm_audit_helper_usrinfo(task_valid, audit_buf); xfrm_audit_helper_sainfo(x, audit_buf); audit_log_format(audit_buf, " res=%u", result); + audit_log_task_lsms(audit_buf); audit_log_end(audit_buf); } EXPORT_SYMBOL_GPL(xfrm_audit_state_add); @@ -2659,6 +2660,7 @@ void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid) xfrm_audit_helper_usrinfo(task_valid, audit_buf); xfrm_audit_helper_sainfo(x, audit_buf); audit_log_format(audit_buf, " res=%u", result); + audit_log_task_lsms(audit_buf); audit_log_end(audit_buf); } EXPORT_SYMBOL_GPL(xfrm_audit_state_delete); diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index b481bbc2e55f..7eb8784f15a4 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -365,6 +365,7 @@ void ima_audit_measurement(struct integrity_iint_cache *iint, audit_log_format(ab, " hash=\"%s:%s\"", algo_name, hash); audit_log_task_info(ab); + audit_log_task_lsms(ab); audit_log_end(ab); iint->flags |= IMA_AUDITED; diff --git a/security/integrity/integrity_audit.c b/security/integrity/integrity_audit.c index 5109173839cc..bca89ae72e3d 100644 --- a/security/integrity/integrity_audit.c +++ b/security/integrity/integrity_audit.c @@ -54,5 +54,6 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode, audit_log_format(ab, " ino=%lu", inode->i_ino); } audit_log_format(ab, " res=%d", !result); + audit_log_task_lsms(ab); audit_log_end(ab); } diff --git a/security/security.c b/security/security.c index d6600bb81829..a66786c255aa 100644 --- a/security/security.c +++ b/security/security.c @@ -480,7 +480,31 @@ static int lsm_append(const char *new, char **result) * 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]; +static struct lsm_id *lsm_slotlist[LSMBLOB_ENTRIES] __lsm_ro_after_init; + +/** + * security_lsm_slot_name - Get the name of the security module in a slot + * @slot: index into the "display" slot list. + * + * Provide the name of the security module associated with + * a display slot. + * + * If @slot is LSMBLOB_INVALID return the value + * for slot 0 if it has been set, otherwise NULL. + * + * Returns a pointer to the name string or NULL. + */ +const char *security_lsm_slot_name(int slot) +{ + if (slot == LSMBLOB_INVALID) + slot = 0; + else if (slot >= LSMBLOB_ENTRIES || slot < 0) + return NULL; + + if (lsm_slotlist[slot] == NULL) + return NULL; + return lsm_slotlist[slot]->lsm; +} /** * security_add_hooks - Add a modules hooks to the hook lists. @@ -2169,13 +2193,32 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp) +int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp, + int display) { struct security_hook_list *hp; - int display = lsm_task_display(current); memset(cp, 0, sizeof(*cp)); + /* + * display either is the slot number use for formatting + * or an instruction on which relative slot to use. + */ + if (display == LSMBLOB_DISPLAY) + display = lsm_task_display(current); + else if (display == LSMBLOB_FIRST) + display = LSMBLOB_INVALID; + else if (display < 0) { + WARN_ONCE(true, + "LSM: security_secid_to_secctx unknown display\n"); + display = LSMBLOB_INVALID; + } else if (display >= lsm_slot) { + WARN_ONCE(true, + "LSM: security_secid_to_secctx invalid display\n"); + display = LSMBLOB_INVALID; + } + + 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; @@ -2186,7 +2229,7 @@ int security_secid_to_secctx(struct lsmblob *blob, struct lsmcontext *cp) &cp->context, &cp->len); } } - return 0; + return -EOPNOTSUPP; } EXPORT_SYMBOL(security_secid_to_secctx); From patchwork Fri Feb 14 23:42: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: 11383623 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 83EEF159A for ; Fri, 14 Feb 2020 23:45:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5A8B224649 for ; Fri, 14 Feb 2020 23:45:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="RLx+piZq" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728271AbgBNXpj (ORCPT ); Fri, 14 Feb 2020 18:45:39 -0500 Received: from sonic314-27.consmr.mail.ne1.yahoo.com ([66.163.189.153]:33804 "EHLO sonic314-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728316AbgBNXpi (ORCPT ); Fri, 14 Feb 2020 18:45:38 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723936; bh=JSaMrCw5rIOsb/PJrZw0TEWxJjBXsuaEn7uKyAVvJ7M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=RLx+piZqTjZmaqa0SKq5x0oDwLKUgvQNYWFXVMoY/PZQLKmMGSs026/rweZFmu5azxzOnhd2fGHpdskg20udkA4hZhssDNkQCU+4oYzNL7BtlRfMJ0w5XdcRjX3Qf6JHyOAVoizuXbMhDhxRzHsqy949CfZ55FKsep8s2Tu3CpeT/J//0WYRlY44yubksroWi3xv6LN2t3kJHQ1qLCVwQsVl3Ua2PPEcUYb/x8QIsCqZ/AV24FW1gGahz38/QahT8GF0rBzYEAR/6ytQqRhuhz/PhKJSnBzAK6XX7RayySJrh25+NvL8rrhffdfQti7XiU2SriMWz6gP27tah7AsQg== X-YMail-OSG: XJUCSRsVM1kP_jOV_1_9cVy9zgBl6JG.awfK1uulwir_M2ervU_BXEt4Fyn9jr6 l5AX5v.Cjeu7D5aNiV9FX4IsLm3SOdP_PkIu61x9mQzFupnxebbEuQSr75GNA6hknknx4a_P5UKV Nqtbc0MUXrUlHJvZyhtovz20_67oQKRgF9DNZn.xCs7GGLQ5uYYzx_f1HxIq7UmBL8Qi1ss1_SUX fDRLSdoOGrva3jp8cPJHejtIiBqF1oNYjYd0fSlibu2pcDTLqxDWuO1p0WdwZ3e3DX71qb9rk_nu LwOj3wpTibaksxQGMuZdmlaIgax8.bb3GWUAxbLwLBgh.1IM_Rkhj0fb.hcmNTWBT0wvRZBf37jb omxqV7JMG6Ix5RfL_uVaicXReAnSP08BfxemGVlRaiTCBYFB.MMyw719AyhTUqSDpP2copbYGpAB 2i0D66WdZSoarH0oM5WC3CwevInyRyw.lC2T_2CTAJzazgDeK7s2Rjvv9f5KOpaolaoabwYNroZl KxKfKCpgsWTB1xjLYRzZQ31HbOMz7Fb9ZeuWdSMDjuxxqBK4Ww7KJYxqARRF3eCCOu1SztaOJ0sR kxKvRx3J.G_jTiPotZfR8mu4pFnZCOCCvgd7rQQ801YyZLGMLLwYlQx0SE1NpIieEwPe1jZDo5OU hmY8pYBD5VIY5vIvblJghavjtG.GoqR8i5R5fraCPjYA2tF0h.Wa8zIgOSpAv0jg3HlA9Lx9WmlY yjl8s7qIqv0GuAeOfNtHh1TejHvfiYZkNonhBz4NRTChyrtGyjXF_mZVYqIWK08X87u6FvJt58Av ZrxrNAMFvhTVI_H78Wfd8jZPajyd40bn.5HA.ED4cQXWcXU_49QJ_UryXmrWy8pMuSkjJ5i74wVY K3PH099o6AltJaD6WzA1M_mPSxNqTUOOizB4eW9uWWBiWplMEQPyQks2NyqRrTLpYgGHd5eztPjl Ri4.ZPK87Tgl0h6wyZRbTkGakyKJhMLRhX3eTEYoAAAHM5_UMrDyffiLgKjAbKsmYF2Bs7mngr3K ._faAz_R9ooZO1Z1xlynmNACuYCxjSSayBYA.S4nEenndn_ykbSEWiOMC3tmfoc7sxrBGudFkLNE 9dvSbtfWhr1Zyn640o2oEseKTkIScW1Na559YKJ4ZYDT_tZ95zHWXVdSizUAo0A_dXPT9byItZ3E 0bOa_piuYN8J9NStJCnG.lwil7asqHDAwZQfWe1kOVpDHqe3uU2MhpxjGn59i_nf74e1hhNIl9b4 QsFfrsC3gnFwpqjQhEvdL6y6K9jedFKKe2O3umQaD4ytMeHGIpdbdzGF4GSCUINZs.Ge6Fo4Qp.H Ogsolv4QCTJcGyYTKhbJGgP6bjPxd0iQe8tgIRbtRt9okamBgAxoQi_Clbdn4nAZLDFg2Pf4HmJU FrmsLrj15uPFPYMeDKmXV4joEfBdoszKT Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:45:36 +0000 Received: by smtp419.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID ce63e428e13fa705f0ae101fe46b87ce; Fri, 14 Feb 2020 23:45:32 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 21/23] Audit: Include object data for all security modules Date: Fri, 14 Feb 2020 15:42:01 -0800 Message-Id: <20200214234203.7086-22-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org When there is more than one context displaying security module extend what goes into the audit record by supplimenting the "obj=" with an "obj_=" for each such security module. Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler Cc:linux-audit@redhat.com --- kernel/audit.h | 4 +- kernel/auditsc.c | 106 ++++++++++++++++++++++++----------------------- 2 files changed, 56 insertions(+), 54 deletions(-) diff --git a/kernel/audit.h b/kernel/audit.h index f65f516913c6..9a26ba213f6a 100644 --- a/kernel/audit.h +++ b/kernel/audit.h @@ -78,7 +78,7 @@ struct audit_names { kuid_t uid; kgid_t gid; dev_t rdev; - u32 osid; + struct lsmblob oblob; struct audit_cap_data fcap; unsigned int fcap_ver; unsigned char type; /* record type */ @@ -152,7 +152,7 @@ struct audit_context { kuid_t uid; kgid_t gid; umode_t mode; - u32 osid; + struct lsmblob oblob; int has_perm; uid_t perm_uid; gid_t perm_gid; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 68ae5fa843c1..7dab48661e31 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -659,7 +659,6 @@ 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( &blob, f->type, @@ -667,7 +666,6 @@ static int audit_filter_rules(struct task_struct *tsk, 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( &blob, f->type, @@ -681,8 +679,7 @@ static int audit_filter_rules(struct task_struct *tsk, /* Find ipc objects that match */ if (!ctx || ctx->type != AUDIT_IPC) break; - lsmblob_init(&blob, ctx->ipc.osid); - if (security_audit_rule_match(&blob, + if (security_audit_rule_match(&ctx->ipc.oblob, f->type, f->op, f->lsm_rules)) ++result; @@ -956,13 +953,57 @@ static inline void audit_free_context(struct audit_context *context) kfree(context); } +static int audit_log_object_context(struct audit_buffer *ab, + struct lsmblob *blob) +{ + struct lsmcontext context; + const char *lsm; + int i; + + /* + * None of the installed modules have object labels. + */ + if (security_lsm_slot_name(0) == NULL) + return 0; + + if (blob->secid[0] != 0) { + if (security_secid_to_secctx(blob, &context, 0)) { + audit_log_format(ab, " obj=?"); + return 1; + } + audit_log_format(ab, " obj=%s", context.context); + security_release_secctx(&context); + } + + /* + * Don't do anything more unless there is more than one LSM + * with a security context to report. + */ + if (security_lsm_slot_name(1) == NULL) + return 0; + + for (i = 0; i < LSMBLOB_ENTRIES; i++) { + lsm = security_lsm_slot_name(i); + if (lsm == NULL) + break; + if (blob->secid[i] == 0) + continue; + if (security_secid_to_secctx(blob, &context, i)) { + audit_log_format(ab, " obj_%s=?", lsm); + continue; + } + audit_log_format(ab, " obj_%s=%s", lsm, context.context); + security_release_secctx(&context); + } + return 0; +} + static int audit_log_pid_context(struct audit_context *context, pid_t pid, kuid_t auid, kuid_t uid, unsigned int sessionid, struct lsmblob *blob, char *comm) { struct audit_buffer *ab; - struct lsmcontext lsmctx; int rc = 0; ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); @@ -972,15 +1013,7 @@ 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 (lsmblob_is_set(blob)) { - if (security_secid_to_secctx(blob, &lsmctx, LSMBLOB_FIRST)) { - audit_log_format(ab, " obj=(none)"); - rc = 1; - } else { - audit_log_format(ab, " obj=%s", lsmctx.context); - security_release_secctx(&lsmctx); - } - } + rc = audit_log_object_context(ab, blob); audit_log_format(ab, " ocomm="); audit_log_untrustedstring(ab, comm); audit_log_end(ab); @@ -1207,26 +1240,14 @@ static void show_special(struct audit_context *context, int *call_panic) context->socketcall.args[i]); break; } case AUDIT_IPC: { - u32 osid = context->ipc.osid; + struct lsmblob *oblob = & context->ipc.oblob; audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho", from_kuid(&init_user_ns, context->ipc.uid), from_kgid(&init_user_ns, context->ipc.gid), context->ipc.mode); - if (osid) { - struct lsmcontext lsmcxt; - struct lsmblob blob; - - lsmblob_init(&blob, osid); - if (security_secid_to_secctx(&blob, &lsmcxt, - LSMBLOB_FIRST)) { - audit_log_format(ab, " osid=%u", osid); - *call_panic = 1; - } else { - audit_log_format(ab, " obj=%s", lsmcxt.context); - security_release_secctx(&lsmcxt); - } - } + if (audit_log_object_context(ab, oblob)) + *call_panic = 1; if (context->ipc.has_perm) { audit_log_end(ab); ab = audit_log_start(context, GFP_KERNEL, @@ -1366,20 +1387,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, from_kgid(&init_user_ns, n->gid), MAJOR(n->rdev), MINOR(n->rdev)); - if (n->osid != 0) { - struct lsmblob blob; - struct lsmcontext lsmctx; - - lsmblob_init(&blob, n->osid); - if (security_secid_to_secctx(&blob, &lsmctx, LSMBLOB_FIRST)) { - audit_log_format(ab, " osid=%u", n->osid); - if (call_panic) - *call_panic = 2; - } else { - audit_log_format(ab, " obj=%s", lsmctx.context); - security_release_secctx(&lsmctx); - } - } + if (audit_log_object_context(ab, &n->oblob) && call_panic) + *call_panic = 2; /* log the audit_names record type */ switch (n->type) { @@ -1929,17 +1938,13 @@ 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, &blob); - /* scaffolding until osid is updated */ - name->osid = blob.secid[0]; + security_inode_getsecid(inode, &name->oblob); if (flags & AUDIT_INODE_NOEVAL) { name->fcap_ver = -1; return; @@ -2285,14 +2290,11 @@ 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, &blob); - /* scaffolding on the [0] - change "osid" to a lsmblob */ - context->ipc.osid = blob.secid[0]; + security_ipc_getsecid(ipcp, &context->ipc.oblob); context->type = AUDIT_IPC; } From patchwork Fri Feb 14 23:42: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: 11383629 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 6C474159A for ; Fri, 14 Feb 2020 23:45:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 42E5524649 for ; Fri, 14 Feb 2020 23:45:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="rgUTfyym" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728316AbgBNXp6 (ORCPT ); Fri, 14 Feb 2020 18:45:58 -0500 Received: from sonic314-27.consmr.mail.ne1.yahoo.com ([66.163.189.153]:39654 "EHLO sonic314-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728405AbgBNXp5 (ORCPT ); Fri, 14 Feb 2020 18:45:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723956; bh=kiR1fAfASnrLSNJIBdQL70/PHVrJKSucioMphf4/9pc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=rgUTfyym9T/NI3bqlY5APUkcYQTiHA/u8mp7UipnFERzsS/TSra4XHhaSKeyq/QbSEhQG5vgzQaRHUZNlsMEnhjUpvZXSZUtXZxYfJ8RowHc/nax7Lh1c7NX1UJ0xO58+PFWg+qUGsWb/bMomJBjxUrNHv0fSJPHCmbc0zwkvVGVeDlGCNvzTs0Hkp8Yyy6F5MF2KYvSdEdsL2oq52dDSmriM8erILq9YJmwA9Cr2o1hQq1/E/8G6qj5yA76e5EEcwWU4aYAktCGa3Z8oQk1AEV5XsnT2d5eGsyP5pfp80m8lLeFsOeunFoddtjCapblfZiQOE4lpvvIfPeWp6rbGQ== X-YMail-OSG: 5T0M3rMVM1meDatpn5HUqZvPHfKj7o4R.0_cQA0X7qNeD_KeqDc8ciZqIPprQF3 ebr5m5k3_eO_zwoABANRzuXnQlgk222vaspqdaLQb_FzIt6YDLUho1r_ygNleVC50yK5RK7OGEju mU.ammRk9CEh4rsSMUHOPghrBqfY0yyoxBrfs.RD7DIWhrlEzpHA_9Lw3v0zJLQzdznXTHenpRLw v2n8ry3kFdqeCLFbY7f4AEYeHAezt3_olJc0gqSgst5JwuyyS_XrrqHY6rpx3GuupOzTIODTgF2I MT8WwYgT79va2.bj4MB8SH6WWMlvoe4qkR6mKVPY0cR7DEFUAw4pNf5jsWAcIbjisEXXcW0PoSRV TV54ZqA3B4d0Vo8FHIqayoV_rzV4tISm2mEFc7QO16f9UcNzqe.HDoEjfZdPze82yZBQo329oWil E_3B8cG2Hs96HiG80NX45zc9CV7GGnnAbM6aM0qXo_efQ124uD8snxNueZ3UCKev7nS9RGk5NMW5 gXaOHnQSolkfzIVWk_WTZmCLsXwyugwHBg2vvGL4L8AJfGC.5ioC5BKEz7nRlcUlZ_H8NoZfNKVh kt0FtfIBMg4cwwwHwSQMy8LvWuAPQNdOjAnMgNPSTh61Z.MiEyJnFpR4C9vbe1Fc8vThVU.cGfcc qaMnlLzK1qTWSoN3P7f518cpHg9s2a5Qo8x2uu.OotqW3fIwSPfee2vlKThXQbyVNUNK7zHxY32N gkJ8MSmkqZrsFgaa3V5S40cQmac8ZMTgNyjo1_5kjMVBmBPLt6Hmg1LasXiNSHousP3WRGdv.HE5 SDxzzR5qIxAhT35MZFW0tu9dZgvLyD0ei6pNLLHG03jLCOSVV1zafkQp9o00rNHtBEP7wrJZJHYO cSqfS0pGy8HjvEG5LExw5eG.Bbil0d20iSxG3rSqJ8mc5QvixkotAVZaBz5Ri8XEIXgVLhjsTkel CtiIDChnj6IXS4TeJ8D3YVeYmFReopQ1fJK.DKiMpPx36N_w3CzuxN9u7F9d6c8Bp.eWrD538pFm vtdnd7r873Vwn1SmqemYWqblZIheQSCwHwdxPCRenzQA95bTi5fwyzR28ikvtcZZrrMMF2RraL9B wlzplor96ykKehfthjznCHNfRjmXEujO_6hBBcyddoHGGM61MkRoubeyccattiHhkdzTk_BDg.h6 yokO4dWaMm65brqrZZjYqj2TR_.NLOrxURN7gn2lJSuVoSsjo0hKh7p_QbwLYFgAPWzifx0j3o_N .aIsr6OEsC1TSUJgjkMwNT7ASMryEzVQFljNLw0s_YzNLltnfhUr6Z1NrCWDtAyVSubOsLoKJac6 NR868rSU4PJG1_K84Q3JmgK80GA4y2DAlCwnKDr6wC.exEhFDcp_GKvFwOdwpTxrJONBNt6YNeBh aH_NkHiqM0f5q5xsBhAYDQRPBXp_u.B3LlBlPEJPOT_CrSznUMVLjyfgPmRgfFA297w-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic314.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:45:56 +0000 Received: by smtp419.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID d59e699c21931303bcffa3291bec6e27; Fri, 14 Feb 2020 23:45:50 +0000 (UTC) From: Casey Schaufler To: casey.schaufler@intel.com, jmorris@namei.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org Cc: casey@schaufler-ca.com, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 22/23] LSM: Add /proc attr entry for full LSM context Date: Fri, 14 Feb 2020 15:42:02 -0800 Message-Id: <20200214234203.7086-23-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Add an entry /proc/.../attr/context which displays the full process security "context" in compound format: lsm1\0value\0lsm2\0value\0... This entry is not writable. Signed-off-by: Casey Schaufler Cc: linux-api@vger.kernel.org --- Documentation/security/lsm.rst | 22 ++++++++++ fs/proc/base.c | 1 + include/linux/lsm_hooks.h | 6 +++ security/apparmor/include/procattr.h | 2 +- security/apparmor/lsm.c | 8 +++- security/apparmor/procattr.c | 22 +++++----- security/security.c | 63 ++++++++++++++++++++++++++++ security/selinux/hooks.c | 2 +- security/smack/smack_lsm.c | 2 +- 9 files changed, 113 insertions(+), 15 deletions(-) diff --git a/Documentation/security/lsm.rst b/Documentation/security/lsm.rst index aadf47c808c0..faec18e7e7d1 100644 --- a/Documentation/security/lsm.rst +++ b/Documentation/security/lsm.rst @@ -199,3 +199,25 @@ capability-related fields: - ``fs/nfsd/auth.c``::c:func:`nfsd_setuser()` - ``fs/proc/array.c``::c:func:`task_cap()` + +LSM External Interfaces +======================= + +The LSM infrastructure does not generally provide external interfaces. +The individual security modules provide what external interfaces they +require. + +The infrastructure does provide an interface for the special +case where multiple security modules provide a process context. +This is provided in compound context format. + +- `lsm1\0value\0lsm2\0value\0` + +The `value` is a nul terminated bytestring. It may contain +whitespace or non-printable characters. + +The special file ``/proc/pid/attr/context`` provides the security +context of the identified process. + +The special file ``/sys/kernel/security/lsm`` provides a comma +separated list of the active security modules. diff --git a/fs/proc/base.c b/fs/proc/base.c index 505331ab7a14..4cc418ce9c3e 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2744,6 +2744,7 @@ static const struct pid_entry attr_dir_stuff[] = { ATTR(NULL, "keycreate", 0666), ATTR(NULL, "sockcreate", 0666), ATTR(NULL, "display", 0666), + ATTR(NULL, "context", 0444), #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 2bf82e1cf347..61977a33f2c3 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1321,6 +1321,12 @@ * @pages contains the number of pages. * Return 0 if permission is granted. * + * @getprocattr: + * Provide the named process attribute for display in special files in + * the /proc/.../attr directory. Attribute naming and the data displayed + * is at the discretion of the security modules. The exception is the + * "context" attribute, which will contain the security context of the + * task as a nul terminated text string without trailing whitespace. * @ismaclabel: * Check if the extended attribute specified by @name * represents a MAC label. Returns 1 if name is a MAC diff --git a/security/apparmor/include/procattr.h b/security/apparmor/include/procattr.h index 31689437e0e1..03dbfdb2f2c0 100644 --- a/security/apparmor/include/procattr.h +++ b/security/apparmor/include/procattr.h @@ -11,7 +11,7 @@ #ifndef __AA_PROCATTR_H #define __AA_PROCATTR_H -int aa_getprocattr(struct aa_label *label, char **string); +int aa_getprocattr(struct aa_label *label, char **string, bool newline); int aa_setprocattr_changehat(char *args, size_t size, int flags); #endif /* __AA_PROCATTR_H */ diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 16b992235c11..02f305ab2c69 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -593,6 +593,7 @@ static int apparmor_getprocattr(struct task_struct *task, char *name, const struct cred *cred = get_task_cred(task); struct aa_task_ctx *ctx = task_ctx(current); struct aa_label *label = NULL; + bool newline = true; if (strcmp(name, "current") == 0) label = aa_get_newest_label(cred_label(cred)); @@ -600,11 +601,14 @@ static int apparmor_getprocattr(struct task_struct *task, char *name, label = aa_get_newest_label(ctx->previous); else if (strcmp(name, "exec") == 0 && ctx->onexec) label = aa_get_newest_label(ctx->onexec); - else + else if (strcmp(name, "context") == 0) { + label = aa_get_newest_label(cred_label(cred)); + newline = false; + } else error = -EINVAL; if (label) - error = aa_getprocattr(label, value); + error = aa_getprocattr(label, value, newline); aa_put_label(label); put_cred(cred); diff --git a/security/apparmor/procattr.c b/security/apparmor/procattr.c index c929bf4a3df1..be3b083d9b74 100644 --- a/security/apparmor/procattr.c +++ b/security/apparmor/procattr.c @@ -20,6 +20,7 @@ * aa_getprocattr - Return the profile information for @profile * @profile: the profile to print profile info about (NOT NULL) * @string: Returns - string containing the profile info (NOT NULL) + * @newline: Should a newline be added to @string. * * Returns: length of @string on success else error on failure * @@ -30,20 +31,21 @@ * * Returns: size of string placed in @string else error code on failure */ -int aa_getprocattr(struct aa_label *label, char **string) +int aa_getprocattr(struct aa_label *label, char **string, bool newline) { struct aa_ns *ns = labels_ns(label); struct aa_ns *current_ns = aa_get_current_ns(); + int flags = FLAG_VIEW_SUBNS | FLAG_HIDDEN_UNCONFINED; int len; if (!aa_ns_visible(current_ns, ns, true)) { aa_put_ns(current_ns); return -EACCES; } + if (newline) + flags |= FLAG_SHOW_MODE; - len = aa_label_snxprint(NULL, 0, current_ns, label, - FLAG_SHOW_MODE | FLAG_VIEW_SUBNS | - FLAG_HIDDEN_UNCONFINED); + len = aa_label_snxprint(NULL, 0, current_ns, label, flags); AA_BUG(len < 0); *string = kmalloc(len + 2, GFP_KERNEL); @@ -52,19 +54,19 @@ int aa_getprocattr(struct aa_label *label, char **string) return -ENOMEM; } - len = aa_label_snxprint(*string, len + 2, current_ns, label, - FLAG_SHOW_MODE | FLAG_VIEW_SUBNS | - FLAG_HIDDEN_UNCONFINED); + len = aa_label_snxprint(*string, len + 2, current_ns, label, flags); if (len < 0) { aa_put_ns(current_ns); return len; } - (*string)[len] = '\n'; - (*string)[len + 1] = 0; + if (newline) { + (*string)[len] = '\n'; + (*string)[++len] = 0; + } aa_put_ns(current_ns); - return len + 1; + return len; } /** diff --git a/security/security.c b/security/security.c index a66786c255aa..89b635277245 100644 --- a/security/security.c +++ b/security/security.c @@ -754,6 +754,42 @@ static void __init lsm_early_task(struct task_struct *task) panic("%s: Early task alloc failed.\n", __func__); } +/** + * append_ctx - append a lsm/context pair to a compound context + * @ctx: the existing compound context + * @ctxlen: size of the old context, including terminating nul byte + * @lsm: new lsm name, nul terminated + * @new: new context, possibly nul terminated + * @newlen: maximum size of @new + * + * replace @ctx with a new compound context, appending @newlsm and @new + * to @ctx. On exit the new data replaces the old, which is freed. + * @ctxlen is set to the new size, which includes a trailing nul byte. + * + * Returns 0 on success, -ENOMEM if no memory is available. + */ +static int append_ctx(char **ctx, int *ctxlen, const char *lsm, char *new, + int newlen) +{ + char *final; + int llen; + + llen = strlen(lsm) + 1; + newlen = strnlen(new, newlen) + 1; + + final = kzalloc(*ctxlen + llen + newlen, GFP_KERNEL); + if (final == NULL) + return -ENOMEM; + if (*ctxlen) + memcpy(final, *ctx, *ctxlen); + memcpy(final + *ctxlen, lsm, llen); + memcpy(final + *ctxlen + llen, new, newlen); + kfree(*ctx); + *ctx = final; + *ctxlen = *ctxlen + llen + newlen; + return 0; +} + /* * Hook list operation macros. * @@ -2073,6 +2109,10 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name, char **value) { struct security_hook_list *hp; + char *final = NULL; + char *cp; + int rc = 0; + int finallen = 0; int display = lsm_task_display(current); int slot = 0; @@ -2100,6 +2140,29 @@ int security_getprocattr(struct task_struct *p, const char *lsm, char *name, return -ENOMEM; } + if (!strcmp(name, "context")) { + hlist_for_each_entry(hp, &security_hook_heads.getprocattr, + list) { + rc = hp->hook.getprocattr(p, "context", &cp); + if (rc == -EINVAL || rc == -ENOPROTOOPT) + continue; + if (rc < 0) { + kfree(final); + return rc; + } + rc = append_ctx(&final, &finallen, hp->lsmid->lsm, + cp, rc); + if (rc < 0) { + kfree(final); + return rc; + } + } + if (final == NULL) + return -EINVAL; + *value = final; + return finallen; + } + hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) { if (lsm != NULL && strcmp(lsm, hp->lsmid->lsm)) continue; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4618e2d0c032..ab2a150e28ca 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6257,7 +6257,7 @@ static int selinux_getprocattr(struct task_struct *p, goto bad; } - if (!strcmp(name, "current")) + if (!strcmp(name, "current") || !strcmp(name, "context")) sid = __tsec->sid; else if (!strcmp(name, "prev")) sid = __tsec->osid; diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 5bee05bd7a42..453923eee950 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3479,7 +3479,7 @@ static int smack_getprocattr(struct task_struct *p, char *name, char **value) char *cp; int slen; - if (strcmp(name, "current") != 0) + if (strcmp(name, "current") != 0 && strcmp(name, "context") != 0) return -EINVAL; cp = kstrdup(skp->smk_known, GFP_KERNEL); From patchwork Fri Feb 14 23:42: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: 11383625 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 4B7B7159A for ; Fri, 14 Feb 2020 23:45:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2B13024649 for ; Fri, 14 Feb 2020 23:45:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="Rkq9dkQa" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728407AbgBNXp4 (ORCPT ); Fri, 14 Feb 2020 18:45:56 -0500 Received: from sonic308-16.consmr.mail.ne1.yahoo.com ([66.163.187.39]:36348 "EHLO sonic308-16.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728316AbgBNXp4 (ORCPT ); Fri, 14 Feb 2020 18:45:56 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1581723955; bh=Q8pZI23fVgfFGKWrmlgNPluY61x22Nwjp2FtFTY2yZQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=Rkq9dkQaNoxE1Xw+Z3Nv+O6P4ZNS5pExvgY9nkypzVP0WZ3qMHqPRGkvTUQ3wpkjj9Tn4pzGebPWwGbV82Kqxscsh0fxtrptKJA4f0m4A0fXDq6WANNsQOJa+EMkyIkVMtY0qT6puhVRWTcLpmRMaP7Ww+ggALgbFovlAPzCtXcwdT1a56ATtm5KHIjdDSfPtQfEfduvsThnu1AQUlHYMSnbaKG10F21BozTCPPCB7tVlxqxgRuVUccTQaWZaM0rntPtAj1Rt9acUPTLDJRmfFyvg2hbWYnZ1LxO4sKc34Pu766ivvnFYBJyBj+BsLx2VPMHgf4oAI1dD4FpmsrDwA== X-YMail-OSG: kyx.NW4VM1lwDs8qckf6WaVXgAaTqSHAPI1R4rhDABpo2Bu71vub5MotftI6OX. xkh33swdObjzKRY9Ud7KC9aoheK51GgxamrU631YG5TXJnP3_FAGESdn1i3uJMjDBw.uGMHya0iG 1duZAxyKFNWNVcmxZjYkNG7rzTWWjNPiR7TgYFgv4W9WdrV2scNWMXQIXLxdqOEfcmgs2aOiWkb2 SOe599bqhvPPGcuK0mneK2ofc7fpiKNzvo.kl.yGb37a383gcTPjWAmNV7uThc7USMWGOdDs3pC. MoFZwVInj33ufG2HDciIsc4YtbuziDAGEGwkVc6BkyQialaAHWyCXu1C6vN6y_ff2a64U3KCxEkw DStFSHE3PntAb0vhcSP0xThcLJ82iQMolNZnsTCOTPFdaEn8w_Exlr4Yyda0rdyjwtADXnOv35EJ 2JeWpSAUDqLNuaGFbZtUtEVZzme1dnh11sSAaDhUZk_8QbtwoCFSEQloozxidAkcWIWUG27mHC7N dmV7QNp9gzwArzLxbmugQayJbjIFSSGPivvEhrl6h6N_h35thNFv3oRCrsaUOhh1s2HrK4BdeJs7 B82NSOGq7uTk.IXfDgUQcpmcLbGxC3rvIQ_hGpSWvNqACPBCziSkvkWqMM3D5rGTTX2xe.F7F2Jl .Qg1tabXf8q56WDzq769KCEFq78PKT116dyB3lEDmQLUvAAqayZWs60I_Ba9oCKUvFPEoHKvhqBM Y3Zh2whYADDvUiBCvwVzIpxTBcCVVIGVLDQLaxHJwW4mKFjmqLQ2pauBlyrE6oNdhGUeYRJxJBLK wUBgZu9Izc1Ik.L4n8sLNPIx.kuGcP3sGouWDZ3sgomAxEb0_naqmFhLtmW1A37TYuWTLfg2FbXI CXSS7M.fSmquqNhdHqxcNE6PS_VKQegKf_JBcuUxsR1gns.pB9.Meu1IxkWNQUM98Ugn3Vxh7T85 _X0uWixBD2ahKuNXoytgtzlq9nlqeFk5D7IBG34wtapfFmcnDemsdO3Hy5J4wO21HLWmvQwHJXl5 QKWLSn21CkGYu2f46RkFLM5SkCMZV1UQEJ9Ld1hUdk2yIHiI6ztAOyLOIzk8gdZ7zNoAu5Vbe.DC cN2fUZVatB_v4yL_IBsJ8AmJbnSWJ3AJitxQI2ujmsbwXMXfmZzMmyvUXEZh4b8S6MA6feX4tcTU I6kdWAlnp7cGRkmAZevQVks4DZBBNH1fGjR9x7G_B7bjxduGiuPURDx.UarJF8.PWDxcp9Mkio0M _iA1JmQsVZRYmU9qSXftiveY0ldl48bHBuI4C5mdcQrCBttFF25b3.ofRkH.YrOGb0O_xtZ_rcUn edXLlKo4XXZ1_7kHwAXHVPr.MPRBDfZWBvCFJ2XEcIr.BJYl.xlwDGd_K0hktBn0CXyaADc5zfaP Y9RiNXuH7Cr9Puw.bRHOVisnYxKvMpx.Y4rWV1d7y5Hm9kg1oucyl.NZIjbjwC0dfPVKoLwky Received: from sonic.gate.mail.ne1.yahoo.com by sonic308.consmr.mail.ne1.yahoo.com with HTTP; Fri, 14 Feb 2020 23:45:55 +0000 Received: by smtp419.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID d59e699c21931303bcffa3291bec6e27; Fri, 14 Feb 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, keescook@chromium.org, john.johansen@canonical.com, penguin-kernel@i-love.sakura.ne.jp, paul@paul-moore.com, sds@tycho.nsa.gov Subject: [PATCH v15 23/23] AppArmor: Remove the exclusive flag Date: Fri, 14 Feb 2020 15:42:03 -0800 Message-Id: <20200214234203.7086-24-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200214234203.7086-1-casey@schaufler-ca.com> References: <20200214234203.7086-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org With the inclusion of the "display" process attribute mechanism AppArmor no longer needs to be treated as an "exclusive" security module. Remove the flag that indicates it is exclusive. Remove the stub getpeersec_dgram AppArmor hook as it has no effect in the single LSM case and interferes in the multiple LSM case. Reviewed-by: Kees Cook Reviewed-by: John Johansen Signed-off-by: Casey Schaufler Acked-by: Stephen Smalley --- security/apparmor/lsm.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 02f305ab2c69..07729c28275e 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1124,22 +1124,6 @@ static int apparmor_socket_getpeersec_stream(struct socket *sock, return error; } -/** - * apparmor_socket_getpeersec_dgram - get security label of packet - * @sock: the peer socket - * @skb: packet data - * @secid: pointer to where to put the secid of the packet - * - * Sets the netlabel socket state on sk from parent - */ -static int apparmor_socket_getpeersec_dgram(struct socket *sock, - struct sk_buff *skb, u32 *secid) - -{ - /* TODO: requires secid support */ - return -ENOPROTOOPT; -} - /** * apparmor_sock_graft - Initialize newly created socket * @sk: child sock @@ -1243,8 +1227,6 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { #endif LSM_HOOK_INIT(socket_getpeersec_stream, apparmor_socket_getpeersec_stream), - LSM_HOOK_INIT(socket_getpeersec_dgram, - apparmor_socket_getpeersec_dgram), LSM_HOOK_INIT(sock_graft, apparmor_sock_graft), #ifdef CONFIG_NETWORK_SECMARK LSM_HOOK_INIT(inet_conn_request, apparmor_inet_conn_request), @@ -1913,7 +1895,7 @@ static int __init apparmor_init(void) DEFINE_LSM(apparmor) = { .name = "apparmor", - .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE, + .flags = LSM_FLAG_LEGACY_MAJOR, .enabled = &apparmor_enabled, .blobs = &apparmor_blob_sizes, .init = apparmor_init,