Open-Source-Software-Entwicklung und Downloads

Browse Subversion Repository

Contents of /trunk/1.6.x/ccs-patch/include/linux/tomoyo_vfs.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1379 - (show annotations) (download) (as text)
Thu Jul 10 06:52:35 2008 UTC (15 years, 10 months ago) by kumaneko
File MIME type: text/x-chdr
File size: 9604 byte(s)


1 /*
2 * include/linux/tomoyo_vfs.h
3 *
4 * Implementation of the Domain-Based Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2008 NTT DATA CORPORATION
7 *
8 * Version: 1.6.3-pre 2008/07/10
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 #ifndef _LINUX_TOMOYO_VFS_H
16 #define _LINUX_TOMOYO_VFS_H
17
18 #include <linux/version.h>
19
20 /*
21 * This file contains copy of some of VFS helper functions.
22 *
23 * Since TOMOYO Linux requires "struct vfsmount" parameter to calculate
24 * an absolute pathname of the requested "struct dentry" parameter
25 * but the VFS helper functions don't receive "struct vfsmount" parameter,
26 * TOMOYO Linux checks permission outside VFS helper functions.
27 * To keep the DAC's permission checks are performed before the
28 * TOMOYO Linux's permission checks are performed, I'm manually inserting
29 * these functions that performs the DAC's permission checks into fs/namei.c.
30 *
31 * The approach to obtain "struct vfsmount" parameter from
32 * the "struct task_struct" doesn't work because it triggers deadlock.
33 */
34
35 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
36
37 /* Some of permission checks from vfs_create(). */
38 static inline int pre_vfs_create(struct inode *dir, struct dentry *dentry)
39 {
40 int error;
41 down(&dir->i_zombie);
42 error = may_create(dir, dentry);
43 if (!error && (!dir->i_op || !dir->i_op->create))
44 error = -EACCES;
45 up(&dir->i_zombie);
46 return error;
47 }
48
49 /*
50 * Some of permission checks from vfs_mknod().
51 *
52 * This function is exported because
53 * vfs_mknod() is called from net/unix/af_unix.c.
54 */
55 int pre_vfs_mknod(struct inode *dir, struct dentry *dentry)
56 {
57 int error;
58 down(&dir->i_zombie);
59 error = may_create(dir, dentry);
60 if (!error && (!dir->i_op || !dir->i_op->mknod))
61 error = -EPERM;
62 up(&dir->i_zombie);
63 return error;
64 }
65 EXPORT_SYMBOL(pre_vfs_mknod);
66
67 /* Some of permission checks from vfs_mkdir(). */
68 static inline int pre_vfs_mkdir(struct inode *dir, struct dentry *dentry)
69 {
70 int error;
71 down(&dir->i_zombie);
72 error = may_create(dir, dentry);
73 if (!error && (!dir->i_op || !dir->i_op->mkdir))
74 error = -EPERM;
75 up(&dir->i_zombie);
76 return error;
77 }
78
79 /* Some of permission checks from vfs_rmdir(). */
80 static inline int pre_vfs_rmdir(struct inode *dir, struct dentry *dentry)
81 {
82 int error = may_delete(dir, dentry, 1);
83 if (!error && (!dir->i_op || !dir->i_op->rmdir))
84 error = -EPERM;
85 return error;
86 }
87
88 /* Some of permission checks from vfs_unlink(). */
89 static inline int pre_vfs_unlink(struct inode *dir, struct dentry *dentry)
90 {
91 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 33)
92 int error;
93 down(&dir->i_zombie);
94 error = may_delete(dir, dentry, 0);
95 if (!error && (!dir->i_op || !dir->i_op->unlink))
96 error = -EPERM;
97 up(&dir->i_zombie);
98 return error;
99 #else
100 int error;
101 struct inode *inode;
102 error = may_delete(dir, dentry, 0);
103 if (error)
104 return error;
105 inode = dentry->d_inode;
106 atomic_inc(&inode->i_count);
107 double_down(&dir->i_zombie, &inode->i_zombie);
108 error = -EPERM;
109 if (dir->i_op && dir->i_op->unlink)
110 error = 0;
111 double_up(&dir->i_zombie, &inode->i_zombie);
112 iput(inode);
113 return error;
114 #endif
115 }
116
117 /* Permission checks from vfs_symlink(). */
118 static inline int pre_vfs_symlink(struct inode *dir, struct dentry *dentry)
119 {
120 int error;
121 down(&dir->i_zombie);
122 error = may_create(dir, dentry);
123 if (error)
124 goto exit_lock;
125 if (!dir->i_op || !dir->i_op->symlink)
126 error = -EPERM;
127 exit_lock:
128 up(&dir->i_zombie);
129 return error;
130 }
131
132 /* Some of permission checks from vfs_link(). */
133 static inline int pre_vfs_link(struct dentry *old_dentry, struct inode *dir,
134 struct dentry *new_dentry)
135 {
136 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 33)
137 struct inode *inode;
138 int error;
139 down(&dir->i_zombie);
140 error = -ENOENT;
141 inode = old_dentry->d_inode;
142 if (!inode)
143 goto exit_lock;
144 error = may_create(dir, new_dentry);
145 if (error)
146 goto exit_lock;
147 error = -EXDEV;
148 if (dir->i_dev != inode->i_dev)
149 goto exit_lock;
150 error = -EPERM;
151 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
152 goto exit_lock;
153 if (!dir->i_op || !dir->i_op->link)
154 goto exit_lock;
155 error = 0;
156 exit_lock:
157 up(&dir->i_zombie);
158 return error;
159 #else
160 struct inode *inode;
161 int error;
162 error = -ENOENT;
163 inode = old_dentry->d_inode;
164 if (!inode)
165 goto exit;
166 error = -EXDEV;
167 if (dir->i_dev != inode->i_dev)
168 goto exit;
169 double_down(&dir->i_zombie, &old_dentry->d_inode->i_zombie);
170 error = may_create(dir, new_dentry);
171 if (error)
172 goto exit_lock;
173 error = -EPERM;
174 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
175 goto exit_lock;
176 if (!dir->i_op || !dir->i_op->link)
177 goto exit_lock;
178 error = 0;
179 exit_lock:
180 double_up(&dir->i_zombie, &old_dentry->d_inode->i_zombie);
181 exit:
182 return error;
183 #endif
184 }
185
186 /* Some of permission checks from vfs_rename_dir(). */
187 static inline int pre_vfs_rename_dir(struct inode *old_dir,
188 struct dentry *old_dentry,
189 struct inode *new_dir,
190 struct dentry *new_dentry)
191 {
192 int error;
193 if (old_dentry->d_inode == new_dentry->d_inode)
194 return 0;
195 error = may_delete(old_dir, old_dentry, 1);
196 if (error)
197 return error;
198 if (new_dir->i_dev != old_dir->i_dev)
199 return -EXDEV;
200 if (!new_dentry->d_inode)
201 error = may_create(new_dir, new_dentry);
202 else
203 error = may_delete(new_dir, new_dentry, 1);
204 if (error)
205 return error;
206 if (!old_dir->i_op || !old_dir->i_op->rename)
207 return -EPERM;
208 if (new_dir != old_dir)
209 error = permission(old_dentry->d_inode, MAY_WRITE);
210 return error;
211 }
212
213 /* Some of permission checks from vfs_rename_other(). */
214 static inline int pre_vfs_rename_other(struct inode *old_dir,
215 struct dentry *old_dentry,
216 struct inode *new_dir,
217 struct dentry *new_dentry)
218 {
219 int error;
220 if (old_dentry->d_inode == new_dentry->d_inode)
221 return 0;
222 error = may_delete(old_dir, old_dentry, 0);
223 if (error)
224 return error;
225 if (new_dir->i_dev != old_dir->i_dev)
226 return -EXDEV;
227 if (!new_dentry->d_inode)
228 error = may_create(new_dir, new_dentry);
229 else
230 error = may_delete(new_dir, new_dentry, 0);
231 if (error)
232 return error;
233 if (!old_dir->i_op || !old_dir->i_op->rename)
234 return -EPERM;
235 return 0;
236 }
237
238 /* Some of permission checks from vfs_rename(). */
239 static inline int pre_vfs_rename(struct inode *old_dir,
240 struct dentry *old_dentry,
241 struct inode *new_dir,
242 struct dentry *new_dentry)
243 {
244 int error;
245 lock_kernel(); /* From do_rename(). */
246 if (S_ISDIR(old_dentry->d_inode->i_mode))
247 error = pre_vfs_rename_dir(old_dir, old_dentry,
248 new_dir, new_dentry);
249 else
250 error = pre_vfs_rename_other(old_dir, old_dentry,
251 new_dir, new_dentry);
252 unlock_kernel(); /* From do_rename(). */
253 return error;
254 }
255
256 #else
257
258 /*
259 * Permission checks before security_inode_mknod() is called.
260 *
261 * This function is exported because
262 * vfs_mknod() is called from net/unix/af_unix.c.
263 */
264 int pre_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode)
265 {
266 int error = may_create(dir, dentry, NULL);
267 if (error)
268 return error;
269 if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD))
270 return -EPERM;
271 if (!dir->i_op || !dir->i_op->mknod)
272 return -EPERM;
273 return 0;
274 }
275 EXPORT_SYMBOL(pre_vfs_mknod);
276
277 /* Permission checks before security_inode_mkdir() is called. */
278 static inline int pre_vfs_mkdir(struct inode *dir, struct dentry *dentry)
279 {
280 int error = may_create(dir, dentry, NULL);
281 if (error)
282 return error;
283 if (!dir->i_op || !dir->i_op->mkdir)
284 return -EPERM;
285 return 0;
286 }
287
288 /* Some of permission checks before security_inode_rmdir() is called. */
289 static inline int pre_vfs_rmdir(struct inode *dir, struct dentry *dentry)
290 {
291 int error = may_delete(dir, dentry, 1);
292 if (error)
293 return error;
294 if (!dir->i_op || !dir->i_op->rmdir)
295 return -EPERM;
296 return 0;
297 }
298
299 /* Some of permission checks before security_inode_unlink() is called. */
300 static inline int pre_vfs_unlink(struct inode *dir, struct dentry *dentry)
301 {
302 int error = may_delete(dir, dentry, 0);
303 if (error)
304 return error;
305 if (!dir->i_op || !dir->i_op->unlink)
306 return -EPERM;
307 return 0;
308 }
309
310 /* Permission checks before security_inode_link() is called. */
311 static inline int pre_vfs_link(struct dentry *old_dentry, struct inode *dir,
312 struct dentry *new_dentry)
313 {
314 struct inode *inode = old_dentry->d_inode;
315 int error;
316 if (!inode)
317 return -ENOENT;
318 error = may_create(dir, new_dentry, NULL);
319 if (error)
320 return error;
321 if (dir->i_sb != inode->i_sb)
322 return -EXDEV;
323 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
324 return -EPERM;
325 if (!dir->i_op || !dir->i_op->link)
326 return -EPERM;
327 if (S_ISDIR(old_dentry->d_inode->i_mode))
328 return -EPERM;
329 return 0;
330 }
331
332 /* Permission checks before security_inode_symlink() is called. */
333 static inline int pre_vfs_symlink(struct inode *dir, struct dentry *dentry)
334 {
335 int error = may_create(dir, dentry, NULL);
336 if (error)
337 return error;
338 if (!dir->i_op || !dir->i_op->symlink)
339 return -EPERM;
340 return 0;
341 }
342
343 /* Permission checks before security_inode_rename() is called. */
344 static inline int pre_vfs_rename(struct inode *old_dir,
345 struct dentry *old_dentry,
346 struct inode *new_dir,
347 struct dentry *new_dentry)
348 {
349 int error;
350 const int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
351 if (old_dentry->d_inode == new_dentry->d_inode)
352 return 0;
353 error = may_delete(old_dir, old_dentry, is_dir);
354 if (error)
355 return error;
356 if (!new_dentry->d_inode)
357 error = may_create(new_dir, new_dentry, NULL);
358 else
359 error = may_delete(new_dir, new_dentry, is_dir);
360 if (error)
361 return error;
362 if (!old_dir->i_op || !old_dir->i_op->rename)
363 return -EPERM;
364 if (is_dir && new_dir != old_dir)
365 error = permission(old_dentry->d_inode, MAY_WRITE, NULL);
366 return error;
367 }
368
369 #endif
370
371 #endif

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