Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 387 - (hide 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 kumaneko 233 /*
2     * lsm.c
3     *
4     * Copyright (C) 2010-2013 Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
5     *
6 kumaneko 378 * Version: 0.2.11 2023/05/27
7 kumaneko 233 */
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 kumaneko 371 #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 kumaneko 233 #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 kumaneko 377 if ((gfp & GFP_KERNEL) == GFP_KERNEL)
165 kumaneko 233 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 kumaneko 387 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0)
172 kumaneko 233 /**
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 kumaneko 387 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 kumaneko 233 static void cs_bprm_committing_creds(struct linux_binprm *bprm)
192     {
193     cs_clear_execve(0, cs_current_security());
194     }
195 kumaneko 387 #endif
196 kumaneko 233
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 kumaneko 338 #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 kumaneko 233 return cs_start_execve(bprm, &security->r);
294     }
295    
296 kumaneko 288 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) || (defined(RHEL_MAJOR) && RHEL_MAJOR == 8)
297 kumaneko 233 /**
298     * cs_file_open - Check permission for open().
299     *
300     * @f: Pointer to "struct file".
301 kumaneko 267 *
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 kumaneko 233 * @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 kumaneko 267 #endif
322 kumaneko 233
323 kumaneko 374 #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 kumaneko 233 #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 kumaneko 368 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
516 kumaneko 233 /**
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 kumaneko 368 * @flags: Rename flags.
524 kumaneko 233 *
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 kumaneko 368 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 kumaneko 233 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 kumaneko 368 #endif
566 kumaneko 233
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 kumaneko 280 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
1078 kumaneko 233 /**
1079 kumaneko 280 * 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 kumaneko 233 * 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 kumaneko 280 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
1157     MY_HOOK_INIT(move_mount, cs_move_mount),
1158     #endif
1159 kumaneko 233 MY_HOOK_INIT(sb_umount, cs_sb_umount),
1160 kumaneko 374 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 2, 0)
1161     MY_HOOK_INIT(file_truncate, cs_file_truncate),
1162     #endif
1163 kumaneko 233 #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 kumaneko 262 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1206     hlist_add_tail_rcu(&hook->list, hook->head);
1207     #else
1208 kumaneko 233 list_add_tail_rcu(&hook->list, hook->head);
1209 kumaneko 262 #endif
1210 kumaneko 233 }
1211    
1212     static void __init swap_hook(struct security_hook_list *hook,
1213     union security_list_options *original)
1214     {
1215 kumaneko 262 #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 kumaneko 233 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 kumaneko 262
1239 kumaneko 233 *original = shp->hook;
1240     smp_wmb();
1241     shp->hook = hook->hook;
1242     }
1243 kumaneko 262 #endif
1244 kumaneko 233 }
1245    
1246 kumaneko 262 #if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(CONFIG_SECURITY_WRITABLE_HOOKS)
1247 kumaneko 239 #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 kumaneko 262 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1279     struct hlist_head *list = &hooks->capable;
1280    
1281 kumaneko 371 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
1282 kumaneko 262 if (!probe_kernel_write(list, list, sizeof(void *)))
1283     return true;
1284 kumaneko 371 #else
1285     if (!my_copy_to_kernel_nofault(list, list, sizeof(void *)))
1286     return true;
1287 kumaneko 310 #endif
1288 kumaneko 262 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 kumaneko 259 struct list_head *list = &hooks->capable;
1301 kumaneko 239
1302 kumaneko 259 if (!probe_kernel_write(list, list, sizeof(void *)))
1303 kumaneko 239 return true;
1304     for (i = 0; i < ARRAY_SIZE(caitsith_hooks); i++) {
1305 kumaneko 259 struct list_head *head = caitsith_hooks[i].head;
1306     struct security_hook_list *shp;
1307 kumaneko 239
1308 kumaneko 259 if (!lsm_test_page_ro(&head->next) ||
1309     !lsm_test_page_ro(&head->prev))
1310 kumaneko 239 return false;
1311 kumaneko 259 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 kumaneko 239 }
1316 kumaneko 262 #endif
1317 kumaneko 239 return true;
1318     }
1319     #else
1320     static bool __init check_ro_pages(struct security_hook_heads *hooks)
1321     {
1322 kumaneko 262 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
1323     struct hlist_head *list = &hooks->capable;
1324     #else
1325 kumaneko 259 struct list_head *list = &hooks->capable;
1326 kumaneko 262 #endif
1327 kumaneko 259
1328 kumaneko 371 #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
1329 kumaneko 259 return !probe_kernel_write(list, list, sizeof(void *));
1330 kumaneko 371 #else
1331     return !my_copy_to_kernel_nofault(list, list, sizeof(void *));
1332     #endif
1333 kumaneko 239 }
1334     #endif
1335     #endif
1336    
1337 kumaneko 233 /**
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 kumaneko 371 #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 kumaneko 239 #if defined(NEED_TO_CHECK_HOOKS_ARE_WRITABLE)
1359     if (!check_ro_pages(hooks)) {
1360 kumaneko 382 printk(KERN_INFO "Can't update security_hook_heads due to write protected. Retry with rodata=off kernel command line option added.\n");
1361 kumaneko 239 return -EINVAL;
1362     }
1363     #endif
1364 kumaneko 233 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 kumaneko 239 #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 kumaneko 233 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 kumaneko 239 #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 kumaneko 233 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 kumaneko 258 smp_rmb();
1474 kumaneko 233 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