Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

LSM: Infrastructure management of the ipc security blob

Move management of the kern_ipc_perm->security and
msg_msg->security blobs 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.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
[kees: adjusted for ordered init series]
Signed-off-by: Kees Cook <keescook@chromium.org>

authored by

Casey Schaufler and committed by
Kees Cook
ecd5f82e 019bcca4

+110 -121
+2
include/linux/lsm_hooks.h
··· 2034 2034 int lbs_cred; 2035 2035 int lbs_file; 2036 2036 int lbs_inode; 2037 + int lbs_ipc; 2038 + int lbs_msg_msg; 2037 2039 int lbs_task; 2038 2040 }; 2039 2041
+87 -4
security/security.c
··· 30 30 #include <linux/personality.h> 31 31 #include <linux/backing-dev.h> 32 32 #include <linux/string.h> 33 + #include <linux/msg.h> 33 34 #include <net/flow.h> 34 35 35 36 #define MAX_LSM_EVM_XATTR 2 ··· 170 169 if (needed->lbs_inode && blob_sizes.lbs_inode == 0) 171 170 blob_sizes.lbs_inode = sizeof(struct rcu_head); 172 171 lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode); 172 + lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc); 173 + lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg); 173 174 lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task); 174 175 } 175 176 ··· 296 293 init_debug("cred blob size = %d\n", blob_sizes.lbs_cred); 297 294 init_debug("file blob size = %d\n", blob_sizes.lbs_file); 298 295 init_debug("inode blob size = %d\n", blob_sizes.lbs_inode); 296 + init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc); 297 + init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); 299 298 init_debug("task blob size = %d\n", blob_sizes.lbs_task); 300 299 301 300 /* ··· 539 534 540 535 task->security = kzalloc(blob_sizes.lbs_task, GFP_KERNEL); 541 536 if (task->security == NULL) 537 + return -ENOMEM; 538 + return 0; 539 + } 540 + 541 + /** 542 + * lsm_ipc_alloc - allocate a composite ipc blob 543 + * @kip: the ipc that needs a blob 544 + * 545 + * Allocate the ipc blob for all the modules 546 + * 547 + * Returns 0, or -ENOMEM if memory can't be allocated. 548 + */ 549 + int lsm_ipc_alloc(struct kern_ipc_perm *kip) 550 + { 551 + if (blob_sizes.lbs_ipc == 0) { 552 + kip->security = NULL; 553 + return 0; 554 + } 555 + 556 + kip->security = kzalloc(blob_sizes.lbs_ipc, GFP_KERNEL); 557 + if (kip->security == NULL) 558 + return -ENOMEM; 559 + return 0; 560 + } 561 + 562 + /** 563 + * lsm_msg_msg_alloc - allocate a composite msg_msg blob 564 + * @mp: the msg_msg that needs a blob 565 + * 566 + * Allocate the ipc blob for all the modules 567 + * 568 + * Returns 0, or -ENOMEM if memory can't be allocated. 569 + */ 570 + int lsm_msg_msg_alloc(struct msg_msg *mp) 571 + { 572 + if (blob_sizes.lbs_msg_msg == 0) { 573 + mp->security = NULL; 574 + return 0; 575 + } 576 + 577 + mp->security = kzalloc(blob_sizes.lbs_msg_msg, GFP_KERNEL); 578 + if (mp->security == NULL) 542 579 return -ENOMEM; 543 580 return 0; 544 581 } ··· 1678 1631 1679 1632 int security_msg_msg_alloc(struct msg_msg *msg) 1680 1633 { 1681 - return call_int_hook(msg_msg_alloc_security, 0, msg); 1634 + int rc = lsm_msg_msg_alloc(msg); 1635 + 1636 + if (unlikely(rc)) 1637 + return rc; 1638 + rc = call_int_hook(msg_msg_alloc_security, 0, msg); 1639 + if (unlikely(rc)) 1640 + security_msg_msg_free(msg); 1641 + return rc; 1682 1642 } 1683 1643 1684 1644 void security_msg_msg_free(struct msg_msg *msg) 1685 1645 { 1686 1646 call_void_hook(msg_msg_free_security, msg); 1647 + kfree(msg->security); 1648 + msg->security = NULL; 1687 1649 } 1688 1650 1689 1651 int security_msg_queue_alloc(struct kern_ipc_perm *msq) 1690 1652 { 1691 - return call_int_hook(msg_queue_alloc_security, 0, msq); 1653 + int rc = lsm_ipc_alloc(msq); 1654 + 1655 + if (unlikely(rc)) 1656 + return rc; 1657 + rc = call_int_hook(msg_queue_alloc_security, 0, msq); 1658 + if (unlikely(rc)) 1659 + security_msg_queue_free(msq); 1660 + return rc; 1692 1661 } 1693 1662 1694 1663 void security_msg_queue_free(struct kern_ipc_perm *msq) 1695 1664 { 1696 1665 call_void_hook(msg_queue_free_security, msq); 1666 + kfree(msq->security); 1667 + msq->security = NULL; 1697 1668 } 1698 1669 1699 1670 int security_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) ··· 1738 1673 1739 1674 int security_shm_alloc(struct kern_ipc_perm *shp) 1740 1675 { 1741 - return call_int_hook(shm_alloc_security, 0, shp); 1676 + int rc = lsm_ipc_alloc(shp); 1677 + 1678 + if (unlikely(rc)) 1679 + return rc; 1680 + rc = call_int_hook(shm_alloc_security, 0, shp); 1681 + if (unlikely(rc)) 1682 + security_shm_free(shp); 1683 + return rc; 1742 1684 } 1743 1685 1744 1686 void security_shm_free(struct kern_ipc_perm *shp) 1745 1687 { 1746 1688 call_void_hook(shm_free_security, shp); 1689 + kfree(shp->security); 1690 + shp->security = NULL; 1747 1691 } 1748 1692 1749 1693 int security_shm_associate(struct kern_ipc_perm *shp, int shmflg) ··· 1772 1698 1773 1699 int security_sem_alloc(struct kern_ipc_perm *sma) 1774 1700 { 1775 - return call_int_hook(sem_alloc_security, 0, sma); 1701 + int rc = lsm_ipc_alloc(sma); 1702 + 1703 + if (unlikely(rc)) 1704 + return rc; 1705 + rc = call_int_hook(sem_alloc_security, 0, sma); 1706 + if (unlikely(rc)) 1707 + security_sem_free(sma); 1708 + return rc; 1776 1709 } 1777 1710 1778 1711 void security_sem_free(struct kern_ipc_perm *sma) 1779 1712 { 1780 1713 call_void_hook(sem_free_security, sma); 1714 + kfree(sma->security); 1715 + sma->security = NULL; 1781 1716 } 1782 1717 1783 1718 int security_sem_associate(struct kern_ipc_perm *sma, int semflg)
+13 -85
security/selinux/hooks.c
··· 5626 5626 return selinux_nlmsg_perm(sk, skb); 5627 5627 } 5628 5628 5629 - static int ipc_alloc_security(struct kern_ipc_perm *perm, 5630 - u16 sclass) 5629 + static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass) 5631 5630 { 5632 - struct ipc_security_struct *isec; 5633 - 5634 - isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); 5635 - if (!isec) 5636 - return -ENOMEM; 5637 - 5638 5631 isec->sclass = sclass; 5639 5632 isec->sid = current_sid(); 5640 - perm->security = isec; 5641 - 5642 - return 0; 5643 - } 5644 - 5645 - static void ipc_free_security(struct kern_ipc_perm *perm) 5646 - { 5647 - struct ipc_security_struct *isec = perm->security; 5648 - perm->security = NULL; 5649 - kfree(isec); 5650 5633 } 5651 5634 5652 5635 static int msg_msg_alloc_security(struct msg_msg *msg) 5653 5636 { 5654 5637 struct msg_security_struct *msec; 5655 5638 5656 - msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL); 5657 - if (!msec) 5658 - return -ENOMEM; 5659 - 5639 + msec = selinux_msg_msg(msg); 5660 5640 msec->sid = SECINITSID_UNLABELED; 5661 - msg->security = msec; 5662 5641 5663 5642 return 0; 5664 - } 5665 - 5666 - static void msg_msg_free_security(struct msg_msg *msg) 5667 - { 5668 - struct msg_security_struct *msec = msg->security; 5669 - 5670 - msg->security = NULL; 5671 - kfree(msec); 5672 5643 } 5673 5644 5674 5645 static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, ··· 5663 5692 return msg_msg_alloc_security(msg); 5664 5693 } 5665 5694 5666 - static void selinux_msg_msg_free_security(struct msg_msg *msg) 5667 - { 5668 - msg_msg_free_security(msg); 5669 - } 5670 - 5671 5695 /* message queue security operations */ 5672 5696 static int selinux_msg_queue_alloc_security(struct kern_ipc_perm *msq) 5673 5697 { ··· 5671 5705 u32 sid = current_sid(); 5672 5706 int rc; 5673 5707 5674 - rc = ipc_alloc_security(msq, SECCLASS_MSGQ); 5675 - if (rc) 5676 - return rc; 5677 - 5678 - isec = msq->security; 5708 + isec = selinux_ipc(msq); 5709 + ipc_init_security(isec, SECCLASS_MSGQ); 5679 5710 5680 5711 ad.type = LSM_AUDIT_DATA_IPC; 5681 5712 ad.u.ipc_id = msq->key; ··· 5680 5717 rc = avc_has_perm(&selinux_state, 5681 5718 sid, isec->sid, SECCLASS_MSGQ, 5682 5719 MSGQ__CREATE, &ad); 5683 - if (rc) { 5684 - ipc_free_security(msq); 5685 - return rc; 5686 - } 5687 - return 0; 5688 - } 5689 - 5690 - static void selinux_msg_queue_free_security(struct kern_ipc_perm *msq) 5691 - { 5692 - ipc_free_security(msq); 5720 + return rc; 5693 5721 } 5694 5722 5695 5723 static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) ··· 5810 5856 u32 sid = current_sid(); 5811 5857 int rc; 5812 5858 5813 - rc = ipc_alloc_security(shp, SECCLASS_SHM); 5814 - if (rc) 5815 - return rc; 5816 - 5817 - isec = shp->security; 5859 + isec = selinux_ipc(shp); 5860 + ipc_init_security(isec, SECCLASS_SHM); 5818 5861 5819 5862 ad.type = LSM_AUDIT_DATA_IPC; 5820 5863 ad.u.ipc_id = shp->key; ··· 5819 5868 rc = avc_has_perm(&selinux_state, 5820 5869 sid, isec->sid, SECCLASS_SHM, 5821 5870 SHM__CREATE, &ad); 5822 - if (rc) { 5823 - ipc_free_security(shp); 5824 - return rc; 5825 - } 5826 - return 0; 5827 - } 5828 - 5829 - static void selinux_shm_free_security(struct kern_ipc_perm *shp) 5830 - { 5831 - ipc_free_security(shp); 5871 + return rc; 5832 5872 } 5833 5873 5834 5874 static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg) ··· 5895 5953 u32 sid = current_sid(); 5896 5954 int rc; 5897 5955 5898 - rc = ipc_alloc_security(sma, SECCLASS_SEM); 5899 - if (rc) 5900 - return rc; 5901 - 5902 - isec = sma->security; 5956 + isec = selinux_ipc(sma); 5957 + ipc_init_security(isec, SECCLASS_SEM); 5903 5958 5904 5959 ad.type = LSM_AUDIT_DATA_IPC; 5905 5960 ad.u.ipc_id = sma->key; ··· 5904 5965 rc = avc_has_perm(&selinux_state, 5905 5966 sid, isec->sid, SECCLASS_SEM, 5906 5967 SEM__CREATE, &ad); 5907 - if (rc) { 5908 - ipc_free_security(sma); 5909 - return rc; 5910 - } 5911 - return 0; 5912 - } 5913 - 5914 - static void selinux_sem_free_security(struct kern_ipc_perm *sma) 5915 - { 5916 - ipc_free_security(sma); 5968 + return rc; 5917 5969 } 5918 5970 5919 5971 static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg) ··· 6537 6607 .lbs_cred = sizeof(struct task_security_struct), 6538 6608 .lbs_file = sizeof(struct file_security_struct), 6539 6609 .lbs_inode = sizeof(struct inode_security_struct), 6610 + .lbs_ipc = sizeof(struct ipc_security_struct), 6611 + .lbs_msg_msg = sizeof(struct msg_security_struct), 6540 6612 }; 6541 6613 6542 6614 static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { ··· 6650 6718 LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid), 6651 6719 6652 6720 LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security), 6653 - LSM_HOOK_INIT(msg_msg_free_security, selinux_msg_msg_free_security), 6654 6721 6655 6722 LSM_HOOK_INIT(msg_queue_alloc_security, 6656 6723 selinux_msg_queue_alloc_security), 6657 - LSM_HOOK_INIT(msg_queue_free_security, selinux_msg_queue_free_security), 6658 6724 LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate), 6659 6725 LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl), 6660 6726 LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd), 6661 6727 LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv), 6662 6728 6663 6729 LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security), 6664 - LSM_HOOK_INIT(shm_free_security, selinux_shm_free_security), 6665 6730 LSM_HOOK_INIT(shm_associate, selinux_shm_associate), 6666 6731 LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl), 6667 6732 LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat), 6668 6733 6669 6734 LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security), 6670 - LSM_HOOK_INIT(sem_free_security, selinux_sem_free_security), 6671 6735 LSM_HOOK_INIT(sem_associate, selinux_sem_associate), 6672 6736 LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl), 6673 6737 LSM_HOOK_INIT(sem_semop, selinux_sem_semop),
+2 -2
security/selinux/include/objsec.h
··· 179 179 static inline struct msg_security_struct *selinux_msg_msg( 180 180 const struct msg_msg *msg_msg) 181 181 { 182 - return msg_msg->security; 182 + return msg_msg->security + selinux_blob_sizes.lbs_msg_msg; 183 183 } 184 184 185 185 static inline struct ipc_security_struct *selinux_ipc( 186 186 const struct kern_ipc_perm *ipc) 187 187 { 188 - return ipc->security; 188 + return ipc->security + selinux_blob_sizes.lbs_ipc; 189 189 } 190 190 191 191 #endif /* _SELINUX_OBJSEC_H_ */
+2 -2
security/smack/smack.h
··· 376 376 377 377 static inline struct smack_known **smack_msg_msg(const struct msg_msg *msg) 378 378 { 379 - return (struct smack_known **)&msg->security; 379 + return msg->security + smack_blob_sizes.lbs_msg_msg; 380 380 } 381 381 382 382 static inline struct smack_known **smack_ipc(const struct kern_ipc_perm *ipc) 383 383 { 384 - return (struct smack_known **)&ipc->security; 384 + return ipc->security + smack_blob_sizes.lbs_ipc; 385 385 } 386 386 387 387 /*
+4 -28
security/smack/smack_lsm.c
··· 2809 2809 */ 2810 2810 static int smack_msg_msg_alloc_security(struct msg_msg *msg) 2811 2811 { 2812 - struct smack_known *skp = smk_of_current(); 2812 + struct smack_known **blob = smack_msg_msg(msg); 2813 2813 2814 - msg->security = skp; 2814 + *blob = smk_of_current(); 2815 2815 return 0; 2816 - } 2817 - 2818 - /** 2819 - * smack_msg_msg_free_security - Clear the security blob for msg_msg 2820 - * @msg: the object 2821 - * 2822 - * Clears the blob pointer 2823 - */ 2824 - static void smack_msg_msg_free_security(struct msg_msg *msg) 2825 - { 2826 - msg->security = NULL; 2827 2816 } 2828 2817 2829 2818 /** ··· 2840 2851 2841 2852 *blob = smk_of_current(); 2842 2853 return 0; 2843 - } 2844 - 2845 - /** 2846 - * smack_ipc_free_security - Clear the security blob for ipc 2847 - * @isp: the object 2848 - * 2849 - * Clears the blob pointer 2850 - */ 2851 - static void smack_ipc_free_security(struct kern_ipc_perm *isp) 2852 - { 2853 - isp->security = NULL; 2854 2854 } 2855 2855 2856 2856 /** ··· 4489 4511 .lbs_cred = sizeof(struct task_smack), 4490 4512 .lbs_file = sizeof(struct smack_known *), 4491 4513 .lbs_inode = sizeof(struct inode_smack), 4514 + .lbs_ipc = sizeof(struct smack_known *), 4515 + .lbs_msg_msg = sizeof(struct smack_known *), 4492 4516 }; 4493 4517 4494 4518 static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { ··· 4561 4581 LSM_HOOK_INIT(ipc_getsecid, smack_ipc_getsecid), 4562 4582 4563 4583 LSM_HOOK_INIT(msg_msg_alloc_security, smack_msg_msg_alloc_security), 4564 - LSM_HOOK_INIT(msg_msg_free_security, smack_msg_msg_free_security), 4565 4584 4566 4585 LSM_HOOK_INIT(msg_queue_alloc_security, smack_ipc_alloc_security), 4567 - LSM_HOOK_INIT(msg_queue_free_security, smack_ipc_free_security), 4568 4586 LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate), 4569 4587 LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl), 4570 4588 LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd), 4571 4589 LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv), 4572 4590 4573 4591 LSM_HOOK_INIT(shm_alloc_security, smack_ipc_alloc_security), 4574 - LSM_HOOK_INIT(shm_free_security, smack_ipc_free_security), 4575 4592 LSM_HOOK_INIT(shm_associate, smack_shm_associate), 4576 4593 LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl), 4577 4594 LSM_HOOK_INIT(shm_shmat, smack_shm_shmat), 4578 4595 4579 4596 LSM_HOOK_INIT(sem_alloc_security, smack_ipc_alloc_security), 4580 - LSM_HOOK_INIT(sem_free_security, smack_ipc_free_security), 4581 4597 LSM_HOOK_INIT(sem_associate, smack_sem_associate), 4582 4598 LSM_HOOK_INIT(sem_semctl, smack_sem_semctl), 4583 4599 LSM_HOOK_INIT(sem_semop, smack_sem_semop),