hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/security/tomoyo/domain.c
....@@ -30,10 +30,10 @@
3030 */
3131 int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
3232 struct tomoyo_acl_param *param,
33
- bool (*check_duplicate) (const struct tomoyo_acl_head
34
- *,
35
- const struct tomoyo_acl_head
36
- *))
33
+ bool (*check_duplicate)(const struct tomoyo_acl_head
34
+ *,
35
+ const struct tomoyo_acl_head
36
+ *))
3737 {
3838 int error = param->is_delete ? -ENOENT : -ENOMEM;
3939 struct tomoyo_acl_head *entry;
....@@ -41,7 +41,8 @@
4141
4242 if (mutex_lock_interruptible(&tomoyo_policy_lock))
4343 return -ENOMEM;
44
- list_for_each_entry_rcu(entry, list, list) {
44
+ list_for_each_entry_rcu(entry, list, list,
45
+ srcu_read_lock_held(&tomoyo_ss)) {
4546 if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
4647 continue;
4748 if (!check_duplicate(entry, new_entry))
....@@ -90,13 +91,13 @@
9091 */
9192 int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
9293 struct tomoyo_acl_param *param,
93
- bool (*check_duplicate) (const struct tomoyo_acl_info
94
- *,
95
- const struct tomoyo_acl_info
96
- *),
97
- bool (*merge_duplicate) (struct tomoyo_acl_info *,
98
- struct tomoyo_acl_info *,
99
- const bool))
94
+ bool (*check_duplicate)(const struct tomoyo_acl_info
95
+ *,
96
+ const struct tomoyo_acl_info
97
+ *),
98
+ bool (*merge_duplicate)(struct tomoyo_acl_info *,
99
+ struct tomoyo_acl_info *,
100
+ const bool))
100101 {
101102 const bool is_delete = param->is_delete;
102103 int error = is_delete ? -ENOENT : -ENOMEM;
....@@ -119,7 +120,8 @@
119120 }
120121 if (mutex_lock_interruptible(&tomoyo_policy_lock))
121122 goto out;
122
- list_for_each_entry_rcu(entry, list, list) {
123
+ list_for_each_entry_rcu(entry, list, list,
124
+ srcu_read_lock_held(&tomoyo_ss)) {
123125 if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
124126 continue;
125127 if (!tomoyo_same_acl_head(entry, new_entry) ||
....@@ -157,16 +159,17 @@
157159 * Caller holds tomoyo_read_lock().
158160 */
159161 void tomoyo_check_acl(struct tomoyo_request_info *r,
160
- bool (*check_entry) (struct tomoyo_request_info *,
161
- const struct tomoyo_acl_info *))
162
+ bool (*check_entry)(struct tomoyo_request_info *,
163
+ const struct tomoyo_acl_info *))
162164 {
163165 const struct tomoyo_domain_info *domain = r->domain;
164166 struct tomoyo_acl_info *ptr;
165
- bool retried = false;
166167 const struct list_head *list = &domain->acl_info_list;
168
+ u16 i = 0;
167169
168170 retry:
169
- list_for_each_entry_rcu(ptr, list, list) {
171
+ list_for_each_entry_rcu(ptr, list, list,
172
+ srcu_read_lock_held(&tomoyo_ss)) {
170173 if (ptr->is_deleted || ptr->type != r->param_type)
171174 continue;
172175 if (!check_entry(r, ptr))
....@@ -177,9 +180,10 @@
177180 r->granted = true;
178181 return;
179182 }
180
- if (!retried) {
181
- retried = true;
182
- list = &domain->ns->acl_group[domain->group];
183
+ for (; i < TOMOYO_MAX_ACL_GROUPS; i++) {
184
+ if (!test_bit(i, domain->group))
185
+ continue;
186
+ list = &domain->ns->acl_group[i++];
183187 goto retry;
184188 }
185189 r->granted = false;
....@@ -198,6 +202,7 @@
198202 static const char *tomoyo_last_word(const char *name)
199203 {
200204 const char *cp = strrchr(name, ' ');
205
+
201206 if (cp)
202207 return cp + 1;
203208 return name;
....@@ -220,6 +225,7 @@
220225 const struct tomoyo_transition_control *p2 = container_of(b,
221226 typeof(*p2),
222227 head);
228
+
223229 return p1->type == p2->type && p1->is_last_name == p2->is_last_name
224230 && p1->domainname == p2->domainname
225231 && p1->program == p2->program;
....@@ -240,6 +246,7 @@
240246 int error = param->is_delete ? -ENOENT : -ENOMEM;
241247 char *program = param->data;
242248 char *domainname = strstr(program, " from ");
249
+
243250 if (domainname) {
244251 *domainname = '\0';
245252 domainname += 6;
....@@ -293,7 +300,9 @@
293300 const enum tomoyo_transition_type type)
294301 {
295302 const struct tomoyo_transition_control *ptr;
296
- list_for_each_entry_rcu(ptr, list, head.list) {
303
+
304
+ list_for_each_entry_rcu(ptr, list, head.list,
305
+ srcu_read_lock_held(&tomoyo_ss)) {
297306 if (ptr->head.is_deleted || ptr->type != type)
298307 continue;
299308 if (ptr->domainname) {
....@@ -338,9 +347,11 @@
338347 {
339348 const char *last_name = tomoyo_last_word(domainname->name);
340349 enum tomoyo_transition_type type = TOMOYO_TRANSITION_CONTROL_NO_RESET;
350
+
341351 while (type < TOMOYO_MAX_TRANSITION_TYPE) {
342352 const struct list_head * const list =
343353 &ns->policy_list[TOMOYO_ID_TRANSITION_CONTROL];
354
+
344355 if (!tomoyo_scan_transition(list, domainname, program,
345356 last_name, type)) {
346357 type++;
....@@ -375,6 +386,7 @@
375386 head);
376387 const struct tomoyo_aggregator *p2 = container_of(b, typeof(*p2),
377388 head);
389
+
378390 return p1->original_name == p2->original_name &&
379391 p1->aggregated_name == p2->aggregated_name;
380392 }
....@@ -394,6 +406,7 @@
394406 int error = param->is_delete ? -ENOENT : -ENOMEM;
395407 const char *original_name = tomoyo_read_token(param);
396408 const char *aggregated_name = tomoyo_read_token(param);
409
+
397410 if (!tomoyo_correct_word(original_name) ||
398411 !tomoyo_correct_path(aggregated_name))
399412 return -EINVAL;
....@@ -426,6 +439,7 @@
426439 (const char *name, const unsigned int len)
427440 {
428441 struct tomoyo_policy_namespace *ns;
442
+
429443 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
430444 if (strncmp(name, ns->name, len) ||
431445 (name[len] && name[len] != ' '))
....@@ -451,6 +465,7 @@
451465 struct tomoyo_policy_namespace *entry;
452466 const char *cp = domainname;
453467 unsigned int len = 0;
468
+
454469 while (*cp && *cp++ != ' ')
455470 len++;
456471 ptr = tomoyo_find_namespace(domainname, len);
....@@ -466,6 +481,7 @@
466481 ptr = tomoyo_find_namespace(domainname, len);
467482 if (!ptr && tomoyo_memory_ok(entry)) {
468483 char *name = (char *) (entry + 1);
484
+
469485 ptr = entry;
470486 memmove(name, domainname, len);
471487 name[len] = '\0';
....@@ -490,6 +506,7 @@
490506 {
491507 const char *namespace = tomoyo_current_namespace()->name;
492508 const int len = strlen(namespace);
509
+
493510 return strncmp(domainname, namespace, len) ||
494511 (domainname[len] && domainname[len] != ' ');
495512 }
....@@ -510,6 +527,7 @@
510527 struct tomoyo_domain_info e = { };
511528 struct tomoyo_domain_info *entry = tomoyo_find_domain(domainname);
512529 bool created = false;
530
+
513531 if (entry) {
514532 if (transit) {
515533 /*
....@@ -546,8 +564,9 @@
546564 */
547565 if (transit) {
548566 const struct tomoyo_domain_info *domain = tomoyo_domain();
567
+
549568 e.profile = domain->profile;
550
- e.group = domain->group;
569
+ memcpy(e.group, domain->group, sizeof(e.group));
551570 }
552571 e.domainname = tomoyo_get_name(domainname);
553572 if (!e.domainname)
....@@ -569,12 +588,17 @@
569588 if (entry && transit) {
570589 if (created) {
571590 struct tomoyo_request_info r;
591
+ int i;
592
+
572593 tomoyo_init_request_info(&r, entry,
573594 TOMOYO_MAC_FILE_EXECUTE);
574595 r.granted = false;
575596 tomoyo_write_log(&r, "use_profile %u\n",
576597 entry->profile);
577
- tomoyo_write_log(&r, "use_group %u\n", entry->group);
598
+ for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
599
+ if (test_bit(i, entry->group))
600
+ tomoyo_write_log(&r, "use_group %u\n",
601
+ i);
578602 tomoyo_update_stat(TOMOYO_STAT_POLICY_UPDATES);
579603 }
580604 }
....@@ -712,9 +736,11 @@
712736 struct tomoyo_aggregator *ptr;
713737 struct list_head *list =
714738 &old_domain->ns->policy_list[TOMOYO_ID_AGGREGATOR];
739
+
715740 /* Check 'aggregator' directive. */
716741 candidate = &exename;
717
- list_for_each_entry_rcu(ptr, list, head.list) {
742
+ list_for_each_entry_rcu(ptr, list, head.list,
743
+ srcu_read_lock_held(&tomoyo_ss)) {
718744 if (ptr->head.is_deleted ||
719745 !tomoyo_path_matches_pattern(&exename,
720746 ptr->original_name))
....@@ -741,12 +767,13 @@
741767
742768 /*
743769 * Check for domain transition preference if "file execute" matched.
744
- * If preference is given, make do_execve() fail if domain transition
770
+ * If preference is given, make execve() fail if domain transition
745771 * has failed, for domain transition preference should be used with
746772 * destination domain defined.
747773 */
748774 if (ee->transition) {
749775 const char *domainname = ee->transition->name;
776
+
750777 reject_on_transition_failure = true;
751778 if (!strcmp(domainname, "keep"))
752779 goto force_keep_domain;
....@@ -758,6 +785,7 @@
758785 goto force_initialize_domain;
759786 if (!strcmp(domainname, "parent")) {
760787 char *cp;
788
+
761789 strncpy(ee->tmp, old_domain->domainname->name,
762790 TOMOYO_EXEC_TMPSIZE - 1);
763791 cp = strrchr(ee->tmp, ' ');
....@@ -782,7 +810,7 @@
782810 snprintf(ee->tmp, TOMOYO_EXEC_TMPSIZE - 1, "<%s>",
783811 candidate->name);
784812 /*
785
- * Make do_execve() fail if domain transition across namespaces
813
+ * Make execve() fail if domain transition across namespaces
786814 * has failed.
787815 */
788816 reject_on_transition_failure = true;
....@@ -822,8 +850,7 @@
822850 if (domain)
823851 retval = 0;
824852 else if (reject_on_transition_failure) {
825
- printk(KERN_WARNING "ERROR: Domain '%s' not ready.\n",
826
- ee->tmp);
853
+ pr_warn("ERROR: Domain '%s' not ready.\n", ee->tmp);
827854 retval = -ENOMEM;
828855 } else if (ee->r.mode == TOMOYO_CONFIG_ENFORCING)
829856 retval = -ENOMEM;
....@@ -834,16 +861,20 @@
834861 ee->r.granted = false;
835862 tomoyo_write_log(&ee->r, "%s", tomoyo_dif
836863 [TOMOYO_DIF_TRANSITION_FAILED]);
837
- printk(KERN_WARNING
838
- "ERROR: Domain '%s' not defined.\n", ee->tmp);
864
+ pr_warn("ERROR: Domain '%s' not defined.\n", ee->tmp);
839865 }
840866 }
841867 out:
842868 if (!domain)
843869 domain = old_domain;
844870 /* Update reference count on "struct tomoyo_domain_info". */
845
- atomic_inc(&domain->users);
846
- bprm->cred->security = domain;
871
+ {
872
+ struct tomoyo_task *s = tomoyo_task(current);
873
+
874
+ s->old_domain_info = s->domain_info;
875
+ s->domain_info = domain;
876
+ atomic_inc(&domain->users);
877
+ }
847878 kfree(exename.name);
848879 if (!retval) {
849880 ee->r.domain = domain;
....@@ -883,7 +914,7 @@
883914 * (represented by bprm). 'current' is the process doing
884915 * the execve().
885916 */
886
- if (get_user_pages_remote(current, bprm->mm, pos, 1,
917
+ if (get_user_pages_remote(bprm->mm, pos, 1,
887918 FOLL_FORCE, &page, NULL, NULL) <= 0)
888919 return false;
889920 #else