Blame view
security/tomoyo/domain.c
14.6 KB
26a2a1c9e Domain transition... |
1 2 3 |
/* * security/tomoyo/domain.c * |
c3ef1500e TOMOYO: Split fil... |
4 |
* Domain transition functions for TOMOYO. |
26a2a1c9e Domain transition... |
5 |
* |
c3ef1500e TOMOYO: Split fil... |
6 |
* Copyright (C) 2005-2010 NTT DATA CORPORATION |
26a2a1c9e Domain transition... |
7 8 9 |
*/ #include "common.h" |
26a2a1c9e Domain transition... |
10 |
#include <linux/binfmts.h> |
5a0e3ad6a include cleanup: ... |
11 |
#include <linux/slab.h> |
26a2a1c9e Domain transition... |
12 13 14 15 16 |
/* Variables definitions.*/ /* The initial domain. */ struct tomoyo_domain_info tomoyo_kernel_domain; |
237ab459f TOMOYO: Use callb... |
17 |
/** |
36f5e1ffb TOMOYO: Use callb... |
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
* tomoyo_update_policy - Update an entry for exception policy. * * @new_entry: Pointer to "struct tomoyo_acl_info". * @size: Size of @new_entry in bytes. * @is_delete: True if it is a delete request. * @list: Pointer to "struct list_head". * @check_duplicate: Callback function to find duplicated entry. * * Returns 0 on success, negative value otherwise. * * Caller holds tomoyo_read_lock(). */ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size, bool is_delete, struct list_head *list, bool (*check_duplicate) (const struct tomoyo_acl_head *, const struct tomoyo_acl_head *)) { int error = is_delete ? -ENOENT : -ENOMEM; struct tomoyo_acl_head *entry; if (mutex_lock_interruptible(&tomoyo_policy_lock)) return -ENOMEM; list_for_each_entry_rcu(entry, list, list) { if (!check_duplicate(entry, new_entry)) continue; entry->is_deleted = is_delete; error = 0; break; } if (error && !is_delete) { entry = tomoyo_commit_ok(new_entry, size); if (entry) { list_add_tail_rcu(&entry->list, list); error = 0; } } mutex_unlock(&tomoyo_policy_lock); return error; } /** |
237ab459f TOMOYO: Use callb... |
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
* tomoyo_update_domain - Update an entry for domain policy. * * @new_entry: Pointer to "struct tomoyo_acl_info". * @size: Size of @new_entry in bytes. * @is_delete: True if it is a delete request. * @domain: Pointer to "struct tomoyo_domain_info". * @check_duplicate: Callback function to find duplicated entry. * @merge_duplicate: Callback function to merge duplicated entry. * * Returns 0 on success, negative value otherwise. * * Caller holds tomoyo_read_lock(). */ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, bool is_delete, struct tomoyo_domain_info *domain, bool (*check_duplicate) (const struct tomoyo_acl_info *, const struct tomoyo_acl_info *), bool (*merge_duplicate) (struct tomoyo_acl_info *, struct tomoyo_acl_info *, const bool)) { int error = is_delete ? -ENOENT : -ENOMEM; struct tomoyo_acl_info *entry; if (mutex_lock_interruptible(&tomoyo_policy_lock)) return error; list_for_each_entry_rcu(entry, &domain->acl_info_list, list) { if (!check_duplicate(entry, new_entry)) continue; if (merge_duplicate) entry->is_deleted = merge_duplicate(entry, new_entry, is_delete); else entry->is_deleted = is_delete; error = 0; break; } if (error && !is_delete) { entry = tomoyo_commit_ok(new_entry, size); if (entry) { list_add_tail_rcu(&entry->list, &domain->acl_info_list); error = 0; } } mutex_unlock(&tomoyo_policy_lock); return error; } |
99a852596 TOMOYO: Use callb... |
110 |
void tomoyo_check_acl(struct tomoyo_request_info *r, |
484ca79c6 TOMOYO: Use pathn... |
111 |
bool (*check_entry) (struct tomoyo_request_info *, |
99a852596 TOMOYO: Use callb... |
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
const struct tomoyo_acl_info *)) { const struct tomoyo_domain_info *domain = r->domain; struct tomoyo_acl_info *ptr; list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { if (ptr->is_deleted || ptr->type != r->param_type) continue; if (check_entry(r, ptr)) { r->granted = true; return; } } r->granted = false; } |
a230f9e71 TOMOYO: Use array... |
127 |
/* The list for "struct tomoyo_domain_info". */ |
26a2a1c9e Domain transition... |
128 |
LIST_HEAD(tomoyo_domain_list); |
26a2a1c9e Domain transition... |
129 |
|
a230f9e71 TOMOYO: Use array... |
130 131 |
struct list_head tomoyo_policy_list[TOMOYO_MAX_POLICY]; struct list_head tomoyo_group_list[TOMOYO_MAX_GROUP]; |
26a2a1c9e Domain transition... |
132 |
/** |
e2bf69077 TOMOYO: Rename sy... |
133 |
* tomoyo_last_word - Get last component of a domainname. |
26a2a1c9e Domain transition... |
134 |
* |
e2bf69077 TOMOYO: Rename sy... |
135 |
* @domainname: Domainname to check. |
26a2a1c9e Domain transition... |
136 |
* |
e2bf69077 TOMOYO: Rename sy... |
137 |
* Returns the last word of @domainname. |
26a2a1c9e Domain transition... |
138 |
*/ |
e2bf69077 TOMOYO: Rename sy... |
139 |
static const char *tomoyo_last_word(const char *name) |
26a2a1c9e Domain transition... |
140 |
{ |
e2bf69077 TOMOYO: Rename sy... |
141 142 143 144 |
const char *cp = strrchr(name, ' '); if (cp) return cp + 1; return name; |
26a2a1c9e Domain transition... |
145 |
} |
e2bf69077 TOMOYO: Rename sy... |
146 147 |
static bool tomoyo_same_transition_control(const struct tomoyo_acl_head *a, const struct tomoyo_acl_head *b) |
36f5e1ffb TOMOYO: Use callb... |
148 |
{ |
5448ec4f5 TOMOYO: Use commo... |
149 150 151 152 153 154 155 |
const struct tomoyo_transition_control *p1 = container_of(a, typeof(*p1), head); const struct tomoyo_transition_control *p2 = container_of(b, typeof(*p2), head); return p1->type == p2->type && p1->is_last_name == p2->is_last_name |
36f5e1ffb TOMOYO: Use callb... |
156 157 158 |
&& p1->domainname == p2->domainname && p1->program == p2->program; } |
26a2a1c9e Domain transition... |
159 |
/** |
5448ec4f5 TOMOYO: Use commo... |
160 |
* tomoyo_update_transition_control_entry - Update "struct tomoyo_transition_control" list. |
26a2a1c9e Domain transition... |
161 |
* |
5448ec4f5 TOMOYO: Use commo... |
162 163 164 |
* @domainname: The name of domain. Maybe NULL. * @program: The name of program. Maybe NULL. * @type: Type of transition. |
26a2a1c9e Domain transition... |
165 166 167 168 |
* @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. */ |
5448ec4f5 TOMOYO: Use commo... |
169 |
static int tomoyo_update_transition_control_entry(const char *domainname, |
26a2a1c9e Domain transition... |
170 |
const char *program, |
5448ec4f5 TOMOYO: Use commo... |
171 |
const u8 type, |
26a2a1c9e Domain transition... |
172 173 |
const bool is_delete) { |
5448ec4f5 TOMOYO: Use commo... |
174 |
struct tomoyo_transition_control e = { .type = type }; |
ca0b7df33 TOMOYO: Reduce li... |
175 |
int error = is_delete ? -ENOENT : -ENOMEM; |
5448ec4f5 TOMOYO: Use commo... |
176 177 178 179 180 181 182 |
if (program) { if (!tomoyo_correct_path(program)) return -EINVAL; e.program = tomoyo_get_name(program); if (!e.program) goto out; } |
26a2a1c9e Domain transition... |
183 |
if (domainname) { |
5448ec4f5 TOMOYO: Use commo... |
184 185 186 |
if (!tomoyo_correct_domain(domainname)) { if (!tomoyo_correct_path(domainname)) goto out; |
9e4b50e93 TOMOYO: Use stack... |
187 |
e.is_last_name = true; |
5448ec4f5 TOMOYO: Use commo... |
188 |
} |
9e4b50e93 TOMOYO: Use stack... |
189 190 |
e.domainname = tomoyo_get_name(domainname); if (!e.domainname) |
ca0b7df33 TOMOYO: Reduce li... |
191 |
goto out; |
26a2a1c9e Domain transition... |
192 |
} |
36f5e1ffb TOMOYO: Use callb... |
193 |
error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
a230f9e71 TOMOYO: Use array... |
194 |
&tomoyo_policy_list |
5448ec4f5 TOMOYO: Use commo... |
195 |
[TOMOYO_ID_TRANSITION_CONTROL], |
e2bf69077 TOMOYO: Rename sy... |
196 |
tomoyo_same_transition_control); |
ca0b7df33 TOMOYO: Reduce li... |
197 |
out: |
9e4b50e93 TOMOYO: Use stack... |
198 199 |
tomoyo_put_name(e.domainname); tomoyo_put_name(e.program); |
26a2a1c9e Domain transition... |
200 201 202 203 |
return error; } /** |
5448ec4f5 TOMOYO: Use commo... |
204 |
* tomoyo_write_transition_control - Write "struct tomoyo_transition_control" list. |
26a2a1c9e Domain transition... |
205 206 |
* * @data: String to parse. |
26a2a1c9e Domain transition... |
207 |
* @is_delete: True if it is a delete request. |
5448ec4f5 TOMOYO: Use commo... |
208 |
* @type: Type of this entry. |
26a2a1c9e Domain transition... |
209 210 211 |
* * Returns 0 on success, negative value otherwise. */ |
5448ec4f5 TOMOYO: Use commo... |
212 213 |
int tomoyo_write_transition_control(char *data, const bool is_delete, const u8 type) |
26a2a1c9e Domain transition... |
214 |
{ |
5448ec4f5 TOMOYO: Use commo... |
215 216 217 218 219 220 221 222 |
char *domainname = strstr(data, " from "); if (domainname) { *domainname = '\0'; domainname += 6; } else if (type == TOMOYO_TRANSITION_CONTROL_NO_KEEP || type == TOMOYO_TRANSITION_CONTROL_KEEP) { domainname = data; data = NULL; |
26a2a1c9e Domain transition... |
223 |
} |
5448ec4f5 TOMOYO: Use commo... |
224 |
return tomoyo_update_transition_control_entry(domainname, data, type, |
26a2a1c9e Domain transition... |
225 226 227 228 |
is_delete); } /** |
5448ec4f5 TOMOYO: Use commo... |
229 |
* tomoyo_transition_type - Get domain transition type. |
26a2a1c9e Domain transition... |
230 231 232 |
* * @domainname: The name of domain. * @program: The name of program. |
26a2a1c9e Domain transition... |
233 |
* |
5448ec4f5 TOMOYO: Use commo... |
234 235 236 |
* Returns TOMOYO_TRANSITION_CONTROL_INITIALIZE if executing @program * reinitializes domain transition, TOMOYO_TRANSITION_CONTROL_KEEP if executing * @program suppresses domain transition, others otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
237 238 |
* * Caller holds tomoyo_read_lock(). |
26a2a1c9e Domain transition... |
239 |
*/ |
5448ec4f5 TOMOYO: Use commo... |
240 241 |
static u8 tomoyo_transition_type(const struct tomoyo_path_info *domainname, const struct tomoyo_path_info *program) |
26a2a1c9e Domain transition... |
242 |
{ |
5448ec4f5 TOMOYO: Use commo... |
243 244 245 246 247 248 249 250 251 |
const struct tomoyo_transition_control *ptr; const char *last_name = tomoyo_last_word(domainname->name); u8 type; for (type = 0; type < TOMOYO_MAX_TRANSITION_TYPE; type++) { next: list_for_each_entry_rcu(ptr, &tomoyo_policy_list [TOMOYO_ID_TRANSITION_CONTROL], head.list) { if (ptr->head.is_deleted || ptr->type != type) |
26a2a1c9e Domain transition... |
252 |
continue; |
5448ec4f5 TOMOYO: Use commo... |
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
if (ptr->domainname) { if (!ptr->is_last_name) { if (ptr->domainname != domainname) continue; } else { /* * Use direct strcmp() since this is * unlikely used. */ if (strcmp(ptr->domainname->name, last_name)) continue; } } if (ptr->program && tomoyo_pathcmp(ptr->program, program)) |
26a2a1c9e Domain transition... |
269 |
continue; |
5448ec4f5 TOMOYO: Use commo... |
270 271 272 273 274 275 276 277 278 |
if (type == TOMOYO_TRANSITION_CONTROL_NO_INITIALIZE) { /* * Do not check for initialize_domain if * no_initialize_domain matched. */ type = TOMOYO_TRANSITION_CONTROL_NO_KEEP; goto next; } goto done; |
26a2a1c9e Domain transition... |
279 |
} |
26a2a1c9e Domain transition... |
280 |
} |
5448ec4f5 TOMOYO: Use commo... |
281 282 |
done: return type; |
26a2a1c9e Domain transition... |
283 |
} |
e2bf69077 TOMOYO: Rename sy... |
284 285 |
static bool tomoyo_same_aggregator(const struct tomoyo_acl_head *a, const struct tomoyo_acl_head *b) |
36f5e1ffb TOMOYO: Use callb... |
286 |
{ |
e2bf69077 TOMOYO: Rename sy... |
287 288 |
const struct tomoyo_aggregator *p1 = container_of(a, typeof(*p1), head); const struct tomoyo_aggregator *p2 = container_of(b, typeof(*p2), head); |
36f5e1ffb TOMOYO: Use callb... |
289 290 291 |
return p1->original_name == p2->original_name && p1->aggregated_name == p2->aggregated_name; } |
1084307ca TOMOYO: Add pathn... |
292 |
/** |
e2bf69077 TOMOYO: Rename sy... |
293 |
* tomoyo_update_aggregator_entry - Update "struct tomoyo_aggregator" list. |
1084307ca TOMOYO: Add pathn... |
294 295 296 297 298 299 300 301 302 303 304 305 306 |
* * @original_name: The original program's name. * @aggregated_name: The program name to use. * @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. * * Caller holds tomoyo_read_lock(). */ static int tomoyo_update_aggregator_entry(const char *original_name, const char *aggregated_name, const bool is_delete) { |
e2bf69077 TOMOYO: Rename sy... |
307 |
struct tomoyo_aggregator e = { }; |
1084307ca TOMOYO: Add pathn... |
308 |
int error = is_delete ? -ENOENT : -ENOMEM; |
75093152a TOMOYO: Rename sy... |
309 310 |
if (!tomoyo_correct_path(original_name) || !tomoyo_correct_path(aggregated_name)) |
1084307ca TOMOYO: Add pathn... |
311 312 313 314 315 316 |
return -EINVAL; e.original_name = tomoyo_get_name(original_name); e.aggregated_name = tomoyo_get_name(aggregated_name); if (!e.original_name || !e.aggregated_name || e.aggregated_name->is_patterned) /* No patterns allowed. */ goto out; |
36f5e1ffb TOMOYO: Use callb... |
317 |
error = tomoyo_update_policy(&e.head, sizeof(e), is_delete, |
a230f9e71 TOMOYO: Use array... |
318 |
&tomoyo_policy_list[TOMOYO_ID_AGGREGATOR], |
e2bf69077 TOMOYO: Rename sy... |
319 |
tomoyo_same_aggregator); |
1084307ca TOMOYO: Add pathn... |
320 321 322 323 324 325 326 |
out: tomoyo_put_name(e.original_name); tomoyo_put_name(e.aggregated_name); return error; } /** |
e2bf69077 TOMOYO: Rename sy... |
327 |
* tomoyo_write_aggregator - Write "struct tomoyo_aggregator" list. |
1084307ca TOMOYO: Add pathn... |
328 329 330 331 332 333 334 335 |
* * @data: String to parse. * @is_delete: True if it is a delete request. * * Returns 0 on success, negative value otherwise. * * Caller holds tomoyo_read_lock(). */ |
e2bf69077 TOMOYO: Rename sy... |
336 |
int tomoyo_write_aggregator(char *data, const bool is_delete) |
1084307ca TOMOYO: Add pathn... |
337 338 339 340 341 342 343 344 |
{ char *cp = strchr(data, ' '); if (!cp) return -EINVAL; *cp++ = '\0'; return tomoyo_update_aggregator_entry(data, cp, is_delete); } |
26a2a1c9e Domain transition... |
345 |
/** |
e2bf69077 TOMOYO: Rename sy... |
346 |
* tomoyo_assign_domain - Create a domain. |
26a2a1c9e Domain transition... |
347 348 349 350 351 |
* * @domainname: The name of domain. * @profile: Profile number to assign if the domain was newly created. * * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
352 353 |
* * Caller holds tomoyo_read_lock(). |
26a2a1c9e Domain transition... |
354 |
*/ |
e2bf69077 TOMOYO: Rename sy... |
355 356 |
struct tomoyo_domain_info *tomoyo_assign_domain(const char *domainname, const u8 profile) |
26a2a1c9e Domain transition... |
357 |
{ |
ca0b7df33 TOMOYO: Reduce li... |
358 |
struct tomoyo_domain_info *entry; |
292823814 TOMOYO: Use mutex... |
359 |
struct tomoyo_domain_info *domain = NULL; |
26a2a1c9e Domain transition... |
360 |
const struct tomoyo_path_info *saved_domainname; |
ca0b7df33 TOMOYO: Reduce li... |
361 |
bool found = false; |
26a2a1c9e Domain transition... |
362 |
|
75093152a TOMOYO: Rename sy... |
363 |
if (!tomoyo_correct_domain(domainname)) |
ca0b7df33 TOMOYO: Reduce li... |
364 |
return NULL; |
bf24fb016 TOMOYO: Add refco... |
365 |
saved_domainname = tomoyo_get_name(domainname); |
26a2a1c9e Domain transition... |
366 |
if (!saved_domainname) |
ca0b7df33 TOMOYO: Reduce li... |
367 |
return NULL; |
4e5d6f7ec TOMOYO: Use GFP_N... |
368 |
entry = kzalloc(sizeof(*entry), GFP_NOFS); |
292823814 TOMOYO: Use mutex... |
369 370 |
if (mutex_lock_interruptible(&tomoyo_policy_lock)) goto out; |
ca0b7df33 TOMOYO: Reduce li... |
371 372 373 374 375 376 377 378 379 380 |
list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { if (domain->is_deleted || tomoyo_pathcmp(saved_domainname, domain->domainname)) continue; found = true; break; } if (!found && tomoyo_memory_ok(entry)) { INIT_LIST_HEAD(&entry->acl_info_list); entry->domainname = saved_domainname; |
bf24fb016 TOMOYO: Add refco... |
381 |
saved_domainname = NULL; |
ca0b7df33 TOMOYO: Reduce li... |
382 383 384 385 386 |
entry->profile = profile; list_add_tail_rcu(&entry->list, &tomoyo_domain_list); domain = entry; entry = NULL; found = true; |
26a2a1c9e Domain transition... |
387 |
} |
f737d95dd TOMOYO: Replace r... |
388 |
mutex_unlock(&tomoyo_policy_lock); |
292823814 TOMOYO: Use mutex... |
389 |
out: |
bf24fb016 TOMOYO: Add refco... |
390 |
tomoyo_put_name(saved_domainname); |
ca0b7df33 TOMOYO: Reduce li... |
391 392 |
kfree(entry); return found ? domain : NULL; |
26a2a1c9e Domain transition... |
393 394 395 396 397 |
} /** * tomoyo_find_next_domain - Find a domain. * |
56f8c9bc4 TOMOYO: Remove ne... |
398 |
* @bprm: Pointer to "struct linux_binprm". |
26a2a1c9e Domain transition... |
399 400 |
* * Returns 0 on success, negative value otherwise. |
fdb8ebb72 TOMOYO: Use RCU p... |
401 402 |
* * Caller holds tomoyo_read_lock(). |
26a2a1c9e Domain transition... |
403 |
*/ |
56f8c9bc4 TOMOYO: Remove ne... |
404 |
int tomoyo_find_next_domain(struct linux_binprm *bprm) |
26a2a1c9e Domain transition... |
405 |
{ |
17fcfbd9d TOMOYO: Add inter... |
406 |
struct tomoyo_request_info r; |
c8c57e842 TOMOYO: Support l... |
407 |
char *tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS); |
26a2a1c9e Domain transition... |
408 409 |
struct tomoyo_domain_info *old_domain = tomoyo_domain(); struct tomoyo_domain_info *domain = NULL; |
26a2a1c9e Domain transition... |
410 |
const char *original_name = bprm->filename; |
57c2590fb TOMOYO: Update pr... |
411 412 |
u8 mode; bool is_enforce; |
26a2a1c9e Domain transition... |
413 |
int retval = -ENOMEM; |
c8c57e842 TOMOYO: Support l... |
414 415 |
bool need_kfree = false; struct tomoyo_path_info rn = { }; /* real name */ |
26a2a1c9e Domain transition... |
416 |
|
57c2590fb TOMOYO: Update pr... |
417 418 |
mode = tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_EXECUTE); is_enforce = (mode == TOMOYO_CONFIG_ENFORCING); |
26a2a1c9e Domain transition... |
419 420 |
if (!tmp) goto out; |
17fcfbd9d TOMOYO: Add inter... |
421 |
retry: |
c8c57e842 TOMOYO: Support l... |
422 423 424 425 |
if (need_kfree) { kfree(rn.name); need_kfree = false; } |
0617c7ff3 TOMOYO: Remove al... |
426 |
/* Get symlink's pathname of program. */ |
26a2a1c9e Domain transition... |
427 |
retval = -ENOENT; |
0617c7ff3 TOMOYO: Remove al... |
428 |
rn.name = tomoyo_realpath_nofollow(original_name); |
c8c57e842 TOMOYO: Support l... |
429 |
if (!rn.name) |
26a2a1c9e Domain transition... |
430 |
goto out; |
c8c57e842 TOMOYO: Support l... |
431 432 |
tomoyo_fill_path_info(&rn); need_kfree = true; |
1084307ca TOMOYO: Add pathn... |
433 434 |
/* Check 'aggregator' directive. */ { |
e2bf69077 TOMOYO: Rename sy... |
435 |
struct tomoyo_aggregator *ptr; |
a230f9e71 TOMOYO: Use array... |
436 437 |
list_for_each_entry_rcu(ptr, &tomoyo_policy_list [TOMOYO_ID_AGGREGATOR], head.list) { |
82e0f001a TOMOYO: Use commo... |
438 |
if (ptr->head.is_deleted || |
1084307ca TOMOYO: Add pathn... |
439 440 441 |
!tomoyo_path_matches_pattern(&rn, ptr->original_name)) continue; |
0617c7ff3 TOMOYO: Remove al... |
442 |
kfree(rn.name); |
1084307ca TOMOYO: Add pathn... |
443 444 445 446 447 448 |
need_kfree = false; /* This is OK because it is read only. */ rn = *ptr->aggregated_name; break; } } |
26a2a1c9e Domain transition... |
449 |
/* Check execute permission. */ |
05336dee9 TOMOYO: Use commo... |
450 |
retval = tomoyo_path_permission(&r, TOMOYO_TYPE_EXECUTE, &rn); |
17fcfbd9d TOMOYO: Add inter... |
451 452 |
if (retval == TOMOYO_RETRY_REQUEST) goto retry; |
26a2a1c9e Domain transition... |
453 454 |
if (retval < 0) goto out; |
484ca79c6 TOMOYO: Use pathn... |
455 456 457 458 459 460 461 462 463 464 465 466 467 |
/* * To be able to specify domainnames with wildcards, use the * pathname specified in the policy (which may contain * wildcard) rather than the pathname passed to execve() * (which never contains wildcard). */ if (r.param.path.matched_path) { if (need_kfree) kfree(rn.name); need_kfree = false; /* This is OK because it is read only. */ rn = *r.param.path.matched_path; } |
26a2a1c9e Domain transition... |
468 |
|
5448ec4f5 TOMOYO: Use commo... |
469 470 471 |
/* Calculate domain to transit to. */ switch (tomoyo_transition_type(old_domain->domainname, &rn)) { case TOMOYO_TRANSITION_CONTROL_INITIALIZE: |
26a2a1c9e Domain transition... |
472 |
/* Transit to the child of tomoyo_kernel_domain domain. */ |
5448ec4f5 TOMOYO: Use commo... |
473 474 475 476 |
snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, TOMOYO_ROOT_NAME " " "%s", rn.name); break; case TOMOYO_TRANSITION_CONTROL_KEEP: |
26a2a1c9e Domain transition... |
477 478 |
/* Keep current domain. */ domain = old_domain; |
5448ec4f5 TOMOYO: Use commo... |
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
break; default: if (old_domain == &tomoyo_kernel_domain && !tomoyo_policy_loaded) { /* * Needn't to transit from kernel domain before * starting /sbin/init. But transit from kernel domain * if executing initializers because they might start * before /sbin/init. */ domain = old_domain; } else { /* Normal domain transition. */ snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1, "%s %s", old_domain->domainname->name, rn.name); } break; |
26a2a1c9e Domain transition... |
496 |
} |
c8c57e842 TOMOYO: Support l... |
497 |
if (domain || strlen(tmp) >= TOMOYO_EXEC_TMPSIZE - 10) |
26a2a1c9e Domain transition... |
498 |
goto done; |
c8c57e842 TOMOYO: Support l... |
499 |
domain = tomoyo_find_domain(tmp); |
26a2a1c9e Domain transition... |
500 501 |
if (domain) goto done; |
17fcfbd9d TOMOYO: Add inter... |
502 503 504 |
if (is_enforce) { int error = tomoyo_supervisor(&r, "# wants to create domain " |
c8c57e842 TOMOYO: Support l... |
505 506 |
"%s ", tmp); |
17fcfbd9d TOMOYO: Add inter... |
507 508 509 510 511 |
if (error == TOMOYO_RETRY_REQUEST) goto retry; if (error < 0) goto done; } |
e2bf69077 TOMOYO: Rename sy... |
512 |
domain = tomoyo_assign_domain(tmp, old_domain->profile); |
26a2a1c9e Domain transition... |
513 514 515 |
done: if (domain) goto out; |
c8c57e842 TOMOYO: Support l... |
516 517 |
printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined. ", tmp); |
26a2a1c9e Domain transition... |
518 519 520 |
if (is_enforce) retval = -EPERM; else |
ea13ddbad TOMOYO: Extract b... |
521 |
old_domain->transition_failed = true; |
26a2a1c9e Domain transition... |
522 |
out: |
56f8c9bc4 TOMOYO: Remove ne... |
523 524 |
if (!domain) domain = old_domain; |
ec8e6a4e0 TOMOYO: Add refco... |
525 526 |
/* Update reference count on "struct tomoyo_domain_info". */ atomic_inc(&domain->users); |
56f8c9bc4 TOMOYO: Remove ne... |
527 |
bprm->cred->security = domain; |
c8c57e842 TOMOYO: Support l... |
528 529 |
if (need_kfree) kfree(rn.name); |
8e2d39a16 TOMOYO: Remove us... |
530 |
kfree(tmp); |
26a2a1c9e Domain transition... |
531 532 |
return retval; } |