aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss')
-rw-r--r--security/selinux/ss/mls.c32
-rw-r--r--security/selinux/ss/mls.h4
-rw-r--r--security/selinux/ss/services.c239
3 files changed, 271 insertions, 4 deletions
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 640d0bfdbc68..7bc5b6440f70 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -8,7 +8,7 @@
8 * 8 *
9 * Support for enhanced MLS infrastructure. 9 * Support for enhanced MLS infrastructure.
10 * 10 *
11 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 11 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
12 */ 12 */
13 13
14#include <linux/kernel.h> 14#include <linux/kernel.h>
@@ -264,7 +264,7 @@ int mls_context_to_sid(char oldc,
264 264
265 if (!selinux_mls_enabled) { 265 if (!selinux_mls_enabled) {
266 if (def_sid != SECSID_NULL && oldc) 266 if (def_sid != SECSID_NULL && oldc)
267 *scontext += strlen(*scontext); 267 *scontext += strlen(*scontext)+1;
268 return 0; 268 return 0;
269 } 269 }
270 270
@@ -385,6 +385,34 @@ out:
385} 385}
386 386
387/* 387/*
388 * Set the MLS fields in the security context structure
389 * `context' based on the string representation in
390 * the string `str'. This function will allocate temporary memory with the
391 * given constraints of gfp_mask.
392 */
393int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
394{
395 char *tmpstr, *freestr;
396 int rc;
397
398 if (!selinux_mls_enabled)
399 return -EINVAL;
400
401 /* we need freestr because mls_context_to_sid will change
402 the value of tmpstr */
403 tmpstr = freestr = kstrdup(str, gfp_mask);
404 if (!tmpstr) {
405 rc = -ENOMEM;
406 } else {
407 rc = mls_context_to_sid(':', &tmpstr, context,
408 NULL, SECSID_NULL);
409 kfree(freestr);
410 }
411
412 return rc;
413}
414
415/*
388 * Copies the effective MLS range from `src' into `dst'. 416 * Copies the effective MLS range from `src' into `dst'.
389 */ 417 */
390static inline int mls_scopy_context(struct context *dst, 418static inline int mls_scopy_context(struct context *dst,
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index 03de697c8058..fbb42f07dd7c 100644
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -8,7 +8,7 @@
8 * 8 *
9 * Support for enhanced MLS infrastructure. 9 * Support for enhanced MLS infrastructure.
10 * 10 *
11 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 11 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
12 */ 12 */
13 13
14#ifndef _SS_MLS_H_ 14#ifndef _SS_MLS_H_
@@ -27,6 +27,8 @@ int mls_context_to_sid(char oldc,
27 struct sidtab *s, 27 struct sidtab *s,
28 u32 def_sid); 28 u32 def_sid);
29 29
30int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
31
30int mls_convert_context(struct policydb *oldp, 32int mls_convert_context(struct policydb *oldp,
31 struct policydb *newp, 33 struct policydb *newp,
32 struct context *context); 34 struct context *context);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 61492485de84..c284dbb8b8c0 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -7,12 +7,13 @@
7 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> 7 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
8 * 8 *
9 * Support for enhanced MLS infrastructure. 9 * Support for enhanced MLS infrastructure.
10 * Support for context based audit filters.
10 * 11 *
11 * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> 12 * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
12 * 13 *
13 * Added conditional policy language extensions 14 * Added conditional policy language extensions
14 * 15 *
15 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 16 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
16 * Copyright (C) 2003 - 2004 Tresys Technology, LLC 17 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
17 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> 18 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
18 * This program is free software; you can redistribute it and/or modify 19 * This program is free software; you can redistribute it and/or modify
@@ -593,6 +594,10 @@ int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
593 594
594 *scontext_len = strlen(initial_sid_to_string[sid]) + 1; 595 *scontext_len = strlen(initial_sid_to_string[sid]) + 1;
595 scontextp = kmalloc(*scontext_len,GFP_ATOMIC); 596 scontextp = kmalloc(*scontext_len,GFP_ATOMIC);
597 if (!scontextp) {
598 rc = -ENOMEM;
599 goto out;
600 }
596 strcpy(scontextp, initial_sid_to_string[sid]); 601 strcpy(scontextp, initial_sid_to_string[sid]);
597 *scontext = scontextp; 602 *scontext = scontextp;
598 goto out; 603 goto out;
@@ -1811,3 +1816,235 @@ out:
1811 POLICY_RDUNLOCK; 1816 POLICY_RDUNLOCK;
1812 return rc; 1817 return rc;
1813} 1818}
1819
1820struct selinux_audit_rule {
1821 u32 au_seqno;
1822 struct context au_ctxt;
1823};
1824
1825void selinux_audit_rule_free(struct selinux_audit_rule *rule)
1826{
1827 if (rule) {
1828 context_destroy(&rule->au_ctxt);
1829 kfree(rule);
1830 }
1831}
1832
1833int selinux_audit_rule_init(u32 field, u32 op, char *rulestr,
1834 struct selinux_audit_rule **rule)
1835{
1836 struct selinux_audit_rule *tmprule;
1837 struct role_datum *roledatum;
1838 struct type_datum *typedatum;
1839 struct user_datum *userdatum;
1840 int rc = 0;
1841
1842 *rule = NULL;
1843
1844 if (!ss_initialized)
1845 return -ENOTSUPP;
1846
1847 switch (field) {
1848 case AUDIT_SE_USER:
1849 case AUDIT_SE_ROLE:
1850 case AUDIT_SE_TYPE:
1851 /* only 'equals' and 'not equals' fit user, role, and type */
1852 if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL)
1853 return -EINVAL;
1854 break;
1855 case AUDIT_SE_SEN:
1856 case AUDIT_SE_CLR:
1857 /* we do not allow a range, indicated by the presense of '-' */
1858 if (strchr(rulestr, '-'))
1859 return -EINVAL;
1860 break;
1861 default:
1862 /* only the above fields are valid */
1863 return -EINVAL;
1864 }
1865
1866 tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL);
1867 if (!tmprule)
1868 return -ENOMEM;
1869
1870 context_init(&tmprule->au_ctxt);
1871
1872 POLICY_RDLOCK;
1873
1874 tmprule->au_seqno = latest_granting;
1875
1876 switch (field) {
1877 case AUDIT_SE_USER:
1878 userdatum = hashtab_search(policydb.p_users.table, rulestr);
1879 if (!userdatum)
1880 rc = -EINVAL;
1881 else
1882 tmprule->au_ctxt.user = userdatum->value;
1883 break;
1884 case AUDIT_SE_ROLE:
1885 roledatum = hashtab_search(policydb.p_roles.table, rulestr);
1886 if (!roledatum)
1887 rc = -EINVAL;
1888 else
1889 tmprule->au_ctxt.role = roledatum->value;
1890 break;
1891 case AUDIT_SE_TYPE:
1892 typedatum = hashtab_search(policydb.p_types.table, rulestr);
1893 if (!typedatum)
1894 rc = -EINVAL;
1895 else
1896 tmprule->au_ctxt.type = typedatum->value;
1897 break;
1898 case AUDIT_SE_SEN:
1899 case AUDIT_SE_CLR:
1900 rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC);
1901 break;
1902 }
1903
1904 POLICY_RDUNLOCK;
1905
1906 if (rc) {
1907 selinux_audit_rule_free(tmprule);
1908 tmprule = NULL;
1909 }
1910
1911 *rule = tmprule;
1912
1913 return rc;
1914}
1915
1916int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op,
1917 struct selinux_audit_rule *rule,
1918 struct audit_context *actx)
1919{
1920 struct context *ctxt;
1921 struct mls_level *level;
1922 int match = 0;
1923
1924 if (!rule) {
1925 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
1926 "selinux_audit_rule_match: missing rule\n");
1927 return -ENOENT;
1928 }
1929
1930 POLICY_RDLOCK;
1931
1932 if (rule->au_seqno < latest_granting) {
1933 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
1934 "selinux_audit_rule_match: stale rule\n");
1935 match = -ESTALE;
1936 goto out;
1937 }
1938
1939 ctxt = sidtab_search(&sidtab, ctxid);
1940 if (!ctxt) {
1941 audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR,
1942 "selinux_audit_rule_match: unrecognized SID %d\n",
1943 ctxid);
1944 match = -ENOENT;
1945 goto out;
1946 }
1947
1948 /* a field/op pair that is not caught here will simply fall through
1949 without a match */
1950 switch (field) {
1951 case AUDIT_SE_USER:
1952 switch (op) {
1953 case AUDIT_EQUAL:
1954 match = (ctxt->user == rule->au_ctxt.user);
1955 break;
1956 case AUDIT_NOT_EQUAL:
1957 match = (ctxt->user != rule->au_ctxt.user);
1958 break;
1959 }
1960 break;
1961 case AUDIT_SE_ROLE:
1962 switch (op) {
1963 case AUDIT_EQUAL:
1964 match = (ctxt->role == rule->au_ctxt.role);
1965 break;
1966 case AUDIT_NOT_EQUAL:
1967 match = (ctxt->role != rule->au_ctxt.role);
1968 break;
1969 }
1970 break;
1971 case AUDIT_SE_TYPE:
1972 switch (op) {
1973 case AUDIT_EQUAL:
1974 match = (ctxt->type == rule->au_ctxt.type);
1975 break;
1976 case AUDIT_NOT_EQUAL:
1977 match = (ctxt->type != rule->au_ctxt.type);
1978 break;
1979 }
1980 break;
1981 case AUDIT_SE_SEN:
1982 case AUDIT_SE_CLR:
1983 level = (op == AUDIT_SE_SEN ?
1984 &ctxt->range.level[0] : &ctxt->range.level[1]);
1985 switch (op) {
1986 case AUDIT_EQUAL:
1987 match = mls_level_eq(&rule->au_ctxt.range.level[0],
1988 level);
1989 break;
1990 case AUDIT_NOT_EQUAL:
1991 match = !mls_level_eq(&rule->au_ctxt.range.level[0],
1992 level);
1993 break;
1994 case AUDIT_LESS_THAN:
1995 match = (mls_level_dom(&rule->au_ctxt.range.level[0],
1996 level) &&
1997 !mls_level_eq(&rule->au_ctxt.range.level[0],
1998 level));
1999 break;
2000 case AUDIT_LESS_THAN_OR_EQUAL:
2001 match = mls_level_dom(&rule->au_ctxt.range.level[0],
2002 level);
2003 break;
2004 case AUDIT_GREATER_THAN:
2005 match = (mls_level_dom(level,
2006 &rule->au_ctxt.range.level[0]) &&
2007 !mls_level_eq(level,
2008 &rule->au_ctxt.range.level[0]));
2009 break;
2010 case AUDIT_GREATER_THAN_OR_EQUAL:
2011 match = mls_level_dom(level,
2012 &rule->au_ctxt.range.level[0]);
2013 break;
2014 }
2015 }
2016
2017out:
2018 POLICY_RDUNLOCK;
2019 return match;
2020}
2021
2022static int (*aurule_callback)(void) = NULL;
2023
2024static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid,
2025 u16 class, u32 perms, u32 *retained)
2026{
2027 int err = 0;
2028
2029 if (event == AVC_CALLBACK_RESET && aurule_callback)
2030 err = aurule_callback();
2031 return err;
2032}
2033
2034static int __init aurule_init(void)
2035{
2036 int err;
2037
2038 err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET,
2039 SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0);
2040 if (err)
2041 panic("avc_add_callback() failed, error %d\n", err);
2042
2043 return err;
2044}
2045__initcall(aurule_init);
2046
2047void selinux_audit_set_callback(int (*callback)(void))
2048{
2049 aurule_callback = callback;
2050}