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

Subversion リポジトリの参照

Contents of /trunk/1.6.x/ccs-patch/fs/sakura_maymount.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1903 - (show annotations) (download) (as text)
Mon Dec 1 06:16:16 2008 UTC (15 years, 5 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 4318 byte(s)


1 /*
2 * fs/sakura_maymount.c
3 *
4 * Implementation of the Domain-Free Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2008 NTT DATA CORPORATION
7 *
8 * Version: 1.6.6-pre 2008/12/01
9 *
10 * This file is applicable to both 2.4.30 and 2.6.11 and later.
11 * See README.ccs for ChangeLog.
12 *
13 */
14
15 #include <linux/ccs_common.h>
16 #include <linux/sakura.h>
17 #include <linux/realpath.h>
18 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
19 #include <linux/mount.h>
20 #include <linux/mnt_namespace.h>
21 #else
22 #include <linux/namespace.h>
23 #endif
24 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
25 #include <linux/namei.h>
26 #endif
27
28 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
29 #define PATH_or_NAMEIDATA path
30 #else
31 #define PATH_or_NAMEIDATA nameidata
32 #endif
33
34 /**
35 * check_conceal_mount - Check whether this mount request shadows existing mounts.
36 *
37 * @path: Pointer to "struct path" (for 2.6.27 and later).
38 * Pointer to "struct nameidata" (for 2.6.26 and earlier).
39 * @vfsmnt: Pointer to "struct vfsmount".
40 * @dentry: Pointer to "struct dentry".
41 *
42 * Returns true if @vfsmnt is parent directory compared to @nd, false otherwise.
43 */
44 static bool check_conceal_mount(struct PATH_or_NAMEIDATA *path,
45 struct vfsmount *vfsmnt, struct dentry *dentry)
46 {
47 /***** CRITICAL SECTION START *****/
48 while (1) {
49 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
50 if (path->path.mnt->mnt_root == vfsmnt->mnt_root &&
51 path->path.dentry == dentry)
52 return true;
53 #else
54 if (path->mnt->mnt_root == vfsmnt->mnt_root &&
55 path->dentry == dentry)
56 return true;
57 #endif
58 if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
59 if (vfsmnt->mnt_parent == vfsmnt)
60 break;
61 dentry = vfsmnt->mnt_mountpoint;
62 vfsmnt = vfsmnt->mnt_parent;
63 continue;
64 }
65 dentry = dentry->d_parent;
66 }
67 return false;
68 /***** CRITICAL SECTION END *****/
69 }
70
71 /**
72 * print_error - Print error message.
73 *
74 * @r: Pointer to "struct ccs_request_info".
75 * @path: Pointer to "struct path" (for 2.6.27 and later).
76 * Pointer to "struct nameidata" (for 2.6.26 and earlier).
77 *
78 * Returns 0 if @r->mode is not enforcing or permitted by the administrator's
79 * decision, negative value otherwise.
80 */
81 static int print_error(struct ccs_request_info *r,
82 struct PATH_or_NAMEIDATA *path)
83 {
84 int error;
85 const bool is_enforce = (r->mode == 3);
86 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
87 const char *dir = ccs_realpath_from_dentry(path->path.dentry,
88 path->path.mnt);
89 #else
90 const char *dir = ccs_realpath_from_dentry(path->dentry, path->mnt);
91 #endif
92 const char *exename = ccs_get_exe();
93 printk(KERN_WARNING "SAKURA-%s: mount %s (pid=%d:exe=%s): "
94 "Permission denied.\n", ccs_get_msg(is_enforce), dir,
95 (pid_t) sys_getpid(), exename);
96 if (is_enforce)
97 error = ccs_check_supervisor(r, "# %s is requesting\n"
98 "mount on %s\n", exename, dir);
99 else
100 error = 0;
101 ccs_free(exename);
102 ccs_free(dir);
103 return error;
104 }
105
106 /**
107 * ccs_may_mount - Check whether this mount request shadows existing mounts.
108 *
109 * @nd: Pointer to "struct nameidata".
110 *
111 * Returns 0 on success, negative value otherwise.
112 */
113 int ccs_may_mount(struct PATH_or_NAMEIDATA *path)
114 {
115 struct ccs_request_info r;
116 struct list_head *p;
117 bool flag = false;
118 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
119 struct namespace *namespace = current->namespace;
120 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
121 struct namespace *namespace = current->nsproxy->namespace;
122 #else
123 struct mnt_namespace *namespace = current->nsproxy->mnt_ns;
124 #endif
125 if (!ccs_can_sleep())
126 return 0;
127 ccs_init_request_info(&r, NULL, CCS_SAKURA_DENY_CONCEAL_MOUNT);
128 if (!r.mode)
129 return 0;
130 if (!namespace)
131 return 0;
132 retry:
133 list_for_each(p, &namespace->list) {
134 struct vfsmount *vfsmnt = list_entry(p, struct vfsmount,
135 mnt_list);
136 struct dentry *dentry = vfsmnt->mnt_root;
137 /***** CRITICAL SECTION START *****/
138 ccs_realpath_lock();
139 if (IS_ROOT(dentry) || !d_unhashed(dentry))
140 flag = check_conceal_mount(path, vfsmnt, dentry);
141 ccs_realpath_unlock();
142 /***** CRITICAL SECTION END *****/
143 if (flag)
144 break;
145 }
146 if (flag) {
147 int error = print_error(&r, path);
148 if (error == 1)
149 goto retry;
150 return error;
151 }
152 return 0;
153 }

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