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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1644 - (show annotations) (download) (as text)
Wed Oct 1 07:12:42 2008 UTC (15 years, 7 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 4395 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.5-pre 2008/10/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 * @path: Pointer to "struct path" (for 2.6.27 and later).
75 * Pointer to "struct nameidata" (for 2.6.26 and earlier).
76 * @mode: Access control mode.
77 * @retries: How many retries are made for this request.
78 *
79 * Returns 0 if @mode is not enforcing or permitted by the administrator's
80 * decision, negative value otherwise.
81 */
82 static int print_error(struct PATH_or_NAMEIDATA *path, const u8 mode,
83 const unsigned short int retries)
84 {
85 int error;
86 const bool is_enforce = (mode == 3);
87 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
88 const char *dir = ccs_realpath_from_dentry(path->path.dentry,
89 path->path.mnt);
90 #else
91 const char *dir = ccs_realpath_from_dentry(path->dentry, path->mnt);
92 #endif
93 const char *exename = ccs_get_exe();
94 printk(KERN_WARNING "SAKURA-%s: mount %s (pid=%d:exe=%s): "
95 "Permission denied.\n", ccs_get_msg(is_enforce), dir,
96 current->pid, exename);
97 if (is_enforce)
98 error = ccs_check_supervisor(retries, NULL,
99 "# %s is requesting\n"
100 "mount on %s\n", exename, dir);
101 else
102 error = 0;
103 ccs_free(exename);
104 ccs_free(dir);
105 return error;
106 }
107
108 /**
109 * ccs_may_mount - Check whether this mount request shadows existing mounts.
110 *
111 * @nd: Pointer to "struct nameidata".
112 *
113 * Returns 0 on success, negative value otherwise.
114 */
115 int ccs_may_mount(struct PATH_or_NAMEIDATA *path)
116 {
117 unsigned short int retries = 0;
118 struct list_head *p;
119 bool flag = false;
120 const u8 mode = ccs_check_flags(CCS_SAKURA_DENY_CONCEAL_MOUNT);
121 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
122 struct namespace *namespace = current->namespace;
123 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
124 struct namespace *namespace = current->nsproxy->namespace;
125 #else
126 struct mnt_namespace *namespace = current->nsproxy->mnt_ns;
127 #endif
128 if (!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(path, mode, retries);
148 if (error == 1) {
149 retries++;
150 goto retry;
151 }
152 return error;
153 }
154 return 0;
155 }

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