From patchwork Sat Aug 13 20:37:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 9279333 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id AD46860780 for ; Sun, 14 Aug 2016 11:50:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9E61F28A06 for ; Sun, 14 Aug 2016 11:50:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9326928A57; Sun, 14 Aug 2016 11:50:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E6AC428A4A for ; Sun, 14 Aug 2016 11:50:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753269AbcHNLuf (ORCPT ); Sun, 14 Aug 2016 07:50:35 -0400 Received: from nm38-vm9.bullet.mail.bf1.yahoo.com ([72.30.239.25]:57762 "EHLO nm38-vm9.bullet.mail.bf1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753234AbcHNLue (ORCPT ); Sun, 14 Aug 2016 07:50:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1471120674; bh=KFhw0oRuZQFaWZuimFqhCCcJR4kh2/6VhCOvAcasWWk=; h=Subject:To:References:Cc:From:Date:In-Reply-To:From:Subject; b=EgguNKWEHTm+cQkEISDcv+l6sJQWPejWGW4HJUBlQ/2/xU/ubKNqLW6NUe1YI2TQNAv02GXc+sFeudV1s+qb/CrXPwn6DWG6DOuYmphDsaM8C7TOsFsDmVRte80RobbGaqE73P+dHnwPzCQpwHlx6r2CFGOKaPxGqapm/QiOp/6A10Wd5VOuB6X++2VHPsQRs1WjgMMqpg6985/eyDA8uEoSg3KDCkRLN4IXXcP20XYLnyFoFckggk2Tl8EH0pBbimZvFfMUfyNJumKyPRtgE4d9LEN/8nyeA30cQZI2yDP6LTpYh7HqCKusvz2YPCfU/x2R7lj5fmy/jIdiSE7flA== Received: from [98.139.214.32] by nm38.bullet.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:37:54 -0000 Received: from [98.139.213.8] by tm15.bullet.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:37:54 -0000 Received: from [127.0.0.1] by smtp108.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:37:54 -0000 X-Yahoo-Newman-Id: 20217.21646.bm@smtp108.mail.bf1.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: SgrfMRsVM1k7VCFWodghAyGQVEP7a8c1n2w7Ral222wPReC vSrwNmGya5725TlP0uZrms2XidYF55HafnqO8nWZeL7dNgyxugn9.HTUlFJq r214P8g0ijjW1TyD3qU2azIsxIO.rtq.63C4Gcbtyt691OJ9LNqVIPIdRolz UBC_hcfiVGGbxpXqlBaZhrxRaDGYVbM1KqSlA0w1jtQ_71st0f9jNvJfjVls dcqXNWsIMv.0Ux6mR_V9aBjTNymBvc8ab4d_CpYZ1_Qxlw3MQPdEI_VZHZuk mV5VQ3M1MMVJysLiRkg2OIFGAKZ5iR37QlHutDQQaKiNlYCCY_LtHXcd5dXu GtI.o6PiyaQ9saTZ2BaZ51DuO9s.Vd_uI6LvIu2lXci31nr7PhtS68DaLj73 YSBVXjosCxHHQxgCytGuDcPaSab3lpHJjWvaUAewSOJLTMHJ85hOEiJsAwIY .k7ujMaV8QPHeBnJ7nhPKy26XNkBGbQ3Hzn6uGhToJZcmyLHW7jiDpCyrcBL aScpdai149mJ5P3Dbr3jP2jy_LK3np18rinpDBTv0quDAdZkqN9HjoLMQs70 O16mlDtB9Sebc X-Yahoo-SMTP: OIJXglSswBDfgLtXluJ6wiAYv6_cnw-- Subject: [PATCH 19/25] LSM: Infrastructure managed socket security blob To: LSM , James Morris References: <801ef9a9-e594-387c-f285-8d90879ee2bf@schaufler-ca.com> Cc: John Johansen , Tetsuo Handa , Paul Moore , Stephen Smalley From: Casey Schaufler Message-ID: <12c680cb-e160-0fbb-ea2c-17f59414703b@schaufler-ca.com> Date: Sat, 13 Aug 2016 13:37:51 -0700 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 In-Reply-To: <801ef9a9-e594-387c-f285-8d90879ee2bf@schaufler-ca.com> Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP Subject: [PATCH 19/25] LSM: Infrastructure managed socket security blob Move management of the sock security blob from the security modules to the LSM infrastructure. This requires that the modules declare the blob size they require, so the module registration process has to include that. Signed-off-by: Casey Schaufler --- include/linux/lsm_hooks.h | 1 + security/security.c | 34 ++++++++++++++++++++++++++++++++++ security/selinux/hooks.c | 10 ++-------- security/selinux/include/objsec.h | 4 ++++ security/smack/smack.h | 4 ++++ security/smack/smack_lsm.c | 25 +++---------------------- 6 files changed, 48 insertions(+), 30 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 9cc0e49..c03d339 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1851,6 +1851,7 @@ struct lsm_blob_sizes { int lbs_cred; int lbs_file; int lbs_inode; + int lbs_sock; }; /* diff --git a/security/security.c b/security/security.c index 9fc5967..b728624 100644 --- a/security/security.c +++ b/security/security.c @@ -26,6 +26,7 @@ #include #include #include +#include #define MAX_LSM_EVM_XATTR 2 @@ -87,6 +88,7 @@ int __init security_init(void) pr_info("LSM: cred blob size = %d\n", blob_sizes.lbs_cred); pr_info("LSM: file blob size = %d\n", blob_sizes.lbs_file); pr_info("LSM: inode blob size = %d\n", blob_sizes.lbs_inode); + pr_info("LSM: sock blob size = %d\n", blob_sizes.lbs_sock); #endif return 0; @@ -227,6 +229,7 @@ void __init security_add_blobs(struct lsm_blob_sizes *needed) lsm_set_size(&needed->lbs_cred, &blob_sizes.lbs_cred); lsm_set_size(&needed->lbs_file, &blob_sizes.lbs_file); lsm_set_size(&needed->lbs_inode, &blob_sizes.lbs_inode); + lsm_set_size(&needed->lbs_sock, &blob_sizes.lbs_sock); } /** @@ -279,6 +282,31 @@ int lsm_inode_alloc(struct inode *inode) return 0; } +/** + * lsm_sock_alloc - allocate a composite sock blob + * @sock: the sock that needs a blob + * + * Allocate the sock blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_sock_alloc(struct sock *sock) +{ +#ifdef CONFIG_SECURITY_STACKING_DEBUG + if (sock->sk_security) { + pr_info("%s: Inbound sock blob is not NULL.\n", __func__); + return 0; + } +#endif + if (blob_sizes.lbs_sock == 0) + return 0; + + sock->sk_security = kzalloc(blob_sizes.lbs_sock, GFP_KERNEL); + if (sock->sk_security == NULL) + return -ENOMEM; + return 0; +} + /* * Hook list operation macros. * @@ -1645,12 +1673,18 @@ EXPORT_SYMBOL(security_socket_getpeersec_dgram); int security_sk_alloc(struct sock *sk, int family, gfp_t priority) { + int rc = lsm_sock_alloc(sk); + + if (rc) + return rc; return call_int_hook(sk_alloc_security, 0, sk, family, priority); } 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 7219a6a..f930c9f 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4639,17 +4639,12 @@ out: 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; } @@ -4658,9 +4653,7 @@ static void selinux_sk_free_security(struct sock *sk) { 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) @@ -5966,6 +5959,7 @@ struct lsm_blob_sizes selinux_blob_sizes = { .lbs_cred = sizeof(struct task_security_struct), .lbs_file = sizeof(struct file_security_struct), .lbs_inode = sizeof(struct inode_security_struct), + .lbs_sock = sizeof(struct sk_security_struct), }; static struct security_hook_list selinux_hooks[] = { diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 7f5f4b8..f2820a8 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -183,7 +183,11 @@ static inline struct key_security_struct *selinux_key(const struct key *key) static inline struct sk_security_struct *selinux_sock(const struct sock *sock) { +#ifdef CONFIG_SECURITY_STACKING + return sock->sk_security + selinux_blob_sizes.lbs_sock; +#else return sock->sk_security; +#endif } #endif /* _SELINUX_OBJSEC_H_ */ diff --git a/security/smack/smack.h b/security/smack/smack.h index 141f3bf..d377efe 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -370,7 +370,11 @@ static inline struct inode_smack *smack_inode(const struct inode *inode) static inline struct socket_smack *smack_sock(const struct sock *sock) { +#ifdef CONFIG_SECURITY_STACKING + return sock->sk_security + smack_blob_sizes.lbs_sock; +#else return sock->sk_security; +#endif } static inline struct superblock_smack *smack_superblock( diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 6dea0a7..c8e4d02 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -1859,7 +1859,7 @@ static int smack_file_receive(struct file *file) if (S_ISSOCK(inode->i_mode)) { 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 @@ -2279,35 +2279,16 @@ 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); ssp->smk_in = skp; ssp->smk_out = skp; ssp->smk_packet = NULL; - sk->sk_security = ssp; - return 0; } /** - * smack_sk_free_security - Free a socket blob - * @sk: the socket - * - * Clears the blob pointer - */ -static void smack_sk_free_security(struct sock *sk) -{ - struct socket_smack *ssp = smack_sock(sk); - - kfree(ssp); -} - -/** * smack_ipv4host_label - check host based restrictions * @sip: the object end * @@ -4569,6 +4550,7 @@ struct lsm_blob_sizes smack_blob_sizes = { .lbs_cred = sizeof(struct task_smack), .lbs_file = sizeof(struct smack_known *), .lbs_inode = sizeof(struct inode_smack), + .lbs_sock = sizeof(struct socket_smack), }; static struct security_hook_list smack_hooks[] = { @@ -4681,7 +4663,6 @@ static struct security_hook_list smack_hooks[] = { 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), - LSM_HOOK_INIT(sk_free_security, smack_sk_free_security), 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),