diff options
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r-- | security/selinux/ss/services.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 85e429884393..b00ec69f0ffd 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -1817,6 +1817,75 @@ out: | |||
1817 | return rc; | 1817 | return rc; |
1818 | } | 1818 | } |
1819 | 1819 | ||
1820 | /* | ||
1821 | * security_sid_mls_copy() - computes a new sid based on the given | ||
1822 | * sid and the mls portion of mls_sid. | ||
1823 | */ | ||
1824 | int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) | ||
1825 | { | ||
1826 | struct context *context1; | ||
1827 | struct context *context2; | ||
1828 | struct context newcon; | ||
1829 | char *s; | ||
1830 | u32 len; | ||
1831 | int rc = 0; | ||
1832 | |||
1833 | if (!ss_initialized) { | ||
1834 | *new_sid = sid; | ||
1835 | goto out; | ||
1836 | } | ||
1837 | |||
1838 | context_init(&newcon); | ||
1839 | |||
1840 | POLICY_RDLOCK; | ||
1841 | context1 = sidtab_search(&sidtab, sid); | ||
1842 | if (!context1) { | ||
1843 | printk(KERN_ERR "security_sid_mls_copy: unrecognized SID " | ||
1844 | "%d\n", sid); | ||
1845 | rc = -EINVAL; | ||
1846 | goto out_unlock; | ||
1847 | } | ||
1848 | |||
1849 | context2 = sidtab_search(&sidtab, mls_sid); | ||
1850 | if (!context2) { | ||
1851 | printk(KERN_ERR "security_sid_mls_copy: unrecognized SID " | ||
1852 | "%d\n", mls_sid); | ||
1853 | rc = -EINVAL; | ||
1854 | goto out_unlock; | ||
1855 | } | ||
1856 | |||
1857 | newcon.user = context1->user; | ||
1858 | newcon.role = context1->role; | ||
1859 | newcon.type = context1->type; | ||
1860 | rc = mls_copy_context(&newcon, context2); | ||
1861 | if (rc) | ||
1862 | goto out_unlock; | ||
1863 | |||
1864 | |||
1865 | /* Check the validity of the new context. */ | ||
1866 | if (!policydb_context_isvalid(&policydb, &newcon)) { | ||
1867 | rc = convert_context_handle_invalid_context(&newcon); | ||
1868 | if (rc) | ||
1869 | goto bad; | ||
1870 | } | ||
1871 | |||
1872 | rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid); | ||
1873 | goto out_unlock; | ||
1874 | |||
1875 | bad: | ||
1876 | if (!context_struct_to_string(&newcon, &s, &len)) { | ||
1877 | audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, | ||
1878 | "security_sid_mls_copy: invalid context %s", s); | ||
1879 | kfree(s); | ||
1880 | } | ||
1881 | |||
1882 | out_unlock: | ||
1883 | POLICY_RDUNLOCK; | ||
1884 | context_destroy(&newcon); | ||
1885 | out: | ||
1886 | return rc; | ||
1887 | } | ||
1888 | |||
1820 | struct selinux_audit_rule { | 1889 | struct selinux_audit_rule { |
1821 | u32 au_seqno; | 1890 | u32 au_seqno; |
1822 | struct context au_ctxt; | 1891 | struct context au_ctxt; |