bpf_obj_do_pin(): switch to vfs_mkobj(), quit abusing ->mknod()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2017-12-01 17:22:19 -05:00
parent 8e6c848ece
commit a4a0683fd5
1 changed files with 22 additions and 28 deletions

View File

@ -150,39 +150,29 @@ static int bpf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
return 0; return 0;
} }
static int bpf_mkobj_ops(struct inode *dir, struct dentry *dentry, static int bpf_mkobj_ops(struct dentry *dentry, umode_t mode, void *raw,
umode_t mode, const struct inode_operations *iops) const struct inode_operations *iops)
{ {
struct inode *inode; struct inode *dir = dentry->d_parent->d_inode;
struct inode *inode = bpf_get_inode(dir->i_sb, dir, mode);
inode = bpf_get_inode(dir->i_sb, dir, mode | S_IFREG);
if (IS_ERR(inode)) if (IS_ERR(inode))
return PTR_ERR(inode); return PTR_ERR(inode);
inode->i_op = iops; inode->i_op = iops;
inode->i_private = dentry->d_fsdata; inode->i_private = raw;
bpf_dentry_finalize(dentry, inode, dir); bpf_dentry_finalize(dentry, inode, dir);
return 0; return 0;
} }
static int bpf_mkobj(struct inode *dir, struct dentry *dentry, umode_t mode, static int bpf_mkprog(struct dentry *dentry, umode_t mode, void *arg)
dev_t devt)
{ {
enum bpf_type type = MINOR(devt); return bpf_mkobj_ops(dentry, mode, arg, &bpf_prog_iops);
}
if (MAJOR(devt) != UNNAMED_MAJOR || !S_ISREG(mode) || static int bpf_mkmap(struct dentry *dentry, umode_t mode, void *arg)
dentry->d_fsdata == NULL) {
return -EPERM; return bpf_mkobj_ops(dentry, mode, arg, &bpf_map_iops);
switch (type) {
case BPF_TYPE_PROG:
return bpf_mkobj_ops(dir, dentry, mode, &bpf_prog_iops);
case BPF_TYPE_MAP:
return bpf_mkobj_ops(dir, dentry, mode, &bpf_map_iops);
default:
return -EPERM;
}
} }
static struct dentry * static struct dentry *
@ -218,7 +208,6 @@ static int bpf_symlink(struct inode *dir, struct dentry *dentry,
static const struct inode_operations bpf_dir_iops = { static const struct inode_operations bpf_dir_iops = {
.lookup = bpf_lookup, .lookup = bpf_lookup,
.mknod = bpf_mkobj,
.mkdir = bpf_mkdir, .mkdir = bpf_mkdir,
.symlink = bpf_symlink, .symlink = bpf_symlink,
.rmdir = simple_rmdir, .rmdir = simple_rmdir,
@ -234,7 +223,6 @@ static int bpf_obj_do_pin(const struct filename *pathname, void *raw,
struct inode *dir; struct inode *dir;
struct path path; struct path path;
umode_t mode; umode_t mode;
dev_t devt;
int ret; int ret;
dentry = kern_path_create(AT_FDCWD, pathname->name, &path, 0); dentry = kern_path_create(AT_FDCWD, pathname->name, &path, 0);
@ -242,9 +230,8 @@ static int bpf_obj_do_pin(const struct filename *pathname, void *raw,
return PTR_ERR(dentry); return PTR_ERR(dentry);
mode = S_IFREG | ((S_IRUSR | S_IWUSR) & ~current_umask()); mode = S_IFREG | ((S_IRUSR | S_IWUSR) & ~current_umask());
devt = MKDEV(UNNAMED_MAJOR, type);
ret = security_path_mknod(&path, dentry, mode, devt); ret = security_path_mknod(&path, dentry, mode, 0);
if (ret) if (ret)
goto out; goto out;
@ -254,9 +241,16 @@ static int bpf_obj_do_pin(const struct filename *pathname, void *raw,
goto out; goto out;
} }
dentry->d_fsdata = raw; switch (type) {
ret = vfs_mknod(dir, dentry, mode, devt); case BPF_TYPE_PROG:
dentry->d_fsdata = NULL; ret = vfs_mkobj(dentry, mode, bpf_mkprog, raw);
break;
case BPF_TYPE_MAP:
ret = vfs_mkobj(dentry, mode, bpf_mkmap, raw);
break;
default:
ret = -EPERM;
}
out: out:
done_path_create(&path, dentry); done_path_create(&path, dentry);
return ret; return ret;