~ubuntu-branches/ubuntu/quantal/apparmor/quantal-updates

« back to all changes in this revision

Viewing changes to kernel-patches/for-mainline/file-handle-ops-2.diff

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2007-03-23 16:42:01 UTC
  • Revision ID: james.westby@ubuntu.com-20070323164201-jkax6f0oku087b7l
Tags: upstream-2.0.1+510.dfsg
ImportĀ upstreamĀ versionĀ 2.0.1+510.dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Index: b/security/apparmor/lsm.c
 
2
===================================================================
 
3
--- a/security/apparmor/lsm.c
 
4
+++ b/security/apparmor/lsm.c
 
5
@@ -251,7 +251,7 @@ out:
 
6
 }
 
7
 
 
8
 static int aa_permission(struct inode *inode, struct dentry *dentry,
 
9
-                        struct vfsmount *mnt, int mask, int leaf)
 
10
+                        struct vfsmount *mnt, int mask, int check)
 
11
 {
 
12
        int error = 0;
 
13
 
 
14
@@ -259,7 +259,7 @@ static int aa_permission(struct inode *i
 
15
                struct aa_profile *profile = aa_get_profile(current);
 
16
 
 
17
                if (profile)
 
18
-                       error = aa_perm(profile, dentry, mnt, mask, leaf);
 
19
+                       error = aa_perm(profile, dentry, mnt, mask, check);
 
20
                aa_put_profile(profile);
 
21
        }
 
22
        return error;
 
23
@@ -268,7 +268,7 @@ static int aa_permission(struct inode *i
 
24
 static int apparmor_inode_create(struct inode *dir, struct dentry *dentry,
 
25
                                 struct vfsmount *mnt, int mask)
 
26
 {
 
27
-       return aa_permission(dir, dentry, mnt, MAY_WRITE, 1);
 
28
+       return aa_permission(dir, dentry, mnt, MAY_WRITE, AA_CHECK_LEAF);
 
29
 }
 
30
 
 
31
 static int apparmor_inode_link(struct dentry *old_dentry,
 
32
@@ -298,19 +298,19 @@ static int apparmor_inode_unlink(struct 
 
33
                                 struct dentry *dentry,
 
34
                                 struct vfsmount *mnt)
 
35
 {
 
36
-       return aa_permission(dir, dentry, mnt, MAY_WRITE, 1);
 
37
+       return aa_permission(dir, dentry, mnt, MAY_WRITE, AA_CHECK_LEAF);
 
38
 }
 
39
 
 
40
 static int apparmor_inode_symlink(struct inode *dir, struct dentry *dentry,
 
41
                                  struct vfsmount *mnt, const char *old_name)
 
42
 {
 
43
-       return aa_permission(dir, dentry, mnt, MAY_WRITE, 1);
 
44
+       return aa_permission(dir, dentry, mnt, MAY_WRITE, AA_CHECK_LEAF);
 
45
 }
 
46
 
 
47
 static int apparmor_inode_mknod(struct inode *dir, struct dentry *dentry,
 
48
                                struct vfsmount *mnt, int mode, dev_t dev)
 
49
 {
 
50
-       return aa_permission(dir, dentry, mnt, MAY_WRITE, 1);
 
51
+       return aa_permission(dir, dentry, mnt, MAY_WRITE, AA_CHECK_LEAF);
 
52
 }
 
53
 
 
54
 static int apparmor_inode_rename(struct inode *old_dir,
 
55
@@ -331,11 +331,11 @@ static int apparmor_inode_rename(struct 
 
56
        if (profile) {
 
57
                if (old_mnt)
 
58
                        error = aa_perm(profile, old_dentry, old_mnt,
 
59
-                                       MAY_READ | MAY_WRITE, 1);
 
60
+                                       MAY_READ | MAY_WRITE, AA_CHECK_LEAF);
 
61
 
 
62
                if (!error && new_mnt)
 
63
                        error = aa_perm(profile, new_dentry, new_mnt,
 
64
-                                       MAY_WRITE, 1);
 
65
+                                       MAY_WRITE, AA_CHECK_LEAF);
 
66
        }
 
67
 
 
68
        aa_put_profile(profile);
 
69
@@ -395,16 +395,17 @@ out:
 
70
 
 
71
 static int aa_xattr_permission(struct dentry *dentry, struct vfsmount *mnt,
 
72
                               const char *name, const char *operation,
 
73
-                              int mask)
 
74
+                              int mask, struct file *file)
 
75
 {
 
76
        int error = 0;
 
77
 
 
78
        if (mnt && mediated_filesystem(dentry->d_inode)) {
 
79
                struct aa_profile *profile = aa_get_profile(current);
 
80
+               int check = file ? AA_CHECK_FD : 0;
 
81
 
 
82
                if (profile)
 
83
                        error = aa_perm_xattr(profile, dentry, mnt, name,
 
84
-                                             operation, mask);
 
85
+                                             operation, mask, check);
 
86
                aa_put_profile(profile);
 
87
        }
 
88
 
 
89
@@ -413,27 +414,32 @@ static int aa_xattr_permission(struct de
 
90
 
 
91
 static int apparmor_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
 
92
                                   char *name, void *value, size_t size,
 
93
-                                  int flags)
 
94
+                                  int flags, struct file *file)
 
95
 {
 
96
-       return aa_xattr_permission(dentry, mnt, name, "xattr set", MAY_WRITE);
 
97
+       return aa_xattr_permission(dentry, mnt, name, "xattr set", MAY_WRITE,
 
98
+                                  file);
 
99
 }
 
100
 
 
101
 static int apparmor_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
 
102
-                                  char *name)
 
