From patchwork Sat Aug 13 20:38:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 9279375 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 2DAB960780 for ; Sun, 14 Aug 2016 11:53:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1C2EC28A06 for ; Sun, 14 Aug 2016 11:53:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 110BE28A57; Sun, 14 Aug 2016 11:53:48 +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 8FBF028A06 for ; Sun, 14 Aug 2016 11:53:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965311AbcHNLxl (ORCPT ); Sun, 14 Aug 2016 07:53:41 -0400 Received: from nm35.bullet.mail.bf1.yahoo.com ([72.30.238.197]:47260 "EHLO nm35.bullet.mail.bf1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965330AbcHNLxf (ORCPT ); Sun, 14 Aug 2016 07:53:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1471120685; bh=xJDOxXeiQmbliIG870p/WQC5wQlABI75Ruu8MN5uHHs=; h=Subject:To:References:Cc:From:Date:In-Reply-To:From:Subject; b=MVFTNPSB9sO7dhy0H0xlsuUUX/4Uhby3vY2/SNOdmNRuiWzX99S6oRPixGquwZqT5pDHfioqEr0JDZmJMUJN3jBcBkdRO8Nh6FqimqmhiAvqC1j1jJ051UVVsOQpunGzZmstnBD5q7Aa2D7Y/6pNPPNfHfssCqDptgJWYPJIiqiLPAvDATzhQeGuRi9g6Rm+JVeO5DgZTfVPVEfN/Y8PWQ++KlsJq9zXFy9ja8HFZcvRQb/c8S8pMxOrjTc9OX5ZrhEfXXfJ+3cQ96a8l3XaH/DqrrIWSx6xRDKKq18tltVDh2E1OcWqQxV99AEzC46R4SPOLgdSLtmhCXfRYBXy7w== Received: from [98.139.214.32] by nm35.bullet.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:38:05 -0000 Received: from [98.139.213.8] by tm15.bullet.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:38:05 -0000 Received: from [127.0.0.1] by smtp108.mail.bf1.yahoo.com with NNFMP; 13 Aug 2016 20:38:05 -0000 X-Yahoo-Newman-Id: 856168.78121.bm@smtp108.mail.bf1.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: .CIkXSUVM1n0jTpbYG7wKnUKlE8C6wz3O9mHbmrFcxFplHT UiLuCPqL6.UbsQFQo7JoDoLGI4n3RX9E.HFyF82OD0H1bxYi9wjGGtxrKhs0 ieppqvuEzkKJyKLqi7PpzmgRAoRP7ziPECpVJY0SbcbE07hJ2r_YjdBA.C3K b6MZk.v._aTB4k129Xqb7HOn1DRYrzhoP90vbZ1d79xo6lpT4tNvvrsXmKGD mVK3V5m5HMd0l9a85WOvQ3LA11Q0U_a7j9okciGl82yW7HuYWH4RlhZj2yFN 608Bs0K5PvzOvyRaUkTNvRuEQgkouiqEaGYjNPZTUQqzNkiddoDDhsgI3LWd e_0QEGYjud9bCr4w7AYAxNXmlXqH66FCN081mAjHT8TnmiaypeBIIEuHtbXg TT2NTWEij2cigB8KGEAAuobl5P_QeLclmhaJfZiF.n7VjSnTci_rVF6Bzwf1 iyc8iB61EdlPcEbPpUB6yPomcOid6Z17vPdYVBOP1Kb2TJw7iZOj2RO11wPQ GKGwDGfx.400yxm33l3salgbZIvOc0_ebSsicvXWDO3NcCH5R7iRddHLP6hg XMBRNbI.u0dn4 X-Yahoo-SMTP: OIJXglSswBDfgLtXluJ6wiAYv6_cnw-- Subject: [PATCH 21/25] LSM: Infrastructure managed ipc and key security blobs 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: <8e0b4eda-995e-66f5-69b2-5d46b81d2fd7@schaufler-ca.com> Date: Sat, 13 Aug 2016 13:38:03 -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 21/25] LSM: Infrastructure managed ipc and key security blobs Move management of the ipc, msg_msg and key security blobs 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 | 3 + security/security.c | 118 ++++++++++++++++++++++++++++++ security/selinux/hooks.c | 104 ++++----------------------- security/selinux/include/objsec.h | 12 ++++ security/smack/smack.h | 18 ++++- security/smack/smack_lsm.c | 146 ++++++++------------------------------ 6 files changed, 189 insertions(+), 212 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 70a2e7f..585d169 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1851,6 +1851,9 @@ struct lsm_blob_sizes { int lbs_cred; int lbs_file; int lbs_inode; + int lbs_ipc; + int lbs_key; + int lbs_msg_msg; int lbs_sock; int lbs_superblock; }; diff --git a/security/security.c b/security/security.c index 36ce44f..5dd1d57 100644 --- a/security/security.c +++ b/security/security.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -88,6 +89,9 @@ 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: ipc blob size = %d\n", blob_sizes.lbs_ipc); + pr_info("LSM: key blob size = %d\n", blob_sizes.lbs_key); + pr_info("LSM: msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); pr_info("LSM: sock blob size = %d\n", blob_sizes.lbs_sock); pr_info("LSM: superblock blob size = %d\n", blob_sizes.lbs_superblock); #endif @@ -230,6 +234,9 @@ 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_ipc, &blob_sizes.lbs_ipc); + lsm_set_size(&needed->lbs_key, &blob_sizes.lbs_key); + lsm_set_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg); lsm_set_size(&needed->lbs_sock, &blob_sizes.lbs_sock); lsm_set_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock); } @@ -285,6 +292,81 @@ int lsm_inode_alloc(struct inode *inode) } /** + * lsm_ipc_alloc - allocate a composite ipc blob + * @kip: the ipc that needs a blob + * + * Allocate the ipc blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_ipc_alloc(struct kern_ipc_perm *kip) +{ +#ifdef CONFIG_SECURITY_STACKING_DEBUG + if (kip->security) { + pr_info("%s: Inbound ipc blob is not NULL.\n", __func__); + return 0; + } +#endif + if (blob_sizes.lbs_ipc == 0) + return 0; + + kip->security = kzalloc(blob_sizes.lbs_ipc, GFP_KERNEL); + if (kip->security == NULL) + return -ENOMEM; + return 0; +} + +/** + * lsm_key_alloc - allocate a composite key blob + * @key: the key that needs a blob + * + * Allocate the key blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_key_alloc(struct key *key) +{ +#ifdef CONFIG_SECURITY_STACKING_DEBUG + if (key->security) { + pr_info("%s: Inbound key blob is not NULL.\n", __func__); + return 0; + } +#endif + if (blob_sizes.lbs_key == 0) + return 0; + + key->security = kzalloc(blob_sizes.lbs_key, GFP_KERNEL); + if (key->security == NULL) + return -ENOMEM; + return 0; +} + +/** + * lsm_msg_msg_alloc - allocate a composite msg_msg blob + * @mp: the msg_msg that needs a blob + * + * Allocate the ipc blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_msg_msg_alloc(struct msg_msg *mp) +{ +#ifdef CONFIG_SECURITY_STACKING_DEBUG + if (mp->security) { + pr_info("%s: Inbound msg_msg blob is not NULL.\n", __func__); + return 0; + } +#endif + if (blob_sizes.lbs_msg_msg == 0) + return 0; + + mp->security = kzalloc(blob_sizes.lbs_msg_msg, GFP_KERNEL); + if (mp->security == NULL) + return -ENOMEM; + return 0; +} + +/** * lsm_sock_alloc - allocate a composite sock blob * @sock: the sock that needs a blob * @@ -1313,22 +1395,36 @@ void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) int security_msg_msg_alloc(struct msg_msg *msg) { + int rc = lsm_msg_msg_alloc(msg); + + if (rc) + return rc; return call_int_hook(msg_msg_alloc_security, 0, msg); } void security_msg_msg_free(struct msg_msg *msg) { call_void_hook(msg_msg_free_security, msg); + kfree(msg->security); + msg->security = NULL; } int security_msg_queue_alloc(struct msg_queue *msq) { + int rc = lsm_ipc_alloc(&msq->q_perm); + + if (rc) + return rc; return call_int_hook(msg_queue_alloc_security, 0, msq); } void security_msg_queue_free(struct msg_queue *msq) { + struct kern_ipc_perm *kip = &msq->q_perm; + call_void_hook(msg_queue_free_security, msq); + kfree(kip->security); + kip->security = NULL; } int security_msg_queue_associate(struct msg_queue *msq, int msqflg) @@ -1355,12 +1451,20 @@ int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, int security_shm_alloc(struct shmid_kernel *shp) { + int rc = lsm_ipc_alloc(&shp->shm_perm); + + if (rc) + return rc; return call_int_hook(shm_alloc_security, 0, shp); } void security_shm_free(struct shmid_kernel *shp) { + struct kern_ipc_perm *kip = &shp->shm_perm; + call_void_hook(shm_free_security, shp); + kfree(kip->security); + kip->security = NULL; } int security_shm_associate(struct shmid_kernel *shp, int shmflg) @@ -1380,12 +1484,20 @@ int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmfl int security_sem_alloc(struct sem_array *sma) { + int rc = lsm_ipc_alloc(&sma->sem_perm); + + if (rc) + return rc; return call_int_hook(sem_alloc_security, 0, sma); } void security_sem_free(struct sem_array *sma) { + struct kern_ipc_perm *kip = &sma->sem_perm; + call_void_hook(sem_free_security, sma); + kfree(kip->security); + kip->security = NULL; } int security_sem_associate(struct sem_array *sma, int semflg) @@ -1920,12 +2032,18 @@ EXPORT_SYMBOL(security_skb_classify_flow); int security_key_alloc(struct key *key, const struct cred *cred, unsigned long flags) { + int rc = lsm_key_alloc(key); + + if (rc) + return rc; return call_int_hook(key_alloc, 0, key, cred, flags); } void security_key_free(struct key *key) { call_void_hook(key_free, key); + kfree(key->security); + key->security = NULL; } int security_key_permission(key_ref_t key_ref, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6effdf9..d20c46a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -5192,54 +5192,26 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) return selinux_nlmsg_perm(sk, skb); } -static int ipc_alloc_security(struct task_struct *task, - struct kern_ipc_perm *perm, +static void ipc_init_security(struct task_struct *task, + struct ipc_security_struct *isec, u16 sclass) { - struct ipc_security_struct *isec; u32 sid; - isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); - if (!isec) - return -ENOMEM; - sid = task_sid(task); isec->sclass = sclass; isec->sid = sid; - perm->security = isec; - - return 0; -} - -static void ipc_free_security(struct kern_ipc_perm *perm) -{ - struct ipc_security_struct *isec = selinux_ipc(perm); - perm->security = NULL; - kfree(isec); } static int msg_msg_alloc_security(struct msg_msg *msg) { - struct msg_security_struct *msec; - - msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL); - if (!msec) - return -ENOMEM; + struct msg_security_struct *msec = selinux_msg_msg(msg); msec->sid = SECINITSID_UNLABELED; - msg->security = msec; return 0; } -static void msg_msg_free_security(struct msg_msg *msg) -{ - struct msg_security_struct *msec = selinux_msg_msg(msg); - - msg->security = NULL; - kfree(msec); -} - static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, u32 perms) { @@ -5260,11 +5232,6 @@ static int selinux_msg_msg_alloc_security(struct msg_msg *msg) return msg_msg_alloc_security(msg); } -static void selinux_msg_msg_free_security(struct msg_msg *msg) -{ - msg_msg_free_security(msg); -} - /* message queue security operations */ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) { @@ -5273,29 +5240,19 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) u32 sid = current_sid(); int rc; - rc = ipc_alloc_security(current, &msq->q_perm, SECCLASS_MSGQ); - if (rc) - return rc; - isec = selinux_ipc(&msq->q_perm); + ipc_init_security(current, isec, SECCLASS_MSGQ); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = msq->q_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, MSGQ__CREATE, &ad); - if (rc) { - ipc_free_security(&msq->q_perm); + if (rc) return rc; - } return 0; } -static void selinux_msg_queue_free_security(struct msg_queue *msq) -{ - ipc_free_security(&msq->q_perm); -} - static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) { struct ipc_security_struct *isec; @@ -5414,29 +5371,19 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) u32 sid = current_sid(); int rc; - rc = ipc_alloc_security(current, &shp->shm_perm, SECCLASS_SHM); - if (rc) - return rc; - isec = selinux_ipc(&shp->shm_perm); + ipc_init_security(current, isec, SECCLASS_SHM); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = shp->shm_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, SHM__CREATE, &ad); - if (rc) { - ipc_free_security(&shp->shm_perm); + if (rc) return rc; - } return 0; } -static void selinux_shm_free_security(struct shmid_kernel *shp) -{ - ipc_free_security(&shp->shm_perm); -} - static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) { struct ipc_security_struct *isec; @@ -5506,29 +5453,19 @@ static int selinux_sem_alloc_security(struct sem_array *sma) u32 sid = current_sid(); int rc; - rc = ipc_alloc_security(current, &sma->sem_perm, SECCLASS_SEM); - if (rc) - return rc; - isec = selinux_ipc(&sma->sem_perm); + ipc_init_security(current, isec, SECCLASS_SEM); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = sma->sem_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, SEM__CREATE, &ad); - if (rc) { - ipc_free_security(&sma->sem_perm); + if (rc) return rc; - } return 0; } -static void selinux_sem_free_security(struct sem_array *sma) -{ - ipc_free_security(&sma->sem_perm); -} - static int selinux_sem_associate(struct sem_array *sma, int semflg) { struct ipc_security_struct *isec; @@ -5874,11 +5811,7 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred, unsigned long flags) { const struct task_security_struct *tsec; - struct key_security_struct *ksec; - - ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL); - if (!ksec) - return -ENOMEM; + struct key_security_struct *ksec = selinux_key(k); tsec = selinux_cred(cred); if (tsec->keycreate_sid) @@ -5886,18 +5819,9 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred, else ksec->sid = tsec->sid; - k->security = ksec; return 0; } -static void selinux_key_free(struct key *k) -{ - struct key_security_struct *ksec = selinux_key(k); - - k->security = NULL; - kfree(ksec); -} - static int selinux_key_permission(key_ref_t key_ref, const struct cred *cred, unsigned perm) @@ -5942,6 +5866,9 @@ 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_ipc = sizeof(struct ipc_security_struct), + .lbs_key = sizeof(struct key_security_struct), + .lbs_msg_msg = sizeof(struct msg_security_struct), .lbs_sock = sizeof(struct sk_security_struct), .lbs_superblock = sizeof(struct superblock_security_struct), }; @@ -6049,24 +5976,20 @@ static struct security_hook_list selinux_hooks[] = { LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid), LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security), - LSM_HOOK_INIT(msg_msg_free_security, selinux_msg_msg_free_security), LSM_HOOK_INIT(msg_queue_alloc_security, selinux_msg_queue_alloc_security), - LSM_HOOK_INIT(msg_queue_free_security, selinux_msg_queue_free_security), LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate), LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl), LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd), LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv), LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security), - LSM_HOOK_INIT(shm_free_security, selinux_shm_free_security), LSM_HOOK_INIT(shm_associate, selinux_shm_associate), LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl), LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat), LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security), - LSM_HOOK_INIT(sem_free_security, selinux_sem_free_security), LSM_HOOK_INIT(sem_associate, selinux_sem_associate), LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl), LSM_HOOK_INIT(sem_semop, selinux_sem_semop), @@ -6141,7 +6064,6 @@ static struct security_hook_list selinux_hooks[] = { #ifdef CONFIG_KEYS LSM_HOOK_INIT(key_alloc, selinux_key_alloc), - LSM_HOOK_INIT(key_free, selinux_key_free), LSM_HOOK_INIT(key_permission, selinux_key_permission), LSM_HOOK_INIT(key_getsecurity, selinux_key_getsecurity), #endif diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 336172e..cd12239 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -171,18 +171,30 @@ static inline struct superblock_security_struct *selinux_superblock( static inline struct msg_security_struct *selinux_msg_msg( const struct msg_msg *msg_msg) { +#ifdef CONFIG_SECURITY_STACKING + return msg_msg->security + selinux_blob_sizes.lbs_msg_msg; +#else return msg_msg->security; +#endif } static inline struct ipc_security_struct *selinux_ipc( const struct kern_ipc_perm *ipc) { +#ifdef CONFIG_SECURITY_STACKING + return ipc->security + selinux_blob_sizes.lbs_ipc; +#else return ipc->security; +#endif } static inline struct key_security_struct *selinux_key(const struct key *key) { +#ifdef CONFIG_SECURITY_STACKING + return key->security + selinux_blob_sizes.lbs_key; +#else return key->security; +#endif } static inline struct sk_security_struct *selinux_sock(const struct sock *sock) diff --git a/security/smack/smack.h b/security/smack/smack.h index e8de2fc..f7c2945 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -387,19 +387,31 @@ static inline struct superblock_smack *smack_superblock( #endif } -static inline struct smack_known *smack_msg_msg(const struct msg_msg *msg) +static inline struct smack_known **smack_msg_msg(const struct msg_msg *msg) { +#ifdef CONFIG_SECURITY_STACKING + return msg->security + smack_blob_sizes.lbs_msg_msg; +#else return msg->security; +#endif } -static inline struct smack_known *smack_ipc(const struct kern_ipc_perm *ipc) +static inline struct smack_known **smack_ipc(const struct kern_ipc_perm *ipc) { +#ifdef CONFIG_SECURITY_STACKING + return ipc->security + smack_blob_sizes.lbs_ipc; +#else return ipc->security; +#endif } -static inline struct smack_known *smack_key(const struct key *key) +static inline struct smack_known **smack_key(const struct key *key) { +#ifdef CONFIG_SECURITY_STACKING + return key->security + smack_blob_sizes.lbs_key; +#else return key->security; +#endif } /* diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 76df1e1..9ac6487 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -2828,35 +2828,13 @@ static int smack_flags_to_may(int flags) */ static int smack_msg_msg_alloc_security(struct msg_msg *msg) { - struct smack_known *skp = smk_of_current(); + struct smack_known **blob = smack_msg_msg(msg); - msg->security = skp; + *blob = smk_of_current(); return 0; } /** - * smack_msg_msg_free_security - Clear the security blob for msg_msg - * @msg: the object - * - * Clears the blob pointer - */ -static void smack_msg_msg_free_security(struct msg_msg *msg) -{ - msg->security = NULL; -} - -/** - * smack_of_shm - the smack pointer for the shm - * @shp: the object - * - * Returns a pointer to the smack value - */ -static struct smack_known *smack_of_shm(struct shmid_kernel *shp) -{ - return smack_ipc(&shp->shm_perm); -} - -/** * smack_shm_alloc_security - Set the security blob for shm * @shp: the object * @@ -2864,27 +2842,13 @@ static struct smack_known *smack_of_shm(struct shmid_kernel *shp) */ static int smack_shm_alloc_security(struct shmid_kernel *shp) { - struct kern_ipc_perm *isp = &shp->shm_perm; - struct smack_known *skp = smk_of_current(); + struct smack_known **blob = smack_ipc(&shp->shm_perm); - isp->security = skp; + *blob = smk_of_current(); return 0; } /** - * smack_shm_free_security - Clear the security blob for shm - * @shp: the object - * - * Clears the blob pointer - */ -static void smack_shm_free_security(struct shmid_kernel *shp) -{ - struct kern_ipc_perm *isp = &shp->shm_perm; - - isp->security = NULL; -} - -/** * smk_curacc_shm : check if current has access on shm * @shp : the object * @access : access requested @@ -2893,7 +2857,8 @@ static void smack_shm_free_security(struct shmid_kernel *shp) */ static int smk_curacc_shm(struct shmid_kernel *shp, int access) { - struct smack_known *ssp = smack_of_shm(shp); + struct smack_known **blob = smack_ipc(&shp->shm_perm); + struct smack_known *ssp = *blob; struct smk_audit_info ad; int rc; @@ -2973,17 +2938,6 @@ static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, } /** - * smack_of_sem - the smack pointer for the sem - * @sma: the object - * - * Returns a pointer to the smack value - */ -static struct smack_known *smack_of_sem(struct sem_array *sma) -{ - return smack_ipc(&sma->sem_perm); -} - -/** * smack_sem_alloc_security - Set the security blob for sem * @sma: the object * @@ -2991,27 +2945,13 @@ static struct smack_known *smack_of_sem(struct sem_array *sma) */ static int smack_sem_alloc_security(struct sem_array *sma) { - struct kern_ipc_perm *isp = &sma->sem_perm; - struct smack_known *skp = smk_of_current(); + struct smack_known **blob = smack_ipc(&sma->sem_perm); - isp->security = skp; + *blob = smk_of_current(); return 0; } /** - * smack_sem_free_security - Clear the security blob for sem - * @sma: the object - * - * Clears the blob pointer - */ -static void smack_sem_free_security(struct sem_array *sma) -{ - struct kern_ipc_perm *isp = &sma->sem_perm; - - isp->security = NULL; -} - -/** * smk_curacc_sem : check if current has access on sem * @sma : the object * @access : access requested @@ -3020,7 +2960,8 @@ static void smack_sem_free_security(struct sem_array *sma) */ static int smk_curacc_sem(struct sem_array *sma, int access) { - struct smack_known *ssp = smack_of_sem(sma); + struct smack_known **blob = smack_ipc(&sma->sem_perm); + struct smack_known *ssp = *blob; struct smk_audit_info ad; int rc; @@ -3113,38 +3054,13 @@ static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops, */ static int smack_msg_queue_alloc_security(struct msg_queue *msq) { - struct kern_ipc_perm *kisp = &msq->q_perm; - struct smack_known *skp = smk_of_current(); + struct smack_known **blob = smack_ipc(&msq->q_perm); - kisp->security = skp; + *blob = smk_of_current(); return 0; } /** - * smack_msg_queue_free_security - Clear the security blob for msg - * @msq: the object - * - * Clears the blob pointer - */ -static void smack_msg_queue_free_security(struct msg_queue *msq) -{ - struct kern_ipc_perm *kisp = &msq->q_perm; - - kisp->security = NULL; -} - -/** - * smack_of_msq - the smack pointer for the msq - * @msq: the object - * - * Returns a pointer to the smack label entry - */ -static struct smack_known *smack_of_msq(struct msg_queue *msq) -{ - return smack_ipc(&msq->q_perm); -} - -/** * smk_curacc_msq : helper to check if current has access on msq * @msq : the msq * @access : access requested @@ -3153,7 +3069,8 @@ static struct smack_known *smack_of_msq(struct msg_queue *msq) */ static int smk_curacc_msq(struct msg_queue *msq, int access) { - struct smack_known *msp = smack_of_msq(msq); + struct smack_known **blob = smack_ipc(&msq->q_perm); + struct smack_known *msp = *blob; struct smk_audit_info ad; int rc; @@ -3256,7 +3173,8 @@ static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, */ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) { - struct smack_known *iskp = smack_ipc(ipp); + struct smack_known **blob = smack_ipc(ipp); + struct smack_known *iskp = *blob; int may = smack_flags_to_may(flag); struct smk_audit_info ad; int rc; @@ -3277,7 +3195,8 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) */ static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid) { - struct smack_known *iskp = smack_ipc(ipp); + struct smack_known **blob = smack_ipc(ipp); + struct smack_known *iskp = *blob; *secid = iskp->smk_secid; } @@ -4241,24 +4160,14 @@ static void smack_inet_csk_clone(struct sock *sk, static int smack_key_alloc(struct key *key, const struct cred *cred, unsigned long flags) { + struct smack_known **blob = smack_key(key); struct smack_known *skp = smk_of_task(smack_cred(cred)); - key->security = skp; + *blob = skp; return 0; } /** - * smack_key_free - Clear the key security blob - * @key: the object - * - * Clear the blob pointer - */ -static void smack_key_free(struct key *key) -{ - key->security = NULL; -} - -/** * smack_key_permission - Smack access on a key * @key_ref: gets to the object * @cred: the credentials to use @@ -4270,6 +4179,7 @@ static void smack_key_free(struct key *key) static int smack_key_permission(key_ref_t key_ref, const struct cred *cred, unsigned perm) { + struct smack_known **blob; struct smack_known *skp; struct key *keyp; struct smk_audit_info ad; @@ -4284,7 +4194,8 @@ static int smack_key_permission(key_ref_t key_ref, * If the key hasn't been initialized give it access so that * it may do so. */ - skp = smack_key(keyp); + blob = smack_key(keyp); + skp = *blob; if (skp == NULL) return 0; /* @@ -4317,7 +4228,8 @@ static int smack_key_permission(key_ref_t key_ref, */ static int smack_key_getsecurity(struct key *key, char **_buffer) { - struct smack_known *skp = smack_key(key); + struct smack_known **blob = smack_key(key); + struct smack_known *skp = *blob; size_t length; char *copy; @@ -4531,6 +4443,9 @@ 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_ipc = sizeof(struct smack_known *), + .lbs_key = sizeof(struct smack_known *), + .lbs_msg_msg = sizeof(struct smack_known *), .lbs_sock = sizeof(struct socket_smack), .lbs_superblock = sizeof(struct superblock_smack), }; @@ -4605,23 +4520,19 @@ static struct security_hook_list smack_hooks[] = { LSM_HOOK_INIT(ipc_getsecid, smack_ipc_getsecid), LSM_HOOK_INIT(msg_msg_alloc_security, smack_msg_msg_alloc_security), - LSM_HOOK_INIT(msg_msg_free_security, smack_msg_msg_free_security), LSM_HOOK_INIT(msg_queue_alloc_security, smack_msg_queue_alloc_security), - LSM_HOOK_INIT(msg_queue_free_security, smack_msg_queue_free_security), LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate), LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl), LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd), LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv), LSM_HOOK_INIT(shm_alloc_security, smack_shm_alloc_security), - LSM_HOOK_INIT(shm_free_security, smack_shm_free_security), LSM_HOOK_INIT(shm_associate, smack_shm_associate), LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl), LSM_HOOK_INIT(shm_shmat, smack_shm_shmat), LSM_HOOK_INIT(sem_alloc_security, smack_sem_alloc_security), - LSM_HOOK_INIT(sem_free_security, smack_sem_free_security), LSM_HOOK_INIT(sem_associate, smack_sem_associate), LSM_HOOK_INIT(sem_semctl, smack_sem_semctl), LSM_HOOK_INIT(sem_semop, smack_sem_semop), @@ -4651,7 +4562,6 @@ static struct security_hook_list smack_hooks[] = { /* key management security hooks */ #ifdef CONFIG_KEYS LSM_HOOK_INIT(key_alloc, smack_key_alloc), - LSM_HOOK_INIT(key_free, smack_key_free), LSM_HOOK_INIT(key_permission, smack_key_permission), LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity), #endif /* CONFIG_KEYS */