diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-03-25 12:06:51 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-03-27 23:49:27 -0400 |
commit | 0c93b7d85d40b690f04786ea0f18798b73182e4f (patch) | |
tree | ad64b11f241ea7142977cd7a750f4e87c6bf07bc | |
parent | 798434bda36e357af9ccaf68a7ba1129658c8332 (diff) |
bpf: reject invalid names right in ->lookup()
... and other methods won't see them at all
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | kernel/bpf/inode.c | 37 |
1 files changed, 8 insertions, 29 deletions
diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index f2ece3c174a5..35d21c189bb0 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c | |||
@@ -119,18 +119,10 @@ static int bpf_inode_type(const struct inode *inode, enum bpf_type *type) | |||
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
121 | 121 | ||
122 | static bool bpf_dname_reserved(const struct dentry *dentry) | ||
123 | { | ||
124 | return strchr(dentry->d_name.name, '.'); | ||
125 | } | ||
126 | |||
127 | static int bpf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | 122 | static int bpf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
128 | { | 123 | { |
129 | struct inode *inode; | 124 | struct inode *inode; |
130 | 125 | ||
131 | if (bpf_dname_reserved(dentry)) | ||
132 | return -EPERM; | ||
133 | |||
134 | inode = bpf_get_inode(dir->i_sb, dir, mode | S_IFDIR); | 126 | inode = bpf_get_inode(dir->i_sb, dir, mode | S_IFDIR); |
135 | if (IS_ERR(inode)) | 127 | if (IS_ERR(inode)) |
136 | return PTR_ERR(inode); | 128 | return PTR_ERR(inode); |
@@ -152,9 +144,6 @@ static int bpf_mkobj_ops(struct inode *dir, struct dentry *dentry, | |||
152 | { | 144 | { |
153 | struct inode *inode; | 145 | struct inode *inode; |
154 | 146 | ||
155 | if (bpf_dname_reserved(dentry)) | ||
156 | return -EPERM; | ||
157 | |||
158 | inode = bpf_get_inode(dir->i_sb, dir, mode | S_IFREG); | 147 | inode = bpf_get_inode(dir->i_sb, dir, mode | S_IFREG); |
159 | if (IS_ERR(inode)) | 148 | if (IS_ERR(inode)) |
160 | return PTR_ERR(inode); | 149 | return PTR_ERR(inode); |
@@ -187,31 +176,21 @@ static int bpf_mkobj(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
187 | } | 176 | } |
188 | } | 177 | } |
189 | 178 | ||
190 | static int bpf_link(struct dentry *old_dentry, struct inode *dir, | 179 | static struct dentry * |
191 | struct dentry *new_dentry) | 180 | bpf_lookup(struct inode *dir, struct dentry *dentry, unsigned flags) |
192 | { | 181 | { |
193 | if (bpf_dname_reserved(new_dentry)) | 182 | if (strchr(dentry->d_name.name, '.')) |
194 | return -EPERM; | 183 | return ERR_PTR(-EPERM); |
195 | 184 | return simple_lookup(dir, dentry, flags); | |
196 | return simple_link(old_dentry, dir, new_dentry); | ||
197 | } | ||
198 | |||
199 | static int bpf_rename(struct inode *old_dir, struct dentry *old_dentry, | ||
200 | struct inode *new_dir, struct dentry *new_dentry) | ||
201 | { | ||
202 | if (bpf_dname_reserved(new_dentry)) | ||
203 | return -EPERM; | ||
204 | |||
205 | return simple_rename(old_dir, old_dentry, new_dir, new_dentry); | ||
206 | } | 185 | } |
207 | 186 | ||
208 | static const struct inode_operations bpf_dir_iops = { | 187 | static const struct inode_operations bpf_dir_iops = { |
209 | .lookup = simple_lookup, | 188 | .lookup = bpf_lookup, |
210 | .mknod = bpf_mkobj, | 189 | .mknod = bpf_mkobj, |
211 | .mkdir = bpf_mkdir, | 190 | .mkdir = bpf_mkdir, |
212 | .rmdir = simple_rmdir, | 191 | .rmdir = simple_rmdir, |
213 | .rename = bpf_rename, | 192 | .rename = simple_rename, |
214 | .link = bpf_link, | 193 | .link = simple_link, |
215 | .unlink = simple_unlink, | 194 | .unlink = simple_unlink, |
216 | }; | 195 | }; |
217 | 196 | ||