Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/caitsith-patch/caitsith/lsm-4.12.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 387 - (show annotations) (download) (as text)
Mon Dec 25 14:08:19 2023 UTC (3 months, 2 weeks ago) by kumaneko
File MIME type: text/x-csrc
File size: 41458 byte(s)


1 /*
2 * lsm.c
3 *
4 * Copyright (C) 2010-2013 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5 *
6 * Version: 0.2.11 2023/05/27
7 */
8
9 #include "caitsith.h"
10 #include "probe.h"
11
12 /* Prototype definition. */
13 static int __cs_alloc_task_security(const struct task_struct *task);
14 static void __cs_free_task_security(const struct task_struct *task);
15
16 /* Dummy security context for avoiding NULL pointer dereference. */
17 static struct cs_security cs_oom_security = {
18 .cs_domain_info = &cs_kernel_domain
19 };
20
21 /* Dummy security context for avoiding NULL pointer dereference. */
22 static struct cs_security cs_default_security = {
23 .cs_domain_info = &cs_kernel_domain
24 };
25
26 /* List of "struct cs_security". */
27 struct list_head cs_task_security_list[CS_MAX_TASK_SECURITY_HASH];
28 /* Lock for protecting cs_task_security_list[]. */
29 static DEFINE_SPINLOCK(cs_task_security_list_lock);
30
31 /* For exporting variables and functions. */
32 struct caitsith_exports caitsith_exports;
33
34 /* Original hooks. */
35 static union security_list_options original_cred_prepare;
36 static union security_list_options original_task_alloc;
37 static union security_list_options original_task_free;
38
39 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
40 long (*my_copy_to_kernel_nofault) (void *dst, const void *src, size_t size);
41 #endif
42
43 #if !defined(CONFIG_CAITSITH_DEBUG)
44 #define cs_debug_trace(pos) do { } while (0)
45 #else
46 #define cs_debug_trace(pos) \
47 do { \
48 static bool done; \
49 if (!done) { \
50 printk(KERN_INFO \
51 "CAITSITH: Debug trace: " pos " of 2\n"); \
52 done = true; \
53 } \
54 } while (0)
55 #endif
56
57 /**
58 * cs_clear_execve - Release memory used by do_execve().
59 *
60 * @ret: 0 if do_execve() succeeded, negative value otherwise.
61 * @security: Pointer to "struct cs_security".
62 *
63 * Returns nothing.
64 */
65 static void cs_clear_execve(int ret, struct cs_security *security)
66 {
67 struct cs_request_info *r = security->r;
68
69 if (security == &cs_default_security || security == &cs_oom_security ||
70 !r)
71 return;
72 security->r = NULL;
73 cs_finish_execve(ret, r);
74 }
75
76 /**
77 * cs_task_alloc_security - Allocate memory for new tasks.
78 *
79 * @p: Pointer to "struct task_struct".
80 * @clone_flags: Flags passed to clone().
81 *
82 * Returns 0 on success, negative value otherwise.
83 */
84 static int cs_task_alloc_security(struct task_struct *p,
85 unsigned long clone_flags)
86 {
87 int rc = __cs_alloc_task_security(p);
88
89 if (rc)
90 return rc;
91 if (original_task_alloc.task_alloc) {
92 rc = original_task_alloc.task_alloc(p, clone_flags);
93 if (rc)
94 __cs_free_task_security(p);
95 }
96 return rc;
97 }
98
99 /**
100 * cs_task_free_security - Release memory for "struct task_struct".
101 *
102 * @p: Pointer to "struct task_struct".
103 *
104 * Returns nothing.
105 */
106 static void cs_task_free_security(struct task_struct *p)
107 {
108 struct cs_security *ptr = cs_find_task_security(p);
109 struct cs_request_info *r = ptr->r;
110
111 if (original_task_free.task_free)
112 original_task_free.task_free(p);
113 /*
114 * Since an LSM hook for reverting domain transition is missing,
115 * cs_finish_execve() is not called if exited immediately after
116 * execve() failed.
117 */
118 if (r) {
119 cs_debug_trace("2");
120 kfree(r->handler_path);
121 kfree(r);
122 ptr->r = NULL;
123 }
124 __cs_free_task_security(p);
125 }
126
127 /**
128 * __cs_free_task_security - Release memory associated with "struct task_struct".
129 *
130 * @task: Pointer to "struct task_struct".
131 *
132 * Returns nothing.
133 */
134 static void __cs_free_task_security(const struct task_struct *task)
135 {
136 unsigned long flags;
137 struct cs_security *ptr = cs_find_task_security(task);
138
139 if (ptr == &cs_default_security || ptr == &cs_oom_security)
140 return;
141 spin_lock_irqsave(&cs_task_security_list_lock, flags);
142 list_del_rcu(&ptr->list);
143 spin_unlock_irqrestore(&cs_task_security_list_lock, flags);
144 kfree_rcu(ptr, rcu);
145 }
146
147 /**
148 * cs_cred_prepare - Allocate memory for new credentials.
149 *
150 * @new: Pointer to "struct cred".
151 * @old: Pointer to "struct cred".
152 * @gfp: Memory allocation flags.
153 *
154 * Returns 0 on success, negative value otherwise.
155 */
156 static int cs_cred_prepare(struct cred *new, const struct cred *old,
157 gfp_t gfp)
158 {
159 /*
160 * For checking whether reverting domain transition is needed or not.
161 *
162 * See cs_find_task_security() for reason.
163 */
164 if ((gfp & GFP_KERNEL) == GFP_KERNEL)
165 cs_find_task_security(current);
166 if (original_cred_prepare.cred_prepare)
167 return original_cred_prepare.cred_prepare(new, old, gfp);
168 return 0;
169 }
170
171 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0)
172 /**
173 * cs_bprm_committing_creds - A hook which is called when do_execve() succeeded.
174 *
175 * @bprm: Pointer to "struct linux_binprm".
176 *
177 * Returns nothing.
178 */
179 static void cs_bprm_committing_creds(const struct linux_binprm *bprm)
180 {
181 cs_clear_execve(0, cs_current_security());
182 }
183 #else
184 /**
185 * cs_bprm_committing_creds - A hook which is called when do_execve() succeeded.
186 *
187 * @bprm: Pointer to "struct linux_binprm".
188 *
189 * Returns nothing.
190 */
191 static void cs_bprm_committing_creds(struct linux_binprm *bprm)
192 {
193 cs_clear_execve(0, cs_current_security());
194 }
195 #endif
196
197 #ifndef CONFIG_CAITSITH_OMIT_USERSPACE_LOADER
198
199 /**
200 * cs_policy_loader_exists - Check whether /sbin/caitsith-init exists.
201 *
202 * Returns true if /sbin/caitsith-init exists, false otherwise.
203 */
204 static _Bool cs_policy_loader_exists(void)
205 {
206 struct path path;
207
208 if (kern_path(CONFIG_CAITSITH_POLICY_LOADER, LOOKUP_FOLLOW, &path)
209 == 0) {
210 path_put(&path);
211 return 1;
212 }
213 printk(KERN_INFO "Not activating CaitSith as %s does not exist.\n",
214 CONFIG_CAITSITH_POLICY_LOADER);
215 return 0;
216 }
217
218 /**
219 * cs_load_policy - Run external policy loader to load policy.
220 *
221 * @filename: The program about to start.
222 *
223 * Returns nothing.
224 *
225 * This function checks whether @filename is /sbin/init, and if so
226 * invoke /sbin/caitsith-init and wait for the termination of
227 * /sbin/caitsith-init and then continues invocation of /sbin/init.
228 * /sbin/caitsith-init reads policy files in /etc/caitsith/ directory and
229 * writes to /sys/kernel/security/caitsith/ interfaces.
230 */
231 static void cs_load_policy(const char *filename)
232 {
233 static _Bool done;
234
235 if (done)
236 return;
237 if (strcmp(filename, CONFIG_CAITSITH_ACTIVATION_TRIGGER))
238 return;
239 if (!cs_policy_loader_exists())
240 return;
241 done = 1;
242 {
243 char *argv[2];
244 char *envp[3];
245
246 printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
247 CONFIG_CAITSITH_POLICY_LOADER);
248 argv[0] = (char *) CONFIG_CAITSITH_POLICY_LOADER;
249 argv[1] = NULL;
250 envp[0] = "HOME=/";
251 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
252 envp[2] = NULL;
253 call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
254 }
255 cs_check_profile();
256 }
257
258 #endif
259
260 /**
261 * cs_bprm_check_security - Check permission for execve().
262 *
263 * @bprm: Pointer to "struct linux_binprm".
264 *
265 * Returns 0 on success, negative value otherwise.
266 */
267 static int cs_bprm_check_security(struct linux_binprm *bprm)
268 {
269 struct cs_security *security = cs_current_security();
270
271 if (security == &cs_default_security || security == &cs_oom_security)
272 return -ENOMEM;
273 if (security->r)
274 return 0;
275 #ifndef CONFIG_CAITSITH_OMIT_USERSPACE_LOADER
276 if (!cs_policy_loaded)
277 cs_load_policy(bprm->filename);
278 #endif
279 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)
280 if (!strcmp(bprm->filename, "none")) {
281 /*
282 * Since we can't calculate pathname when called from
283 * call_usermodehelper_setup_file() from fork_usermode_blob(),
284 * skip permission check and suppress domain transition.
285 */
286 const char *s = kstrdup_const(bprm->filename, GFP_NOWAIT | __GFP_NOWARN);
287
288 if (s == bprm->filename)
289 return 0;
290 kfree_const(s);
291 }
292 #endif
293 return cs_start_execve(bprm, &security->r);
294 }
295
296 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) || (defined(RHEL_MAJOR) && RHEL_MAJOR == 8)
297 /**
298 * cs_file_open - Check permission for open().
299 *
300 * @f: Pointer to "struct file".
301 *
302 * Returns 0 on success, negative value otherwise.
303 */
304 static int cs_file_open(struct file *f)
305 {
306 return cs_open_permission(&f->f_path, f->f_flags);
307 }
308 #else
309 /**
310 * cs_file_open - Check permission for open().
311 *
312 * @f: Pointer to "struct file".
313 * @cred: Pointer to "struct cred".
314 *
315 * Returns 0 on success, negative value otherwise.
316 */
317 static int cs_file_open(struct file *f, const struct cred *cred)
318 {
319 return cs_open_permission(&f->f_path, f->f_flags);
320 }
321 #endif
322
323 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 2, 0)
324 /**
325 * cs_file_truncate - Check permission for truncate().
326 *
327 * @file: Pointer to "struct file".
328 *
329 * Returns 0 on success, negative value otherwise.
330 */
331 static int cs_file_truncate(struct file *file)
332 {
333 return cs_truncate_permission(&file->f_path);
334
335 }
336 #endif
337
338 #ifdef CONFIG_SECURITY_PATH
339
340 /**
341 * cs_path_chown - Check permission for chown()/chgrp().
342 *
343 * @path: Pointer to "struct path".
344 * @user: User ID.
345 * @group: Group ID.
346 *
347 * Returns 0 on success, negative value otherwise.
348 */
349 static int cs_path_chown(const struct path *path, kuid_t user, kgid_t group)
350 {
351 return cs_chown_permission(path, user, group);
352 }
353
354 /**
355 * cs_path_chmod - Check permission for chmod().
356 *
357 * @path: Pointer to "struct path".
358 * @mode: Mode.
359 *
360 * Returns 0 on success, negative value otherwise.
361 */
362 static int cs_path_chmod(const struct path *path, umode_t mode)
363 {
364 return cs_chmod_permission(path, mode);
365 }
366
367 /**
368 * cs_path_chroot - Check permission for chroot().
369 *
370 * @path: Pointer to "struct path".
371 *
372 * Returns 0 on success, negative value otherwise.
373 */
374 static int cs_path_chroot(const struct path *path)
375 {
376 return cs_chroot_permission(path);
377 }
378
379 /**
380 * cs_path_truncate - Check permission for truncate().
381 *
382 * @path: Pointer to "struct path".
383 *
384 * Returns 0 on success, negative value otherwise.
385 */
386 static int cs_path_truncate(const struct path *path)
387 {
388 return cs_truncate_permission(path);
389 }
390
391 #else
392
393 /**
394 * cs_inode_setattr - Check permission for chown()/chgrp()/chmod()/truncate().
395 *
396 * @dentry: Pointer to "struct dentry".
397 * @attr: Pointer to "struct iattr".
398 *
399 * Returns 0 on success, negative value otherwise.
400 */
401 static int cs_inode_setattr(struct dentry *dentry, struct iattr *attr)
402 {
403 int rc = 0;
404 struct path path = { .mnt = NULL, .dentry = dentry };
405
406 if (attr->ia_valid & ATTR_UID)
407 rc = cs_chown_permission(&path, attr->ia_uid, INVALID_GID);
408 if (!rc && (attr->ia_valid & ATTR_GID))
409 rc = cs_chown_permission(&path, INVALID_UID, attr->ia_gid);
410 if (!rc && (attr->ia_valid & ATTR_MODE))
411 rc = cs_chmod_permission(&path, attr->ia_mode);
412 if (!rc && (attr->ia_valid & ATTR_SIZE))
413 rc = cs_truncate_permission(&path);
414 return rc;
415 }
416
417 #endif
418
419 /**
420 * cs_inode_getattr - Check permission for stat().
421 *
422 * @path: Pointer to "struct path".
423 *
424 * Returns 0 on success, negative value otherwise.
425 */
426 static int cs_inode_getattr(const struct path *path)
427 {
428 return cs_getattr_permission(path);
429 }
430
431 #ifdef CONFIG_SECURITY_PATH
432
433 /**
434 * cs_path_mknod - Check permission for mknod().
435 *
436 * @dir: Pointer to "struct path".
437 * @dentry: Pointer to "struct dentry".
438 * @mode: Create mode.
439 * @dev: Device major/minor number.
440 *
441 * Returns 0 on success, negative value otherwise.
442 */
443 static int cs_path_mknod(const struct path *dir, struct dentry *dentry,
444 umode_t mode, unsigned int dev)
445 {
446 struct path path = { .mnt = dir->mnt, .dentry = dentry };
447
448 return cs_mknod_permission(&path, mode, dev);
449 }
450
451 /**
452 * cs_path_mkdir - Check permission for mkdir().
453 *
454 * @dir: Pointer to "struct path".
455 * @dentry: Pointer to "struct dentry".
456 * @mode: Create mode.
457 *
458 * Returns 0 on success, negative value otherwise.
459 */
460 static int cs_path_mkdir(const struct path *dir, struct dentry *dentry,
461 umode_t mode)
462 {
463 struct path path = { .mnt = dir->mnt, .dentry = dentry };
464
465 return cs_mkdir_permission(&path, mode);
466 }
467
468 /**
469 * cs_path_rmdir - Check permission for rmdir().
470 *
471 * @dir: Pointer to "struct path".
472 * @dentry: Pointer to "struct dentry".
473 *
474 * Returns 0 on success, negative value otherwise.
475 */
476 static int cs_path_rmdir(const struct path *dir, struct dentry *dentry)
477 {
478 struct path path = { .mnt = dir->mnt, .dentry = dentry };
479
480 return cs_rmdir_permission(&path);
481 }
482
483 /**
484 * cs_path_unlink - Check permission for unlink().
485 *
486 * @dir: Pointer to "struct path".
487 * @dentry: Pointer to "struct dentry".
488 *
489 * Returns 0 on success, negative value otherwise.
490 */
491 static int cs_path_unlink(const struct path *dir, struct dentry *dentry)
492 {
493 struct path path = { .mnt = dir->mnt, .dentry = dentry };
494
495 return cs_unlink_permission(&path);
496 }
497
498 /**
499 * cs_path_symlink - Check permission for symlink().
500 *
501 * @dir: Pointer to "struct path".
502 * @dentry: Pointer to "struct dentry".
503 * @old_name: Content of symbolic link.
504 *
505 * Returns 0 on success, negative value otherwise.
506 */
507 static int cs_path_symlink(const struct path *dir, struct dentry *dentry,
508 const char *old_name)
509 {
510 struct path path = { .mnt = dir->mnt, .dentry = dentry };
511
512 return cs_symlink_permission(&path, old_name);
513 }
514
515 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
516 /**
517 * cs_path_rename - Check permission for rename().
518 *
519 * @old_dir: Pointer to "struct path".
520 * @old_dentry: Pointer to "struct dentry".
521 * @new_dir: Pointer to "struct path".
522 * @new_dentry: Pointer to "struct dentry".
523 * @flags: Rename flags.
524 *
525 * Returns 0 on success, negative value otherwise.
526 */
527 static int cs_path_rename(const struct path *old_dir,
528 struct dentry *old_dentry,
529 const struct path *new_dir,
530 struct dentry *new_dentry,
531 const unsigned int flags)
532 {
533 struct path old = { .mnt = old_dir->mnt, .dentry = old_dentry };
534 struct path new = { .mnt = new_dir->mnt, .dentry = new_dentry };
535
536 if (flags & RENAME_EXCHANGE) {
537 const int err = cs_rename_permission(&new, &old);
538
539 if (err)
540 return err;
541 }
542 return cs_rename_permission(&old, &new);
543 }
544 #else
545 /**
546 * cs_path_rename - Check permission for rename().
547 *
548 * @old_dir: Pointer to "struct path".
549 * @old_dentry: Pointer to "struct dentry".
550 * @new_dir: Pointer to "struct path".
551 * @new_dentry: Pointer to "struct dentry".
552 *
553 * Returns 0 on success, negative value otherwise.
554 */
555 static int cs_path_rename(const struct path *old_dir,
556 struct dentry *old_dentry,
557 const struct path *new_dir,
558 struct dentry *new_dentry)
559 {
560 struct path old = { .mnt = old_dir->mnt, .dentry = old_dentry };
561 struct path new = { .mnt = new_dir->mnt, .dentry = new_dentry };
562
563 return cs_rename_permission(&old, &new);
564 }
565 #endif
566
567 /**
568 * cs_path_link - Check permission for link().
569 *
570 * @old_dentry: Pointer to "struct dentry".
571 * @new_dir: Pointer to "struct path".
572 * @new_dentry: Pointer to "struct dentry".
573 *
574 * Returns 0 on success, negative value otherwise.
575 */
576 static int cs_path_link(struct dentry *old_dentry, const struct path *new_dir,
577 struct dentry *new_dentry)
578 {
579 struct path old = { .mnt = new_dir->mnt, .dentry = old_dentry };
580 struct path new = { .mnt = new_dir->mnt, .dentry = new_dentry };
581
582 return cs_link_permission(&old, &new);
583 }
584
585 #else
586
587 /**
588 * cs_inode_mknod - Check permission for mknod().
589 *
590 * @dir: Pointer to "struct inode".
591 * @dentry: Pointer to "struct dentry".
592 * @mode: Create mode.
593 * @dev: Device major/minor number.
594 *
595 * Returns 0 on success, negative value otherwise.
596 */
597 static int cs_inode_mknod(struct inode *dir, struct dentry *dentry,
598 umode_t mode, dev_t dev)
599 {
600 struct path path = { .mnt = NULL, .dentry = dentry };
601
602 return cs_mknod_permission(&path, mode, dev);
603 }
604
605 /**
606 * cs_inode_mkdir - Check permission for mkdir().
607 *
608 * @dir: Pointer to "struct inode".
609 * @dentry: Pointer to "struct dentry".
610 * @mode: Create mode.
611 *
612 * Returns 0 on success, negative value otherwise.
613 */
614 static int cs_inode_mkdir(struct inode *dir, struct dentry *dentry,
615 umode_t mode)
616 {
617 struct path path = { .mnt = NULL, .dentry = dentry };
618
619 return cs_mkdir_permission(&path, mode);
620 }
621
622 /**
623 * cs_inode_rmdir - Check permission for rmdir().
624 *
625 * @dir: Pointer to "struct inode".
626 * @dentry: Pointer to "struct dentry".
627 *
628 * Returns 0 on success, negative value otherwise.
629 */
630 static int cs_inode_rmdir(struct inode *dir, struct dentry *dentry)
631 {
632 struct path path = { .mnt = NULL, .dentry = dentry };
633
634 return cs_rmdir_permission(&path);
635 }
636
637 /**
638 * cs_inode_unlink - Check permission for unlink().
639 *
640 * @dir: Pointer to "struct inode".
641 * @dentry: Pointer to "struct dentry".
642 *
643 * Returns 0 on success, negative value otherwise.
644 */
645 static int cs_inode_unlink(struct inode *dir, struct dentry *dentry)
646 {
647 struct path path = { .mnt = NULL, .dentry = dentry };
648
649 return cs_unlink_permission(&path);
650 }
651
652 /**
653 * cs_inode_symlink - Check permission for symlink().
654 *
655 * @dir: Pointer to "struct inode".
656 * @dentry: Pointer to "struct dentry".
657 * @old_name: Content of symbolic link.
658 *
659 * Returns 0 on success, negative value otherwise.
660 */
661 static int cs_inode_symlink(struct inode *dir, struct dentry *dentry,
662 const char *old_name)
663 {
664 struct path path = { .mnt = NULL, .dentry = dentry };
665
666 return cs_symlink_permission(&path, old_name);
667 }
668
669 /**
670 * cs_inode_rename - Check permission for rename().
671 *
672 * @old_dir: Pointer to "struct inode".
673 * @old_dentry: Pointer to "struct dentry".
674 * @new_dir: Pointer to "struct inode".
675 * @new_dentry: Pointer to "struct dentry".
676 *
677 * Returns 0 on success, negative value otherwise.
678 */
679 static int cs_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
680 struct inode *new_dir, struct dentry *new_dentry)
681 {
682 struct path old = { .mnt = NULL, .dentry = old_dentry };
683 struct path new = { .mnt = NULL, .dentry = new_dentry };
684
685 return cs_rename_permission(&old, &new);
686 }
687
688 /**
689 * cs_inode_link - Check permission for link().
690 *
691 * @old_dentry: Pointer to "struct dentry".
692 * @dir: Pointer to "struct inode".
693 * @new_dentry: Pointer to "struct dentry".
694 *
695 * Returns 0 on success, negative value otherwise.
696 */
697 static int cs_inode_link(struct dentry *old_dentry, struct inode *dir,
698 struct dentry *new_dentry)
699 {
700 struct path old = { .mnt = NULL, .dentry = old_dentry };
701 struct path new = { .mnt = NULL, .dentry = new_dentry };
702
703 return cs_link_permission(&old, &new);
704 }
705
706 /**
707 * cs_inode_create - Check permission for creat().
708 *
709 * @dir: Pointer to "struct inode".
710 * @dentry: Pointer to "struct dentry".
711 * @mode: Create mode.
712 *
713 * Returns 0 on success, negative value otherwise.
714 */
715 static int cs_inode_create(struct inode *dir, struct dentry *dentry,
716 umode_t mode)
717 {
718 struct path path = { .mnt = NULL, .dentry = dentry };
719
720 return cs_mknod_permission(&path, mode, 0);
721 }
722
723 #endif
724
725 #ifdef CONFIG_SECURITY_NETWORK
726
727 #include <net/sock.h>
728
729 /* Structure for remembering an accept()ed socket's status. */
730 struct cs_socket_tag {
731 struct list_head list;
732 struct inode *inode;
733 int status;
734 struct rcu_head rcu;
735 };
736
737 /*
738 * List for managing accept()ed sockets.
739 * Since we don't need to keep an accept()ed socket into this list after
740 * once the permission was granted, the number of entries in this list is
741 * likely small. Therefore, we don't use hash tables.
742 */
743 static LIST_HEAD(cs_accepted_socket_list);
744 /* Lock for protecting cs_accepted_socket_list . */
745 static DEFINE_SPINLOCK(cs_accepted_socket_list_lock);
746
747 /**
748 * cs_update_socket_tag - Update tag associated with accept()ed sockets.
749 *
750 * @inode: Pointer to "struct inode".
751 * @status: New status.
752 *
753 * Returns nothing.
754 *
755 * If @status == 0, memory for that socket will be released after RCU grace
756 * period.
757 */
758 static void cs_update_socket_tag(struct inode *inode, int status)
759 {
760 struct cs_socket_tag *ptr;
761 /*
762 * Protect whole section because multiple threads may call this
763 * function with same "sock" via cs_validate_socket().
764 */
765 spin_lock(&cs_accepted_socket_list_lock);
766 rcu_read_lock();
767 list_for_each_entry_rcu(ptr, &cs_accepted_socket_list, list) {
768 if (ptr->inode != inode)
769 continue;
770 ptr->status = status;
771 if (status)
772 break;
773 list_del_rcu(&ptr->list);
774 kfree_rcu(ptr, rcu);
775 break;
776 }
777 rcu_read_unlock();
778 spin_unlock(&cs_accepted_socket_list_lock);
779 }
780
781 /**
782 * cs_validate_socket - Check post accept() permission if needed.
783 *
784 * @sock: Pointer to "struct socket".
785 *
786 * Returns 0 on success, negative value otherwise.
787 */
788 static int cs_validate_socket(struct socket *sock)
789 {
790 struct inode *inode = SOCK_INODE(sock);
791 struct cs_socket_tag *ptr;
792 int ret = 0;
793
794 rcu_read_lock();
795 list_for_each_entry_rcu(ptr, &cs_accepted_socket_list, list) {
796 if (ptr->inode != inode)
797 continue;
798 ret = ptr->status;
799 break;
800 }
801 rcu_read_unlock();
802 if (ret <= 0)
803 /*
804 * This socket is not an accept()ed socket or this socket is
805 * an accept()ed socket and post accept() permission is done.
806 */
807 return ret;
808 /*
809 * Check post accept() permission now.
810 *
811 * Strictly speaking, we need to pass both listen()ing socket and
812 * accept()ed socket to __cs_socket_post_accept_permission().
813 * But since socket's family and type are same for both sockets,
814 * passing the accept()ed socket in place for the listen()ing socket
815 * will work.
816 */
817 ret = cs_socket_post_accept_permission(sock, sock);
818 /*
819 * If permission was granted, we forget that this is an accept()ed
820 * socket. Otherwise, we remember that this socket needs to return
821 * error for subsequent socketcalls.
822 */
823 cs_update_socket_tag(inode, ret);
824 return ret;
825 }
826
827 /**
828 * cs_socket_accept - Check permission for accept().
829 *
830 * @sock: Pointer to "struct socket".
831 * @newsock: Pointer to "struct socket".
832 *
833 * Returns 0 on success, negative value otherwise.
834 *
835 * This hook is used for setting up environment for doing post accept()
836 * permission check. If dereferencing sock->ops->something() were ordered by
837 * rcu_dereference(), we could replace sock->ops with "a copy of original
838 * sock->ops with modified sock->ops->accept()" using rcu_assign_pointer()
839 * in order to do post accept() permission check before returning to userspace.
840 * If we make the copy in security_socket_post_create(), it would be possible
841 * to safely replace sock->ops here, but we don't do so because we don't want
842 * to allocate memory for sockets which do not call sock->ops->accept().
843 * Therefore, we do post accept() permission check upon next socket syscalls
844 * rather than between sock->ops->accept() and returning to userspace.
845 * This means that if a socket was close()d before calling some socket
846 * syscalls, post accept() permission check will not be done.
847 */
848 static int cs_socket_accept(struct socket *sock, struct socket *newsock)
849 {
850 struct cs_socket_tag *ptr;
851 const int rc = cs_validate_socket(sock);
852
853 if (rc < 0)
854 return rc;
855 ptr = kzalloc(sizeof(*ptr), GFP_KERNEL);
856 if (!ptr)
857 return -ENOMEM;
858 /*
859 * Subsequent LSM hooks will receive "newsock". Therefore, I mark
860 * "newsock" as "an accept()ed socket but post accept() permission
861 * check is not done yet" by allocating memory using inode of the
862 * "newsock" as a search key.
863 */
864 ptr->inode = SOCK_INODE(newsock);
865 ptr->status = 1; /* Check post accept() permission later. */
866 spin_lock(&cs_accepted_socket_list_lock);
867 list_add_tail_rcu(&ptr->list, &cs_accepted_socket_list);
868 spin_unlock(&cs_accepted_socket_list_lock);
869 return 0;
870 }
871
872 /**
873 * cs_socket_listen - Check permission for listen().
874 *
875 * @sock: Pointer to "struct socket".
876 * @backlog: Backlog parameter.
877 *
878 * Returns 0 on success, negative value otherwise.
879 */
880 static int cs_socket_listen(struct socket *sock, int backlog)
881 {
882 const int rc = cs_validate_socket(sock);
883
884 if (rc < 0)
885 return rc;
886 return cs_socket_listen_permission(sock);
887 }
888
889 /**
890 * cs_socket_connect - Check permission for connect().
891 *
892 * @sock: Pointer to "struct socket".
893 * @addr: Pointer to "struct sockaddr".
894 * @addr_len: Size of @addr.
895 *
896 * Returns 0 on success, negative value otherwise.
897 */
898 static int cs_socket_connect(struct socket *sock, struct sockaddr *addr,
899 int addr_len)
900 {
901 const int rc = cs_validate_socket(sock);
902
903 if (rc < 0)
904 return rc;
905 return cs_socket_connect_permission(sock, addr, addr_len);
906 }
907
908 /**
909 * cs_socket_bind - Check permission for bind().
910 *
911 * @sock: Pointer to "struct socket".
912 * @addr: Pointer to "struct sockaddr".
913 * @addr_len: Size of @addr.
914 *
915 * Returns 0 on success, negative value otherwise.
916 */
917 static int cs_socket_bind(struct socket *sock, struct sockaddr *addr,
918 int addr_len)
919 {
920 const int rc = cs_validate_socket(sock);
921
922 if (rc < 0)
923 return rc;
924 return cs_socket_bind_permission(sock, addr, addr_len);
925 }
926
927 /**
928 * cs_socket_sendmsg - Check permission for sendmsg().
929 *
930 * @sock: Pointer to "struct socket".
931 * @msg: Pointer to "struct msghdr".
932 * @size: Size of message.
933 *
934 * Returns 0 on success, negative value otherwise.
935 */
936 static int cs_socket_sendmsg(struct socket *sock, struct msghdr *msg,
937 int size)
938 {
939 const int rc = cs_validate_socket(sock);
940
941 if (rc < 0)
942 return rc;
943 return cs_socket_sendmsg_permission(sock, msg, size);
944 }
945
946 /**
947 * cs_socket_recvmsg - Check permission for recvmsg().
948 *
949 * @sock: Pointer to "struct socket".
950 * @msg: Pointer to "struct msghdr".
951 * @size: Size of message.
952 * @flags: Flags.
953 *
954 * Returns 0 on success, negative value otherwise.
955 */
956 static int cs_socket_recvmsg(struct socket *sock, struct msghdr *msg,
957 int size, int flags)
958 {
959 return cs_validate_socket(sock);
960 }
961
962 /**
963 * cs_socket_getsockname - Check permission for getsockname().
964 *
965 * @sock: Pointer to "struct socket".
966 *
967 * Returns 0 on success, negative value otherwise.
968 */
969 static int cs_socket_getsockname(struct socket *sock)
970 {
971 return cs_validate_socket(sock);
972 }
973
974 /**
975 * cs_socket_getpeername - Check permission for getpeername().
976 *
977 * @sock: Pointer to "struct socket".
978 *
979 * Returns 0 on success, negative value otherwise.
980 */
981 static int cs_socket_getpeername(struct socket *sock)
982 {
983 return cs_validate_socket(sock);
984 }
985
986 /**
987 * cs_socket_getsockopt - Check permission for getsockopt().
988 *
989 * @sock: Pointer to "struct socket".
990 * @level: Level.
991 * @optname: Option's name,
992 *
993 * Returns 0 on success, negative value otherwise.
994 */
995 static int cs_socket_getsockopt(struct socket *sock, int level, int optname)
996 {
997 return cs_validate_socket(sock);
998 }
999
1000 /**
1001 * cs_socket_setsockopt - Check permission for setsockopt().
1002 *
1003 * @sock: Pointer to "struct socket".
1004 * @level: Level.
1005 * @optname: Option's name,
1006 *
1007 * Returns 0 on success, negative value otherwise.
1008 */
1009 static int cs_socket_setsockopt(struct socket *sock, int level, int optname)
1010 {
1011 return cs_validate_socket(sock);
1012 }
1013
1014 /**
1015 * cs_socket_shutdown - Check permission for shutdown().
1016 *
1017 * @sock: Pointer to "struct socket".
1018 * @how: Shutdown mode.
1019 *
1020 * Returns 0 on success, negative value otherwise.
1021 */
1022 static int cs_socket_shutdown(struct socket *sock, int how)
1023 {
1024 return cs_validate_socket(sock);
1025 }
1026
1027 #define SOCKFS_MAGIC 0x534F434B
1028
1029 /**
1030 * cs_inode_free_security - Release memory associated with an inode.
1031 *
1032 * @inode: Pointer to "struct inode".
1033 *
1034 * Returns nothing.
1035 *
1036 * We use this hook for releasing memory associated with an accept()ed socket.
1037 */
1038 static void cs_inode_free_security(struct inode *inode)
1039 {
1040 if (inode->i_sb && inode->i_sb->s_magic == SOCKFS_MAGIC)
1041 cs_update_socket_tag(inode, 0);
1042 }
1043
1044 #endif
1045
1046 /**
1047 * cs_sb_pivotroot - Check permission for pivot_root().
1048 *
1049 * @old_path: Pointer to "struct path".
1050 * @new_path: Pointer to "struct path".
1051 *
1052 * Returns 0 on success, negative value otherwise.
1053 */
1054 static int cs_sb_pivotroot(const struct path *old_path,
1055 const struct path *new_path)
1056 {
1057 return cs_pivot_root_permission(old_path, new_path);
1058 }
1059
1060 /**
1061 * cs_sb_mount - Check permission for mount().
1062 *
1063 * @dev_name: Name of device file.
1064 * @path: Pointer to "struct path".
1065 * @type: Name of filesystem type. Maybe NULL.
1066 * @flags: Mount options.
1067 * @data_page: Optional data. Maybe NULL.
1068 *
1069 * Returns 0 on success, negative value otherwise.
1070 */
1071 static int cs_sb_mount(const char *dev_name, const struct path *path,
1072 const char *type, unsigned long flags, void *data_page)
1073 {
1074 return cs_mount_permission(dev_name, path, type, flags, data_page);
1075 }
1076
1077 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
1078 /**
1079 * cs_move_mount - Check permission for move_mount().
1080 *
1081 * @from_path: Pointer to "struct path".
1082 * @to_path: Pointer to "struct path".
1083 *
1084 * Returns 0 on success, negative value otherwise.
1085 */
1086 static int cs_move_mount(const struct path *from_path,
1087 const struct path *to_path)
1088 {
1089 return cs_move_mount_permission(from_path, to_path);
1090 }
1091 #endif
1092
1093 /**
1094 * cs_sb_umount - Check permission for umount().
1095 *
1096 * @mnt: Pointer to "struct vfsmount".
1097 * @flags: Unmount flags.
1098 *
1099 * Returns 0 on success, negative value otherwise.
1100 */
1101 static int cs_sb_umount(struct vfsmount *mnt, int flags)
1102 {
1103 struct path path = { .mnt = mnt, .dentry = mnt->mnt_root };
1104
1105 return cs_umount_permission(&path, flags);
1106 }
1107
1108 /**
1109 * cs_file_fcntl - Check permission for fcntl().
1110 *
1111 * @file: Pointer to "struct file".
1112 * @cmd: Command number.
1113 * @arg: Value for @cmd.
1114 *
1115 * Returns 0 on success, negative value otherwise.
1116 */
1117 static int cs_file_fcntl(struct file *file, unsigned int cmd,
1118 unsigned long arg)
1119 {
1120 return cs_fcntl_permission(file, cmd, arg);
1121 }
1122
1123 /**
1124 * cs_file_ioctl - Check permission for ioctl().
1125 *
1126 * @filp: Pointer to "struct file".
1127 * @cmd: Command number.
1128 * @arg: Value for @cmd.
1129 *
1130 * Returns 0 on success, negative value otherwise.
1131 */
1132 static int cs_file_ioctl(struct file *filp, unsigned int cmd,
1133 unsigned long arg)
1134 {
1135 return cs_ioctl_permission(filp, cmd, arg);
1136 }
1137
1138 #define MY_HOOK_INIT(HEAD, HOOK) \
1139 { .head = &probe_dummy_security_hook_heads.HEAD, \
1140 .hook = { .HEAD = HOOK } }
1141
1142 static struct security_hook_list caitsith_hooks[] = {
1143 /* Security context allocator. */
1144 MY_HOOK_INIT(task_free, cs_task_free_security),
1145 MY_HOOK_INIT(cred_prepare, cs_cred_prepare),
1146 MY_HOOK_INIT(task_alloc, cs_task_alloc_security),
1147 /* Security context updater for successful execve(). */
1148 MY_HOOK_INIT(bprm_check_security, cs_bprm_check_security),
1149 MY_HOOK_INIT(bprm_committing_creds, cs_bprm_committing_creds),
1150 /* Various permission checker. */
1151 MY_HOOK_INIT(file_open, cs_file_open),
1152 MY_HOOK_INIT(file_fcntl, cs_file_fcntl),
1153 MY_HOOK_INIT(file_ioctl, cs_file_ioctl),
1154 MY_HOOK_INIT(sb_pivotroot, cs_sb_pivotroot),
1155 MY_HOOK_INIT(sb_mount, cs_sb_mount),
1156 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
1157 MY_HOOK_INIT(move_mount, cs_move_mount),
1158 #endif
1159 MY_HOOK_INIT(sb_umount, cs_sb_umount),
1160 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 2, 0)
1161 MY_HOOK_INIT(file_truncate, cs_file_truncate),
1162 #endif
1163 #ifdef CONFIG_SECURITY_PATH
1164 MY_HOOK_INIT(path_mknod, cs_path_mknod),
1165 MY_HOOK_INIT(path_mkdir, cs_path_mkdir),
1166 MY_HOOK_INIT(path_rmdir, cs_path_rmdir),
1167 MY_HOOK_INIT(path_unlink, cs_path_unlink),
1168 MY_HOOK_INIT(path_symlink, cs_path_symlink),
1169 MY_HOOK_INIT(path_rename, cs_path_rename),
1170 MY_HOOK_INIT(path_link, cs_path_link),
1171 MY_HOOK_INIT(path_truncate, cs_path_truncate),
1172 MY_HOOK_INIT(path_chmod, cs_path_chmod),
1173 MY_HOOK_INIT(path_chown, cs_path_chown),
1174 MY_HOOK_INIT(path_chroot, cs_path_chroot),
1175 #else
1176 MY_HOOK_INIT(inode_mknod, cs_inode_mknod),
1177 MY_HOOK_INIT(inode_mkdir, cs_inode_mkdir),
1178 MY_HOOK_INIT(inode_rmdir, cs_inode_rmdir),
1179 MY_HOOK_INIT(inode_unlink, cs_inode_unlink),
1180 MY_HOOK_INIT(inode_symlink, cs_inode_symlink),
1181 MY_HOOK_INIT(inode_rename, cs_inode_rename),
1182 MY_HOOK_INIT(inode_link, cs_inode_link),
1183 MY_HOOK_INIT(inode_create, cs_inode_create),
1184 MY_HOOK_INIT(inode_setattr, cs_inode_setattr),
1185 #endif
1186 MY_HOOK_INIT(inode_getattr, cs_inode_getattr),
1187 #ifdef CONFIG_SECURITY_NETWORK
1188 MY_HOOK_INIT(socket_bind, cs_socket_bind),
1189 MY_HOOK_INIT(socket_connect, cs_socket_connect),
1190 MY_HOOK_INIT(socket_listen, cs_socket_listen),
1191 MY_HOOK_INIT(socket_sendmsg, cs_socket_sendmsg),
1192 MY_HOOK_INIT(socket_recvmsg, cs_socket_recvmsg),
1193 MY_HOOK_INIT(socket_getsockname, cs_socket_getsockname),
1194 MY_HOOK_INIT(socket_getpeername, cs_socket_getpeername),
1195 MY_HOOK_INIT(socket_getsockopt, cs_socket_getsockopt),
1196 MY_HOOK_INIT(socket_setsockopt, cs_socket_setsockopt),
1197 MY_HOOK_INIT(socket_shutdown, cs_socket_shutdown),
1198 MY_HOOK_INIT(socket_accept, cs_socket_accept),
1199 MY_HOOK_INIT(inode_free_security, cs_inode_free_security),
1200 #endif
1201 };
1202
1203 static inline void add_hook(struct security_hook_list *hook)
1204 {
1205 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1206 hlist_add_tail_rcu(&hook->list, hook->head);
1207 #else
1208 list_add_tail_rcu(&hook->list, hook->head);
1209 #endif
1210 }
1211
1212 static void __init swap_hook(struct security_hook_list *hook,
1213 union security_list_options *original)
1214 {
1215 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1216 struct hlist_head *list = hook->head;
1217
1218 if (hlist_empty(list)) {
1219 add_hook(hook);
1220 } else {
1221 struct security_hook_list *shp =
1222 hlist_entry(list->first, typeof(*shp), list);
1223
1224 while (shp->list.next)
1225 shp = hlist_entry(shp->list.next, typeof(*shp), list);
1226 *original = shp->hook;
1227 smp_wmb();
1228 shp->hook = hook->hook;
1229 }
1230 #else
1231 struct list_head *list = hook->head;
1232
1233 if (list_empty(list)) {
1234 add_hook(hook);
1235 } else {
1236 struct security_hook_list *shp =
1237 list_last_entry(list, struct security_hook_list, list);
1238
1239 *original = shp->hook;
1240 smp_wmb();
1241 shp->hook = hook->hook;
1242 }
1243 #endif
1244 }
1245
1246 #if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(CONFIG_SECURITY_WRITABLE_HOOKS)
1247 #include <linux/uaccess.h> /* probe_kernel_write() */
1248 #define NEED_TO_CHECK_HOOKS_ARE_WRITABLE
1249
1250 #if defined(CONFIG_X86)
1251 #define MAX_RO_PAGES 1024
1252 static struct page *ro_pages[MAX_RO_PAGES] __initdata;
1253 static unsigned int ro_pages_len __initdata;
1254
1255 static bool __init lsm_test_page_ro(void *addr)
1256 {
1257 unsigned int i;
1258 int unused;
1259 struct page *page;
1260
1261 page = (struct page *) lookup_address((unsigned long) addr, &unused);
1262 if (!page)
1263 return false;
1264 if (test_bit(_PAGE_BIT_RW, &(page->flags)))
1265 return true;
1266 for (i = 0; i < ro_pages_len; i++)
1267 if (page == ro_pages[i])
1268 return true;
1269 if (ro_pages_len == MAX_RO_PAGES)
1270 return false;
1271 ro_pages[ro_pages_len++] = page;
1272 return true;
1273 }
1274
1275 static bool __init check_ro_pages(struct security_hook_heads *hooks)
1276 {
1277 int i;
1278 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1279 struct hlist_head *list = &hooks->capable;
1280
1281 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
1282 if (!probe_kernel_write(list, list, sizeof(void *)))
1283 return true;
1284 #else
1285 if (!my_copy_to_kernel_nofault(list, list, sizeof(void *)))
1286 return true;
1287 #endif
1288 for (i = 0; i < ARRAY_SIZE(caitsith_hooks); i++) {
1289 struct hlist_head *head = caitsith_hooks[i].head;
1290 struct security_hook_list *shp;
1291
1292 if (!lsm_test_page_ro(&head->first))
1293 return false;
1294 hlist_for_each_entry(shp, head, list)
1295 if (!lsm_test_page_ro(&shp->list.next) ||
1296 !lsm_test_page_ro(&shp->list.pprev))
1297 return false;
1298 }
1299 #else
1300 struct list_head *list = &hooks->capable;
1301
1302 if (!probe_kernel_write(list, list, sizeof(void *)))
1303 return true;
1304 for (i = 0; i < ARRAY_SIZE(caitsith_hooks); i++) {
1305 struct list_head *head = caitsith_hooks[i].head;
1306 struct security_hook_list *shp;
1307
1308 if (!lsm_test_page_ro(&head->next) ||
1309 !lsm_test_page_ro(&head->prev))
1310 return false;
1311 list_for_each_entry(shp, head, list)
1312 if (!lsm_test_page_ro(&shp->list.next) ||
1313 !lsm_test_page_ro(&shp->list.prev))
1314 return false;
1315 }
1316 #endif
1317 return true;
1318 }
1319 #else
1320 static bool __init check_ro_pages(struct security_hook_heads *hooks)
1321 {
1322 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1323 struct hlist_head *list = &hooks->capable;
1324 #else
1325 struct list_head *list = &hooks->capable;
1326 #endif
1327
1328 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
1329 return !probe_kernel_write(list, list, sizeof(void *));
1330 #else
1331 return !my_copy_to_kernel_nofault(list, list, sizeof(void *));
1332 #endif
1333 }
1334 #endif
1335 #endif
1336
1337 /**
1338 * cs_init - Initialize this module.
1339 *
1340 * Returns 0 on success, negative value otherwise.
1341 */
1342 static int __init cs_init(void)
1343 {
1344 int idx;
1345 struct security_hook_heads *hooks = probe_security_hook_heads();
1346
1347 if (!hooks)
1348 goto out;
1349 for (idx = 0; idx < ARRAY_SIZE(caitsith_hooks); idx++)
1350 caitsith_hooks[idx].head = ((void *) hooks)
1351 + ((unsigned long) caitsith_hooks[idx].head)
1352 - ((unsigned long) &probe_dummy_security_hook_heads);
1353 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
1354 my_copy_to_kernel_nofault = probe_copy_to_kernel_nofault();
1355 if (!my_copy_to_kernel_nofault)
1356 goto out;
1357 #endif
1358 #if defined(NEED_TO_CHECK_HOOKS_ARE_WRITABLE)
1359 if (!check_ro_pages(hooks)) {
1360 printk(KERN_INFO "Can't update security_hook_heads due to write protected. Retry with rodata=off kernel command line option added.\n");
1361 return -EINVAL;
1362 }
1363 #endif
1364 caitsith_exports.find_task_by_vpid = probe_find_task_by_vpid();
1365 if (!caitsith_exports.find_task_by_vpid)
1366 goto out;
1367 caitsith_exports.find_task_by_pid_ns = probe_find_task_by_pid_ns();
1368 if (!caitsith_exports.find_task_by_pid_ns)
1369 goto out;
1370 caitsith_exports.d_absolute_path = probe_d_absolute_path();
1371 if (!caitsith_exports.d_absolute_path)
1372 goto out;
1373 for (idx = 0; idx < CS_MAX_TASK_SECURITY_HASH; idx++)
1374 INIT_LIST_HEAD(&cs_task_security_list[idx]);
1375 cs_init_module();
1376 #if defined(NEED_TO_CHECK_HOOKS_ARE_WRITABLE) && defined(CONFIG_X86)
1377 for (idx = 0; idx < ro_pages_len; idx++)
1378 set_bit(_PAGE_BIT_RW, &(ro_pages[idx]->flags));
1379 #endif
1380 swap_hook(&caitsith_hooks[0], &original_task_free);
1381 swap_hook(&caitsith_hooks[1], &original_cred_prepare);
1382 swap_hook(&caitsith_hooks[2], &original_task_alloc);
1383 for (idx = 3; idx < ARRAY_SIZE(caitsith_hooks); idx++)
1384 add_hook(&caitsith_hooks[idx]);
1385 #if defined(NEED_TO_CHECK_HOOKS_ARE_WRITABLE) && defined(CONFIG_X86)
1386 for (idx = 0; idx < ro_pages_len; idx++)
1387 clear_bit(_PAGE_BIT_RW, &(ro_pages[idx]->flags));
1388 #endif
1389 return 0;
1390 out:
1391 return -EINVAL;
1392 }
1393
1394 module_init(cs_init);
1395 MODULE_LICENSE("GPL");
1396
1397 /**
1398 * cs_used_by_cred - Check whether the given domain is in use or not.
1399 *
1400 * @domain: Pointer to "struct cs_domain_info".
1401 *
1402 * Returns true if @domain is in use, false otherwise.
1403 *
1404 * Caller holds rcu_read_lock().
1405 */
1406 bool cs_used_by_cred(const struct cs_domain_info *domain)
1407 {
1408 return false;
1409 }
1410
1411 /**
1412 * cs_add_task_security - Add "struct cs_security" to list.
1413 *
1414 * @ptr: Pointer to "struct cs_security".
1415 * @list: Pointer to "struct list_head".
1416 *
1417 * Returns nothing.
1418 */
1419 static void cs_add_task_security(struct cs_security *ptr,
1420 struct list_head *list)
1421 {
1422 unsigned long flags;
1423
1424 spin_lock_irqsave(&cs_task_security_list_lock, flags);
1425 list_add_rcu(&ptr->list, list);
1426 spin_unlock_irqrestore(&cs_task_security_list_lock, flags);
1427 }
1428
1429 /**
1430 * __cs_alloc_task_security - Allocate memory for new tasks.
1431 *
1432 * @task: Pointer to "struct task_struct".
1433 *
1434 * Returns 0 on success, negative value otherwise.
1435 */
1436 static int __cs_alloc_task_security(const struct task_struct *task)
1437 {
1438 struct cs_security *old_security = cs_current_security();
1439 struct cs_security *new_security = kzalloc(sizeof(*new_security),
1440 GFP_KERNEL);
1441 struct list_head *list = &cs_task_security_list
1442 [hash_ptr((void *) task, CS_TASK_SECURITY_HASH_BITS)];
1443
1444 if (!new_security)
1445 return -ENOMEM;
1446 new_security->task = task;
1447 new_security->cs_domain_info = old_security->cs_domain_info;
1448 new_security->cs_flags = old_security->cs_flags;
1449 cs_add_task_security(new_security, list);
1450 return 0;
1451 }
1452
1453 /**
1454 * cs_find_task_security - Find "struct cs_security" for given task.
1455 *
1456 * @task: Pointer to "struct task_struct".
1457 *
1458 * Returns pointer to "struct cs_security" on success, &cs_oom_security on
1459 * out of memory, &cs_default_security otherwise.
1460 *
1461 * If @task is current thread and "struct cs_security" for current thread was
1462 * not found, I try to allocate it. But if allocation failed, current thread
1463 * will be killed by SIGKILL. Note that if current->pid == 1, sending SIGKILL
1464 * won't work.
1465 */
1466 struct cs_security *cs_find_task_security(const struct task_struct *task)
1467 {
1468 struct cs_security *ptr;
1469 struct list_head *list = &cs_task_security_list
1470 [hash_ptr((void *) task, CS_TASK_SECURITY_HASH_BITS)];
1471 /* Make sure INIT_LIST_HEAD() in cs_mm_init() takes effect. */
1472 while (!list->next)
1473 smp_rmb();
1474 rcu_read_lock();
1475 list_for_each_entry_rcu(ptr, list, list) {
1476 if (ptr->task != task)
1477 continue;
1478 rcu_read_unlock();
1479 /*
1480 * Current thread needs to transit from old domain to new
1481 * domain before do_execve() succeeds in order to check
1482 * permission for interpreters and environment variables using
1483 * new domain's ACL rules. The domain transition has to be
1484 * visible from other CPU in order to allow interactive
1485 * enforcing mode. Also, the domain transition has to be
1486 * reverted if do_execve() failed. However, an LSM hook for
1487 * reverting domain transition is missing.
1488 *
1489 * security_prepare_creds() is called from prepare_creds() from
1490 * prepare_bprm_creds() from do_execve() before setting
1491 * current->in_execve flag, and current->in_execve flag is
1492 * cleared by the time next do_execve() request starts.
1493 * This means that we can emulate the missing LSM hook for
1494 * reverting domain transition, by calling this function from
1495 * security_prepare_creds().
1496 *
1497 * If current->in_execve is not set but ptr->cs_flags has
1498 * CS_TASK_IS_IN_EXECVE set, it indicates that do_execve()
1499 * has failed and reverting domain transition is needed.
1500 */
1501 if (task == current &&
1502 (ptr->cs_flags & CS_TASK_IS_IN_EXECVE) &&
1503 !current->in_execve) {
1504 cs_debug_trace("1");
1505 cs_clear_execve(-1, ptr);
1506 }
1507 return ptr;
1508 }
1509 rcu_read_unlock();
1510 if (task != current)
1511 return &cs_default_security;
1512 /* Use GFP_ATOMIC because caller may have called rcu_read_lock(). */
1513 ptr = kzalloc(sizeof(*ptr), GFP_ATOMIC);
1514 if (!ptr) {
1515 printk(KERN_WARNING "Unable to allocate memory for pid=%u\n",
1516 task->pid);
1517 send_sig(SIGKILL, current, 0);
1518 return &cs_oom_security;
1519 }
1520 *ptr = cs_default_security;
1521 ptr->task = task;
1522 cs_add_task_security(ptr, list);
1523 return ptr;
1524 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26