aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-03-25 12:06:51 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-03-27 23:49:27 -0400
commit0c93b7d85d40b690f04786ea0f18798b73182e4f (patch)
treead64b11f241ea7142977cd7a750f4e87c6bf07bc
parent798434bda36e357af9ccaf68a7ba1129658c8332 (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.c37
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
122static bool bpf_dname_reserved(const struct dentry *dentry)
123{
124 return strchr(dentry->d_name.name, '.');
125}
126
127static int bpf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 122static 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
190static int bpf_link(struct dentry *old_dentry, struct inode *dir, 179static struct dentry *
191 struct dentry *new_dentry) 180bpf_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
199static 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
208static const struct inode_operations bpf_dir_iops = { 187static 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