103
+                                  char *name, struct file *file)
 
104
 {
 
105
-       return aa_xattr_permission(dentry, mnt, name, "xattr get", MAY_READ);
 
106
+       return aa_xattr_permission(dentry, mnt, name, "xattr get", MAY_READ,
 
107
+                                  file);
 
108
 }
 
109
 
 
110
-static int apparmor_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt)
 
111
+static int apparmor_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt,
 
112
+                                   struct file *file)
 
113
 {
 
114
-       return aa_xattr_permission(dentry, mnt, NULL, "xattr list", MAY_READ);
 
115
+       return aa_xattr_permission(dentry, mnt, NULL, "xattr list", MAY_READ,
 
116
+                                  file);
 
117
 }
 
118
 
 
119
 static int apparmor_inode_removexattr(struct dentry *dentry,
 
120
-                                     struct vfsmount *mnt, char *name)
 
121
+                                     struct vfsmount *mnt, char *name,
 
122
+                                     struct file *file)
 
123
 {
 
124
        return aa_xattr_permission(dentry, mnt, name, "xattr remove",
 
125
-                                  MAY_WRITE);
 
126
+                                  MAY_WRITE, file);
 
127
 }
 
128
 
 
129
 static int apparmor_file_permission(struct file *file, int mask)
 
130
@@ -459,7 +465,8 @@ static int apparmor_file_permission(stru
 
131
                 *        against.
 
132
                 */
 
133
                mask &= (MAY_READ | MAY_WRITE | MAY_EXEC);
 
134
-               error = aa_permission(dentry->d_inode, dentry, mnt, mask, 1);
 
135
+               error = aa_permission(dentry->d_inode, dentry, mnt, mask,
 
136
+                                     AA_CHECK_LEAF | AA_CHECK_FD);
 
137
        }
 
138
        aa_put_profile(profile);
 
139
 
 
140
@@ -520,7 +527,8 @@ static inline int aa_mmap(struct file *f
 
141
                mask |= AA_EXEC_MMAP;
 
142
 
 
143
        dentry = file->f_dentry;
 
144
-       return aa_permission(dentry->d_inode, dentry, file->f_vfsmnt, mask, 1);
 
145
+       return aa_permission(dentry->d_inode, dentry, file->f_vfsmnt, mask,
 
146
+                            AA_CHECK_LEAF | AA_CHECK_FD);
 
147
 }
 
148
 
 
149
 static int apparmor_file_mmap(struct file *file, unsigned long reqprot,
 
150
Index: b/security/apparmor/main.c
 
151
===================================================================
 
152
--- a/security/apparmor/main.c
 
153
+++ b/security/apparmor/main.c
 
154
@@ -137,13 +137,12 @@ static int aa_link_denied(struct aa_prof
 
155
 }
 
156
 
 
157
 static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt,
 
158
-                        char **buffer, int is_dir)
 
159
+                        char **buffer, int check)
 
