hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/security/tomoyo/tomoyo.c
....@@ -9,17 +9,19 @@
99 #include "common.h"
1010
1111 /**
12
- * tomoyo_cred_alloc_blank - Target for security_cred_alloc_blank().
12
+ * tomoyo_domain - Get "struct tomoyo_domain_info" for current thread.
1313 *
14
- * @new: Pointer to "struct cred".
15
- * @gfp: Memory allocation flags.
16
- *
17
- * Returns 0.
14
+ * Returns pointer to "struct tomoyo_domain_info" for current thread.
1815 */
19
-static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
16
+struct tomoyo_domain_info *tomoyo_domain(void)
2017 {
21
- new->security = NULL;
22
- return 0;
18
+ struct tomoyo_task *s = tomoyo_task(current);
19
+
20
+ if (s->old_domain_info && !current->in_execve) {
21
+ atomic_dec(&s->old_domain_info->users);
22
+ s->old_domain_info = NULL;
23
+ }
24
+ return s->domain_info;
2325 }
2426
2527 /**
....@@ -34,74 +36,50 @@
3436 static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
3537 gfp_t gfp)
3638 {
37
- struct tomoyo_domain_info *domain = old->security;
38
- new->security = domain;
39
- if (domain)
40
- atomic_inc(&domain->users);
39
+ /* Restore old_domain_info saved by previous execve() request. */
40
+ struct tomoyo_task *s = tomoyo_task(current);
41
+
42
+ if (s->old_domain_info && !current->in_execve) {
43
+ atomic_dec(&s->domain_info->users);
44
+ s->domain_info = s->old_domain_info;
45
+ s->old_domain_info = NULL;
46
+ }
4147 return 0;
4248 }
4349
4450 /**
45
- * tomoyo_cred_transfer - Target for security_transfer_creds().
51
+ * tomoyo_bprm_committed_creds - Target for security_bprm_committed_creds().
4652 *
47
- * @new: Pointer to "struct cred".
48
- * @old: Pointer to "struct cred".
53
+ * @bprm: Pointer to "struct linux_binprm".
4954 */
50
-static void tomoyo_cred_transfer(struct cred *new, const struct cred *old)
55
+static void tomoyo_bprm_committed_creds(struct linux_binprm *bprm)
5156 {
52
- tomoyo_cred_prepare(new, old, 0);
57
+ /* Clear old_domain_info saved by execve() request. */
58
+ struct tomoyo_task *s = tomoyo_task(current);
59
+
60
+ atomic_dec(&s->old_domain_info->users);
61
+ s->old_domain_info = NULL;
5362 }
5463
64
+#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
5565 /**
56
- * tomoyo_cred_free - Target for security_cred_free().
57
- *
58
- * @cred: Pointer to "struct cred".
59
- */
60
-static void tomoyo_cred_free(struct cred *cred)
61
-{
62
- struct tomoyo_domain_info *domain = cred->security;
63
- if (domain)
64
- atomic_dec(&domain->users);
65
-}
66
-
67
-/**
68
- * tomoyo_bprm_set_creds - Target for security_bprm_set_creds().
66
+ * tomoyo_bprm_for_exec - Target for security_bprm_creds_for_exec().
6967 *
7068 * @bprm: Pointer to "struct linux_binprm".
7169 *
72
- * Returns 0 on success, negative value otherwise.
70
+ * Returns 0.
7371 */
74
-static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
72
+static int tomoyo_bprm_creds_for_exec(struct linux_binprm *bprm)
7573 {
76
- /*
77
- * Do only if this function is called for the first time of an execve
78
- * operation.
79
- */
80
- if (bprm->called_set_creds)
81
- return 0;
82
-#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
8374 /*
8475 * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
8576 * for the first time.
8677 */
8778 if (!tomoyo_policy_loaded)
8879 tomoyo_load_policy(bprm->filename);
89
-#endif
90
- /*
91
- * Release reference to "struct tomoyo_domain_info" stored inside
92
- * "bprm->cred->security". New reference to "struct tomoyo_domain_info"
93
- * stored inside "bprm->cred->security" will be acquired later inside
94
- * tomoyo_find_next_domain().
95
- */
96
- atomic_dec(&((struct tomoyo_domain_info *)
97
- bprm->cred->security)->users);
98
- /*
99
- * Tell tomoyo_bprm_check_security() is called for the first time of an
100
- * execve operation.
101
- */
102
- bprm->cred->security = NULL;
10380 return 0;
10481 }
82
+#endif
10583
10684 /**
10785 * tomoyo_bprm_check_security - Target for security_bprm_check().
....@@ -112,23 +90,24 @@
11290 */
11391 static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
11492 {
115
- struct tomoyo_domain_info *domain = bprm->cred->security;
93
+ struct tomoyo_task *s = tomoyo_task(current);
11694
11795 /*
118
- * Execute permission is checked against pathname passed to do_execve()
96
+ * Execute permission is checked against pathname passed to execve()
11997 * using current domain.
12098 */
121
- if (!domain) {
99
+ if (!s->old_domain_info) {
122100 const int idx = tomoyo_read_lock();
123101 const int err = tomoyo_find_next_domain(bprm);
102
+
124103 tomoyo_read_unlock(idx);
125104 return err;
126105 }
127106 /*
128107 * Read permission is checked against interpreters using next domain.
129108 */
130
- return tomoyo_check_open_permission(domain, &bprm->file->f_path,
131
- O_RDONLY);
109
+ return tomoyo_check_open_permission(s->domain_info,
110
+ &bprm->file->f_path, O_RDONLY);
132111 }
133112
134113 /**
....@@ -167,6 +146,7 @@
167146 static int tomoyo_path_unlink(const struct path *parent, struct dentry *dentry)
168147 {
169148 struct path path = { .mnt = parent->mnt, .dentry = dentry };
149
+
170150 return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path, NULL);
171151 }
172152
....@@ -183,6 +163,7 @@
183163 umode_t mode)
184164 {
185165 struct path path = { .mnt = parent->mnt, .dentry = dentry };
166
+
186167 return tomoyo_path_number_perm(TOMOYO_TYPE_MKDIR, &path,
187168 mode & S_IALLUGO);
188169 }
....@@ -198,6 +179,7 @@
198179 static int tomoyo_path_rmdir(const struct path *parent, struct dentry *dentry)
199180 {
200181 struct path path = { .mnt = parent->mnt, .dentry = dentry };
182
+
201183 return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path, NULL);
202184 }
203185
....@@ -214,6 +196,7 @@
214196 const char *old_name)
215197 {
216198 struct path path = { .mnt = parent->mnt, .dentry = dentry };
199
+
217200 return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path, old_name);
218201 }
219202
....@@ -271,6 +254,7 @@
271254 {
272255 struct path path1 = { .mnt = new_dir->mnt, .dentry = old_dentry };
273256 struct path path2 = { .mnt = new_dir->mnt, .dentry = new_dentry };
257
+
274258 return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2);
275259 }
276260
....@@ -291,6 +275,7 @@
291275 {
292276 struct path path1 = { .mnt = old_parent->mnt, .dentry = old_dentry };
293277 struct path path2 = { .mnt = new_parent->mnt, .dentry = new_dentry };
278
+
294279 return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2);
295280 }
296281
....@@ -322,11 +307,11 @@
322307 */
323308 static int tomoyo_file_open(struct file *f)
324309 {
325
- int flags = f->f_flags;
326
- /* Don't check read permission here if called from do_execve(). */
310
+ /* Don't check read permission here if called from execve(). */
327311 if (current->in_execve)
328312 return 0;
329
- return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
313
+ return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path,
314
+ f->f_flags);
330315 }
331316
332317 /**
....@@ -370,6 +355,7 @@
370355 static int tomoyo_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
371356 {
372357 int error = 0;
358
+
373359 if (uid_valid(uid))
374360 error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path,
375361 from_kuid(&init_user_ns, uid));
....@@ -419,6 +405,7 @@
419405 static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
420406 {
421407 struct path path = { .mnt = mnt, .dentry = mnt->mnt_root };
408
+
422409 return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path, NULL);
423410 }
424411
....@@ -493,16 +480,61 @@
493480 return tomoyo_socket_sendmsg_permission(sock, msg, size);
494481 }
495482
483
+struct lsm_blob_sizes tomoyo_blob_sizes __lsm_ro_after_init = {
484
+ .lbs_task = sizeof(struct tomoyo_task),
485
+};
486
+
487
+/**
488
+ * tomoyo_task_alloc - Target for security_task_alloc().
489
+ *
490
+ * @task: Pointer to "struct task_struct".
491
+ * @flags: clone() flags.
492
+ *
493
+ * Returns 0.
494
+ */
495
+static int tomoyo_task_alloc(struct task_struct *task,
496
+ unsigned long clone_flags)
497
+{
498
+ struct tomoyo_task *old = tomoyo_task(current);
499
+ struct tomoyo_task *new = tomoyo_task(task);
500
+
501
+ new->domain_info = old->domain_info;
502
+ atomic_inc(&new->domain_info->users);
503
+ new->old_domain_info = NULL;
504
+ return 0;
505
+}
506
+
507
+/**
508
+ * tomoyo_task_free - Target for security_task_free().
509
+ *
510
+ * @task: Pointer to "struct task_struct".
511
+ */
512
+static void tomoyo_task_free(struct task_struct *task)
513
+{
514
+ struct tomoyo_task *s = tomoyo_task(task);
515
+
516
+ if (s->domain_info) {
517
+ atomic_dec(&s->domain_info->users);
518
+ s->domain_info = NULL;
519
+ }
520
+ if (s->old_domain_info) {
521
+ atomic_dec(&s->old_domain_info->users);
522
+ s->old_domain_info = NULL;
523
+ }
524
+}
525
+
496526 /*
497527 * tomoyo_security_ops is a "struct security_operations" which is used for
498528 * registering TOMOYO.
499529 */
500530 static struct security_hook_list tomoyo_hooks[] __lsm_ro_after_init = {
501
- LSM_HOOK_INIT(cred_alloc_blank, tomoyo_cred_alloc_blank),
502531 LSM_HOOK_INIT(cred_prepare, tomoyo_cred_prepare),
503
- LSM_HOOK_INIT(cred_transfer, tomoyo_cred_transfer),
504
- LSM_HOOK_INIT(cred_free, tomoyo_cred_free),
505
- LSM_HOOK_INIT(bprm_set_creds, tomoyo_bprm_set_creds),
532
+ LSM_HOOK_INIT(bprm_committed_creds, tomoyo_bprm_committed_creds),
533
+ LSM_HOOK_INIT(task_alloc, tomoyo_task_alloc),
534
+ LSM_HOOK_INIT(task_free, tomoyo_task_free),
535
+#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
536
+ LSM_HOOK_INIT(bprm_creds_for_exec, tomoyo_bprm_creds_for_exec),
537
+#endif
506538 LSM_HOOK_INIT(bprm_check_security, tomoyo_bprm_check_security),
507539 LSM_HOOK_INIT(file_fcntl, tomoyo_file_fcntl),
508540 LSM_HOOK_INIT(file_open, tomoyo_file_open),
....@@ -531,6 +563,8 @@
531563 /* Lock for GC. */
532564 DEFINE_SRCU(tomoyo_ss);
533565
566
+int tomoyo_enabled __lsm_ro_after_init = 1;
567
+
534568 /**
535569 * tomoyo_init - Register TOMOYO Linux as a LSM module.
536570 *
....@@ -538,16 +572,23 @@
538572 */
539573 static int __init tomoyo_init(void)
540574 {
541
- struct cred *cred = (struct cred *) current_cred();
575
+ struct tomoyo_task *s = tomoyo_task(current);
542576
543
- if (!security_module_enable("tomoyo"))
544
- return 0;
545577 /* register ourselves with the security framework */
546578 security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo");
547
- printk(KERN_INFO "TOMOYO Linux initialized\n");
548
- cred->security = &tomoyo_kernel_domain;
579
+ pr_info("TOMOYO Linux initialized\n");
580
+ s->domain_info = &tomoyo_kernel_domain;
581
+ atomic_inc(&tomoyo_kernel_domain.users);
582
+ s->old_domain_info = NULL;
549583 tomoyo_mm_init();
584
+
550585 return 0;
551586 }
552587
553
-security_initcall(tomoyo_init);
588
+DEFINE_LSM(tomoyo) = {
589
+ .name = "tomoyo",
590
+ .enabled = &tomoyo_enabled,
591
+ .flags = LSM_FLAG_LEGACY_MAJOR,
592
+ .blobs = &tomoyo_blob_sizes,
593
+ .init = tomoyo_init,
594
+};