From patchwork Fri Jan 24 00:22: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: 11349421 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 0CAC1109A for ; Fri, 24 Jan 2020 00:23:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B9964214AF for ; Fri, 24 Jan 2020 00:23:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="tX93TH0s" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729388AbgAXAXW (ORCPT ); Thu, 23 Jan 2020 19:23:22 -0500 Received: from sonic316-27.consmr.mail.ne1.yahoo.com ([66.163.187.153]:46408 "EHLO sonic316-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729318AbgAXAXW (ORCPT ); Thu, 23 Jan 2020 19:23:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825396; bh=8hTq4OJE4mg8tnJbQzMOLmeHI4BiZKH9TeScd8Hhtt4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=tX93TH0sFDKP1aQ38BkZ8IKO1PAqmQoAUbeS38G6NGiuBoNxQMzjR+YY8El+LC54jZG47i9zCxJoeXomgnhpO4LBOfscAgOfnNPXfOg1pgkJuRZbwYqph3wRQVrwZE6GhzdR9L5cTBUxncK99v/omhUfdypcvXT3m4azpmNbQVwfjw65gB8UkQIVyETh3Y8rJTvGsdJLjo/qcKj4wGNCenXHrj0K87xZAXQIOTGjHp7gj3Ky9eJRMXNeor8DGeGw+f+dK56Ve6Q8kAEfO7WZs3mYNhndzByAFaK9ttfJ0ClG5IGq3HQUmr42e3xIo/x5UBq2I5yuHh8W34+nkOtr4g== X-YMail-OSG: 0zMB68sVM1k50xacLh.IdlPk9hkpcMDOucSHwQQjFJnPM.xzaK50XgBJvs2trGf F20SWWMmfYiOp4nYTKsmpV1FUNteaL3qxvWD.cgiSCVf6aZ.mhWaQGGwLPBTlqgej.i8yEcb9.5. xhGkZG3xRRSggp2WzMyH9LRAWmKtpHBgoY3fv.MEGy3Rh7ESbQSvFpc.e..I07akY2rrynEgmE3K p3Zx8LHgQ.GN.Cu14SKecJwXdKNWjP8nO_AKXu5Akx8VM01XLndDceV_xmmgZYNtR5awxwWQh2Zp FR0eGfUYzu74Nt753C_IymNrjqhsxUWCj6sEhIWEIgtfUddltbyldhMpIPUP088kQeXy1B377zpy tGsb4fSCwfm3PELWwM4JV.BqzZD6ejzhyOrDe0CJ5wn9OPgbXNRYd5QFKGkDbPeG8aLW8Wi69_GD xhkhD0.IhDHpCV0aAp_2_6hH7IJNXSneUuub2VzfocfU9F3wc0UYkxAyTMUEyse6.eN5pditeZ00 hBfUc2MRXFAmp5uGts6O5.CMMdCYqQL_8G.N.i5arr3o_Z4RjcWlNsalTdXVAsDKBBvvBWwQ_sbv 2TomWsV72rCSnozhhBKwyfIzczRnRBfPVLZXWDTXMopdYuDZwueej3dBqZcT0gDKjsj4e6M20Y6j 8FXvIzu1zIlir2mhJx9tZap4Jk.61HlGAcBqabJjRn9YpVRuzvmOctXZXyNpaDKOdl1xJlEizj35 oex0_1Hr.GAoYMZunL2xDS6WCI8BJ7lbPJy7AvHc5rWuzHFj.49qpEyAaVhRZ6g.920c3LNeCKnb Unqa2B5JPKY6BRlk6xWf6OXa19vCgrIO79._YTbmGaIw.2I3QaPQyG9kEWFryIUHRlYtMbPvV5Ut qrq53GN3FqIiktX8oOqLi5bg9Tyh35vOp0pZUZSNEJS6dLeW2PJD7EUDJDNw61wZZ3AJjHMrmamK uO.0uM7xRmuD5Mph6ipZaZIgv8MTJsoe_nrhfvhL0omMseX8mrL6nnmfv9l5YzU54UqmMNjJGSOb 4KSdhCfD0E_Q2wNAS.SztZC1pOnMXrF8md5Cew9KnVE551bm8nn.a68IIqsG8iyOEUxCZZzEBED3 BEEZYsRXPSV2O151_97xeFEuU1nTvMgTIR1TOPjtnnKz4QgOj3mBff6iNGMuxvJydMGwqaCEckTK EqWHdZRtuIHrduuZWKYwdGCDTsQGWbzvDUvsdOFQT5x5DQRYpf0BDBYrqKZMQxsloApvr4hayrv7 BACl2XOFJKpoa9SAjbJkWY4YVEysi.pP6kqNIJ.nEjXnKS7J5oHLEL0YiwfaIgdzUV3lVPwpfCo3 Lyf2SnoJURgMmJsKq7JF8O2xAMzbcL9ct.A8Ie.e_JVPweNXxdyjxZCgwNBCSFLD77SmfbGf_bW_ chwXNHYslDE5AaiMHggNWrEfuPgT5tLBYkg-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic316.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:23:16 +0000 Received: by smtp406.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 8f59dd8f80be770f388a0f3ce229ce42; Fri, 24 Jan 2020 00:23:12 +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 v14 01/23] LSM: Infrastructure management of the sock security Date: Thu, 23 Jan 2020 16:22:44 -0800 Message-Id: <20200124002306.3552-2-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Move management of the sock->sk_security blob out of the individual security modules and into the security infrastructure. Instead of allocating the blobs from within the modules the modules tell the infrastructure how much space is required, and the space is allocated there. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler --- include/linux/lsm_hooks.h | 1 + security/apparmor/include/net.h | 6 ++- security/apparmor/lsm.c | 38 ++++----------- security/security.c | 36 +++++++++++++- security/selinux/hooks.c | 78 +++++++++++++++---------------- security/selinux/include/objsec.h | 5 ++ security/selinux/netlabel.c | 23 ++++----- security/smack/smack.h | 5 ++ security/smack/smack_lsm.c | 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 cd2d18d2d279..7fb6e5bcf6ec 100644 --- a/security/security.c +++ b/security/security.c @@ -28,6 +28,7 @@ #include #include #include +#include #define MAX_LSM_EVM_XATTR 2 @@ -169,6 +170,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); } @@ -304,6 +306,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); /* @@ -622,6 +625,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 @@ -2066,12 +2091,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 116b4d644f68..0839b2fbbf9b 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4475,7 +4475,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,}; @@ -4532,7 +4532,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 */ @@ -4548,8 +4548,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; @@ -4564,7 +4564,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; @@ -4699,7 +4699,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); @@ -4878,9 +4878,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; @@ -4912,8 +4912,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,}; @@ -4955,7 +4955,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,}; @@ -4988,7 +4988,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; @@ -5056,13 +5056,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 || @@ -5122,34 +5124,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; @@ -5163,7 +5158,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; } @@ -5173,7 +5168,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) @@ -5188,7 +5183,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; @@ -5339,8 +5334,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. @@ -5357,7 +5352,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; @@ -5378,7 +5373,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; @@ -5395,7 +5390,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)) @@ -5479,7 +5474,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 @@ -5520,7 +5515,7 @@ static int selinux_nlmsg_perm(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; @@ -5661,7 +5656,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; @@ -5700,7 +5695,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; @@ -5792,7 +5787,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 @@ -5821,7 +5816,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; } @@ -6801,6 +6796,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 a4a86cbcfb0a..572c88700393 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 ecea41ce919b..4cecdfdcd913 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -1455,7 +1455,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; @@ -1837,7 +1837,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 @@ -2244,11 +2244,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. @@ -2262,11 +2258,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 @@ -2275,7 +2270,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) { @@ -2288,9 +2282,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 @@ -2408,7 +2401,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; /* @@ -2453,7 +2446,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(); @@ -2529,7 +2522,7 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address) { struct sock *sk = sock->sk; struct sockaddr_in6 *addr6; - struct socket_smack *ssp = sock->sk->sk_security; + struct socket_smack *ssp = smack_sock(sock->sk); struct smk_port_label *spp; unsigned short port = 0; @@ -2617,7 +2610,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, int act) { struct smk_port_label *spp; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smack_known *skp = NULL; unsigned short port; struct smack_known *object; @@ -2711,7 +2704,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, if (sock == NULL || sock->sk == NULL) return -EOPNOTSUPP; - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); if (strcmp(name, XATTR_SMACK_IPIN) == 0) ssp->smk_in = skp; @@ -2759,7 +2752,7 @@ static int smack_socket_post_create(struct socket *sock, int family, * Sockets created by kernel threads receive web label. */ if (unlikely(current->flags & PF_KTHREAD)) { - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); ssp->smk_in = &smack_known_web; ssp->smk_out = &smack_known_web; } @@ -2784,8 +2777,8 @@ static int smack_socket_post_create(struct socket *sock, int family, static int smack_socket_socketpair(struct socket *socka, struct socket *sockb) { - struct socket_smack *asp = socka->sk->sk_security; - struct socket_smack *bsp = sockb->sk->sk_security; + struct socket_smack *asp = smack_sock(socka->sk); + struct socket_smack *bsp = smack_sock(sockb->sk); asp->smk_packet = bsp->smk_out; bsp->smk_packet = asp->smk_out; @@ -2843,7 +2836,7 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, return 0; #ifdef SMACK_IPV6_SECMARK_LABELING - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); #endif switch (sock->sk->sk_family) { @@ -3585,9 +3578,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 @@ -3633,8 +3626,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; @@ -3671,7 +3664,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; @@ -3844,7 +3837,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; @@ -3965,7 +3958,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; @@ -4015,7 +4008,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: @@ -4028,7 +4021,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) { @@ -4066,7 +4059,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() */ @@ -4086,7 +4079,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; @@ -4185,7 +4178,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) { @@ -4589,6 +4582,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 = { @@ -4698,7 +4692,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 Jan 24 00:22: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: 11349429 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 1D0DD17EF for ; Fri, 24 Jan 2020 00:23:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D43EA2087E for ; Fri, 24 Jan 2020 00:23:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="n2SMkOBp" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729526AbgAXAXk (ORCPT ); Thu, 23 Jan 2020 19:23:40 -0500 Received: from sonic316-27.consmr.mail.ne1.yahoo.com ([66.163.187.153]:40914 "EHLO sonic316-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729365AbgAXAXk (ORCPT ); Thu, 23 Jan 2020 19:23:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825416; bh=g3q1CIUaNHz1NWcbsrdsHl4d5qKsR0/469+BwxkckPY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=n2SMkOBppIfZRGU0/SPB6+LnkqczKNBbgAplngmeEkVpWlLJ8NgzAJWwz7R453O5cDFiK9hmyAB1we5KdBFM0fIVkqKIgQs85DvxLr/nAGjiBjvMbxT0AQ1S5keXoNpiUNX6v0FGPVXSg1TFAIx9p6PaP+rzSjNttNYgu6uIKpvyd7d/R6DMiIHmCcsLiHTO+vqfyxMP5aIcC0uYiCQjAnZ/eafN7hESUQiH52TmB78LlDptKth8zT/CbkrPnCuA/LAKc4CljCsuvP/XCm9EocG/STjIqNj5o7pIXSfxEfaEJEafzS07GiGHoDqNvjvgOzyTxp1MZTIuU50a1kZZ0g== X-YMail-OSG: 6JIvRKkVM1lBGsjiGLxtEPok2Y4EnkW8ibtb4k.gGU0eWOpPKlnGGCc3NU653qE geHRJ88m.bqACuGSfoBfbbI7HyXQKxaQinRI3BRbBmJTLyqTS6MEfDI_7Zc4c5hUIykEzYCsYQ.R yJug7OseWSMAQI2abLhP9fNtTIirjOs_9M0vF2I2jDLeLBimrFd1vpmtcIuAXMl6th9g8Z67Y9uQ 5wSXS.aMuABGOudgqw7ADZ0JX.ZB.W9W.89glFuR1v5U5yhsSxQNK6FDp6FKb9jf3O8qDpg4ZKoI m2tPnaOTTPnVR0GfI9Tc2b7D6nCMgI.1RyX8qjR90FsiYey7.cJLZo.JvwKlp8kcCQ3uc0GAEfvm TPXJBT926HaKVN1TOqq1Fp56qCR2vhHa6k_1OPvFOJjF6Y7ydkDdIIvhm1e8pvqq_KYoYweuMitF 6Khi_zRYx1pLrP9dDAdgx8qCuTUeQjIVjSj2.OTFDS5Qa.fgKUOxjFOx6PRBe3qH8_a4Wm0tytSJ sJHPU1e1VfeYfw7EfT2C2aVhxYWeqrP5IRHmdhCtqizVhYbYAwFiI6KrOz1VFYybdILhh7Gt_SQN jbqNuZGNCHSKlZSow8xLwTXHhCg8pF3Cb.DnUes2Aj71.gnUZ3QmuVgevHuFzEPtfm_q9fDqyrgb D89E1vG1xrLLfB5dNQ89KYjI9VHdpU_AEJ6U_AkLRQWr6mzOQRD8wwI.emBZlIs2484MaKo2HayH Jz6OHG5ImrDjf7_v8QFmI7eawAK2mBJ0MHl4F.aPMeI6qEDIdwQfHSxD84bgRRi0_BZetjX6feUq JtMqFfED61yn222wCEU6Hh_1DO7jlcCWxAQgk5J5QWvd0eUlxuNuThuGdKu2tCgmX7lBEI.o9vp0 WgnILXaDM.p2KQ.bxCscVTTrj5CDiZJebjvFuaGmfwxK4mDogYFwI0XGoUxw9747Ellt8KhXz.d7 KtOdgNRH.SpSUlnQJswWaJeu7kRJ_MM_7J98wnwNUEV3l1j6oPrO3wGPba3kg.ylVRUMfwK37t9G GmpsrP.wTucGJzFuD1dJuF2pnjUObp43qUy3gusV5tskuFhUnHTeX2ld1FPkEYvFnvudy47gy.Zd DlMhBepzlfRmCvhqAm.VzcJ4w5vlPsxQ77ahB7E6GF2puoZpJMd2BWx12fLZdrYv_iq9SUnWqXI4 gjFABzRIVFBDKQ86iZQOg5aaEJmDfTFzdfKx9JQf2M8ose_M8VfJjNTgccEo.BMF1g8VDVEW83UB F_E0GXf_mA.L8GLRNv49EktX1k9B0g_lO5rUXLj5sRXoweCPY7.CGNqGdUY8ZAvWS0nkCpPAG7Iv J.xrp3go48YxggXzIxJxXIt_Qp26CqCYWhyRX3VIfs9BwY17UkHqDoB2TtfgMaRfuEopLsfWHbGJ NU7yq3__9RMpzukq6tRJp5qp9STwiK2ED7_8MSLEd_4lahQgn6PU- Received: from sonic.gate.mail.ne1.yahoo.com by sonic316.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:23:36 +0000 Received: by smtp414.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID e5f705e051cbd06816d6d32e048b9ccb; Fri, 24 Jan 2020 00:23: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 v14 02/23] LSM: Create and manage the lsmblob data structure. Date: Thu, 23 Jan 2020 16:22:45 -0800 Message-Id: <20200124002306.3552-3-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: When more than one security module is exporting data to audit and networking sub-systems a single 32 bit integer is no longer sufficient to represent the data. Add a structure to be used instead. The lsmblob structure is currently an array of u32 "secids". There is an entry for each of the security modules built into the system that would use secids if active. The system assigns the module a "slot" when it registers hooks. If modules are compiled in but not registered there will be unused slots. A new lsm_id structure, which contains the name of the LSM and its slot number, is created. There is an instance for each LSM, which assigns the name and passes it to the infrastructure to set the slot. The audit rules data is expanded to use an array of security module data rather than a single instance. Because IMA uses the audit rule functions it is affected as well. Signed-off-by: Casey Schaufler --- 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 | 36 ++++++++++----- 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, 239 insertions(+), 57 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 3e8d4bacd59d..3422726268d2 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -128,6 +128,64 @@ enum lockdown_reason { LOCKDOWN_CONFIDENTIALITY_MAX, }; +/* + * 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); @@ -1779,8 +1837,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 @@ -1796,12 +1854,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 ef8dfd47c7e3..808c2515fc6a 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -74,7 +74,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]; @@ -82,6 +82,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 @@ -252,9 +262,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); @@ -277,7 +289,7 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) memset(nentry->lsm, 0, sizeof_field(struct ima_rule_entry, lsm)); for (i = 0; i < MAX_LSM_RULES; i++) { - if (!entry->lsm[i].rule) + if (!ima_lsm_isset(entry->lsm[i].rules)) continue; nentry->lsm[i].type = entry->lsm[i].type; @@ -289,7 +301,7 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry) result = security_filter_rule_init(nentry->lsm[i].type, Audit_equal, nentry->lsm[i].args_p, - &nentry->lsm[i].rule); + nentry->lsm[i].rules); if (result == -EINVAL) pr_warn("ima: rule for LSM \'%d\' is undefined\n", entry->lsm[i].type); @@ -329,7 +341,7 @@ static void ima_lsm_update_rules(void) list_for_each_entry_safe(entry, e, &ima_policy_rules, list) { needs_update = 0; for (i = 0; i < MAX_LSM_RULES; i++) { - if (entry->lsm[i].rule) { + if (ima_lsm_isset(entry->lsm[i].rules)) { needs_update = 1; break; } @@ -415,7 +427,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)) continue; switch (i) { @@ -426,7 +438,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: @@ -434,7 +446,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; } @@ -810,7 +822,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); @@ -821,8 +833,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)) { kfree(entry->lsm[lsm_rule].args_p); return -EINVAL; } @@ -1469,7 +1481,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 b2f87015d6e9..91662325e450 100644 --- a/security/lockdown/lockdown.c +++ b/security/lockdown/lockdown.c @@ -102,6 +102,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 = "landlock", + .slot = LSMBLOB_NOT_NEEDED +}; + static int __init lockdown_lsm_init(void) { #if defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY) @@ -110,7 +115,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 7fb6e5bcf6ec..214404a78db1 100644 --- a/security/security.c +++ b/security/security.c @@ -308,6 +308,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 @@ -435,21 +436,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); } @@ -458,7 +474,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__); } } @@ -1906,7 +1922,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); } @@ -1919,7 +1935,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); } @@ -2383,7 +2399,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) @@ -2391,14 +2424,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 0839b2fbbf9b..97f2ee6e4080 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6860,6 +6860,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 +}; + static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), @@ -7128,7 +7133,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 4cecdfdcd913..82cbb3eeec76 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4585,6 +4585,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), @@ -4783,7 +4788,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 Jan 24 00:22: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: 11349427 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 C76D8109A for ; Fri, 24 Jan 2020 00:23:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 963EF2087E for ; Fri, 24 Jan 2020 00:23:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="YAi4IgWd" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729516AbgAXAXj (ORCPT ); Thu, 23 Jan 2020 19:23:39 -0500 Received: from sonic304-28.consmr.mail.ne1.yahoo.com ([66.163.191.154]:37456 "EHLO sonic304-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729526AbgAXAXj (ORCPT ); Thu, 23 Jan 2020 19:23:39 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825417; bh=UIYk2lo/4C4YgySCWdfz+ZkuKqKHQIG1r+HGavT4EVk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=YAi4IgWdPWFWdh4DocLnGyDKmPNEzf/OxgkRN89+fxPkWjQjg1nH4tdcC/9n9WDpZf9h5qPhxYx30rBEoackD1kCAkelteSHPrurjbMycqBFoKeINVZZkMUSanDSDstuJ7tSwBTTD49I+eIlDFiC2CopsMuzl8tXqYroB52HKrcwCF4Xo6bt+aR+28Dbz5wlKPtn2WY2lenEnHXDProNI8ghpIoM3d4VNz3aIO/HOibJJYYbwmSBg50s3Dc7aBhrVdxR0EuHDqi/I1h+yuZfFuSZCDtDgzoAMYCF9kYhQFTfjQb38REgZxJPpjRpjYmx//ULqZMh47rDRKiOMYQhtQ== X-YMail-OSG: 72ttp6cVM1kFUVEHxXIdDnEELSi6LeWgHgHp9T43NRzBejliKtgNgvXD3iiIB_3 dzWCJaNGcb2th_X3DmM7Wec9_1HWqlgPO_nfLmk2XFZ9is_51civKzLolTGdhC.871LKDesBD0kZ zrZ78BDph..lzzyu5VJrmtmVgotsF3YPz8UpeJHgYDKI2lLGgG0yeYWZhdI2nr2kJpNTpFlkIQKn WunOxAQeCSiksyehRTo6HQualT3DoqOTny2hBClwXTZqa_jWucGGrjah_3WCJp.3vOhR3Fe4iAZ_ 66aKyUCctZhwGwoTuf_NRfKQcryP2CtR2VW6FePmPUDZyyCY34RpO_c.CKw8XzQ37dWLE7F6E8xW 4d0A0KyhpP35SQqR5emhxf.TwwSG_UFhYQ3KHaesDfec1wi9OlHCobKMYLzJb0XsSe83Fxm5c7lm fV6T1hgwZH2LePQnPXszn3IZTicfHUXSDCrE7.l6jn4g4WvzzGsCfnzEIqSE5aRBDC3bQbAkQYiS bKmDxu58hmVoAj8SG8lzd6U0_nGAkwMr2Yvc6YWkr4RKFBH3WPALtHsOriAAXs4mviAAsYgFOB14 c4z.jPK7OfOG1qTBJpwiMXp0zQVMDHDA5HAx_FvtyHoYn7bhbeEsALsx7Ny2TDqWdWY4JOOmQmfU D7wtMfHk.HXtldURfprj58JJnF1moVGwA414EUlyoVfE62mz8fV7mQQjOdPi_iO2FxNgRsP808au 8Wx035hiDTvzuUd39tl1S85Ue4i50lVmoIS2Evo3LL4WssDt_UyKH2LTwDF7BJTR1hls0IJGbFXz 7gmrw_XiUX4sSAFjzdD2X0S2aN_XXs_.D_oPacg2dFf4lMA121Ra.yD4mVvL7UwUUI3THr_z4N8X AIkAmD_pphVuPZ9vLdzHxBf.Zp9tYNfqELuxtjoXvrkWd_ucugtSD4U7T67aSvR.qHTR9aXZYL8Z yB.LbqJ28_tpUUaeXggwe7OxXn6FBkU4KyJSABdQq5KK8hf5ScWsACMnNJhrDd4ct0xKHOuZ5k2S PQ3X7Y6xUU3F0u2P9RrkFTWKv5dohc6gBz7RtOnrGbDH36kALF3aKbU5UHE6b8XUGg17e28KDa.g x5b32r_h8wPUrmt_G2OlPCbUD3NxPgNM8jEI0QAL_vlHFrPRvoCt3AzCDSP0.8Lfo0wZS_maEmSJ CxSdW2mJ2kpbq0rk6TxwUfzKoL2XBQUDguXCCZ1e4_ebETeg2f7Fdj6vMNpxo_ojzXDU4qaB63d6 BhEoIF4CdxQvskiNzfxaxP1_8Rstcn7iIG8GOy_3vsTNRmCo4t.Iu7YTmgGrc.dHC640r1msBzF4 mxSTIMIC5Tba_MKnN71OQDFMm95hx6gfY8tInJd2i4VYoOhLT6QootyoXtvJiozZA6bLjRPXY2lI lKgMQgivh0qeH5JVhc9FmHcDVV_knliIKDrqVJBjPkzBOh30.2JocPuk- Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:23:37 +0000 Received: by smtp414.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID e5f705e051cbd06816d6d32e048b9ccb; Fri, 24 Jan 2020 00:23: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 v14 03/23] LSM: Use lsmblob in security_audit_rule_match Date: Thu, 23 Jan 2020 16:22:46 -0800 Message-Id: <20200124002306.3552-4-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Change the secid parameter of security_audit_rule_match to a lsmblob structure pointer. Pass the entry from the lsmblob structure for the approprite slot to the LSM hook. Change the users of security_audit_rule_match to use the lsmblob instead of a u32. 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 3422726268d2..1988b728eb3a 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1837,7 +1837,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 @@ -1853,8 +1854,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 df4ca482fb53..d95b0ece7434 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -381,8 +381,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 808c2515fc6a..27257af4a8cd 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -426,6 +426,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)) continue; @@ -435,7 +436,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); @@ -443,7 +445,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 214404a78db1..3a2529f36269 100644 --- a/security/security.c +++ b/security/security.c @@ -439,7 +439,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. @@ -2435,7 +2435,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; @@ -2443,7 +2444,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 Jan 24 00:22: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: 11349433 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 9218F109A for ; Fri, 24 Jan 2020 00:23:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6C3C1214AF for ; Fri, 24 Jan 2020 00:23:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="WqwlTRfx" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729352AbgAXAXx (ORCPT ); Thu, 23 Jan 2020 19:23:53 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:43217 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726232AbgAXAXw (ORCPT ); Thu, 23 Jan 2020 19:23:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825431; bh=biXKdDal8avL2cs67nKa/B409u1uTk2B3mml7ZtC7Bw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=WqwlTRfxcMCQikY4H3XqHGgeySsb+j7tPoUD2SkUEMRYV8IeBUIAQZaoaSkFAE80H5SmDjI09Z4eluhUuydKpgiL8UCMXKzSJEAWSROh+7ACJoxzxCRERLCnzPEcNBRgHF6Iinb2EDVgVSPI3aebu6mU8aMEsIQyexWGZ92c6kvX0uGlo6QPBtvVYpyKVfGjTOkzssUso+G31gEEBOyzQThCMpCjoTdLkxI0iFR9TiKmMoVl635TLTQA82lVlM0XTDNXSWAahPhYEjgQ1Sxify/ZCa9j7B2OdFYjHlTuTYaDZZdnbm+alf4EaG+OdUQpprdDk1HljF0JENbBOw44cg== X-YMail-OSG: 1yL4WVMVM1kX4JMeoA21MJawYFp3icLszaclCy4nMsBMewVt9bU2kHJrowXZpeE tduKy4I.LAZw4w9V9J42osF1nGVq9VnQEdQ5CvrGcUtqztzwVYyQ0ZDVMNZyHkv3KGb9xh9ZlR4N lPTHsRjvBQ_E.GaCUWBz9q6MP5zMeeyUTw7HR97tGNbgNCS7bT2AMSvNnqIGgfKndChwn6w3IytA IRIGkS8mtp_wjhQxDo.2nSxwCImNCMs9Wdo3I7knWtu7NNF2cGhgBYa.9VK34Aq4eNzdKuwwpTsP xkB42UDiXE7Yr83n7shIHjXHA6WurioRS4pIPrabjuqwbLq.IGl_gsK4ty0a6xwAWM3G1k5VuXAR AsP_cPNOyaO2luvckjJGVxLqNk0kql1gvsFalQwX9ORE7EN27UHtyBsbMoHDE.m1f_K2.kdKtdUT Y1STh97.R3DtbRnHrPSCzxnhsPDKqymf9W198e47REC.fP.nx6s6gXFp2_vbJhx4e2dVs02mEwND UKU6OgbnMDxRmTjUCimvDfnCFNZ4.sDJSU7mExGhNpaQLz.aWapVHk04qpH3j3cwjvprGH4ByJbX YUOsfcaww_1bL1e64OrX7rgIMYOuMWxd1FN_edZhKOScQLNT00rSYbbHr.xya0qpaccNa6lAWomP BkIAWDJ4adsoJqpx6A1xexTUaG2SGmlKGbLHmHd2w9LYA4Xj1sfeXtaCpwyeGi3Su0XGBZMrx1Io EsvHFkFyA3TyIrNZxg5CHhGTCWjQ4TkFzf2_4FENXPd6NnNdQ5aZCApMR3.JKvMNRzzTGWwb1XJv spmA.27UyeXkfcFj0x490fsu2yvXQnAYfwKQKaAOoNgmswGefg3LbxybvnZNJYxDuXUSLUvO_NsA bh9HpPhPIUn6Z3lT8RTS0kaL.dQbiMIq7RSF6kpVVkKPaxameek6muu_uqVUFSwpcbvrB3DTsFZR CSoSzlUJ4fZbe7KWhLCsVJSWywi0pCtS8kbbgf4M2S9YWe.P2gwOggKWjNfo6CP5bvee3KT8MESZ UFdCHSuNy7mHatOxvQcvRYdTphuT_ifObCZ4pa_O4r9R2HIN.LM_Dv3_7TnWufGuhU6zxXVYLgp7 kpFSH0zAcDKfBNFdSYYyo5_QwtnJMY3ACpH3DR9ts_vMO7o1mBlhTNE.pRw8YO7JyJq1inGh8WBx YeE8nCcFVDTts7vv_AAgrWUCxHqIdVGgumhyDVbwyiYI5ohvmnNR5k1BEDm6263Jnl6iQrIJF3Wu aSj1u3qlKVRAfE5TBfXrRa8W3AkZ0hdcMfyBvXUGUbqbnPYeo2aeYas2p5h3XsDFHuof2OSvXMDJ _CcK8a8oK.3ivquxjla7jUTaqto34c.CzDCzHMB4iTt2pCun7kll0lrI5qZAUbWqmPgGuQh0CymT 81oBmB4eisTX4IIV.29Is2bfQwuq8XSCu8yIklmqqmlwh0QqkLyL7oQRo Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:23:51 +0000 Received: by smtp425.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 7441c4768916c3ca0a3a0d8b691cbd8c; Fri, 24 Jan 2020 00:23:49 +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 v14 04/23] LSM: Use lsmblob in security_kernel_act_as Date: Thu, 23 Jan 2020 16:22:47 -0800 Message-Id: <20200124002306.3552-5-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Change the security_kernel_act_as interface to use a lsmblob structure in place of the single u32 secid in support of module stacking. Change its only caller, set_security_override, to do the same. Change that one's only caller, set_security_override_from_ctx, to call it with the new parameter type. 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 1988b728eb3a..4f01878ca5d8 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -437,7 +437,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); @@ -1043,7 +1043,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 9ed51b70ed80..490d72825aa5 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 3a2529f36269..f53805de4343 100644 --- a/security/security.c +++ b/security/security.c @@ -1615,9 +1615,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 Jan 24 00:22: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: 11349439 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 65CC817EF for ; Fri, 24 Jan 2020 00:23:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3F5C121835 for ; Fri, 24 Jan 2020 00:23:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="rmx90JhH" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729449AbgAXAX6 (ORCPT ); Thu, 23 Jan 2020 19:23:58 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:46139 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729208AbgAXAX6 (ORCPT ); Thu, 23 Jan 2020 19:23:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825436; bh=Fz8sEzRXo6xINH4w52JD4gheNiJHSvDE+xrbo49TNrQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=rmx90JhHCe/0Lps6JUlI1/Zkfs5yns4XcPRTQHQUr5A+tFXeOjaeomNylRw00oWop3UQ2T8mBBLrZsmsmxtparoxtc27rJcBOzLhDY3Itvpp6wu0E//4GHIxB1S6mHtKbpdZGZSZ6XdRmwBkSUPvl+GFbi0O7x57a+cL2QUiDdH5bJdCL2S8UP7BVLgwgcJU2+tPafxeGz3XRrG4upQSDWndXa2usqhG3gI5dRklojiU5hXZIjm5+FmVmv3TK/BIFeG8v3gMaNqKsyfDlBbotkjkXD+7aZdqlXQJZKGdAQujXPtqN8ra7kAlenUuB+Z8zxkhl/+UrnzyIxao+TlNFQ== X-YMail-OSG: rPEL.DUVM1lAQI2cHcM56XvrIwVir4kqESBnhiz9zy16Y9TETzV4hltjHcKhefe A6Z_FXnBE4YuYjNNdCjT8z3hLgsnTCoxcJmUtDUSQZ2RXJ_UTAwe0A6rPF_KGDBvOThPIp6mDbU0 83G3VhuBTFh3RBY_7LASKmoLThFu8jWbqyGPcM4xUcxyN_QFs6Sykf4Xgz0fE8SPghg3xK6rOLuu rEXsig6anag8k8Wk4ZM6xqxOgzhA_eLrgZMdzTQw19wlgsLQWrmkmFV4x9oE1ApSYwaSx4ZD8nkc Bm8KnmU8_h3Pkmy77SD5Aaj9LF0hp3fSvGdjdHy3CWIKNZkMrMz6rEKylAN_0BT1xHYlr7zbdH2n erO6ucxtPx_Ev.pKYdR7rcur2zNVJwQReMP7smDJjW1Gfcrmf1nmDrIJOtFeORRgrGYgNo4Wc_dO 4Tc88FXS2ywyYv4auHEwdveu6rQtzSJ3rNKXbGZs0rawWsMihrtZ2LlptcctqAKvHHVwULQmMtJg gR4SHYOhzSjxtUp9SMBlM9FaxQRNyEngH89Pl9iltBnKRZBBbPSrfeSZlHbcibBAG1ZE32vnSiEe pEIavEAwW0zQumppHKyd5RlTz5cjFvGCy32nwJjc6jPQzWkbbBj.2l.1Cupfvj6ei1LMcMVYzjIR Od80SGXzVNhf9H_N6b7J3qbkBCfodLpDrZm9JoXCBFZZsGgDELdvNVpp24M9.D.In.z_cLC5ZieS R8W7LF0Ijd5AdGtus_I0gJ4pz1YwjRwYPImhYPBDjjDj._kf6OtPCd_Ijbd59R_K8MUIr3fE.Ojt 3g5UnUgwYdIn6v2nublQe7U2ME68pAijVnJHeRrGU5YEaTilEvJ0jv3fiNbOE9ZNemvvBuvOzbHR zfi63gW2fU61I9UKv0McSzyrxYbWu6s3PsJGXlXDT4swS5EtkNmj4hrkYqPdOuBOrh4xNlf7lex7 y.Ztmrh8TEDcjG1h4m9qkKrRJwlJjy3bgLGQkanUK1oYSRdWYYfrCcr9O.KZA_1tjKNFJUgAlOAb I_0yXwtfFivprf.VDRBlTF75Mbl1oOPqhsttu93q0KNOS0KlyQ.8lbnu_qKuqV_IkJOltrRw2rK2 boV2c6bCcXvbPcZHWVVjyQqOVtzTDXmHU6mx8Kjxrk7EEyT2OsEfcCz9bPXDK8auP6lME7YUdIz7 exHHjGJUjOTNjgrozD8lsDw0AQufSbvneo_mpYxo2E7T1fCKS10qAvkb0fA4DTg3b_Ul02cmU3oV hbtXml8bzFricqcK8hkpXPaPqxJfLHNLVN5cKcye2jFms7CrQR6Di5u_ldLyZDTSeRvre1u_outW gqge_kAqVjX3AFfDpYavI.lwtMnvHW0q1raOI07by.VLtajfFY3G.lMPQ_FjBc8hRJBuLHhP50KM z6bOXA3IxJ8gXPnyIMOXFwIxICLDpKrztsa6hPXofWXIrD1app3Kt8gmqm9uRPIqCEw-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:23:56 +0000 Received: by smtp425.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 7441c4768916c3ca0a3a0d8b691cbd8c; Fri, 24 Jan 2020 00:23: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 v14 05/23] net: Prepare UDS for security module stacking Date: Thu, 23 Jan 2020 16:22:48 -0800 Message-Id: <20200124002306.3552-6-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: 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 4f01878ca5d8..e53ff7eebcc5 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1356,7 +1356,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); @@ -1494,7 +1495,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 3426d6dacc45..933492c08b8c 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 774babbee045..f0b1d741ab6c 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 f53805de4343..b7404bfc8938 100644 --- a/security/security.c +++ b/security/security.c @@ -2108,10 +2108,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 Jan 24 00:22: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: 11349443 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 7EA8017EF for ; Fri, 24 Jan 2020 00:24:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4DF7B214AF for ; Fri, 24 Jan 2020 00:24:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="QL7uQ59N" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729304AbgAXAYO (ORCPT ); Thu, 23 Jan 2020 19:24:14 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:34902 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729208AbgAXAYN (ORCPT ); Thu, 23 Jan 2020 19:24:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825451; bh=95i6vDMqUvd6jTgBi7Zn4gXL1jNw1342STwQ4VPSjAc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=QL7uQ59NYF9sT2f6G+cfo2PTMxwUimzgfOhQGNOkTi8PM+ysZA6vtvYJl7ALshs3rpJanZtiNNbnaCyrZs75zKPe/l74X1V3XDhMVWnfsCrZMZCYhl3ml/dLPKVkq30XfCYHODsOImpFM8Wr6NRrS1DP425lU6y8mp6J5yx/RDAjum0Xt+3aMCklq/1LZIuqt4v7lZOvgoFXOQg4Dutz9vN/U6wDKHYI1KzTFpnrGR3PzUWdx5H3Ee9e/QXsVY8GinEt+E6F0N0hmsGnsxVcUqxo0wR0bzEV3sHMHJ81YQzPSejxGYGkW/FSpMfXK5+0vlBvPSPvwboc2bWkr4nVSQ== X-YMail-OSG: g.PeG00VM1kTPbrMJdawxHudSK6xbWUbQtLjEEuWfxVyqOxHcQXi8XwYHzZWJpy KGucQjOai5TP_zZU4Gy_Ak5VViD08YRPiRIIJdntZ2uqUqNlU6g5fV8ur2qMM.KuBwmLgSkJEUzA w1VpnzF1vCAEymp.CODj2frhv.Sk0Z8AxlW7CnTnp_WO37VP6.RV91HNNLs3_eAJ1R42uN7MYwLs d4F5MFqRZQh7wUZskpqOWmXWgsnNTLP98ME_KSttrmejdDdZfNfEy0qB8pHMLQZpdKsvky7Vmh.5 jwmIFQvGABvSJf_L2uNQhSXDvNZ7gWa0oY5zZ92lDNj6fti_tjTcw7AXLZfXTNbF705OdeWaz0kx QH2vllYw2HLukjSH8hbASCJ6Ik69AblxTOxgSdTrcsClqYW6w8omaqcSPQA1k0WrHrSjX35_aL17 fmalOuV6qylaAzPPOwyXGZr9.3SMTrUWmLRMXQYZNluFpTfR4tEwv92x7NkAdpoUsf76oVtOdiWa RBsHjtHLRS8tQFCep2PBE2ZRQfhxtB0lJvy3g4CSW0KrzB9QBAfSxkEDpPD6Hd15km6amIuJd76O dtz0dGWNHh0KXBmBcGLSDVna.wG7xR8cuGRapoglOQXbwV6N4wIr_RQq_PDxcYz5nZ.Pl0eEXGKE ly78maivhE7nsYjyYZkzUpC.hXtDigyVjBhXPU2vxbb6r5t5Ks1X7XQW8HSGSNt52Goso2MFE9KF a_lEaIYEYU_c_7FGBFFs2EvN4xh0en94flH4UFh210TG2C_6G8kEmumqRoZ4SmGN_wQml9oxQE_z VvYxvHMd0ocGKXkix4bDZa9.iGLdEKpO2jqMP9szyLmJGLz.7F2vleqARtIWsE3taYdHNDdaGZs. 7gsj3BD.VOF64i3DHaHu8XdF54zRtSqXybfgjxk5695xX3Qx_GZ6V5jYAoGweQpdU9jOBK1Dh3yf lxTrPsRpfy5f.YBlZfx_RJRk523E6CeERMkQXvks6LaYImx.1eOywn2tavE2YcwfSp7GolLsLibE OW19kIvxVzH_BTfYswTLnormtlV7H3.1Cl6oKhBP7Mo1waiQPC.k.PqpmGavPOaGIS_v0u2Gf6.6 jisSF9JCnCSuzUyGTe7LCIfgzEj0UlYg9..ZRM6kHfGUQk1mBA_PRG63iFpwAmwQOK..gStZtijg K..A9by1PqfE4l2XY0w1OG.6LJtT6N1PoEBn5syLAalpJlTLz.d4qir1h93XYY91hxJhSDAE7rW1 2Xfd0Vy3OeXOEcjZGIjQ1.9UC.O_LZr_2RwIFf2u9MMbfrXGWFI1kgllZWwnbYNWi3zxJAJd9PKa XhwUKQ7LJ_qUEEYwkrjBim3BEWZXMz3AHovvgWEBylQilFk2ZifFiaxsMXDqfrJSSvCn4V1ZMz2P TXA4Og7lvVMcoqkFXoJiaaey0BF108YZugL08WyVQfJRdPsyXN2ribJQpHLBPOcR8UA-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:24:11 +0000 Received: by smtp430.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID f455687063dfe584d97e9b33b1091134; Fri, 24 Jan 2020 00:24: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 v14 06/23] Use lsmblob in security_secctx_to_secid Date: Thu, 23 Jan 2020 16:22:49 -0800 Message-Id: <20200124002306.3552-7-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: 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 Signed-off-by: Casey Schaufler Acked-by: Stephen Smalley --- 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 e53ff7eebcc5..5ad7cc8abd55 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -496,7 +496,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); @@ -1302,7 +1303,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 490d72825aa5..b41c2bbd357f 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 9740b554fdb3..259c78d2f371 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -625,21 +625,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 b7404bfc8938..c722cd495517 100644 --- a/security/security.c +++ b/security/security.c @@ -1970,10 +1970,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 Jan 24 00:22: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: 11349445 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 E29C0109A for ; Fri, 24 Jan 2020 00:24:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B0792214AF for ; Fri, 24 Jan 2020 00:24:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="Z/RA1h5B" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729208AbgAXAYO (ORCPT ); Thu, 23 Jan 2020 19:24:14 -0500 Received: from sonic316-27.consmr.mail.ne1.yahoo.com ([66.163.187.153]:32809 "EHLO sonic316-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729497AbgAXAYO (ORCPT ); Thu, 23 Jan 2020 19:24:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825451; bh=QYjyJfuSXcIRwzgeMm9xQXJo2ssgZ7+1Fm3qM1b+m3I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=Z/RA1h5BUG1v7Nh7V2TKNus3BIJYLjHemkv74Rja/RWM10s1O6T15j51YS1v9ZNcY3Q5qGSSvgVazpy7iTb2xNgElidZw9DCgaOsbpTHcc0zlNQQFi2AOfqTvDwm8epocCgoRVLKKAsSXmO4brWVWDMtjQj6SkcEtIjht12nipGAdv/8cz+TNv42wRQq81zmbVZO7ljPnwbUbFoBgB4bu3xIuFWUZtK64rSzhkowd9mbLD8C2wafu9j/M+WmL73ttIqc3F6+0TjlzNpLaJw6e8KWx6Eplqi/r/iHwbRjuLumKygL34D0QIJ+8QYJJ9Mc08XLX3a9MMHPW2lkWxeS8w== X-YMail-OSG: mRDI8DkVM1kWdZi.CVJbA9OUCKuRjsl7DW.neuAi4UYibysHFQ49UbIoBeBg6yT 4MGg3LqBYOLMIFAMDXoTMhmL2fKcXRqEGQnbTiuIxvmmtNLSodBON.WDGaRIju2ayNQ.t_2UwrRy S6P1WqJHpyDxu8I3HgQjrk5qswo870xD3Z8lzKmVUm7hBpEqsg8LejZqVb4MpCv7CjdnMS_4HHTZ 3f43hhLTNtpGSI7fzskbmfmst6G9R.9PkZ.H_luVgY..zJESQGACKP5C.CgWJvOWN.nByrfFbRHD bQE5SpfprG_PLclQ7LP3gEI8mcyjFfzd0crbr4Y28E2.MYLIrg7ggwl0aCOqtdm6qNTfx1ECwJ0R KkL0BaAse6V38r3fHV.597eF.IHAXvPvhhX4P39BEwvdm17N.o0vT4EfrtP_HKlGXuJMRl78IqV3 KRUFL2PbdvhsgkVvAuEQYiWHYeJBtfQ7muTJHcohP8XMh_xsMHwlDUR.hZX4D66AwWITTYWuRJJI 3w7UsSvteFqGQrWaS..OVgRa64VRhkPdWOO59qeJor0jL267Y_nfKL0unFN6qOXOU9QzXsLQvxdX eGME2bfCQVQm5mP_HfWRpY.9p2QOys5auD__b6Q3i00NWSYQFNNF9vwEpNYcyCh.weU0pAz.koiC Z3j49ZFgP_FJR92HsTF1w5ZFnKQP5NUQ2EqBIe_jUS8fQjmVfHoVmXsGaHIHISVn5jaJeYMDXUyO NswI0vvMmAyG99y_9u24RgRrAyFl3KzL6e9Z.2Pwb6wV7aMjqWqquc_SUWWUoq8yRaPeky3C7AA3 z4Aam4SVfAtpiC9PfXhUqLtnIoHdLumCtIVSTkPbrRydbvVHBKugjvyqI.UsHIEqilLQ6fIxOvO4 6gFgQsqw0UMjJdUHnJOvskxwrzoGZOSkpzBq.Slc41b_f.aLnCvX0qn07BFQ.CpiFrk2DaH4cFCE 5wo7xwenupvBQ50NamLa8aBN3mCivLaC3dfA3r3iOaOebHu5df9A3CI5R8ADES0hxoROUaKdyU8I BqUteVf6aJZv6JmBji4m3wLgLMVlyPr1zJbMhVNQeGK9HUN5f3EqBWXVKSbZO9ZHSB.I2cgduDpd Kn.aMhCwKu7u1VsQ9yF_B9kcJGEOWW.hFwWSixTy0CB1cmwbKN1fzIcinCB0_nGhxxGiH7vnut4X Y0QZTKbR0eMtpTx_SWp4DFcU0PQ_dozpaS5Drrs.kVk7ydXL7Mh2zAH2jJL9rRtIYgf7HA9ZbBUq i701uMqt5zpdVI52xSH22owytU.Nfjsl4Hdi5qDu.tgasTZF.7MVrDWcDZCD2YbX4KjKs8nflCPs N2835WQTebWHGwfL7.4slSThkje0l3xCeef_URyd3NO7tHCuGt9hGqTbaaCC7I1742jXq1xsCH0P l1LVXmttdiUtsih90Prc6p59gI4wwNzwi1sox.2EX_S5b6VHXTtR3iXDsKp4- Received: from sonic.gate.mail.ne1.yahoo.com by sonic316.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:24:11 +0000 Received: by smtp430.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID f455687063dfe584d97e9b33b1091134; Fri, 24 Jan 2020 00:24: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 v14 07/23] LSM: Use lsmblob in security_secid_to_secctx Date: Thu, 23 Jan 2020 16:22:50 -0800 Message-Id: <20200124002306.3552-8-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Change security_secid_to_secctx() to take a lsmblob as input instead of a u32 secid. It will then call the LSM hooks using the lsmblob element allocated for that module. The callers have been updated as well. This allows for the possibility that more than one module may be called upon to translate a secid to a string, as can occur in the audit code. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler cc: netdev@vger.kernel.org --- drivers/android/binder.c | 4 +++- include/linux/security.h | 5 +++-- include/net/scm.h | 5 ++--- kernel/audit.c | 9 +++++++-- kernel/auditsc.c | 14 ++++++++++---- net/ipv4/ip_sockglue.c | 3 +-- net/netfilter/nf_conntrack_netlink.c | 8 ++++++-- net/netfilter/nf_conntrack_standalone.c | 4 +++- net/netfilter/nfnetlink_queue.c | 8 ++++++-- net/netlabel/netlabel_unlabeled.c | 18 ++++++++++++++---- net/netlabel/netlabel_user.c | 6 +++--- security/security.c | 16 +++++++++++++--- 12 files changed, 71 insertions(+), 29 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index b2dad43dbf82..f9b67f585e06 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3105,10 +3105,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 5ad7cc8abd55..556660941e5d 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -495,7 +495,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); @@ -1296,7 +1296,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 8e09f0f55b4b..e3e515158295 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1417,7 +1417,10 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) case AUDIT_SIGNAL_INFO: len = 0; if (audit_sig_sid) { - err = security_secid_to_secctx(audit_sig_sid, &ctx, &len); + struct lsmblob blob; + + lsmblob_init(&blob, audit_sig_sid); + err = security_secid_to_secctx(&blob, &ctx, &len); if (err) return err; } @@ -2060,12 +2063,14 @@ int audit_log_task_context(struct audit_buffer *ab) unsigned len; int error; u32 sid; + struct lsmblob blob; security_task_getsecid(current, &sid); if (!sid) return 0; - error = security_secid_to_secctx(sid, &ctx, &len); + lsmblob_init(&blob, sid); + error = security_secid_to_secctx(&blob, &ctx, &len); if (error) { if (error != -EINVAL) goto error_path; diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 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 feabdfb22920..bfa7f12fde99 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -305,13 +305,17 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) { u32 seclen = 0; #if IS_ENABLED(CONFIG_NETWORK_SECMARK) + struct lsmblob blob; + if (!skb || !sk_fullsock(skb->sk)) return 0; read_lock_bh(&skb->sk->sk_callback_lock); - if (skb->secmark) - security_secid_to_secctx(skb->secmark, secdata, &seclen); + if (skb->secmark) { + lsmblob_init(&blob, skb->secmark); + security_secid_to_secctx(&blob, secdata, &seclen); + } read_unlock_bh(&skb->sk->sk_callback_lock); #endif diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 7a5a87f15736..0cda17cb44a0 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -375,6 +375,7 @@ int netlbl_unlhsh_add(struct net *net, struct audit_buffer *audit_buf = NULL; char *secctx = NULL; u32 secctx_len; + struct lsmblob blob; if (addr_len != sizeof(struct in_addr) && addr_len != sizeof(struct in6_addr)) @@ -437,7 +438,8 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return: rcu_read_unlock(); if (audit_buf != NULL) { - if (security_secid_to_secctx(secid, + lsmblob_init(&blob, secid); + if (security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); @@ -474,6 +476,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, struct net_device *dev; char *secctx; u32 secctx_len; + struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr, @@ -493,8 +496,10 @@ static int netlbl_unlhsh_remove_addr4(struct net *net, addr->s_addr, mask->s_addr); if (dev != NULL) dev_put(dev); + if (entry != NULL) + lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(entry->secid, + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); security_release_secctx(secctx, secctx_len); @@ -536,6 +541,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, struct net_device *dev; char *secctx; u32 secctx_len; + struct lsmblob blob; spin_lock(&netlbl_unlhsh_lock); list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list); @@ -554,8 +560,10 @@ static int netlbl_unlhsh_remove_addr6(struct net *net, addr, mask); if (dev != NULL) dev_put(dev); + if (entry != NULL) + lsmblob_init(&blob, entry->secid); if (entry != NULL && - security_secid_to_secctx(entry->secid, + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " sec_obj=%s", secctx); security_release_secctx(secctx, secctx_len); @@ -1076,6 +1084,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, u32 secid; char *secctx; u32 secctx_len; + struct lsmblob blob; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family, @@ -1130,7 +1139,8 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, secid = addr6->secid; } - ret_val = security_secid_to_secctx(secid, &secctx, &secctx_len); + lsmblob_init(&blob, secid); + ret_val = security_secid_to_secctx(&blob, &secctx, &secctx_len); if (ret_val != 0) goto list_cb_failure; ret_val = nla_put(cb_arg->skb, diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 3ed4fea2a2de..893301ae0131 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c @@ -86,6 +86,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, struct audit_buffer *audit_buf; char *secctx; u32 secctx_len; + struct lsmblob blob; if (audit_enabled == AUDIT_OFF) return NULL; @@ -98,10 +99,9 @@ struct audit_buffer *netlbl_audit_start_common(int type, from_kuid(&init_user_ns, audit_info->loginuid), audit_info->sessionid); + lsmblob_init(&blob, audit_info->secid); if (audit_info->secid != 0 && - security_secid_to_secctx(audit_info->secid, - &secctx, - &secctx_len) == 0) { + security_secid_to_secctx(&blob, &secctx, &secctx_len) == 0) { audit_log_format(audit_buf, " subj=%s", secctx); security_release_secctx(secctx, secctx_len); } diff --git a/security/security.c b/security/security.c index c722cd495517..553d8e05be0c 100644 --- a/security/security.c +++ b/security/security.c @@ -1963,10 +1963,20 @@ int security_ismaclabel(const char *name) } EXPORT_SYMBOL(security_ismaclabel); -int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) +int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen) { - return call_int_hook(secid_to_secctx, -EOPNOTSUPP, secid, secdata, - seclen); + struct security_hook_list *hp; + int rc; + + hlist_for_each_entry(hp, &security_hook_heads.secid_to_secctx, list) { + if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot)) + continue; + rc = hp->hook.secid_to_secctx(blob->secid[hp->lsmid->slot], + secdata, seclen); + if (rc != 0) + return rc; + } + return 0; } EXPORT_SYMBOL(security_secid_to_secctx); From patchwork Fri Jan 24 00:22: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: 11349451 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 BED6317EF for ; Fri, 24 Jan 2020 00:24:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 95F19214AF for ; Fri, 24 Jan 2020 00:24:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="hpfVRXFN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729836AbgAXAYd (ORCPT ); Thu, 23 Jan 2020 19:24:33 -0500 Received: from sonic316-27.consmr.mail.ne1.yahoo.com ([66.163.187.153]:34473 "EHLO sonic316-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729491AbgAXAYd (ORCPT ); Thu, 23 Jan 2020 19:24:33 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825471; bh=ca0Tfp0NFYK0VSV67i7qhfcA343IR62LEkNUbdBthlE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=hpfVRXFNmJrWPWsubhWGvFCZTMHODoXlM0R1Xf+b1jF4d0vgrxiKPyRulYjDL/n/+j6vryGzwhNQpKM0+mkbVzaX1cm5gNa37TOUFyN4XQd9+irS8la+5nmcNpBy9EAE2ffhe51RQYRF5qV4GXDT+U8AHGjqSS7JxS/b6rMQcazsMrUHQhBFgZTYrGF9NZ6GmwrqttMem3xnVw2wB4A1TjD1TWoPDZ5rCX631glwOF60KlTgbMsimIq4m/m2MHhyJVG9afdbzi/fLkRUVR6LVOkz/xT/vDXp6rwqnYiB/UlNKEhw6qFC9PEMk87J0XA3MQI8uYP/DznK/O+gmfj+Jg== X-YMail-OSG: k5w_EOAVM1kFbjhU6f287C1trFuTPrvtBzN2E8wl0TWbuhw7AvDVjMLS5Yu_AGy o.tV_tkAzeFBh_FpgmvwyzlAFhLnq1QDwAtbEHoJ78xp60dZfsIgLZJTwqr67sIhJTc2qZ17JoIP fH2.KRJpruJWw3t8Lt04OOgEvX8hPtWilOsAi_W8XsnZjjt4L4.R9tlacNrzGpoYVSiu0mkPbagN aGycgleyFARz9h0Trb83bEb9FhYBN4kDvcyfCJmp3C1CIFVeqMJ_DC65Hr4M5J5ZZ7FJRRGkRuRS QUgdkeg4O7dbLSadImqaVXRqLJQfGp5Wb89fxkP8NvMGautDvBp0LmNCM3K4i19NAshrtDouKynr 70.C9i4m8JWzmTI.wOjn6e2YHSUF9BQ894eGVjDCQn4o2fJNg.btMdOoNAdkvSv0L_gLyOSPpwQz 59Lao9EwlO2A8CXxeB7e_gKW9TBXKS0vl68h6nBv1mKwvkWEJnqAW2fCAAR.U.0xWvpvyFBUQ1md 2IqgADgHyIll43WD3P3ca8aga2ZwCOXkV8uBR9rHR1WSXwHZAyQkaNw.y6eKaEc_wL0ZXJms9fzV bmpcF2pDB949t1E79gnomqcX9VN3NWGgKxLsmYibu28g37dJHvy7eyYp0uyLi..rGAfmGANLSLOK Nllkcbmox2tWK.40PLkSgUG2Y8FZfooe3ffPhOFR0GAW03VPF4DtxpWA.IwHl0uro5AQZKQKqnMr .gYuPwqlSLCf3jeiBovRYXsvp.7aesDdh9RmdMhEscKogECiMa8S1UmWjsiqiCko2l663PL5m0bF c9sCEAWvjRkVVTBVb_NpzjlU65eGHPZezx2.WbCSlSL9QYhVkfzkM_RxWqJoUpae2iaFhh5XaUkh XHYq3E1zlOsP1HSYiGyOQDQ9Qs8eN4cxJLWi.C9HTcr3eEM_hxo4XlWwELM3dWnaDt9njkAiB.mk CxsRssRk2qaQ6yF1A.Nl1LuyCl4dkME51vuapkDsBF8ri4Xx0V_Lk.qfBa.bY0MXpHQx6jKIhTyj nXgy87_bl8M.alh.sHTlblNeaNpI23MQv6Xi5lButOVN0whcskNmah3KY7il7hiKD3ugActp0bd9 BYktKuIOsXCFSFfbPfJBYGaKoQMXxMuoZmDjESNy9wFbVYtPktfnD8aTtj0uth2vG4JSbLDshja5 QV68NAP0OWkdmnKVBk69SN0KNRhUqSQfxkxZR4GvToJ58BtlrouiKWdHClKuN9qZYLF1H2TixcX4 4cC.NDi9R1rJzlWP6.zhxX6usYtcil5XciF9LsEgM.kBsqywf9iWvvGIP1op480vUzWBJAxgVP25 6cFWqZtMBPA.yyieI18oVZHUPs4xFDm6rbAvwjajr5E.TLkZXxQXsDv3mfB6cAa83PwYMA6.x30N EAQLu4Crj6HfyacTVKFTsJV5iVdBJl5k2Am1BP6i6KF7CYJY8bJmspoA5D90ti01V Received: from sonic.gate.mail.ne1.yahoo.com by sonic316.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:24:31 +0000 Received: by smtp424.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 759da4ea465ce667781c92ca655afefe; Fri, 24 Jan 2020 00:24: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 v14 08/23] LSM: Use lsmblob in security_ipc_getsecid Date: Thu, 23 Jan 2020 16:22:51 -0800 Message-Id: <20200124002306.3552-9-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: There may be more than one LSM that provides IPC data for auditing. Change security_ipc_getsecid() to fill in a lsmblob structure instead of the u32 secid. The audit data structure containing the secid will be updated later, so there is a bit of scaffolding here. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley 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 556660941e5d..5444302d2576 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -466,7 +466,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); @@ -1174,9 +1174,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 553d8e05be0c..9e80e55fad6a 100644 --- a/security/security.c +++ b/security/security.c @@ -1783,10 +1783,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 Jan 24 00:22: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: 11349453 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 E252B109A for ; Fri, 24 Jan 2020 00:24:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A04C62087E for ; Fri, 24 Jan 2020 00:24:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="qouYOi4K" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729491AbgAXAYf (ORCPT ); Thu, 23 Jan 2020 19:24:35 -0500 Received: from sonic304-28.consmr.mail.ne1.yahoo.com ([66.163.191.154]:45723 "EHLO sonic304-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729504AbgAXAYf (ORCPT ); Thu, 23 Jan 2020 19:24:35 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825472; bh=S7OOH5VgcJaaTy099CwsAV9KIsMNOrQXt+C3Z0mNlsI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=qouYOi4KFjyBOlF80VDz0uSmXbbgYsjulj9PCSdZvZQv6mxexqrSMvEvaPtobH2kcoO6XR9bylYKECepeZpBEnwEXzP1Wg31vPGZmJc3YRVwOWUcpPCnBEGRrSSCTtQpX84YODcxuc3sA7+0n4kwgSCLbQgNkug3HTgZUxwFiWPV708Jzgtmrj0v8fpuZ1pK2eQ4vJt5BHJRe9frXd/6Weldga7y+/lAaG472NYiPiMtzNATB3ZtMuAEcd7eSdOShGrL5IKUX0NqtdVXX2NPGLWK83jY2c6Qf/S2Jv0DmV6eBDNS0tF40lGa9Kf3Vjjxb7abKWYvD7ExiU95ZZzGNQ== X-YMail-OSG: 1J8fw1YVM1km9QKeYJjZzRRdJhw4I90fVReaBp7HSi6PGuiawIzGB2COOxpT0t6 edPYmwxCROLGvHqRZ6cnNM9bmZ16EJKebekrhehhprgA_cR6blBQiGdvtDZ4dkTl.9XvDVqhJ55i xfYX5c0a3b4nuj_O_0jvb_b9bd_YI.Br0oRlZMl.gRJTNnB_vhgDYhZ7g4jYLidXU0v6hyvQx.aO G1xACqlfs44zHX_4ZeFbsIRqocsCDI1IkpuL68TZDWr7EFhKCRC3eEfYDaQjsE4a4Uhxdhws0YbW H8OCMBetmD6es0XRVpSSdkQ69WSxyt1.VMfx5wEQfa6vtknaxALlBry94cbbCPklr72L24egSdGN hKNOOXSNTlm_1wM6MrD56MI1BK9dQvc9P3pbrD_8mUWH6GLJN5DKTe1lMYLoy1ofIEYeeMvqSEOo 2TBG3cELDtcYHyGd5qhbaaSLg8vGZ5PxRY.LoqNtiC03B3TtCxr4yBAFXNtPrGoJ6ipluBJ4GrIt _RegMPP1bkAMcuR22LqD5Y0qjerORBtZJ9ug7oq7YPdyZU34GgPGQwaYxlgN453JJL_78Z.hWAhJ lGsn1_uoIBdOSC26l6X8gtAe5s7Ev8x9sJBn9Ct4_EiM7BuYFuG6IVB_YgobKQT45FGIN3loKS_J socUvgntCFihzIJxmum6tPYxQS6J_L_frV8JiPu.yh1467CUM.pKx8Qw.uJExB27gadmvt7qGQ1K ljgsQHpJpHMwJ_mtOa6waiXlTEXq.7JtqCHbH29QgKgDmqMx7ykMrrapuB.WUaIpdkkpKqIoikG. _kLDPTZ6Fm3f.pDRx.GNvZ992eM9qwEgOW6.A_7y4_xXwvLUesNmLQh8CSpi1IKNKj76qQrnPI5N zBKlvAXMyASuwzgKQHLPGCiY3fEoE5HkRFEALM4FaXx0x6XnIryozOjJDUEX1.jQcLq7_gpU8xqV epeUzobicazf_XkCBSlNT.ML9BvlaK.sdmYYm6V55rIAGBz1QhDsUeaDzVcxMfCUciksVIT92tr9 jRjAr7_2vR45S3g7lt072uQq3.npAXsjsMajCq_bFvfFNFUV1LXDDwbpY_GvdHwSkQehqftzCsUw rxSEQBdwXcgLvNHGOIBY_qFXptKe4DhgFEavuspvD8IxJFRQolbGivz9K.vaOn.DIlTxGJI8jX.4 abB_Mi2DmqB90av6_6.86X1AkF5waqreygZRHOjJipZC9kis4nNA1liZ0iLGV3ldQHGS8eGNiJs2 uQJzSfO5SGBDA1r18Qhh0foqgbhPSOr8KCxCDB.MnD_q7XVla4yRTqdY4oEHHGzi0aWepqGhkeu. B3Iyi9sxkJ2lSU5J.ZwcOQ7SaTq7hs.PERBaq.ynqGBumtu.nE7_bDT4.FZnIBcNoOJGcP1c942x GibHrb2HE2WDoowwOgH_vB1f9bVqsRqe2hB2qP6lElEeqJe4YB6u_156YiBlo5AY5OzqhS2X6 Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:24:32 +0000 Received: by smtp424.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 759da4ea465ce667781c92ca655afefe; Fri, 24 Jan 2020 00:24: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 v14 09/23] LSM: Use lsmblob in security_task_getsecid Date: Thu, 23 Jan 2020 16:22:52 -0800 Message-Id: <20200124002306.3552-10-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Change the security_task_getsecid() interface to fill in a lsmblob structure instead of a u32 secid in support of LSM stacking. Audit interfaces will need to collect all possible secids for possible reporting. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley 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 | 9 +++--- security/integrity/ima/ima_main.c | 42 +++++++++++++++------------ security/security.c | 12 ++++++-- 10 files changed, 71 insertions(+), 47 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index f9b67f585e06..22fef6e130df 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3104,12 +3104,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 5444302d2576..9ad1d01fbbe4 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -449,7 +449,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); @@ -1101,9 +1101,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 e3e515158295..6ee53e43c986 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -2062,14 +2062,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) @@ -2277,6 +2275,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 || @@ -2287,7 +2286,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 300c8d2943c5..37f540af45bb 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -48,14 +48,15 @@ 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); + 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); } 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 d7e987baf127..7c4bfc051ebc 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); } @@ -548,7 +552,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) && @@ -570,9 +574,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); } /** @@ -653,7 +658,7 @@ void process_buffer_measurement(const void *buf, int size, } hash = {}; int violation = 0; int action = 0; - u32 secid; + struct lsmblob blob; /* * Both LSM hooks and auxilary based buffer measurements are @@ -663,9 +668,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); + security_task_getsecid(current, &blob); + /* scaffolding */ + action = ima_get_action(NULL, current_cred(), blob.secid[0], + 0, func, &pcr, &template); if (!(action & IMA_MEASURE)) return; } diff --git a/security/security.c b/security/security.c index 9e80e55fad6a..78185ddf232d 100644 --- a/security/security.c +++ b/security/security.c @@ -1700,10 +1700,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 Jan 24 00:22: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: 11349457 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 BD39617EA for ; Fri, 24 Jan 2020 00:24:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 95BBB2087E for ; Fri, 24 Jan 2020 00:24:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="rGvAkgKJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729866AbgAXAYx (ORCPT ); Thu, 23 Jan 2020 19:24:53 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:40232 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729852AbgAXAYx (ORCPT ); Thu, 23 Jan 2020 19:24:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825491; bh=9RjDv9BM3moUwDIns8kmS3SpDWeAqOMGyva+HUGwu4U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=rGvAkgKJGa/xdeCK3OVQ92U0O9AfdKhPnuD4AHN+pI5P3uwiRxQj+oEZvG/U8Hl8Gt/84RtG46oS28hfZH6s6FPgFF9QdVH70eXRxZhGhc+Up719NpvywjyCbDR3PQv4B1qK/1XarIgSyPeu5+VqYf+qdCnczIjkBu1uMIkEpuB1WZ/qPiZ7qG4gmOV3IB/rqlDO7DwPbxd9IeXHxXOgs8fn86IiNwKZHC9n3648mPdi8/pdKxdci1aDLRy95CH7xIuul6HuX7Dazpae6YKiM3wyd3s1usUqDs6X+AusXeRLDcfIoM0qv8h8LiJ+nJdyoW1Xuj0MKNqNN1c57VGrKQ== X-YMail-OSG: cTixpBkVM1nkz4z6hObULnOQX4wuSohLsg046JD3Zwgw9Ac6AFs1N1nQ75FBK3B 9lPNxthcZ084SuCCnCAT0XF0z4mHP2MuE8M5g.Y0oY8KlMRcYTgKEkXmNMREuyySmNUBB1Tikyzt 0GLcf8NFoeCXJwogtUbggKXXtOcIX_Z2yNRHb0rN76J1pZpaNfwZX54JIECQ_.6BMiw1DibMYsTx K33h1DvitlDFHup4QWib40sNZiQjFHuGhZU2fCV0pG3VUNOf53Ned0WspS8aARGFT2Lun0ztoSpt O4MhYpTpoSl.VafcZT3K0zHrhNbW4xjvh0d.RXdtcrqcxLk4KfeCmlUnLAm7dGIIwfsZK99ZmB0g P29_Rm0yEL5VQSG5iORfVZ.JhnvKsMDOMeG93yoluJzGkPu0M1r1ob4k_JyVvyyDhYQkyPAjk3_k j_a_GjN8GDs1TqtE0DdPrJnSUrQywgccR9mtQn.t5i2BaNaJc56QWWv8QPZXcnXsGCtZpTfmclJG YeFtblb0j4ODBHmIV9CvAEFFVrx6yPVZoDjcAkjOU67PYh_vj8z5kJDevSX70PqKJSy54hyx6IIK lVDQsqbQpH63KSptDuc9Yy237rQA_K7M3aQ2qFwbv479IlthB0CRLXlSdSbnTXr0bVvA1NefXkQT UrigMHiQ.QEijAxO.0vIqvZESPnyxcTj1PWixpZZidk.9lxNrThn.uXeOzsxhydzEV6UKhy.GPFU 0Ro7g6RGhUqDIZwgORItHEG.MBfJHhyuqlxgrWLZRHf_lsWVY6Bt5sH9j24AG1dYkYjgSpeX37_6 uWVPInylqvw8RVp9__lUveSsNVVzDhfYuThaBclp8aapaMI9UH1IB9shLxO4NSatBDIaYr7jbKpi Wlz6bD5sbfFZw13FAQbeZQe0xBkJZQQoOQiH5z9gZUjnO16Et4dyUOHkHLOE1TgxNpqMNAwEoxZc R3Pm.L1fOfYsNDj7BcLLEwBK4jNPh1Z3mt06xswmeCgIa0dNbHUQY3ycE4iyuh37PBRUFPKWOvqx WhpP40t1MORx4rQDmNUm8F04iuem5VAq5OIh85KMWx.YBEw2QJI8ZwhvPBjz8ZLvENlAhvgImRDS XwBKhPZOIZRin2rQAR6GqN0FwG28skKsEIGfOaZ0MnXxFD1JB4zPFnTASc6_T9lj1KFx0G_C1CjZ HUyjHZMoFlP57hXWYRp0h58DKF1LHLFKnbcwvTiw1ojRDwugk73mlzONNMEbQh_H_Y9.si1Fh2O2 m_U2_AGS6gSPpTtBc9NjcgHgi75Tj0vuOsBNhfDYpNNHkJgXSP0LF7FodXO9oT2XiwDYLg6k3EyJ L8BpUJIuY8s2tJ1o1kTM0Ak._JRSb_MEpfMBxupj3TxH1F5H.g7EHHBj_zobeoor3V_C5pwHx5N7 oTYyvKfEWgpOYVQzf2qzH0Cl9vc12IbYHH_6ugX92Rcmk7lgdsypCm_eO6iQvZq1EyF_l Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:24:51 +0000 Received: by smtp415.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 33e3032ffce284febc475e586577a65a; Fri, 24 Jan 2020 00:24: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 v14 10/23] LSM: Use lsmblob in security_inode_getsecid Date: Thu, 23 Jan 2020 16:22:53 -0800 Message-Id: <20200124002306.3552-11-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Change the security_inode_getsecid() interface to fill in a lsmblob structure instead of a u32 secid. This allows for its callers to gather data from all registered LSMs. Data is provided for IMA and audit. Reviewed-by: Kees Cook Reviewed-by: John Johansen 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 9ad1d01fbbe4..a3426c002644 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -409,7 +409,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, @@ -924,9 +924,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 27257af4a8cd..6771c8c83105 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -425,7 +425,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)) @@ -435,8 +434,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 78185ddf232d..a4a1a7cccd4d 100644 --- a/security/security.c +++ b/security/security.c @@ -1386,9 +1386,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 Jan 24 00:22: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: 11349463 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 E8DC617EF for ; Fri, 24 Jan 2020 00:24:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C255B214AF for ; Fri, 24 Jan 2020 00:24:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="Moe4VIMh" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729860AbgAXAYy (ORCPT ); Thu, 23 Jan 2020 19:24:54 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:35287 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729690AbgAXAYy (ORCPT ); Thu, 23 Jan 2020 19:24:54 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825491; bh=t5dx8TZ4Zg/o/ErUFBiwR6wbezggb3MRRfDYsY5ZhvU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=Moe4VIMh5n5SCmEklrhGk1nfrlM+QCQ13a552U1qP55lpFjVxY383WXPyfmUd7WklBH4taLOtaT06csZ7dUsh8hEcSqrfpchuvyiwhpwr1qGBFKjkbe0AQnrToGITvM5AL9CbuktnRzSuEbtarnscvX0quJOlfhlmHAaGBQlrHW5u5BdZPXSz/X8nq9WJDxf4ncyyI6c3gBLAKOaF+tS4ktdHf7xE3B6Q6l5z43w+Pszqd5hvcU4hsXDO1bloxsWntXtLgoJUO58hs24RuVHHCmoO3mNeqqU0lca6aVKydyaIOdQ1BH8XEm5q3RiInacArOPKKPIQiBurQZJiHrD1w== X-YMail-OSG: XzqbnnkVM1kJFTn3jItq6dpm1uYOpAS1yf0Xab8rK87fJBjn_1QmZ3lNx77.LC6 DuWj65EyX9GVlD7BLConIjMiOt3Hmpr35L52fpq3qvPI4Fct7AW9EEdTEy2Lpb8Xx1oDehtvqZXo XpDD.OHNFGw_G0rahwNrnTk1FNgOBttmY8jcGDl69zm0M8r5v5Z8JnGRaC0ERw0oVWYpotZnbqaa 09TYRAcRQj08mVNrJ1I1UTFC1H9itZHLXW85at0kC_dNB8bH9BJihlTmgGM5SPXFt69zQ6TxOob9 pJiP1J.7.NigqBfeOF0R_8MRROTE97kJatGSkdaUrjZPFIc888G.sEjf8JCyP3rKbxn2hzQo__kj DB7xlGf8KYoK45g9RNBMaz_kzPadm5gxD_SD7mh0DVwEDrGAqcH0885HaVIiliB828wAmmv3bhg0 _jKHAeuYNjE18DiB26ADQl3rhCWiEozbQhZYreodSgZQR.cts5KChJsiFHuaY0EOCWeVNESFKBvO jczU.2jXVVRJ6TzL3sxLIUSOWHNf9C9fL71IJEPMstlx5rPGpqs0cDrkKnsFrRobv63yf0Aq9VqW W7x6ewyy57L5NKIq0b9dS9lt2Wq869.6vzZE88B7tLBq466pMqknJ5P.s2v.CFsipnPGu._g7auK ZZnonPAaE037BRZx3AcMZEi7_5lHu9_wmmND1tUugoCgQZle.uZDizgHA9kOIhYwSrlruI5YY9Bq 5bLQFPL40LphRrbkQUkObUlWllWNT0omFYQKtEiy29pJs2z6ErYqwWaeys0ZhxXyZ0BYnqHhZcIN __6T31mqa.8LoCtaZmOsbgIJ_G3Skbx4RkBZ1ROSZ8f.OrWo2wchY15SYVpfrQjI.CKBT19TdfQE bzYKt1LCRrMofFGFpFHzt8xKe8QwSxfIcRB74PuQ_Hs1awlLQWmKJz.PWiy1JYWlpJ9ORBnjLTnX KdFvCUw5N_x8F5JPCjLE4Lp2ag4Y7x7WXFQ5jpAY5op6KV5YQ0kgj.jd.SOhfV2.jpmH0cEB5baF jiOlOKZ1OBZcdYBfSO.v2C2RzM6izqXyiBFRRRT2pcypgpntjId_Btbdz65OUOqiMl8QibKiLmYW 7vVu1D3NxteMng0fHONA55f6cGNQFFaM_YeIO7hDTm5DmtXjuVKIduWkokQMCB8MlIoAqlZcr3rZ fwt6EAdrbLkzoeqjssEHgJGC.G0Uf4vQcM6L.uxUhbeRupGfj5dVxigzg2g2U6a1Wd296yOeAI8O LK7xYvAJldSuL5dSZvZ1HcTSItMDr8eydvVXZ.jQmQpxYZfmMns3lfLgB3X8L.WPXnYOA3SCJKFz pqXy1QJ8AmSd5Br7NjuFuvxv_JWTQBSIuHtXWxX7w1UgwjzWf_L9KFjsyTO5iXYsiR_3QXmgqlUv EAb99ai8ITfguroZCh7ZgenpcEHME1XyO..s3wCTHg3fsor5SVyItVI9xvUtKOGud77Dj Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:24:51 +0000 Received: by smtp415.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 33e3032ffce284febc475e586577a65a; Fri, 24 Jan 2020 00:24:49 +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 v14 11/23] LSM: Use lsmblob in security_cred_getsecid Date: Thu, 23 Jan 2020 16:22:54 -0800 Message-Id: <20200124002306.3552-12-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Change the security_cred_getsecid() interface to fill in a lsmblob instead of a u32 secid. The associated data elements in the audit sub-system are changed from a secid to a lsmblob to accommodate multiple possible LSM audit users. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley 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 a3426c002644..0c6d37bd43cd 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -436,7 +436,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 6ee53e43c986..69b52f25038a 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -124,7 +124,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] @@ -1416,23 +1416,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); } @@ -2275,7 +2273,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 || @@ -2286,9 +2283,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 7c4bfc051ebc..c8e3e234d446 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 a4a1a7cccd4d..100e55777426 100644 --- a/security/security.c +++ b/security/security.c @@ -1615,10 +1615,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 Jan 24 00:22: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: 11349467 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 204A4109A for ; Fri, 24 Jan 2020 00:25:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E188F2087E for ; Fri, 24 Jan 2020 00:25:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="r/Uw6t1i" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729893AbgAXAZO (ORCPT ); Thu, 23 Jan 2020 19:25:14 -0500 Received: from sonic304-28.consmr.mail.ne1.yahoo.com ([66.163.191.154]:37776 "EHLO sonic304-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729900AbgAXAZO (ORCPT ); Thu, 23 Jan 2020 19:25:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825512; bh=1D8r3Dnj/9NK4aDU/fcz4TTruvjavNXHm1jmWhMDoSQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=r/Uw6t1ifv+NBhCqRjpJDFNZwY6xpflTGqS0b+BWPoSZrSNKX2Mip+IMw2dW5osb7y+NLo2wlqTG2m0TGV/2ZAoULFd25qXHlZZzYWX5f41RZWyZqpKIDc51TgJ0KLzjLnqhJUQIseaXKlSN8gy+6TaLfmwZ3sfXvhCbXs3uPcEcNXipf0I9yzuf1hlSTVA3ghRFkZcUqSW5SFO9QH9HiKOgAfPrS7+Zu7+pfjwhAF0FyCHx8YWwlTjpmdydfOZJv+tdWBxK40bTbdoUY9L/LT20AoqQVfOy7oKK9w1jesswgMVnnmywAzHrXo11MLoUTJ0rN7aaXXx1t4pq71RAUg== X-YMail-OSG: o96SM3cVM1lPYDLbCgpq13s9nC4lwFdJm3Nii7_JoPSjwSUN3qFHXoBPC4tKQFR AxM0sizIGFITdYcXTnYE8W7eqfxgzhk2h7mBpi8xpaGIAxsmDK6kCoLldf6Yw9vUq9GTUcY_dyhQ f0GLpN7.Uq8_ABkIOCYO3bDJxZoziCcE0cf.g1bADJIqjkynZg_K2QlITtMA5DIwR3hPB2jNoh_6 mmCUiw_gfSzEkd5sXK5z.Fwih1kCYLyvelHMq7H8BhKo5z6zfZmeNgZazTwPPni4sYHfhhZmGcbi O0y_HH8VA_v7_uJvQ5ORakggzhrhT30boysxOXG_IKDHC9tdQ0wjkMJnyfQ38X63e1iIln8mvA9m FFFyiCx0hEdJbFCCl0dMRXrEm2rdUCF3RGnKZAjOFDPyXWl4THSaKGqJVA884CyLDm.cp.nPwNv6 CfP8ov6u_Ap0FdF3cbVCtDRGfPWw1SClwi0pPOKp_X43W5oRRrwyWKh4M.KVMX9aEPPrTH9Jx65X HDTbcVats1XT5b6DLfTYfaVo8h5xgcDY0ImW12ximfayi0_sWxNv7Zx4LmSsBMv4riAuJIqD3Ghq sc2CSuYtkJtX9sy0E4y_CrpCE7vG1JzjXSoWMGsd1vQ1D6A85uXvw.SpHFWL3LgoOfUJVZcUXHst 0Tt7B_EDzGca3ilqBvoQdRykFh2i5fQV9NwWu3r9yDI7wJnzuQeusW0cZw18FkeIJ2QF4bftSK9F CqnhTWmA4C3W3CdTHtd6qP.2cF0UHxn11F3ZVLQyUhAsxySKa349OodlCO.6SrOAlUF7sQYbB07y luDm2IGgVctvM8SttjCrX24t9mKk0C9PLr1wg60_bxlsStbeFByBM_uqWcRCOPWxt.zPdzHu7OE6 80DEGZBoLnw61RjhNazz7mwrVXulnf3FXHs9uNAAs9KCGvCT8qCRDSaXw1HgX7m6iirmhrOmW2JM zCHR.kDdVxXAxV1Pd5iEx1t1OSG40sIxDSfQ6MyPYAk_c.1iPTGR0FgtGl3h_xi6nfrYknggNWOx nPuUnqRbVy2sWsAxgcgnwmStczdJ6ADGvnbdIrnEt7DQjeUE2.w8ufdSvgXLzk5ukRkkI9oOK0OP ym2kZPMzdTVvDlrywW5F8sFiCpqfFNsOybr7J_BsPOMM0ZbIQJoAWek.lTP0NOpCvaGmczRGg2hB mnAjegYDw5yDNx6DH3IoFilNfrficujxAPmECumhQycdkzL_f6OtsvlvakIHCffvyTBF5kjtvtmi QC2UhbnywTP0Kq4OH_rdeh81n7dJHmL24SAfdRSLqo80TNzDWIIxAAMOfhi95qYNr4pw8_blNJwf 0D0crs0YSV9FWEflZIzbTp9UWou044e6J33Ndcc7.bFlr.gvpnYzbBH9aFk2oCiXJun_AzJlMedR GmO3rYcC5UEDllLjnwPFiJLKmBbaop.x4bxWFmdlaTfgoQUrxbrEltIbqWiYj2dZZpF8.P3_Khg- - Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:25:12 +0000 Received: by smtp423.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID fa03a9a6bb2ee60ca432da5cd71a54a0; Fri, 24 Jan 2020 00:25: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 v14 12/23] IMA: Change internal interfaces to use lsmblobs Date: Thu, 23 Jan 2020 16:22:55 -0800 Message-Id: <20200124002306.3552-13-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: The IMA interfaces ima_get_action() and ima_match_policy() call LSM functions that use lsmblobs. Change the IMA functions to pass the lsmblob to be compatible with the LSM functions. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler cc: linux-integrity@vger.kernel.org --- security/integrity/ima/ima.h | 11 ++++----- security/integrity/ima/ima_api.c | 10 ++++----- security/integrity/ima/ima_appraise.c | 5 ++--- security/integrity/ima/ima_main.c | 32 +++++++++++---------------- security/integrity/ima/ima_policy.c | 12 +++++----- 5 files changed, 32 insertions(+), 38 deletions(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index d95b0ece7434..96b6662ea39f 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -205,9 +205,9 @@ extern const char *const func_tokens[]; struct modsig; /* 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); int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func); int ima_collect_measurement(struct integrity_iint_cache *iint, struct file *file, void *buf, loff_t size, @@ -232,8 +232,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); void ima_init_policy(void); void ima_update_policy(void); diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index 610759fe63b8..1ab769fa7df6 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 @@ -181,15 +181,15 @@ 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) { 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); } diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 37f540af45bb..01c755a242ac 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -54,9 +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); + return ima_match_policy(inode, current_cred(), &blob, func, mask, + IMA_APPRAISE | IMA_HASH, 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 c8e3e234d446..86cc1419587e 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); 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); } @@ -575,9 +571,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); } /** @@ -669,9 +664,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); + action = ima_get_action(NULL, current_cred(), &blob, 0, func, + &pcr, &template); if (!(action & IMA_MEASURE)) return; } diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 6771c8c83105..227993b8422d 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -380,7 +380,7 @@ int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event, * 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) { int i; @@ -443,7 +443,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, @@ -487,7 +486,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 @@ -500,8 +499,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) { struct ima_rule_entry *entry; @@ -516,7 +516,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)) continue; action |= entry->flags & IMA_ACTION_FLAGS; From patchwork Fri Jan 24 00:22: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: 11349465 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 06D9B109A for ; Fri, 24 Jan 2020 00:25:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BEACD2087E for ; Fri, 24 Jan 2020 00:25:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="gj3lL5Tr" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729927AbgAXAZN (ORCPT ); Thu, 23 Jan 2020 19:25:13 -0500 Received: from sonic316-27.consmr.mail.ne1.yahoo.com ([66.163.187.153]:42616 "EHLO sonic316-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729893AbgAXAZN (ORCPT ); Thu, 23 Jan 2020 19:25:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825511; bh=pFBdkoTTn2iNs67+Pwg1C4/gV1dQ8/C6DKJQQw4XeY4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=gj3lL5Tr1FoSNvU1JEwYq+z5hdS3fFQ+0GR/+H5iAhZ3PHbXBPTC1kVG156NjyhLzZfxL3+P9STF9/dOhvmmAvUS48YKBwN1hte734SAs6gWF1XF5fc9miTj4jBFc9+AelF1fHwMxkVF1RvLB96OXRulKwNhzWddEbw1Ao1xUmcIM8YDtrpsGT1sGF4x9jkdQtH2YuD+IRm7v/8Q4LadIgVLD5EExuJt5F90IO1qbqM61ejn55zYb2a4kfNs8Qb6c6GmePyEgjE4gL8pIMBU0Z4ASYZehfSIYvgpXTKKksL+x1+BStQK/qhGp2bKxDTv4lQGCDqfX91Q7RIpVFM75g== X-YMail-OSG: 03V4izYVM1kCiOZJsb8rLUg9Nenjr1phUckvyfk0SsPhtEoAxqBJrHTk16SvJeC xqqJ7sDWRBk_I.DzUSfmi7h6Uu9r9Ntv0dtw5gwowYeSEAPX74un9PsbWJDr9a0s1eNPG.0eX_yX xRrKNJ4gr3wT7S4U9FhAlY7cxRu2XADw0GJA762vsbOBBg0K8cO9zEM8WDrqCV_iFzXEiexbBiDd qVulVV8TGEomdf9uRwSZDdqoPhW8wHAfaB_H7ZvN7niPLFdUlf5FgbpFkaoMOVC3OOlQlaiVHk9K jLHscNdr.12IPNG345FbF2TI.Q41sWGjN4NibawI1qLLVK9zTf1tRG2opqn7HDcJWloyKn6m20HE NwMt0B.Tsgw4Px5junTzzexcjtyci8UFjMAQQAwSuIGG3KvoSuJJeO0fSQbe4MelTT1OftXQZp1l oMTbvBH0ZWf5Ob.54wnp_vpAm.ah.Qt9hbzLlk3zkuOpS9.lJJu1QL9IuXvVTqWeVWs_1GgSnDmI NquLPLQ9L0rv0gYkekhHPZ_2xl7D.INUQ2lxrNaAW_Quri0BXWPHo1TRl5JWwunXRUFTK_g8Hx.x cv_S.NvsP4VzGG4FH__VajmrMAnoOsj0r5mJj_p61osn3vX5NiIupMH6UPt90TGC9FQyNHckbuXm _E1i7qZEmklat.PecmO620qfN6PDMBotwT67vhCDpRvhmswnxMSVYJi3ForcxvyMg536KLJZ50z9 gk5tNIlHdiaiuJNHN7pkBMvT7YjqzCFKOVLrAaezRlD64GoA9IXjrCjqtJxvJRaOmSv3R2w6BRsZ p3XbufUyaPEIkfcFFS9gzok70ErKkMWTr2svvcHPVI3BC.6qiUKyVnjZj5Cl56_s1X7ZDR54sMdD On6oP6PGFpTBc6OXZIASa4I_5IUiBoz0o1J.rfuWEUrqdGUfs1AzQg2A_FShkHMkUKDGv0Ud8iEQ 19mlLNJh_zjn7_JvUqZxHSK4W8Cs9n2V_8kQRQzSMO8EJVAvoH4qDqy9beG51Am_fMVzjeMhCscA PBeX9aPCWwEX9DXbR7q76n.88Yi5oM4vcyBQlI9u_3sDOlRWm8zmG.Q8dnErX05m2.iHqKxG15z2 je..IK0jNHfVhcTK5WZinpjcpyYVQX9AaTs2x9lKWmENflED93R2gDFQtVaWjtHzsT2ygDzOLq1Z rzhgChJzqWhikEXqX0z8qfVtKQpUh0VjOduU6tatV2li5sDD8gyCNMXSc7mprTg28dtB7..OIn0P HLGmHz1HqN.XymH2EOrL5Co_W6yxykkgv0EhqCB5x3Z_df_l7mXQEyQlM4lBRyMboujmCqrYmWuU FgYTAsWW5C0LZwT_ocQgB3X08ikMh9yqlHSseaBsJ7PCDpJkaz795UkEQVJFiD_bPJl0UyXTpaZG NLQh86P_kEUrtlnLKpnbhm4clX.37UDfigoFBNPiAhrw6ThhxLrpsNYUVaGBm4yNXUudnhMpRe0g - Received: from sonic.gate.mail.ne1.yahoo.com by sonic316.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:25:11 +0000 Received: by smtp423.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID fa03a9a6bb2ee60ca432da5cd71a54a0; Fri, 24 Jan 2020 00:25:10 +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 v14 13/23] LSM: Specify which LSM to display Date: Thu, 23 Jan 2020 16:22:56 -0800 Message-Id: <20200124002306.3552-14-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Create a new entry "display" in the procfs attr directory for controlling which LSM security information is displayed for a process. A process can only read or write its own display value. The name of an active LSM that supplies hooks for human readable data may be written to "display" to set the value. The name of the LSM currently in use can be read from "display". At this point there can only be one LSM capable of display active. A helper function lsm_task_display() is provided to get the display slot for a task_struct. Setting the "display" requires that all security modules using setprocattr hooks allow the action. Each security module is responsible for defining its policy. AppArmor hook provided by John Johansen SELinux hook provided by Stephen Smalley Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler --- 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 ebea9501afb8..950c200cb9ad 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2652,6 +2652,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 100e55777426..80ff19ba62e5 100644 --- a/security/security.c +++ b/security/security.c @@ -43,7 +43,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; @@ -438,8 +445,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. @@ -459,6 +468,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); @@ -588,6 +598,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; @@ -596,6 +608,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; } @@ -1551,14 +1572,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) @@ -1955,23 +1988,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; @@ -1991,15 +2111,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; } @@ -2009,16 +2129,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; } @@ -2026,7 +2145,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); @@ -2151,8 +2277,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 97f2ee6e4080..b8501ca3c8f3 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6323,6 +6323,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 7db24855e12d..323da8a38c43 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 82cbb3eeec76..9737ead06b39 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3518,6 +3518,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 Jan 24 00:22: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: 11349475 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 9A3FE109A for ; Fri, 24 Jan 2020 00:25:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5E152214AF for ; Fri, 24 Jan 2020 00:25:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="c64YBBqO" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729904AbgAXAZh (ORCPT ); Thu, 23 Jan 2020 19:25:37 -0500 Received: from sonic304-28.consmr.mail.ne1.yahoo.com ([66.163.191.154]:46520 "EHLO sonic304-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729690AbgAXAZg (ORCPT ); Thu, 23 Jan 2020 19:25:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825532; bh=1l7UrZs68Vn7NY3/4Z4esp6MR9vnIHN0tYCPnxqOllo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=c64YBBqO3TINs7Xj+KWUWiQFoDHr4UYdK8o3EmE0GzqeEBw9jRe8E1M5jblp9EpuK56JYvjwCiXyUbC3BNzXM1UCoyBY7s2pv2h/0SNkXDF/vZJL57pGL1IXVl12676uqlgG8Sdl9wowWa1u9We2UVf9bUY2OBNp2NBs+XWT/tbzUVutMya8DzFoq1rzHCTyTKnLAITcVZZokmKtB/FcGclyIi0+oNeOKqMVPQng5daz13XCD/mGpiKlD4/966c1L9+a5Tu7GsLuE400LNMqPGTZ/Z3OhP03YR6Ke+fJzsO5m5xDF5GXy1hnmtSPcQ17WaIR/edbIyj6i6+Caa/cgg== X-YMail-OSG: Jk99bMAVM1naiy5XWI.VfkwnrpC2wZvPeT7SJvrrnVWpVbMkusD4ktci3crVFMK qdCIamgPHz643fVMHfGgvcd4O7WWstDAVViKHy9fWJbBFO8JewQCUp1gFnHny7.ay45Yj.XdELzN ppP8UXjciKJsmiLu7p5mL2xwWcMrw2bLMqs.bixWbGjLLFIxIEcJckr33XPYXVkihDTWHqDd64jw IzVIp8CpDmm3dcdNlLh1F8oVsY5sLOt8IOQEPdJb9LOGztcpcOeqHKDCjozrsn5m1okE_wYloxK. 8qWNT2ZZda7N4KpJcPUOCD3_Wk909g8vWQbMijtEhy9WCu0ay2f.BsoPz_4Ay.cdXa2CXYB8pDIa Csy3q_zsvPSlcgxNt0uBU.4N4diwCatQKPVEK06K_szdRXbtZaQgJU5DTLuc9dYGVtfmOyT6qhUq mzvzHmoYE_LoCC2WT7ssxuQeFrZUON7idb_JNW.lZsCQTcvYYZoC0xNtp3PC0eyRd86VmlNOnyxC fiqJiXkNoZOC.bsKG.Tp6_0xNTbP8O17WPcsDUVqMF44YII2ZyAGfAaZN7vLen57jiZ5I7BkydCg MQyaM8E7hHUnXo1lvu0Vesva7bx.GyAun3K6CYg3ECjSsiWMhAWi.PukTcymldoZj4Hn2sphI3zX uX9kJ_tAMQ2yB84zU5hokPkdEd6NeiPEwZ5HOrUP1aO_lDYNjj4ZVcDw67e8ZkIDmGkBE.wHjAWP h2tVdpZTJI_xqVfObWUMZaigtm0.K1WjaTRr8QZoaoIqvAml8LR.lRWpPhwpc5Vm30rW4rTC_nL5 nHhbNQD2sLGDqp1mqErb0cGOzizeAx7m4jI9aNyDJAjPWjYB8wG.S2FF4mK9o3Hr0FXr8Slpv2FN 0ofBzdCa0qg5VfQokFTS66gfCG3KnXal6sY5jimpcKvAKhFZDBa_9houDu0IKRI1unjzHrAIrbg7 RQZhZDLkvV8Sd1FYwP6JzKtMQNrwngsTW8hV5YcHjn1DBn.KaXDkZEpopjtLKqf7r6Qbs9Io1r17 9OAEO6k9A5Az881H4eUl756M50eiEUyN7dKA1nThfbX_35F3cETaxTy5_2a7PDDMm1pPwZDjWrOP mQ3ZTt2PFIVaVZRSX1iUdO.shLflKADQ2vGYTU4DKDtB274uZHO.j8hxXaQBHe69v_FXxwEJIgT6 xfQqApkKlsPW9.B75T3pD7.UqMawfBPRSI8VDfOxD0FpFzQG1XaC857aD27F0iVn6fLy3vypyJ1E X44jSv_EszfHvx6kyykkiwtcfHYgi4SIr3iV4PvtAvpD_zn5l.zmjqPFyH0odKFh1lBQK2xyllmx eU56dTsXdWkHKrmaCm2Rs0cqi6K5NfU3jSmKsmHEsdPL.R3qcPqYp8N_lyi04DMs2CFGa_5zKc5R B7_ZALY.FslnuF61EPG5Nd8l4Y7U0H4BRUo49Gj0ClN1d6veeB00xcG0hFALuQBvEMYAo Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:25:32 +0000 Received: by smtp422.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID c12684b3e67b27066256fcec68912d76; Fri, 24 Jan 2020 00:25: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 v14 14/23] LSM: Ensure the correct LSM context releaser Date: Thu, 23 Jan 2020 16:22:57 -0800 Message-Id: <20200124002306.3552-15-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Add a new lsmcontext data structure to hold all the information about a "security context", including the string, its size and which LSM allocated the string. The allocation information is necessary because LSMs have different policies regarding the lifecycle of these strings. SELinux allocates and destroys them on each use, whereas Smack provides a pointer to an entry in a list that never goes away. Reviewed-by: Kees Cook Reviewed-by: John Johansen Acked-by: Stephen Smalley Signed-off-by: Casey Schaufler Cc: linux-integrity@vger.kernel.org Cc: netdev@vger.kernel.org --- 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 22fef6e130df..7559c5d5eea4 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2861,6 +2861,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; @@ -3157,7 +3158,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; @@ -3490,8 +3492,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 cb18ee637cb7..ad501b5cad2c 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -1271,12 +1271,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 76d37161409a..a30e36654c57 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 d2dc4c0e22e8..e20011281915 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2421,6 +2421,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 @@ -2923,8 +2924,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 0c6d37bd43cd..0837a3594951 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -128,6 +128,37 @@ enum lockdown_reason { LOCKDOWN_CONFIDENTIALITY_MAX, }; +/* + * 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 * @@ -498,7 +529,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); @@ -1312,7 +1343,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 69b52f25038a..3305c4af43a8 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1180,6 +1180,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) @@ -1424,15 +1425,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); @@ -2061,6 +2065,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)) @@ -2074,7 +2079,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 bfa7f12fde99..cc3ef03ee198 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 80ff19ba62e5..9ed550d8221b 100644 --- a/security/security.c +++ b/security/security.c @@ -2143,16 +2143,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 Jan 24 00:22: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: 11349477 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 B515917EA for ; Fri, 24 Jan 2020 00:25:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6C482214AF for ; Fri, 24 Jan 2020 00:25:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="XdFhxzYA" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729631AbgAXAZj (ORCPT ); Thu, 23 Jan 2020 19:25:39 -0500 Received: from sonic316-27.consmr.mail.ne1.yahoo.com ([66.163.187.153]:46310 "EHLO sonic316-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729951AbgAXAZi (ORCPT ); Thu, 23 Jan 2020 19:25:38 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825537; bh=r+dPcLtZVIG1OFUObM00GaBj4hnLtNeD+Qo85lvkjWo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=XdFhxzYAS0s7YapZx9TaFGxi6NDrLv7gBM8LLPkcQG0FiT+yelH7BFRZstlv6xHG2fvGxqlZmheS0XoraO/hdTYfZ8Ig1BtltiwbVwBDETSf3tORUaAKym2fN+hgcLt4kB5wx0hfUyj4buwP9UjCP874kJSObIYcCRAiB5vdAVDveS2inWlXv+U2RUOY0A9REamtctXqah0bclGLjfuvV4j2uMdjyrueRAV/fYUtZKCW7R3VDVCUz2sytKeNjCmXHRkINm+8E8eCUtRkDnf3UJFjxX2AUfREuOaaQg+zBX4Bb0ig3yr5OYRsRetCmZv4ly+R2W1eywf5B4fM0VM8pA== X-YMail-OSG: DnEtBjIVM1lQeX.8zeGeaBmncT_07tb7ePXedG2Jz2H7CTO0BgmUlLVhCJJHh1x u8YqqNZaKL_vq5yyI3WI643DxXPbwuIycmIRfDw2MKtn6w4Gi1.oCJPGB7YuHLHUXT.lHgSA.nNb oKAlIN7FtQszXv1bVsPDv0WJONktG12uzv8w52xKYSuyVYTgXIobBaP5qFsiWTWnUlC2CxdGzw1. CSs5Z5aZ_KOBYeNkqaB1Re.J6hfnWlQkLuDSVU7Kct5FrAnHglJgkQU6rzic7mKeIaP1ZcKBmWp0 hM90SlRAaP5AdaJpkLfQo13APQW5iOxsoPD1Lsl38s2StOGexkgwHV0XsURKvMC6X28mM9PDk_0R ROkGHWIRSV5VK_eeAzSExvxR_XXbLxyuHLn8AOAEUK.b5fbKIaiEPBZ9wILCSC5Sd.4GoxB.kMZ8 _hFplM3Xndpbk0gUTCpBA6WZ_UwvY0o3wsgTUeOmRKptoHELgtDdeIUbFEjmwBUv4OBPsw3iRX4F BN6dhPzSkFOa.0jN7r6oULWwz9eY1R7tPCqUbgClgbWcQjA0YMecm5NnbjK6DeUjl6kAILVqigZf S3FO9BeAa.HEynNN56LkYZgaxnqtTDwQDL1Eee0ZAdpk8hk9IscaMMaBmqMCSn.FUohXv8ujVEsY xtDnzmlNWexdnSeqninYDw518UINRdmg9vcobhhSMaMYesu.MDXDIS9WjSKjf8Ol7X7OsE5HVO3G YPaIXzrTUtqYysHPtkh4MfHMHE0wk0mLIZOIHGQxjSkoN6lRX1944lGYeAl6WCJ8d0ZJJ9xABJUc .rBnMROvBBe0IgB0Ck40av2s.FXVO.wg5nnV.h7zcx8wjkZl0QFsQyRoY4pCHbRAGlSXTka4DUDl 2XkQz6nL3zVT2YctUaptRxyvDLis1RlA2tNqIV4YjmebgGVbEmzEcIxs4eivTC77D5.GQ8Zne.Wf ZhvNocOtsROoz75mqRbYSi8dxWF.0FPNiOOxoLmvCz4VVXr0HGC6WX8WVxNPmwYINWX42WGdy24s lDC_YrfAaHSiTZKJsIROX8e4JhjzogUL3MDnEpQFkTHj19gaaryy0BgYXMOGSqieeVpeOKIR52QS x5Fi.j02QcnjjeawBl4dzFOOYtGgfO9NI8uOPRMNbZDGgC1mU_C3ycrDY.Cwe3BMx6ljDUruhfWc 4ptzhlchJIrKhQ3CSO9oTYePmulqvDcsoAuOYCyrz_vOSoaq2o7etp.Z_9uLT9Yg0L6xCWgr0db4 RsDydsOgtPbYiJC700zJHJShZKDB4A0sFb9epobjFqSmnIlYnP_fiXiSWLu1XnkR2gVg1qSeiG1A mlVCwXvOqFAa4SakwLtr4X7DNIP7Fs_7f26H.MQ5EuDmwZeNN_t4365xN8fTDQwtXikrMnWFQVkT HAHMPTYxaZIEC0Ijpcj0UP5ktIMEyXA92r49HUsvkCiRTCV21kfEJNHFr2RBq Received: from sonic.gate.mail.ne1.yahoo.com by sonic316.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:25:37 +0000 Received: by smtp422.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID c12684b3e67b27066256fcec68912d76; Fri, 24 Jan 2020 00:25: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 v14 15/23] LSM: Use lsmcontext in security_secid_to_secctx Date: Thu, 23 Jan 2020 16:22:58 -0800 Message-Id: <20200124002306.3552-16-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Replace the (secctx,seclen) pointer pair with a single lsmcontext pointer to allow return of the LSM identifier along with the context and context length. This allows security_release_secctx() to know how to release the context. Callers have been modified to use or save the returned data from the new structure. 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 7559c5d5eea4..463372198099 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2859,9 +2859,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; @@ -3109,14 +3107,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 */ @@ -3143,24 +3141,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; @@ -3216,7 +3212,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)) { @@ -3492,10 +3488,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 0837a3594951..1e817130c112 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -526,7 +526,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); @@ -1331,7 +1331,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 3305c4af43a8..f67187a84cb1 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -1178,9 +1178,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) @@ -1416,30 +1414,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: { @@ -2061,26 +2055,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 cc3ef03ee198..2d6668fd026c 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 9ed550d8221b..24e99716f6f2 100644 --- a/security/security.c +++ b/security/security.c @@ -2108,18 +2108,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 Jan 24 00:22: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: 11349483 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 3DBF117EF for ; Fri, 24 Jan 2020 00:25:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 18FC521835 for ; Fri, 24 Jan 2020 00:25:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="a4JPyBmY" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729690AbgAXAZy (ORCPT ); Thu, 23 Jan 2020 19:25:54 -0500 Received: from sonic304-28.consmr.mail.ne1.yahoo.com ([66.163.191.154]:43638 "EHLO sonic304-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729413AbgAXAZy (ORCPT ); Thu, 23 Jan 2020 19:25:54 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825552; bh=vJqgCjIqmAa6l5Qj3Nspn+XKPoD3RLjhS2Uvr/qQK1Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=a4JPyBmYjDEWNvowUZO3mxOzLMbU+JYqlgNaogl3oXIJ+C7FSrw4eRyDSmxzmlwLTHiWn+DB3JeaaUEq9WfAVmqmlTf8wrfbRG86s0NgTccyKByz+aCtjctTCSqSHAC+Bs5wcS2/EQA5BC9KPlXBeQhs6qdzmc36Mzs760XKGOpfY/RQXB+rzpGLwAoN35rucXnP230ELMYPfECa8byeUcStLf1HqcdYQjKtMFWFNWclegykPqzRpKIy69iZc19uwuxHFZOVmYq40PcL2lYbxIj5gGY3dxrzFv/IK/RIzug0vIYUmGYXeoRwkxPAztm4oXPhsfhWjyXR+WU0LpJ/aQ== X-YMail-OSG: 3ffwoWEVM1mz1TiXAD38i0R0zCu4kDkDO7Ekb1TcVPe20vFRSnvLvB.4Vq338L3 XqOtQSTrJ7lbfx5ynkFbZ7HHe1RDJngWYCPOFzqRj1p4SzG4lIIXUt2yoe1aFsDR22kk80caz7Px 2FJmFAK.N6G6qTtuUcUF794iX3eANm_lo6Sle2n6k2vY4U22aGX3OIjnvi9dj7Ptp_pX6GQ0mPUl EsasYWBQLcM6yXfczTbFCX5Oyang3Jk22ubYT51.B_edKUnFUyQjyf4MT8TwD8koUrVLAJyOkM3y mnUr.QpDfEUlT2m_EtkVBMiw_Ewh7FfU5kyGa0TtyCzKATBN2ZAd6Byrappuabd17LwUPOKQEY60 bsZxLsxVG3dgwyf80LmqZxJO7DkpxErR19VnNRRKkMwqivB400OExeEAvcVjGYxPz0pU45CKkMXg nfyK9IxohpEotbYvEhAQcKqPfuupPuyzsbNlxowhDURrI28bEosspIIpWMjKsMhiECa.DpzGOTm8 gv7MzCxDXLSlFWLKdrEp90s9uS_bmFFb6uHCQprIlBFlCk55Cgc4Khpkx7aCwzObjVv2GM6QD1Ly 5ECl7SnSwBsWnzuptBmbYjWD19E0Du_YU_zOJWuR3.gnqoeY_pkZHGQ_4zCgHl9hpkCflGkNDTkE r250033zh_Vwy_u0aRvqBt81vRBGc3ur1oY8za.3CLiVFfkSKFS81nNqRT.4R25zZHkxwTe6Oaw5 i9dJhbadL74awwjQB7D1sz6LnRqbA2tc952t_a6YfmCJ5i9FedzxUI28BcOhN.iS_yqKqLW_VTpy ItibY_P.VNFHlFPKvAqa9aytU13fBJc9AkN53Fb.NYDEa.yOzH30x6k0VDx79gondf3kkK4MLhei rQJPeHYJdGAs9VOOdoP7q2hsznXPXAmRApTgFaz9VRKhpnTgEimgtsgSLojC4VpyXK0ppNDvhIi1 Q3AfL6H08VVI.QIg7yTsbk0.wkKgVTpXB_2nM3jY0ZgOBs3sO7gKGUYAi2UBevPbpy8eVhz2rx0y VbaB25dXm5Kt6UYFeoBpEwd5XyKxn98vW52x7EpgeJ2RnkSPF9QoIRE.SldWAkiKr0ZmoYHrgLrn .OfAxdGOl8damJCwpkytUSWU3SKpWEbouTSkED_j1.WZ3t3aAHNHd8KooMFnRYVPyApoQjscVZlb PPv3DxBUh6FdOy7a1YRDaXqhgXtpbY4yrMi42gkleUEu4JDO4LqBcVrfgpn8TQ8x6MLUGFxanEnk sBFNs5Isy.9TS2421gd1Kn1fcYElbUfQgJUqCn9enTveX8AA1evLaj1P9YY2C96lPjG3Q2igTsb6 ACU4zzWemqkGNenvFDP9u9.RM8NSM6U6CtFXGdb6MSQEqO2pzbeBBmSK4kbtv9m7cNXkubTgYelJ iUr6Xu0bWQTmB7CAQsheO.Nv4_FmdA.0gS7aLRAT0x0pLolmHnPRTcNx_hL9Z Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:25:52 +0000 Received: by smtp412.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 41a84560f838fac6611e7b28424c2970; Fri, 24 Jan 2020 00:25: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 v14 16/23] LSM: Use lsmcontext in security_inode_getsecctx Date: Thu, 23 Jan 2020 16:22:59 -0800 Message-Id: <20200124002306.3552-17-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: 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 e20011281915..98d20178e60f 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2304,11 +2304,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; @@ -2318,13 +2318,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 @@ -2421,9 +2421,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; @@ -2481,7 +2479,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); @@ -2911,8 +2909,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; } @@ -2924,10 +2921,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 1e817130c112..f1a6c9ba907f 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -533,7 +533,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 */ @@ -1359,7 +1359,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 24e99716f6f2..c2e5350e0f63 100644 --- a/security/security.c +++ b/security/security.c @@ -2179,9 +2179,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 Jan 24 00:23: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: 11349487 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 4480F17EA for ; Fri, 24 Jan 2020 00:25:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1E79C2087E for ; Fri, 24 Jan 2020 00:25:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="nmWEVCpD" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729413AbgAXAZ6 (ORCPT ); Thu, 23 Jan 2020 19:25:58 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:35014 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729996AbgAXAZ6 (ORCPT ); Thu, 23 Jan 2020 19:25:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825556; bh=AzN0Yrc5E2uiTrmC3S4nLoRQ2OaZGi8GU7FIVIM3g9c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=nmWEVCpDx0yr2Tj5j33bUBGAM/0K9g4ZVyyPUzwqFN87UMtHP33RytgTsnk2kEhPbTa+x0PvGJoJ+rm67JAqZZmfyBGJGjgq7oGnBOuRYDRu4FcatytbtuWAIRaJA9jZBggtuw2DLbgTvvaQ0KM1eGDVNBSRf9tTOCqYc7NeLTm5jypomKAuN386QboJYBOZKGuHsmMD19ffz9dWuiDu71UPiAapSfU6oaTrr3ZjzFrAs6c1tslxbK8l3eeB82LYDtq5Vzl4QIikjpVtgQY0myGDUE8icZjjHbCCpR0IipGqq3+h/4AHMPRwNDUIyv0adWg4kuzX6zTjqX6osLaosA== X-YMail-OSG: wI7mK6IVM1mE8beoFpyEGNuM3mzu4NgL5y6cvsmHdwDpRE8DiPIoJ9lPpJWaOwX pWVUzgM4i3knfltM5AnIy.U3gUGRTO4uA5NwEzAulhoBYOi84RqXy9sRXnJyKXokbC_OGSxlZ1w_ nwYNT64a6JMJ1uyEVsDYr6crOJSDesV_0wE.Bi9EJXWUQVbmvM5q065IVoJ0B54LJ0MZLSnZknAC EkEfZ3g7DWL28vjDXgLJ3nnSW57RB4sMEQSUVyfdOR81kHHlRdfS0S8lrPpd._g_oYZsP_7fe5hy 9rKLXGkyFbsphEL8tlr6anCuTrLr_SdPK9tRjf47N.PD2Lel7aK8LGxxmOl4xSWsAuIOikB7l3P1 mPg_.IrKWG7GaI86A4CE_M6DedOpOyrp6cPVgqGK6C0NgFh3JUjE866_.4Vh5chN5baU8G6aTVK7 LGFLXMNaeYvu_REHiPLJESWQ8vOoxJNXrPRpT23DLxwzkEEnaNX1flezckaQ6ORhRJY2qGWW.30d iSrSSOr1ccaSgJo89vz8X6ZDHPdvxvE4vCIyuO3ozS7YIGpCNdTjayTkVAg6ucthnJNS4jAb9wfg qPdO8aA1fanNwZVfgVJWjJoDKvBPdgpeGSf31020eSDSWJdb.qLiC5_6FxgrRP47crjQAO2fgLXo GbZH4i__RRU4HAeCTonGTFTv2NzeN7zroKww5cU2xhO7JHnFuSQdXyVNvxqdHq.SpFeoeSQG1ZAI dVOfDfCDc9zxHfw56WN.zZevxGYTmUK1U.KgNpZSazv591AWJjDkjxKHOhHS.02YE5usY68MuQPu K0qMdl8ysOSXXYD_cRaQVEab6scU0EpAo2PdSi5_y5EhDrM1qio18RmhccVBr2qf_voUdoZMEIyd YTWDHvarwPh9WVqRuG1JBpDjWwX47p7nGfkW3TnlCPLZbD6Wf8YI_xbKTX4i5AP3JpJkb5Pgz1_V jvnhSYrful19hsviZkbJCyUcL1OZEt.cBcgDCWJ2O2LkyuBsQSZsjGQB4mK6.XFrWRGOSZ5GfJ3O qDnX1iOwXbX6_6b_QPlGGGUSHar4MQGlXxyv7qG3HQFVibjCfst9lKAW_qzTISfc6aJmnUjwj32j s0W3r81W0fRHgx_SqCDUab_0AHoqGiUUsEIvaC0ejyflVU.Kd8DbRafwkwgrG4elFW.8NFKd7i5S lynOMh6gL.p8EbYPCdOzyXqkv8ow1vO9ibszYBpLVUeQ_JPTvTLPD4vF1WZsQHKVNYRmb4da8Y.E FFlCempO51aqFmL_EMNNbtZDhqKEtsajBJ7I516XnVDzpsGoFbSi7Qyk8Xuyu3CApl_rvXsAyjp_ TKWlUpkj_IwNRSM7B8i1EyNTn_QaVKpIIjH4xZjLmsxtjpJyHPmAOBielsPXJFfqPkQSP4HsmZiR vIuxJ9v01zGq3AtEKtasltif8kbngOd1HmmsrenrLXta88CIGaxpC4fV2F1hi9cjtLnDraZ0J Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:25:56 +0000 Received: by smtp412.mail.ne1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 41a84560f838fac6611e7b28424c2970; Fri, 24 Jan 2020 00:25: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 v14 17/23] LSM: security_secid_to_secctx in netlink netfilter Date: Thu, 23 Jan 2020 16:23:00 -0800 Message-Id: <20200124002306.3552-18-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: 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 2d6668fd026c..a1296453d8f2 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 Jan 24 00:23: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: 11349489 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 B88E417EA for ; Fri, 24 Jan 2020 00:26:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7A6212087E for ; Fri, 24 Jan 2020 00:26:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="OnS5oE1a" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730040AbgAXA0Q (ORCPT ); Thu, 23 Jan 2020 19:26:16 -0500 Received: from sonic316-27.consmr.mail.ne1.yahoo.com ([66.163.187.153]:36820 "EHLO sonic316-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730009AbgAXA0P (ORCPT ); Thu, 23 Jan 2020 19:26:15 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825572; bh=gLD49wnZ6OAH4ihWCo/CcB+525DqTDJ32Ea25pA14Y4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=OnS5oE1acFM89PttKs1EpydEz9hXHRU/oFEQJxzPqmyxtV2XZ+4qnGf+GCwfxYXL/QQ8nWxRpL4GmCQ4K2kX4YVLwXJKZIllB3U8egjSXvb298jw0q6gmqKwPRNhH3kE7jdhJZP68XKwgBrBm9KxbcXFBJ0u0Cu8gDE4rla0JZ7gqqmFlXJlmyHITEs+XKJ9OyLBW7xSQyrm9LYWJ8dBE4iQz5VDEi9AqsoiN+Pz9n+X3+2piuhSEIyHg5OBShzsAP915xVQVMs3KXFH1wfpXRlk7BzTlqoBQeQti66I7rXDbrzZROivdT3jAHJl/I/2yFx+gXk6ywsfAKo3YTZm3A== X-YMail-OSG: 0bUlkl4VM1mrlshCS25LTwQUI3Z4cuZkasr4pRYmYxEqgeOFPZZ_RX06w0qobm1 CPAkSSR1sDN7cdaLSXB0893iwwIc4ttPjL7l4Hm3dZP83dQca.c5e1mSBD2HB5bRrX_83wCMOXHB XAGazzQSWfOURIziPMeXNNGtPOMV0NTihXG9HsmphOEjWlE.9OIpgtYvnTt47ckoGwERgAGqBldH N6BgwfEvOKYLd_WVEsXTORcv9fcPh6UsgES4XzFuKYQntkKU70aJokFfU10VG8_FK_cRla3hMAK2 bKpqVbi4SW1FjwTDJshcWasBNM3IZ4HUD85wuyT9zGWROKEMr_1q8MyfWbLmRZFf4by7rh3Wlijk BPDXK97IL4UR5gIME1UHvIT6lilYeZ_Fb5L8OLzCtb3sW.SiM8SHQPrRAMYHUTw2txNkWo75e.Tv dzye5n7uhEH5AvZvMRGDHxGd__4_BqwDljrXEIHhBNFJbpeTxsrrOcGRKCbTXK1Stu.8P3T0zbN3 UlR9RUaqZR1WAxr24nQ1AI47FL9xGCyS44yJqtmzenjpY8yBzQma_Ug78S4P14ivtyEVQcuZ6owC nQnwsG.naN0cIXBph.g57I4tVUr04iVObjgmjMAPH2WBpT60ifBIRHAhql8DLddWIvTp5gEVZVFl Tyvq.omBqxr.KBLiWWitinioWABfUYTZ87T7LLEPkjSehPWmrLFuO4Gn96bL1_iys5WV81SeiNC7 K3CNM4FQPZGDi2IiqkNE.oyy9KP7bhFpgFz5KCar4IK2flHw.48gJ2oXYHQbU9OeoaRHsJq6ooyV QKkuwKrQLCRUOWQwxKQq4djW41aawXIXEL76.vXjgpKBmreQ3fhrYaQX49Sfa7KKwoRc6RN45NrO nHeWX3IeZ6WUggGEh_6S_NcahHzEiswRu1gmCKe_hE8SpG5Gij.nXMEepLcdS7Clxi62T9GGTygf WKtZTBIlc29ZZ.hoGgUTepK_X0LpzFBPv5dIOFh3p7gPKHVbeINdgaBF0xyBQhAsmtBzHnGpXCZz lA6x5he3UZ8_fKjUhL4Rj0FO8fE45fvtMMuwkYd4eLAzZx1wM_6_2.FA83EcXSrx6QwVLGWER2Zg _Z_n3ob7sF16JMqxEh53oENdWwqFzw0gdR1IowFkFvzWdnEqSnRqU0JDw6IXfHZIyttsc3ueIA.f VaargeTzKhOJ84HaJdlXnNxnQaRqh7IPPCFKBS_YzrZEF2VC2OvSBV5qleGSSuw5dakIQ4zdxP4m B5Sdu6toeCy.JONVRFyvbDbtBtV1IFikhN5H.Jl8e8RRq3px3L5TTjWWUG0nt2.JORXyABZ35YtF USxrT8K1p2qghh0Kvmflufzacwy9wssUbjb4rMhPJOg74yAiFXa_iSrTxmCwiGfeJld.bbmkhxkb X3cU_mRW9ZFIhLWTMlqZeAswJwI1obDL7CdQw8_SFMDtE0Wd7zOvaG_SWveymMCoyo.ErwMSZEev a Received: from sonic.gate.mail.ne1.yahoo.com by sonic316.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:26:12 +0000 Received: by smtp402.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 88a34912a4ffd8dfd14def0eecc3bd0e; Fri, 24 Jan 2020 00:26:10 +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 v14 18/23] NET: Store LSM netlabel data in a lsmblob Date: Thu, 23 Jan 2020 16:23:01 -0800 Message-Id: <20200124002306.3552-19-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: 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 Signed-off-by: Casey Schaufler Acked-by: Stephen Smalley --- 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 b8501ca3c8f3..cd4743331800 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6871,7 +6871,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 ae840634e3c7..741ba0e6dd83 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; +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 a5813c7629c1..2b7680903b6b 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -3599,7 +3599,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); @@ -3672,7 +3672,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 9737ead06b39..9ce67e03ac49 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -3775,7 +3775,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 @@ -4592,7 +4593,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 Jan 24 00:23: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: 11349493 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 B2CFC924 for ; Fri, 24 Jan 2020 00:26:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8E736214AF for ; Fri, 24 Jan 2020 00:26:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="mbwwLXSw" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730055AbgAXA0S (ORCPT ); Thu, 23 Jan 2020 19:26:18 -0500 Received: from sonic305-28.consmr.mail.ne1.yahoo.com ([66.163.185.154]:43604 "EHLO sonic305-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729996AbgAXA0S (ORCPT ); Thu, 23 Jan 2020 19:26:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825577; bh=6/o+2FxbQlHM4gCFaNOF3UkoCGhRevq/xwDOzwpEtLs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=mbwwLXSwIT+BqvtgjfSD2vD/kXIMIQ2iYPAAz9qt3JwGCYpbrUwCOTMpbNYTKqhLLwgNv+KPrdVPo9Kjy3qRhtGOb7W7L1yrrQwOy+Bop9Ky2T+oDOIUXH/E9QMeEULOfHZeDa9rBceTVP45S26RjyMXnDKTVe9EiKh1bx5VZIdwGa7weaohLqYHazCR2h57wvb+f4PS5qBhGSKm6OMi71d+J4oBzod8umLBFk+rzjGffxe2Kv1OkMcqshnkbhIo4fN91jJzTTOhl3ea7kASnqVSzAwvaxL9cdfULyRHQIW9099KXZxsV5ZLOsVDEQFw1non2TXY0+PKkIYNv8zVlA== X-YMail-OSG: fBVJ2r0VM1kyaWjg1lmKDGNq5.N33pI4_8u00ueleX_9cawyiFGciZWLRoQgL2R ahUC0CQHlpvV7.WATo15xKNTXwQpjnct8bdNK80co14pQB.8I3zar3T53bWDxLfihd.CCbnv3Sht QIV1q04vlqfApMUi6Idqo2voNr2qV9dHEOHTc6_o2k0sMN1vm0cki5VTHpCcTDXTFky8nL09UzE0 8mKV7WwL_d4WdTU800eY6uE2U4znLfbGf7Elt_FA2hC_qR9CMvgMwfC4pLkmRJAPrxtTzMV_vxDJ KAbHAtq2.iwGtNoTEKf99Ye3dMn5Z4MTH5yy94MgOy1Ucm2kw5694_WdL9IveUe.41CyRKyMu7i2 YYE..Kpc1ynt9w4Gb_IOQmSAWpTxZSAV2FSFrHMt.Gc7tkOEDbUYoQBijHYHYr2OpdFTEgwzLQaY GKeKuLVRBsdabD.LPMgRE.9yQsOMZ30GlvjKtWKoinzO5MqPLRciQkguoMo.H.nUr.2EZYnnjUx1 E7Co4636GxvCWmrYSmjYec6Ytx5j7l_va02pBHQl6AteXVzgX7RSdaMum1pA.tZid8I2RSrUiA2r K2Se1OcSymtUk5nkmBLUSdEf_c7VDoBTW0AF.RGVtSg2iGZjPVj0cISPKIbGHviAiLaSV5jNzfn9 eYREOBd9A51x0hAyBHGAzSVQDRA6iSB1kOjwxD0T7BhvX6HLpL3h3B.a_hgp7.VGVq7Lyj9VOfvB QDWJo6UyRJXbp_zGo1G.O6TkHuvxYxdZ.Lo5cOitokAlwlRyusnkKTD45W2pj9SB_lFGFPpvBsod liaH7w3oF9UQJn8W_QAm1npUFakG8kJUOYzgKYBwbARClVinEXfBKi5va5fPu6sp9pPCl3izNueB cWoGnbRVtKQDZ4jNX4wMp66st6l6Ok.cvAk_Z_z90ywFbSl.rG4Rz5MnUNxd0A9YbVe.3v1owBVR va_mpFhdoFD3Y.ey8YNoT6sLfowHMe7HcSj4KFF2ibl6mXDoV..05S_VEakCIF4CruoTjcCcI6SD tYrX4DdEucxE1y_04jbrOVZdvHeNfQ_h16z.y9UOajM4jnUnrt59lXB.bGiLpsEIG3bRLuTdtX0k RlxG949EHmyECOItLe0.CIbNM_mulCKehx97N6EK3SvJWx02psYc14FRjBcmufOSgS16CPvnS.2s GD8vAvq6noFU555pyREAEp6sCETi9xaIrAJa0DWfjbByslgK43Gkz9FBPlyWLNkbVkv15NeNhKEI moesnnjzUx7.8QTsu4VGnmCI0xbyNMQt9f8f9qCxVUnH.bfinYNBOEZlvrOn187LXSwyC.C7ZvZ7 yzHGZ5z_OiAfSIeD.5XSqiLd4wYZsyoEAhxb4dz7fluz.h5Bos6DfXhJTvgrRVr7lTkpRmART6.g .nKJUBriQr_cpOHywPVcj3nPZjcud36Lbt47wCMmX77n4xgWnDIBJiGpfOjU- Received: from sonic.gate.mail.ne1.yahoo.com by sonic305.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:26:17 +0000 Received: by smtp402.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 88a34912a4ffd8dfd14def0eecc3bd0e; Fri, 24 Jan 2020 00:26:12 +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 v14 19/23] LSM: Verify LSM display sanity in binder Date: Thu, 23 Jan 2020 16:23:02 -0800 Message-Id: <20200124002306.3552-20-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: 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 c2e5350e0f63..6002075b4c8e 100644 --- a/security/security.c +++ b/security/security.c @@ -737,9 +737,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 Jan 24 00:23: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: 11349503 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 444CF17EF for ; Fri, 24 Jan 2020 00:26:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1E50021835 for ; Fri, 24 Jan 2020 00:26:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="Qq/9xSpy" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730113AbgAXA0k (ORCPT ); Thu, 23 Jan 2020 19:26:40 -0500 Received: from sonic316-27.consmr.mail.ne1.yahoo.com ([66.163.187.153]:45435 "EHLO sonic316-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730075AbgAXA0k (ORCPT ); Thu, 23 Jan 2020 19:26:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825597; bh=cTokApQRdku99OdMYk7hrk3N0auwHjwJeM5U+c5QiGE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=Qq/9xSpySv4Iw35nDA6JmKwajCQe8xeP3mwvCInmzdyvbTph/aqdxtBhFugnsEjjO0iKBWf4N+qB7KdUtXh8m38wF1p278tQmppfftsxq20hZphP4jebDUgMG+gg3MOMhzjeAmrTk+odnwiAP4cwZWMxNaIYjIlna3ezMjOxbNhLacSxq0TBv1DFe+781OB0QeME8MoFLUorpPdJBIlNNNatO73uFM1UZz6htmq/QyhPRu6MqaR22iQilN2+QrCfBBot36jHd0IWbSZmDDd9V287pk1nvvZP3nRgl3LR2rss05qcpQfZMzHel+Z7xFuhnivNPpdPpQqQlP9CnaXlXw== X-YMail-OSG: Rs62kYAVM1nVmKPpk3kJaVp6cyln5UC2j4cM.SPS5ZtH2BVWbWv7kV3efCd68o5 Y7jrV5_neNzPBiH.jh0bMYrOY2CyReZawcVfCPyBnpMd11yIBnVmNCOJ6zI0k66ITjCWoeFiwMwc vfN3zVywj.GiAE8B72cfaaJ0kn5grBRX7BDLTMjptGdZO1YIRBTgGGIjzRc2ftHSEeTMU76SPUd9 .oGnmY75c.MIWszEdCTB8jWEfI58gawk4S8l0NH63j.mEv63PZnJ8hphJws9WQlWxLul5JwXuhd6 EyyUr8zVgK9KenoQzBXQJWTWrdRdxHEQ_91Y.x8g9ohXIQ_ahZYF3Jyb0kPZchntrePbqcMZMMDL 3qm.wpZ9mt3vFcWaqshpOecPf95ihx7eCYJy4I3ZtBbsz.BeGQMHbij1tOzocDKOlpB9pgHPKqRp heSATA3We6OmrDAmmWXJmEEgLxnb8sgsWLwi9gHcNzshfphWwP1CWWHpmpDBthOki5vHcBDYXrJl h6m_q9FTjAodb6nUSP9SG49K7yOZIH72FKgema5TLqH0LkMaDQG1lcWhxsXXqm5Nx_aCITyQV7qD H7ZkbJmSQxXUWLqvf_lBPoVqCWPGLz2hdnkfmH3dtlVtTBRIFouFcMOTVicDsuaFOTFc.dUr247Q iv3JD4wOsv6Ghfe2jXbmJX9TPKdEn7n9Ucl5WtoNGEoqkGC9WiuwS80k5qIFuTrUvrtVVNQOHxp5 FOcWggzrrc_l2U2TM84D_RZlhHA8YdNwFoZuH8zuKJkjbYSZE4rSU2TMLiq3Inmo6ys6pW73tQTb VhNd4DeLnqmEkyv5k9LIW7gDSCAmMIattJg_aoq6CaAutZf5J18d2cNxLoQ.DkYbdFM1xAzxRHWJ JvUuLLDv5_tdMKEf3b1LTNt9bkNmt7qi9xYrwU1Sr0MtyQJBK2G7YgBgvMlbM52winLh2._8wy_B JuszNRCrWQ868nFMDERvkSKpYe7FvWULfkSTIZ5dPP3cALWmq7ZVI7JEpgslfgj5Khx9X4so7Yzc Z3Pja2.4vEBrlya9vgMomIP54nLEKMx1aS6cG0pCNKjveriRH24ZEIdK2CdAtjZu_iopMCE7e_aA 9j6zs1P1A7RK_3WHpUn6BP9kZjwJKwYcpGhQFhOfRi2zQ5hwsrieRyLLVK6z19JBfJUG10V5RAUI SiVJ8tdAoHnD2uHWi7Q4oKjLP7QAIUDUJdRWzKSTzZz6TnMydLOON3MTXhGJgG6t4HSDuIj05YUs k4f9Y49zE0mtEg1FY6WRfVip6LGWGDJLcwPby1SjE8B7VaPWzrM5_dhw5X3Pibk1ndmXssTeOFVG uP4V2bt6fVLm8FiLYgMzixH4ZmDPPW9fodsNKWh.S9fjgjfY6EyKKUpunsFqXYLjrujVXRSP77Tw hquGmaAk9ZoEzUIFH0fpzmZKFm4EvJtMWOvo4Ng-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic316.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:26:37 +0000 Received: by smtp409.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 4426d449a8f49be2e6406d78823572b1; Fri, 24 Jan 2020 00:26:31 +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 v14 20/23] Audit: Add subj_LSM fields when necessary Date: Thu, 23 Jan 2020 16:23:03 -0800 Message-Id: <20200124002306.3552-21-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: 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 463372198099..57e14b80588f 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3107,7 +3107,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 f1a6c9ba907f..c18934f094a5 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -176,6 +176,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. @@ -217,6 +219,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); @@ -526,7 +530,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); @@ -1331,7 +1336,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 f67187a84cb1..c576ab810d86 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -392,6 +392,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; } @@ -1097,6 +1098,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); } @@ -1346,6 +1348,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; @@ -1360,6 +1363,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; } @@ -1373,6 +1377,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: { @@ -1408,6 +1413,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); @@ -1416,7 +1422,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; } @@ -1475,6 +1481,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; } @@ -2053,6 +2060,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; @@ -2063,7 +2097,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; @@ -2171,6 +2205,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); } @@ -2221,6 +2256,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 a1296453d8f2..b6f71be884e8 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 f2d1e573ea55..bd2b36a83e66 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -4206,6 +4206,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); @@ -4221,6 +4222,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 f3423562d933..bfb8402cb28d 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -2642,6 +2642,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); @@ -2656,6 +2657,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 1ab769fa7df6..252dc00700e8 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -363,6 +363,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 6002075b4c8e..6a77c8b2ffbc 100644 --- a/security/security.c +++ b/security/security.c @@ -448,7 +448,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. @@ -2137,13 +2161,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; @@ -2154,7 +2197,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 Jan 24 00:23:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11349497 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 2475A17EF for ; Fri, 24 Jan 2020 00:26:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E751C214AF for ; Fri, 24 Jan 2020 00:26:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="ZovhRzkx" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730101AbgAXA0j (ORCPT ); Thu, 23 Jan 2020 19:26:39 -0500 Received: from sonic316-27.consmr.mail.ne1.yahoo.com ([66.163.187.153]:37783 "EHLO sonic316-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730082AbgAXA0j (ORCPT ); Thu, 23 Jan 2020 19:26:39 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825597; bh=JSaMrCw5rIOsb/PJrZw0TEWxJjBXsuaEn7uKyAVvJ7M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=ZovhRzkxSE7e5eyTAriw0SW8CrS3ogFHroBK3rDIB29yMgFlJ/vXcdri0CEXGMjxukdM1Tog2fkL6ug6OjdOGbPdYRnd4vYvpivrX19XZb0LvupkRn/HLTF4aVpgmYLi6A4X24wb+7uTtuqLVXkWDX8PxHWGde4ij0W4AjthAP0tJr2WzTk6BWuzC3p+s5agG3g0YqGrgQMunMS+6UeGD8pQC54NXQTNJywRy341fNAb97s4BrG9/ciLGYmoPYxRu0bvSUoehJtCcSJKPBc0SejPi1O48Ufw6VAl9tbPSmHEcb3K2X5yvi3s979ywGfhIvCfstnQxyYDUsOYbDEncg== X-YMail-OSG: 9CWl6VEVM1kgal.dA35A6WxLDkVfmTu_1ZsylAN8nsDW7ZI7p7OMCeg6UWtWvbc xxhKhckZOHnWKHxcIKs9Ano73flp57GXi3kFQooWvFzSaXGiKJDGgzKIeWk8SIjxAk0vTtmvfbBR fUPcp1SDmWUfN28Gee4xCtrcsh519sTb7TEt1eza7rcpMMhgUcozsJWuJfbsW4wMUQqmmAQSLDyY .nupYtgpCgqfwrEXWpV.m8IIaFv.Rn_uM9U1hrNt.OJrEKZsSAnTZhT.FUKpKzoYOM_YE7vCXpvA hYFvQy887gVZeHu5YPFtV1.T.PWOXINpKovgP86S7Mb3OD3._DKBtgYOyif0j_VCWYxTWO_T1Fn_ epX8Nuk5_FhFCWrab1V0YAYGyFVRciN_jOLK3w.CLhymqCkpV95aUm_VJZ4wddIaI6G2bCVh6Z.z klAGwJJXPfuvHI_zyj7fnSHKUNURTZgalxv7GOG45QFhHwEXZCgrMNbjlGLxdNlaRRFCbGuC3jZE Ol9_zSeuB_3_P6ew04gnjEkS4K8Dm8Ox27bBJ1fSJ4.t9KgCbGt0lsvFgBiV1iAn0n_zVA7t.Qlu aRaPjKtkdYFoiZN5568D4uCbrQE1b13uXhYuCJC5FVSBeJp9l.Z5WKWlu2h__tEJ3OVUvZt8PIRX VHBvEui0HD4hlQDsswSAMk5yD.E73pCGw3mSIj5jGpQ9Nh79wooSVSxgepxrankMIFBK4MbKl6Y2 VPfKN3gSSMDDKupRkNu5I3MHRZ4U4zURYXcHm3NWCcUrWiaPOAV7Pasj18Ntv3_bt7BBqmRrqN07 f1RgIJ7x9L3zw_Bp1I_AijFEYPnAAqiVgOe.RXorhuiE0AO_iRugUKoX5rxExHcdACKFk5.HpOLm Nieh0kfbFLah00n3vdMZ0Tct3n0SfNcD0oe8QwO0IMQgBXl8NbINbg3SzPUIrRdhwkH3Rz.OxBvt lojU1.ApGHX4OoOfR7ndLY3abzWYbmBYIl41HprKdmsZKgoZejwXJFMfWfgxfntHCOWPfDm4OfaH 8I0fLvdf7zybEA4sWV0Jue54gq_hZDKXRRv7Pp8CyGQ4U2RWedSdFXSv5rLQbSXwzzf_K6gVAj5c hqsZvEki15COsWaLiVROyPgdzpeXVemKv9agIbYxea9gjr07BDuPc7rbPkJDUM87nARahWIPi_pC riN22jWOvEGn.CrUhpb08.RSd.L5.C6PXsEv1Fhax2DVMJnyrOV7wdOyltedB4RpT7Z7iZuEoNZi lUP4wbaMLjY6Sa9TP_KVOpVQLdrzZn7alVENjPsb1bv1A_7zHfAtLHjgdLXeoKLcZSCg7Rtbp2LA I0w9SfMRN.0ki0.5oRDU0xHhCfRaqU3f0ys_hgqAurtRlpVN0Tdmzi_OpJl.nvNZKw0rOeeZ08zZ Rp0SjFskjREXULI91VqyNUHAMIToXASH.KEKI Received: from sonic.gate.mail.ne1.yahoo.com by sonic316.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:26:37 +0000 Received: by smtp409.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 4426d449a8f49be2e6406d78823572b1; Fri, 24 Jan 2020 00:26:33 +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 v14 21/23] Audit: Include object data for all security modules Date: Thu, 23 Jan 2020 16:23:04 -0800 Message-Id: <20200124002306.3552-22-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: 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 Jan 24 00:23:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11349507 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 0B39917EA for ; Fri, 24 Jan 2020 00:27:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D9F9821835 for ; Fri, 24 Jan 2020 00:26:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="P5gA6Ncr" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729917AbgAXA07 (ORCPT ); Thu, 23 Jan 2020 19:26:59 -0500 Received: from sonic316-27.consmr.mail.ne1.yahoo.com ([66.163.187.153]:41290 "EHLO sonic316-27.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729942AbgAXA06 (ORCPT ); Thu, 23 Jan 2020 19:26:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825617; bh=tMXm8ybkTZ71dZq9bLVqDynXKZXLUzbMoItH+eZdOgc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=P5gA6NcrUTf7gxjW7G9WefIUDdVLc+GG6905sp3CLPCNc8fUw3fXSxa8HNkYLSPuDflrh9oQzvT7Brhh00lK8n0n10d0atzjrz5ldDTbUgcefetG/rQCmqgwbJaejjHCM8txGELESnX/7PWlu+MQ9Qk8WNsRPr4/Nk3SV8LXn7W76VcEjSymSSayBGZfDeT5QxOq14zWtVSdUQAZdm8kHrNEnh+OGcHYxN6zTA7kqW56FFQrjNL2CQ2EE1k8g9nIkF4TTKQArarr8MNm4//R6k1/7hIh+jsPQWA9hw0JynKr4skTTW+coVhtiZCeiTZcZS7fVHnZVIa8i265tvL+Nw== X-YMail-OSG: K8QKojcVM1mahkppC8KlUOE1nMqQ_SkLzwruEEinvZZO9mJgjhITjsMvNLv1PHe g6u6eQkVeT94pCHzGN8yDxodWyAjEl5UORGoptu7c6VhtLFLjkp80Kim52RMwNwcRfiu85XfTiJB EzxZ7MqWaKDNd_4unyhxWtTWYw2ItlWVmianzQB61KFpJPKNtnvuK1FsnlB2E4lWYVbS2Rb8IBo0 BzwVbBIlrRSLv4Avi8T0LM0GxhHR5zKWps7Y5AS_XdD.UjOnKsNmN6q15IoGZ5BgDC3Fw7FFmx_v z3xsQn2U_UpZhnc4aqJRYAM09OqsmAgZDhoFThVi4qDKkz3gRXR5CABf378LLoZRjkOcpJ8MTwqb sixIusx.jKgF8FNlxd.10aEIreDEn1JXfFMiHJS6rqchI7uYX_4PYRJL2mBwN0j46itEMGMdtA8r dvuFns8TXdTwEm5En7_PBi046oPmNgK.wHtHOeuaDPy2jQK8Rw43LwSsWZNzNex6R3qPsVy8Ip.a lwm6cuG7oXRQ5Fe0S1z1DHKf_0x0ia7F4dXXknbO1CN6rQL6mHc9T0GTYrhnqLKGw_OuHxkXKkrw fJhlYVQh7BUEWKFqTdQLWrU61_AiyInUBmxq3qORbka8D0T8FKWE5_iXmcYMqeCY8bMzBdReqrkb h3YaiYXL3tz5v8JLIddoDQDfddNXpWCoGdqBOwrxoyOB7WKVpQmYaNIvvED8XeLwVBnYWHNsZicN 6Pcy2fvoQQ5dcf6kg_HTTguljBsSIg4hD4Fg4BHP_2UDMo3ekqJil6NgYzIfPOBYCi8aaZjl2PQw 0J9WmbWfaEkKK5XbLW5S4DmnKfcVnw9mI49R.xdK3syXbA5437g2s0jktk9QdBUw52rjsu_wpEWV TpufMOKSpJILQgus8iNsmON5OcFm0.yKA1gcmi0t2pIQcm_vRxLbgT8efb7.fUYrzj4r8uCTFmbw NN0N4jinGGs6hxCIxRHIxl5vJlK3hFp8sckm2SsHFTZXGC7EiIqjsmIUEwbgxsSJ1dVGxNYdRtum 8xplEKunqkzdwrXJUjKnOTW5s4xANNxakQiX1JyrVTIJ9i_fCgdeXmJs9cDEr1sKMOBBG31zOOlD hkVEpq0wTBCi8kGbceleTjO6RIVa93eoRCX.im4hhqpmaI8z8ZughcRteB_qt0SwtyLq2XajM38y K_t22V_RKRybottMMiVY.R96xsgsDul2N0uusWxJUDVN.78K6NSUFt_fsb4NQAY4SY45CpFZZDjZ g_N_bGLqb7jPwFI04W_VGTRzR37ve6sJ5D1tP_cJ4y28ygROVP72Anu8EeOp6rvG2Ql9e92NGTTf CgggAezBKmWfqI3DWXwWJeIOKwM1nKkuCsQMctAzdg40BxqCREIAxMJ6kwBODKaq.GlbuzzNeIq9 cnccCkvuhcgnglxr4gD_XcHCOAX0r3f.h7thaYtrEs9iBirGORDJ0PkZHHIT4ZRWd1wH0Sw-- Received: from sonic.gate.mail.ne1.yahoo.com by sonic316.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:26:57 +0000 Received: by smtp406.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 50be027cdc8c4f0f0d7e06f64510609a; Fri, 24 Jan 2020 00:26: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 v14 22/23] LSM: Add /proc attr entry for full LSM context Date: Thu, 23 Jan 2020 16:23:05 -0800 Message-Id: <20200124002306.3552-23-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: 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 Signed-off-by: Casey Schaufler --- Documentation/security/lsm.rst | 14 ++++++++ fs/proc/base.c | 1 + security/security.c | 63 ++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/Documentation/security/lsm.rst b/Documentation/security/lsm.rst index aadf47c808c0..a4979060f5d3 100644 --- a/Documentation/security/lsm.rst +++ b/Documentation/security/lsm.rst @@ -199,3 +199,17 @@ 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 special file ``/proc/pid/attr/context`` provides the security +context of the identified process. diff --git a/fs/proc/base.c b/fs/proc/base.c index 950c200cb9ad..d13c2cf50e4b 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2653,6 +2653,7 @@ static const struct pid_entry attr_dir_stuff[] = { ATTR(NULL, "keycreate", 0666), ATTR(NULL, "sockcreate", 0666), ATTR(NULL, "display", 0666), + ATTR(NULL, "context", 0666), #ifdef CONFIG_SECURITY_SMACK DIR("smack", 0555, proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops), diff --git a/security/security.c b/security/security.c index 6a77c8b2ffbc..fdd0c85df89e 100644 --- a/security/security.c +++ b/security/security.c @@ -722,6 +722,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. * @@ -2041,6 +2077,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; @@ -2068,6 +2108,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, "current", &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; From patchwork Fri Jan 24 00:23:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 11349509 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 49B8A18B6 for ; Fri, 24 Jan 2020 00:27:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1A8732087E for ; Fri, 24 Jan 2020 00:27:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=yahoo.com header.i=@yahoo.com header.b="jc0w/mZT" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729942AbgAXA07 (ORCPT ); Thu, 23 Jan 2020 19:26:59 -0500 Received: from sonic304-28.consmr.mail.ne1.yahoo.com ([66.163.191.154]:41498 "EHLO sonic304-28.consmr.mail.ne1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730131AbgAXA07 (ORCPT ); Thu, 23 Jan 2020 19:26:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1579825618; bh=+xZS4OpybWN3jlqSAzuQm4ZwAT9KRm/53SJ0M76W1uw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From:Subject; b=jc0w/mZTwbvBzCmiPCOrfH/afXSNbPbFOR7MsHlRuaZakHzlarl+0lM5sCpHW07TjA7vW3mMh0f4VoyuhyGPBn1+oNhcEnXQbKTZwjIb13bQqCLy6E/vLQ3/piIvl3cdVeeozrCF7+oyChXfrLNm3RBvzLZ9uF9c7Nuh9Neu7C1in5D6yOr1AClFxwXWWT11Krc+HzusCjr+nRk0Ts/4qTWQ9uQ9o1eMcPsV383Fxany8O6M1K+eBXhpfGJaEXlWRohN1JVmIuVqvzbge2xJRI+mHsjl5wbXPErmfzQ732Snm4LEGgFLGB4YWpNp+04zUjSER5Zus+e+KiuI13HPQg== X-YMail-OSG: UIG05bIVM1kB7f17kqwsrUSILfXHyC54N4lQdVkk.rfnv12OyGIvZB9kv6v7PpU Ww63MODvInTkahVqz6ICmW8foGFA0JWaLqzswdAHLZThvJkEIYAMy2VlOQTWgEHSNW3dq8ROKtsK SCvHklQblu5RLPHmAI7ntaWoN5aW92uMhJe9AEl7edE4NelyD29j_nAd4BOK4PEX7iI4f00J.5qA RY06AXw98Z.zcGTZPeChPxPI7UWIO8uPJLcaSUgAtwMC7fjkqvMSF8VDcM2B6sUBCKvfSRSZcq5V mK02CGLZ6phZKkrbP8z7ceYWZpdeZ96WMfndNNar4IJY_DVHO0BBfXZJDby_R3xrs7A8C7suDLpe zbXhdhuunrYWL.rB4Aw9dzRzgPNYfMOb5Z7QeuvAevetRW7Y5VoK7ybbh3ibexukfRLvTkRXyk2A jSAp7kDhtY5Cm8eu.JxzttP0v6W_ZAednSjtP0dpBr_oFSmMFHPQ_Omn9F3gBgioQewl_ihvLPYU j2w8VRSTyqH_NJCmgm85.3fkuz8EtMG2dkwMWweFAnhte2STQbwu9zbzdTnicbdyQTOhV2eb0gDQ rWiLCrlnSNaYPFoyyIVYcywQmzJHQOkGUs.Ip_rEyt2uT5Jq783J766UA7_lW8CJf6zrXIfmWo9h G9qfImMuVOW.juAlG.xjy2nBscZBAMAGfNJYhcshWNIZ2MYw.v5DBopfQ54ZpzVx4qz5SM0HamJ_ fQwlOchxbmf_T7.lrVbHM0cLBN7SJhk6QJPz2rYQ54Dqt8ILSEaTZiMbj1OozUJ.sIT3IBGFEG5k h44LGdyNyEHOGg1vaxffze5GTu5IRActYmOhtVpdBv8rVaPhRHQauvjkzYvbMgIm_B8MUFpipksB EqIqMyX8I2JmRrSmazjyF9BgVn8dn0HrctxY91baHel3I.nDd4TxXcr7YRRmoIfBy3YhBV8LmkFD a.WVDlKH70LvDswyNT9ZmKgklIVyonhmh.bhJkHaClEZPfiRXHvHcmitqeLh2GzRGRP1QGEc_vgz ntT9naM4BRgSs16bRshb82EhNrokdPIGGE430M9xPqZYpzvr.V2d0QRPhFvbSDRC8jEadhgorRMV jTAM0cJ9VcYq_oQQcfbd.Dhe3GpiI3fWc0_bKBPPAl_C8FA3_8TNw3riMlGArQGIUaLwiZrjZ4Mf URxmzoNECCsqDVRPYHhs5o3hW8CKDJwyg8gL49KfCr6p5oJoavHbv_w5r1BdYb4mY1HU6hGnLR4c xQGDQf_CLZk6x_uRIdFQPi.VDNu8ywXh9DxTkbivRJ4oum.SMUjE67wsD8ZMecfUUnbnMV.TTRsp Fs2_2DEZEgWyW1DY2d2Wfmnqh4BRsPmpIYoUeUx9a7dWI3I_enTqHjDcVRc3ApKVcB5dXxVnMpvS bislvbdNj.r4TzYOQxapURBw620iNVxWyTeIiOWCMgFq9vbJgoPxkXlq108gHEGK2RvWCR6lZ Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.ne1.yahoo.com with HTTP; Fri, 24 Jan 2020 00:26:58 +0000 Received: by smtp406.mail.gq1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID 50be027cdc8c4f0f0d7e06f64510609a; Fri, 24 Jan 2020 00:26:53 +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 v14 23/23] AppArmor: Remove the exclusive flag Date: Thu, 23 Jan 2020 16:23:06 -0800 Message-Id: <20200124002306.3552-24-casey@schaufler-ca.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200124002306.3552-1-casey@schaufler-ca.com> References: <20200124002306.3552-1-casey@schaufler-ca.com> MIME-Version: 1.0 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: 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 --- 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 16b992235c11..37d003568e82 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1120,22 +1120,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 @@ -1239,8 +1223,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), @@ -1909,7 +1891,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,