diff options
author | nixiaoming <nixiaoming@huawei.com> | 2018-08-05 05:10:36 -0400 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2018-08-07 17:26:25 -0400 |
commit | 7e4237faa7213c1cc1d0aa65a44c67ba4729ce9f (patch) | |
tree | 73df8262776cde450d4415380490785eb03e8b0f | |
parent | 631d2b490569118c5e4d4e35983efe36d9798cb5 (diff) |
selinux: cleanup dentry and inodes on error in selinuxfs
If the resource requested by d_alloc_name is not added to the linked
list through d_add, then dput needs to be called to release the
subsequent abnormal branch to avoid resource leakage.
Add missing dput to selinuxfs.c
Signed-off-by: nixiaoming <nixiaoming@huawei.com>
[PM: tweak the subject line]
Signed-off-by: Paul Moore <paul@paul-moore.com>
-rw-r--r-- | security/selinux/selinuxfs.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index eb7f12ab5c33..5cc9101ab79b 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -1377,13 +1377,18 @@ static int sel_make_bools(struct selinux_fs_info *fsi) | |||
1377 | 1377 | ||
1378 | ret = -ENOMEM; | 1378 | ret = -ENOMEM; |
1379 | inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR); | 1379 | inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR); |
1380 | if (!inode) | 1380 | if (!inode) { |
1381 | dput(dentry); | ||
1381 | goto out; | 1382 | goto out; |
1383 | } | ||
1382 | 1384 | ||
1383 | ret = -ENAMETOOLONG; | 1385 | ret = -ENAMETOOLONG; |
1384 | len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]); | 1386 | len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]); |
1385 | if (len >= PAGE_SIZE) | 1387 | if (len >= PAGE_SIZE) { |
1388 | dput(dentry); | ||
1389 | iput(inode); | ||
1386 | goto out; | 1390 | goto out; |
1391 | } | ||
1387 | 1392 | ||
1388 | isec = (struct inode_security_struct *)inode->i_security; | 1393 | isec = (struct inode_security_struct *)inode->i_security; |
1389 | ret = security_genfs_sid(fsi->state, "selinuxfs", page, | 1394 | ret = security_genfs_sid(fsi->state, "selinuxfs", page, |
@@ -1598,8 +1603,10 @@ static int sel_make_avc_files(struct dentry *dir) | |||
1598 | return -ENOMEM; | 1603 | return -ENOMEM; |
1599 | 1604 | ||
1600 | inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode); | 1605 | inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode); |
1601 | if (!inode) | 1606 | if (!inode) { |
1607 | dput(dentry); | ||
1602 | return -ENOMEM; | 1608 | return -ENOMEM; |
1609 | } | ||
1603 | 1610 | ||
1604 | inode->i_fop = files[i].ops; | 1611 | inode->i_fop = files[i].ops; |
1605 | inode->i_ino = ++fsi->last_ino; | 1612 | inode->i_ino = ++fsi->last_ino; |
@@ -1644,8 +1651,10 @@ static int sel_make_initcon_files(struct dentry *dir) | |||
1644 | return -ENOMEM; | 1651 | return -ENOMEM; |
1645 | 1652 | ||
1646 | inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); | 1653 | inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); |
1647 | if (!inode) | 1654 | if (!inode) { |
1655 | dput(dentry); | ||
1648 | return -ENOMEM; | 1656 | return -ENOMEM; |
1657 | } | ||
1649 | 1658 | ||
1650 | inode->i_fop = &sel_initcon_ops; | 1659 | inode->i_fop = &sel_initcon_ops; |
1651 | inode->i_ino = i|SEL_INITCON_INO_OFFSET; | 1660 | inode->i_ino = i|SEL_INITCON_INO_OFFSET; |
@@ -1745,8 +1754,10 @@ static int sel_make_perm_files(char *objclass, int classvalue, | |||
1745 | 1754 | ||
1746 | rc = -ENOMEM; | 1755 | rc = -ENOMEM; |
1747 | inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); | 1756 | inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); |
1748 | if (!inode) | 1757 | if (!inode) { |
1758 | dput(dentry); | ||
1749 | goto out; | 1759 | goto out; |
1760 | } | ||
1750 | 1761 | ||
1751 | inode->i_fop = &sel_perm_ops; | 1762 | inode->i_fop = &sel_perm_ops; |
1752 | /* i+1 since perm values are 1-indexed */ | 1763 | /* i+1 since perm values are 1-indexed */ |
@@ -1775,8 +1786,10 @@ static int sel_make_class_dir_entries(char *classname, int index, | |||
1775 | return -ENOMEM; | 1786 | return -ENOMEM; |
1776 | 1787 | ||
1777 | inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); | 1788 | inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); |
1778 | if (!inode) | 1789 | if (!inode) { |
1790 | dput(dentry); | ||
1779 | return -ENOMEM; | 1791 | return -ENOMEM; |
1792 | } | ||
1780 | 1793 | ||
1781 | inode->i_fop = &sel_class_ops; | 1794 | inode->i_fop = &sel_class_ops; |
1782 | inode->i_ino = sel_class_to_ino(index); | 1795 | inode->i_ino = sel_class_to_ino(index); |
@@ -1850,8 +1863,10 @@ static int sel_make_policycap(struct selinux_fs_info *fsi) | |||
1850 | return -ENOMEM; | 1863 | return -ENOMEM; |
1851 | 1864 | ||
1852 | inode = sel_make_inode(fsi->sb, S_IFREG | 0444); | 1865 | inode = sel_make_inode(fsi->sb, S_IFREG | 0444); |
1853 | if (inode == NULL) | 1866 | if (inode == NULL) { |
1867 | dput(dentry); | ||
1854 | return -ENOMEM; | 1868 | return -ENOMEM; |
1869 | } | ||
1855 | 1870 | ||
1856 | inode->i_fop = &sel_policycap_ops; | 1871 | inode->i_fop = &sel_policycap_ops; |
1857 | inode->i_ino = iter | SEL_POLICYCAP_INO_OFFSET; | 1872 | inode->i_ino = iter | SEL_POLICYCAP_INO_OFFSET; |
@@ -1944,8 +1959,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) | |||
1944 | 1959 | ||
1945 | ret = -ENOMEM; | 1960 | ret = -ENOMEM; |
1946 | inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO); | 1961 | inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO); |
1947 | if (!inode) | 1962 | if (!inode) { |
1963 | dput(dentry); | ||
1948 | goto err; | 1964 | goto err; |
1965 | } | ||
1949 | 1966 | ||
1950 | inode->i_ino = ++fsi->last_ino; | 1967 | inode->i_ino = ++fsi->last_ino; |
1951 | isec = (struct inode_security_struct *)inode->i_security; | 1968 | isec = (struct inode_security_struct *)inode->i_security; |