1
Index: b/include/linux/fs.h
2
===================================================================
3
--- a/include/linux/fs.h
4
+++ b/include/linux/fs.h
5
@@ -349,6 +349,9 @@ struct iattr {
6
* Not an attribute, but an auxilary info for filesystems wanting to
7
* implement an ftruncate() like method. NOTE: filesystem should
8
* check for (ia_valid & ATTR_FILE), and not for (ia_file != NULL).
10
+ * The LSM hooks also use this to distinguish operations on a file
11
+ * descriptors from operations on pathnames.
16
===================================================================
19
@@ -520,6 +520,8 @@ asmlinkage long sys_fchmod(unsigned int
21
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
22
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
23
+ newattrs.ia_valid |= ATTR_FILE;
24
+ newattrs.ia_file = file;
25
err = notify_change(dentry, file->f_path.mnt, &newattrs);
26
mutex_unlock(&inode->i_mutex);
28
@@ -570,7 +572,7 @@ asmlinkage long sys_chmod(const char __u
31
static int chown_common(struct dentry * dentry, struct vfsmount *mnt,
32
- uid_t user, gid_t group)
33
+ uid_t user, gid_t group, struct file *file)
37
@@ -598,6 +600,10 @@ static int chown_common(struct dentry *
39
if (!S_ISDIR(inode->i_mode))
40
newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
42
+ newattrs.ia_file = file;
43
+ newattrs.ia_valid |= ATTR_FILE;
45
mutex_lock(&inode->i_mutex);
46
error = notify_change(dentry, mnt, &newattrs);
47
mutex_unlock(&inode->i_mutex);
48
@@ -613,7 +619,7 @@ asmlinkage long sys_chown(const char __u
49
error = user_path_walk(filename, &nd);
52
- error = chown_common(nd.dentry, nd.mnt, user, group);
53
+ error = chown_common(nd.dentry, nd.mnt, user, group, NULL);
57
@@ -633,7 +639,7 @@ asmlinkage long sys_fchownat(int dfd, co
58
error = __user_walk_fd(dfd, filename, follow, &nd);
61
- error = chown_common(nd.dentry, nd.mnt, user, group);
62
+ error = chown_common(nd.dentry, nd.mnt, user, group, NULL);
66
@@ -647,7 +653,7 @@ asmlinkage long sys_lchown(const char __
67
error = user_path_walk_link(filename, &nd);
70
- error = chown_common(nd.dentry, nd.mnt, user, group);
71
+ error = chown_common(nd.dentry, nd.mnt, user, group, NULL);
75
@@ -666,7 +672,7 @@ asmlinkage long sys_fchown(unsigned int
77
dentry = file->f_path.dentry;
78
audit_inode(NULL, dentry->d_inode);
79
- error = chown_common(dentry, file->f_path.mnt, user, group);
80
+ error = chown_common(dentry, file->f_path.mnt, user, group, file);
84
Index: b/security/apparmor/lsm.c
85
===================================================================
86
--- a/security/apparmor/lsm.c
87
+++ b/security/apparmor/lsm.c
88
@@ -82,7 +82,7 @@ static int apparmor_ptrace(struct task_s
89
* under the rules that the kernel normally permits if the two
90
* processes are running under the same profile, but then we
91
* would probably have to reject profile changes for processes
92
- * that are being ptraces as well as for processes ptracing
93
+ * that are being ptraced as well as for processes ptracing
97
Index: b/security/apparmor/main.c
98
===================================================================
99
--- a/security/apparmor/main.c
100
+++ b/security/apparmor/main.c
101
@@ -190,7 +190,7 @@ static inline void aa_put_name_buffer(ch
103
static int aa_perm_dentry(struct aa_profile *profile, struct dentry *dentry,
104
struct vfsmount *mnt, struct aa_audit *sa, int mask,
106
+ int is_dir, int accessed_through_fd)
109
int denied_mask, error;
110
@@ -198,8 +198,11 @@ static int aa_perm_dentry(struct aa_prof
111
sa->name = aa_get_name(dentry, mnt, &buffer, is_dir);
113
if (IS_ERR(sa->name)) {
114
- /* deleted files are given a pass on permission checks */
115
- if (PTR_ERR(sa->name) == -ENOENT)
117
+ * deleted files are given a pass on permission checks when
118
+ * accessed through a file descriptor.
120
+ if (PTR_ERR(sa->name) == -ENOENT && accessed_through_fd)
123
denied_mask = PTR_ERR(sa->name);
124
@@ -538,7 +541,8 @@ int aa_attr(struct aa_profile *profile,
125
sa.gfp_mask = GFP_KERNEL;
127
error = aa_perm_dentry(profile, dentry, mnt, &sa, MAY_WRITE,
128
- S_ISDIR(dentry->d_inode->i_mode));
129
+ S_ISDIR(dentry->d_inode->i_mode),
130
+ iattr->ia_valid & ATTR_FILE);
134
@@ -566,7 +570,8 @@ int aa_perm_xattr(struct aa_profile *pro
135
sa.gfp_mask = GFP_KERNEL;
137
error = aa_perm_dentry(profile, dentry, mnt, &sa, mask,
138
- S_ISDIR(dentry->d_inode->i_mode));
139
+ S_ISDIR(dentry->d_inode->i_mode),
144
@@ -608,7 +613,8 @@ int aa_perm(struct aa_profile *profile,
146
sa.gfp_mask = GFP_KERNEL;
147
error = aa_perm_dentry(profile, dentry, mnt, &sa, mask,
148
- inode && S_ISDIR(inode->i_mode));
149
+ inode && S_ISDIR(inode->i_mode),
154
@@ -636,7 +642,8 @@ int aa_perm_dir(struct aa_profile *profi
156
sa.gfp_mask = GFP_KERNEL;
158
- return aa_perm_dentry(profile, dentry, mnt, &sa, mask, 1);
159
+ return aa_perm_dentry(profile, dentry, mnt, &sa, mask, 1,