160
 {
 
161
        char *name;
 
162
-       int size = 256;
 
163
+       int is_dir, size = 256;
 
164
 
 
165
-       /* Make sure is_dir is either 0 or 1. */
 
166
-       is_dir = !!is_dir;
 
167
+       is_dir = (check & AA_CHECK_DIR) ? 1 : 0;
 
168
 
 
169
        for (;;) {
 
170
                char *buf = kmalloc(size, GFP_KERNEL);
 
171
@@ -190,19 +189,19 @@ static inline void aa_put_name_buffer(ch
 
172
 
 
173
 static int aa_perm_dentry(struct aa_profile *profile, struct dentry *dentry,
 
174
                          struct vfsmount *mnt, struct aa_audit *sa, int mask,
 
175
-                         int is_dir, int accessed_through_fd)
 
176
+                         int check)
 
177
 {
 
178
        char *buffer = NULL;
 
179
        int denied_mask, error;
 
180
 
 
181
-       sa->name = aa_get_name(dentry, mnt, &buffer, is_dir);
 
182
+       sa->name = aa_get_name(dentry, mnt, &buffer, check);
 
183
 
 
184
        if (IS_ERR(sa->name)) {
 
185
                /*
 
186
                 * deleted files are given a pass on permission checks when
 
187
                 * accessed through a file descriptor.
 
188
                 */
 
189
-               if (PTR_ERR(sa->name) == -ENOENT && accessed_through_fd)
 
190
+               if (PTR_ERR(sa->name) == -ENOENT && (check & AA_CHECK_FD))
 
191
                        denied_mask = 0;
 
192
                else
 
193
                        denied_mask = PTR_ERR(sa->name);
 
194
@@ -532,7 +531,8 @@ out:
 
195
 int aa_attr(struct aa_profile *profile, struct dentry *dentry,
 
196
            struct vfsmount *mnt, struct iattr *iattr)
 
197
 {
 
198
-       int error;
 
199
+       struct inode *inode = dentry->d_inode;
 
200
+       int error, check;
 
201
        struct aa_audit sa;
 
202
 
 
203
        sa.type = AA_AUDITTYPE_ATTR;
 
204
@@ -540,9 +540,13 @@ int aa_attr(struct aa_profile *profile, 
 
205
        sa.flags = 0;
 
206
        sa.gfp_mask = GFP_KERNEL;
 
207
 
 
208
-       error = aa_perm_dentry(profile, dentry, mnt, &sa, MAY_WRITE,
 
209
-                              S_ISDIR(dentry->d_inode->i_mode),
 
210
-                              iattr->ia_valid & ATTR_FILE);
 
211
+       check = 0;
 
212
+       if (inode && S_ISDIR(inode->i_mode))
 
213
+               check |= AA_CHECK_DIR;
 
214
+       if (iattr->ia_valid & ATTR_FILE)
 
215
+               check |= AA_CHECK_FD;
 
216
+
 
217
+       error = aa_perm_dentry(profile, dentry, mnt, &sa, MAY_WRITE, check);
 
218
 
 
219
        return error;
 
220
 }
 
221
@@ -558,8 +562,9 @@ int aa_attr(struct aa_profile *profile, 
 
222
  */
 
223
 int aa_perm_xattr(struct aa_profile *profile, struct dentry *dentry,
 
224
                  struct vfsmount *mnt, const char *operation,
 
225
-                 const char *xattr_name, int mask)
 
226
+                 const char *xattr_name, int mask, int check)
 
227
 {
 
228
+       struct inode *inode = dentry->d_inode;
 
229
        int error;
 
230
        struct aa_audit sa;
 
231
 
 
232
@@ -569,9 +574,10 @@ int aa_perm_xattr(struct aa_profile *pro
 
233
        sa.flags = 0;
 
234
        sa.gfp_mask = GFP_KERNEL;
 
235
 
 
236
-       error = aa_perm_dentry(profile, dentry, mnt, &sa, mask,
 
237
-                              S_ISDIR(dentry->d_inode->i_mode),
 
238
-                              0 /* FIXME */);
 
239
+       if (inode && S_ISDIR(inode->i_mode))
 
240
+               check |= AA_CHECK_DIR;
 
241
+
 
242
+       error = aa_perm_dentry(profile, dentry, mnt, &sa, mask, check);
 
243
 
 
244
        return error;
 
245
 }
 
246
@@ -588,13 +594,16 @@ int aa_perm_xattr(struct aa_profile *pro
 
247
  * profile.  Result, %0 (success), -ve (error)
 
248
  */
 
249
 int aa_perm(struct aa_profile *profile, struct dentry *dentry,
 
250
-           struct vfsmount *mnt, int mask, int leaf)
 
251
+           struct vfsmount *mnt, int mask, int check)
 
252
 {
 
253
        struct inode *inode = dentry->d_inode;
 
254
        struct aa_audit sa;
 
255
        int error = 0;
 
256
 
 
257
-       if (!leaf && inode && S_ISDIR(inode->i_mode)) {
 
258
+       if (inode && S_ISDIR(inode->i_mode))
 
259
+               check |= AA_CHECK_DIR;
 
260
+
 
261
+       if ((check & (AA_CHECK_DIR | AA_CHECK_LEAF)) == AA_CHECK_DIR) {
 
262
                /*
 
263
                 * If checking a non-leaf directory, allow traverse and
 
264
                 * write access: we do not require profile access to
 
265
@@ -612,9 +621,7 @@ int aa_perm(struct aa_profile *profile, 
 
266
        sa.mask = mask;
 
267
        sa.flags = 0;
 
268
        sa.gfp_mask = GFP_KERNEL;
 
269
-       error = aa_perm_dentry(profile, dentry, mnt, &sa, mask,
 
270
-                              inode && S_ISDIR(inode->i_mode),
 
271
-                              0 /* FIXME */);
 
272
+       error = aa_perm_dentry(profile, dentry, mnt, &sa, mask, check);
 
273
 
 
274
 out:
 
275
        return error;
 
276
@@ -642,8 +649,7 @@ int aa_perm_dir(struct aa_profile *profi
 
277
        sa.flags = 0;
 
278
        sa.gfp_mask = GFP_KERNEL;
 
279
 
 
280
-       return aa_perm_dentry(profile, dentry, mnt, &sa, mask, 1,
 
281
-                             0 /* FIXME */);
 
282
+       return aa_perm_dentry(profile, dentry, mnt, &sa, mask, AA_CHECK_DIR);
 
283
 }
 
284
 
 
285
 /**
 
286
Index: b/security/apparmor/apparmor.h
 
287
===================================================================
 
288
--- a/security/apparmor/apparmor.h
 
289
+++ b/security/apparmor/apparmor.h
 
290
@@ -204,6 +204,11 @@ struct aa_audit {
 
291
                        "LOGPROF-HINT " hint " " fmt, ##args);\
 
292
        } while(0)
 
293
 
 
294
+/* Flags for the permission check functions */
 
295
+#define AA_CHECK_LEAF  1  /* this is the leaf lookup component */
 
296
+#define AA_CHECK_FD    2  /* coming from a file descriptor */
 
297
+#define AA_CHECK_DIR   4  /* file type is directory */
 
298
+
 
299
 /* main.c */
 
300
 extern int alloc_null_complain_profile(void);
 
301
 extern void free_null_complain_profile(void);
 
302
@@ -218,10 +223,10 @@ extern int aa_attr(struct aa_profile *pr
 
303
                   struct vfsmount *mnt, struct iattr *iattr);
 
304
 extern int aa_perm_xattr(struct aa_profile *profile, struct dentry *dentry,
 
305
                         struct vfsmount *mnt, const char *operation,
 
306
-                        const char *xattr_xattr, int mask);
 
307
+                        const char *xattr_xattr, int mask, int check);
 
308
 extern int aa_capability(struct aa_profile *profile, int cap);
 
309
 extern int aa_perm(struct aa_profile *profile, struct dentry *dentry,
 
310
-                  struct vfsmount *mnt, int mask, int leaf);
 
311
+                  struct vfsmount *mnt, int mask, int check);
 
312
 extern int aa_perm_dir(struct aa_profile *profile, struct dentry *dentry,
 
313
                       struct vfsmount *mnt, const char *operation, int mask);
 
314
 extern int aa_link(struct aa_profile *profile,
 
315
Index: b/fs/nfsd/vfs.c
 
316
===================================================================
 
317
--- a/fs/nfsd/vfs.c
 
318
+++ b/fs/nfsd/vfs.c
 
319
@@ -383,7 +383,7 @@ static ssize_t nfsd_getxattr(struct dent
 
320
 {
 
321
        ssize_t buflen;
 
322
 
 
323
-       buflen = vfs_getxattr(dentry, mnt, key, NULL, 0);
 
324
+       buflen = vfs_getxattr(dentry, mnt, key, NULL, 0, NULL);
 
325
        if (buflen <= 0)
 
326
                return buflen;
 
327
 
 
328
@@ -391,7 +391,7 @@ static ssize_t nfsd_getxattr(struct dent
 
329
        if (!*buf)
 
330
                return -ENOMEM;
 
331
 
 
332
-       return vfs_getxattr(dentry, mnt, key, *buf, buflen);
 
333
+       return vfs_getxattr(dentry, mnt, key, *buf, buflen, NULL);
 
334
 }
 
335
 #endif
 
336
 
 
337
@@ -417,7 +417,7 @@ set_nfsv4_acl_one(struct dentry *dentry,
 
338
                goto out;
 
339
        }
 
340
 
 
341
-       error = vfs_setxattr(dentry, mnt, key, buf, len, 0);
 
342
+       error = vfs_setxattr(dentry, mnt, key, buf, len, 0, NULL);
 
343
 out:
 
344
        kfree(buf);
 
345
        return error;
 
346
@@ -1984,13 +1984,14 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i
 
347
 
 
348
        if (size)
 
349
                error = vfs_setxattr(fhp->fh_dentry, fhp->fh_export->ex_mnt,
 
350
-                                    name, value, size,0);
 
351
+                                    name, value, size, 0, NULL);
 
352
        else {
 
353
                if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
 
354
                        error = 0;
 
355
                else {
 
356
                        error = vfs_removexattr(fhp->fh_dentry,
 
357
-                                               fhp->fh_export->ex_mnt, name);
 
358
+                                               fhp->fh_export->ex_mnt, name,
 
359
+                                               NULL);
 
360
                        if (error == -ENODATA)
 
361
                                error = 0;
 
362
                }