bpf: don't bother with getname/kern_path - use user_path_at
kernel/bpf/inode.c misuses kern_path...() - it's much simpler (and more efficient, on top of that) to use user_path...() counterparts rather than bothering with doing getname() manually. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20200120232858.GF8904@ZenIV.linux.org.uk
This commit is contained in:
parent
d49d0661b9
commit
b87121dd3f
|
@ -380,7 +380,7 @@ static const struct inode_operations bpf_dir_iops = {
|
||||||
.unlink = simple_unlink,
|
.unlink = simple_unlink,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int bpf_obj_do_pin(const struct filename *pathname, void *raw,
|
static int bpf_obj_do_pin(const char __user *pathname, void *raw,
|
||||||
enum bpf_type type)
|
enum bpf_type type)
|
||||||
{
|
{
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
|
@ -389,7 +389,7 @@ static int bpf_obj_do_pin(const struct filename *pathname, void *raw,
|
||||||
umode_t mode;
|
umode_t mode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
dentry = kern_path_create(AT_FDCWD, pathname->name, &path, 0);
|
dentry = user_path_create(AT_FDCWD, pathname, &path, 0);
|
||||||
if (IS_ERR(dentry))
|
if (IS_ERR(dentry))
|
||||||
return PTR_ERR(dentry);
|
return PTR_ERR(dentry);
|
||||||
|
|
||||||
|
@ -422,30 +422,22 @@ out:
|
||||||
|
|
||||||
int bpf_obj_pin_user(u32 ufd, const char __user *pathname)
|
int bpf_obj_pin_user(u32 ufd, const char __user *pathname)
|
||||||
{
|
{
|
||||||
struct filename *pname;
|
|
||||||
enum bpf_type type;
|
enum bpf_type type;
|
||||||
void *raw;
|
void *raw;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
pname = getname(pathname);
|
|
||||||
if (IS_ERR(pname))
|
|
||||||
return PTR_ERR(pname);
|
|
||||||
|
|
||||||
raw = bpf_fd_probe_obj(ufd, &type);
|
raw = bpf_fd_probe_obj(ufd, &type);
|
||||||
if (IS_ERR(raw)) {
|
if (IS_ERR(raw))
|
||||||
ret = PTR_ERR(raw);
|
return PTR_ERR(raw);
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bpf_obj_do_pin(pname, raw, type);
|
ret = bpf_obj_do_pin(pathname, raw, type);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
bpf_any_put(raw, type);
|
bpf_any_put(raw, type);
|
||||||
out:
|
|
||||||
putname(pname);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *bpf_obj_do_get(const struct filename *pathname,
|
static void *bpf_obj_do_get(const char __user *pathname,
|
||||||
enum bpf_type *type, int flags)
|
enum bpf_type *type, int flags)
|
||||||
{
|
{
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
@ -453,7 +445,7 @@ static void *bpf_obj_do_get(const struct filename *pathname,
|
||||||
void *raw;
|
void *raw;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = kern_path(pathname->name, LOOKUP_FOLLOW, &path);
|
ret = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW, &path);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
|
@ -480,36 +472,27 @@ out:
|
||||||
int bpf_obj_get_user(const char __user *pathname, int flags)
|
int bpf_obj_get_user(const char __user *pathname, int flags)
|
||||||
{
|
{
|
||||||
enum bpf_type type = BPF_TYPE_UNSPEC;
|
enum bpf_type type = BPF_TYPE_UNSPEC;
|
||||||
struct filename *pname;
|
|
||||||
int ret = -ENOENT;
|
|
||||||
int f_flags;
|
int f_flags;
|
||||||
void *raw;
|
void *raw;
|
||||||
|
int ret;
|
||||||
|
|
||||||
f_flags = bpf_get_file_flag(flags);
|
f_flags = bpf_get_file_flag(flags);
|
||||||
if (f_flags < 0)
|
if (f_flags < 0)
|
||||||
return f_flags;
|
return f_flags;
|
||||||
|
|
||||||
pname = getname(pathname);
|
raw = bpf_obj_do_get(pathname, &type, f_flags);
|
||||||
if (IS_ERR(pname))
|
if (IS_ERR(raw))
|
||||||
return PTR_ERR(pname);
|
return PTR_ERR(raw);
|
||||||
|
|
||||||
raw = bpf_obj_do_get(pname, &type, f_flags);
|
|
||||||
if (IS_ERR(raw)) {
|
|
||||||
ret = PTR_ERR(raw);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == BPF_TYPE_PROG)
|
if (type == BPF_TYPE_PROG)
|
||||||
ret = bpf_prog_new_fd(raw);
|
ret = bpf_prog_new_fd(raw);
|
||||||
else if (type == BPF_TYPE_MAP)
|
else if (type == BPF_TYPE_MAP)
|
||||||
ret = bpf_map_new_fd(raw, f_flags);
|
ret = bpf_map_new_fd(raw, f_flags);
|
||||||
else
|
else
|
||||||
goto out;
|
return -ENOENT;
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
bpf_any_put(raw, type);
|
bpf_any_put(raw, type);
|
||||||
out:
|
|
||||||
putname(pname);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue