]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.39/patches.suse/fs-may_iops.diff
Add ignored *.diff files of the xen patches
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.suse / fs-may_iops.diff
1 From: Andreas Gruenbacher <agruen@suse.de>
2 Subject: VFS hooks for per-filesystem permission models
3
4 Add may_create and may_delete inode operations that filesystems can
5 implement in order to override the vfs provided default behavior.
6 This is required for implementing permission models which go beyond
7 the traditional UNIX semantics.
8
9 If a filesystem does not implement these hooks, the behavior is
10 unchanged.
11
12 Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
13
14 ---
15 fs/namei.c | 48 +++++++++++++++++++++++++++++++++++++-----------
16 include/linux/fs.h | 2 ++
17 2 files changed, 39 insertions(+), 11 deletions(-)
18
19 --- a/fs/namei.c
20 +++ b/fs/namei.c
21 @@ -1402,13 +1402,24 @@ static int may_delete(struct inode *dir,
22 BUG_ON(victim->d_parent->d_inode != dir);
23 audit_inode_child(victim->d_name.name, victim, dir);
24
25 - error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
26 + if (dir->i_op->may_delete) {
27 + if (IS_RDONLY(dir))
28 + return -EROFS;
29 + if (IS_IMMUTABLE(dir))
30 + return -EACCES;
31 + error = dir->i_op->may_delete(dir, victim->d_inode);
32 + if (!error)
33 + error = security_inode_permission(dir, MAY_WRITE | MAY_EXEC);
34 + } else {
35 + error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
36 + if (!error && check_sticky(dir, victim->d_inode))
37 + error = -EPERM;
38 + }
39 if (error)
40 return error;
41 if (IS_APPEND(dir))
42 return -EPERM;
43 - if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
44 - IS_IMMUTABLE(victim->d_inode))
45 + if (IS_APPEND(victim->d_inode) || IS_IMMUTABLE(victim->d_inode))
46 return -EPERM;
47 if (isdir) {
48 if (!S_ISDIR(victim->d_inode->i_mode))
49 @@ -1432,13 +1443,28 @@ static int may_delete(struct inode *dir,
50 * 3. We should have write and exec permissions on dir
51 * 4. We can't do it if dir is immutable (done in permission())
52 */
53 -static inline int may_create(struct inode *dir, struct dentry *child)
54 +static inline int may_create(struct inode *dir, struct dentry *child,
55 + int isdir)
56 {
57 + int error;
58 +
59 if (child->d_inode)
60 return -EEXIST;
61 if (IS_DEADDIR(dir))
62 return -ENOENT;
63 - return inode_permission(dir, MAY_WRITE | MAY_EXEC);
64 +
65 + if (dir->i_op->may_create) {
66 + if (IS_RDONLY(dir))
67 + return -EROFS;
68 + if (IS_IMMUTABLE(dir))
69 + return -EACCES;
70 + error = dir->i_op->may_create(dir, isdir);
71 + if (!error)
72 + error = security_inode_permission(dir, MAY_WRITE | MAY_EXEC);
73 + } else
74 + error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
75 +
76 + return error;
77 }
78
79 /*
80 @@ -1504,7 +1530,7 @@ void unlock_rename(struct dentry *p1, st
81 int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
82 struct nameidata *nd)
83 {
84 - int error = may_create(dir, dentry);
85 + int error = may_create(dir, dentry, 0);
86
87 if (error)
88 return error;
89 @@ -1948,7 +1974,7 @@ EXPORT_SYMBOL_GPL(lookup_create);
90
91 int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
92 {
93 - int error = may_create(dir, dentry);
94 + int error = may_create(dir, dentry, 0);
95
96 if (error)
97 return error;
98 @@ -2049,7 +2075,7 @@ SYSCALL_DEFINE3(mknod, const char __user
99
100 int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
101 {
102 - int error = may_create(dir, dentry);
103 + int error = may_create(dir, dentry, 1);
104
105 if (error)
106 return error;
107 @@ -2316,7 +2342,7 @@ SYSCALL_DEFINE1(unlink, const char __use
108
109 int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
110 {
111 - int error = may_create(dir, dentry);
112 + int error = may_create(dir, dentry, 0);
113
114 if (error)
115 return error;
116 @@ -2386,7 +2412,7 @@ int vfs_link(struct dentry *old_dentry,
117 if (!inode)
118 return -ENOENT;
119
120 - error = may_create(dir, new_dentry);
121 + error = may_create(dir, new_dentry, S_ISDIR(inode->i_mode));
122 if (error)
123 return error;
124
125 @@ -2594,7 +2620,7 @@ int vfs_rename(struct inode *old_dir, st
126 return error;
127
128 if (!new_dentry->d_inode)
129 - error = may_create(new_dir, new_dentry);
130 + error = may_create(new_dir, new_dentry, is_dir);
131 else
132 error = may_delete(new_dir, new_dentry, is_dir);
133 if (error)
134 --- a/include/linux/fs.h
135 +++ b/include/linux/fs.h
136 @@ -1293,6 +1293,8 @@ struct inode_operations {
137 void (*put_link) (struct dentry *, struct nameidata *, void *);
138 void (*truncate) (struct inode *);
139 int (*permission) (struct inode *, int);
140 + int (*may_create) (struct inode *, int);
141 + int (*may_delete) (struct inode *, struct inode *);
142 int (*setattr) (struct dentry *, struct iattr *);
143 int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
144 int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);