オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Contents of /trunk/akari/lsm-4.12.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 644 - (show annotations) (download) (as text)
Mon Jun 15 02:29:50 2020 UTC (3 years, 11 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 38236 byte(s)


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

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