aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/sidtab.c
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2008-05-07 13:03:20 -0400
committerJames Morris <jmorris@namei.org>2008-07-14 01:01:34 -0400
commit12b29f34558b9b45a2c6eabd4f3c6be939a3980f (patch)
tree9b7921724226cd81901070026572bf05014dc41c /security/selinux/ss/sidtab.c
parentbce7f793daec3e65ec5c5705d2457b81fe7b5725 (diff)
selinux: support deferred mapping of contexts
Introduce SELinux support for deferred mapping of security contexts in the SID table upon policy reload, and use this support for inode security contexts when the context is not yet valid under the current policy. Only processes with CAP_MAC_ADMIN + mac_admin permission in policy can set undefined security contexts on inodes. Inodes with such undefined contexts are treated as having the unlabeled context until the context becomes valid upon a policy reload that defines the context. Context invalidation upon policy reload also uses this support to save the context information in the SID table and later recover it upon a subsequent policy reload that defines the context again. This support is to enable package managers and similar programs to set down file contexts unknown to the system policy at the time the file is created in order to better support placing loadable policy modules in packages and to support build systems that need to create images of different distro releases with different policies w/o requiring all of the contexts to be defined or legal in the build host policy. With this patch applied, the following sequence is possible, although in practice it is recommended that this permission only be allowed to specific program domains such as the package manager. # rmdir baz # rm bar # touch bar # chcon -t foo_exec_t bar # foo_exec_t is not yet defined chcon: failed to change context of `bar' to `system_u:object_r:foo_exec_t': Invalid argument # mkdir -Z system_u:object_r:foo_exec_t baz mkdir: failed to set default file creation context to `system_u:object_r:foo_exec_t': Invalid argument # cat setundefined.te policy_module(setundefined, 1.0) require { type unconfined_t; type unlabeled_t; } files_type(unlabeled_t) allow unconfined_t self:capability2 mac_admin; # make -f /usr/share/selinux/devel/Makefile setundefined.pp # semodule -i setundefined.pp # chcon -t foo_exec_t bar # foo_exec_t is not yet defined # mkdir -Z system_u:object_r:foo_exec_t baz # ls -Zd bar baz -rw-r--r-- root root system_u:object_r:unlabeled_t bar drwxr-xr-x root root system_u:object_r:unlabeled_t baz # cat foo.te policy_module(foo, 1.0) type foo_exec_t; files_type(foo_exec_t) # make -f /usr/share/selinux/devel/Makefile foo.pp # semodule -i foo.pp # defines foo_exec_t # ls -Zd bar baz -rw-r--r-- root root user_u:object_r:foo_exec_t bar drwxr-xr-x root root system_u:object_r:foo_exec_t baz # semodule -r foo # ls -Zd bar baz -rw-r--r-- root root system_u:object_r:unlabeled_t bar drwxr-xr-x root root system_u:object_r:unlabeled_t baz # semodule -i foo.pp # ls -Zd bar baz -rw-r--r-- root root user_u:object_r:foo_exec_t bar drwxr-xr-x root root system_u:object_r:foo_exec_t baz # semodule -r setundefined foo # chcon -t foo_exec_t bar # no longer defined and not allowed chcon: failed to change context of `bar' to `system_u:object_r:foo_exec_t': Invalid argument # rmdir baz # mkdir -Z system_u:object_r:foo_exec_t baz mkdir: failed to set default file creation context to `system_u:object_r:foo_exec_t': Invalid argument Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/ss/sidtab.c')
-rw-r--r--security/selinux/ss/sidtab.c58
1 files changed, 19 insertions, 39 deletions
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index 4a516ff4bcde..ba3541640491 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -86,7 +86,7 @@ out:
86 return rc; 86 return rc;
87} 87}
88 88
89struct context *sidtab_search(struct sidtab *s, u32 sid) 89static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force)
90{ 90{
91 int hvalue; 91 int hvalue;
92 struct sidtab_node *cur; 92 struct sidtab_node *cur;
@@ -99,7 +99,10 @@ struct context *sidtab_search(struct sidtab *s, u32 sid)
99 while (cur != NULL && sid > cur->sid) 99 while (cur != NULL && sid > cur->sid)
100 cur = cur->next; 100 cur = cur->next;
101 101
102 if (cur == NULL || sid != cur->sid) { 102 if (force && cur && sid == cur->sid && cur->context.len)
103 return &cur->context;
104
105 if (cur == NULL || sid != cur->sid || cur->context.len) {
103 /* Remap invalid SIDs to the unlabeled SID. */ 106 /* Remap invalid SIDs to the unlabeled SID. */
104 sid = SECINITSID_UNLABELED; 107 sid = SECINITSID_UNLABELED;
105 hvalue = SIDTAB_HASH(sid); 108 hvalue = SIDTAB_HASH(sid);
@@ -113,6 +116,16 @@ struct context *sidtab_search(struct sidtab *s, u32 sid)
113 return &cur->context; 116 return &cur->context;
114} 117}
115 118
119struct context *sidtab_search(struct sidtab *s, u32 sid)
120{
121 return sidtab_search_core(s, sid, 0);
122}
123
124struct context *sidtab_search_force(struct sidtab *s, u32 sid)
125{
126 return sidtab_search_core(s, sid, 1);
127}
128
116int sidtab_map(struct sidtab *s, 129int sidtab_map(struct sidtab *s,
117 int (*apply) (u32 sid, 130 int (*apply) (u32 sid,
118 struct context *context, 131 struct context *context,
@@ -138,43 +151,6 @@ out:
138 return rc; 151 return rc;
139} 152}
140 153
141void sidtab_map_remove_on_error(struct sidtab *s,
142 int (*apply) (u32 sid,
143 struct context *context,
144 void *args),
145 void *args)
146{
147 int i, ret;
148 struct sidtab_node *last, *cur, *temp;
149
150 if (!s)
151 return;
152
153 for (i = 0; i < SIDTAB_SIZE; i++) {
154 last = NULL;
155 cur = s->htable[i];
156 while (cur != NULL) {
157 ret = apply(cur->sid, &cur->context, args);
158 if (ret) {
159 if (last)
160 last->next = cur->next;
161 else
162 s->htable[i] = cur->next;
163 temp = cur;
164 cur = cur->next;
165 context_destroy(&temp->context);
166 kfree(temp);
167 s->nel--;
168 } else {
169 last = cur;
170 cur = cur->next;
171 }
172 }
173 }
174
175 return;
176}
177
178static inline u32 sidtab_search_context(struct sidtab *s, 154static inline u32 sidtab_search_context(struct sidtab *s,
179 struct context *context) 155 struct context *context)
180{ 156{
@@ -215,6 +191,10 @@ int sidtab_context_to_sid(struct sidtab *s,
215 goto unlock_out; 191 goto unlock_out;
216 } 192 }
217 sid = s->next_sid++; 193 sid = s->next_sid++;
194 if (context->len)
195 printk(KERN_INFO
196 "SELinux: Context %s is not valid (left unmapped).\n",
197 context->str);
218 ret = sidtab_insert(s, sid, context); 198 ret = sidtab_insert(s, sid, context);
219 if (ret) 199 if (ret)
220 s->next_sid--; 200 s->next_sid--;