summaryrefslogtreecommitdiffstats
path: root/kernel/bpf/inode.c
diff options
context:
space:
mode:
authorChenbo Feng <fengc@google.com>2017-10-18 13:00:22 -0700
committerDavid S. Miller <davem@davemloft.net>2017-10-20 13:32:59 +0100
commit6e71b04a82248ccf13a94b85cbc674a9fefe53f5 (patch)
tree45cab2ff677b04d921a2813738dc1ada8c07eaec /kernel/bpf/inode.c
parentaec72f3392b1d598a979e89c4fdb131965ae0ab3 (diff)
downloadlinux-0-day-6e71b04a82248ccf13a94b85cbc674a9fefe53f5.tar.gz
linux-0-day-6e71b04a82248ccf13a94b85cbc674a9fefe53f5.tar.xz
bpf: Add file mode configuration into bpf maps
Introduce the map read/write flags to the eBPF syscalls that returns the map fd. The flags is used to set up the file mode when construct a new file descriptor for bpf maps. To not break the backward capability, the f_flags is set to O_RDWR if the flag passed by syscall is 0. Otherwise it should be O_RDONLY or O_WRONLY. When the userspace want to modify or read the map content, it will check the file mode to see if it is allowed to make the change. Signed-off-by: Chenbo Feng <fengc@google.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/bpf/inode.c')
-rw-r--r--kernel/bpf/inode.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
index be1dde967208e..01aaef1a77c5a 100644
--- a/kernel/bpf/inode.c
+++ b/kernel/bpf/inode.c
@@ -295,7 +295,7 @@ out:
}
static void *bpf_obj_do_get(const struct filename *pathname,
- enum bpf_type *type)
+ enum bpf_type *type, int flags)
{
struct inode *inode;
struct path path;
@@ -307,7 +307,7 @@ static void *bpf_obj_do_get(const struct filename *pathname,
return ERR_PTR(ret);
inode = d_backing_inode(path.dentry);
- ret = inode_permission(inode, MAY_WRITE);
+ ret = inode_permission(inode, ACC_MODE(flags));
if (ret)
goto out;
@@ -326,18 +326,23 @@ out:
return ERR_PTR(ret);
}
-int bpf_obj_get_user(const char __user *pathname)
+int bpf_obj_get_user(const char __user *pathname, int flags)
{
enum bpf_type type = BPF_TYPE_UNSPEC;
struct filename *pname;
int ret = -ENOENT;
+ int f_flags;
void *raw;
+ f_flags = bpf_get_file_flag(flags);
+ if (f_flags < 0)
+ return f_flags;
+
pname = getname(pathname);
if (IS_ERR(pname))
return PTR_ERR(pname);
- raw = bpf_obj_do_get(pname, &type);
+ raw = bpf_obj_do_get(pname, &type, f_flags);
if (IS_ERR(raw)) {
ret = PTR_ERR(raw);
goto out;
@@ -346,7 +351,7 @@ int bpf_obj_get_user(const char __user *pathname)
if (type == BPF_TYPE_PROG)
ret = bpf_prog_new_fd(raw);
else if (type == BPF_TYPE_MAP)
- ret = bpf_map_new_fd(raw);
+ ret = bpf_map_new_fd(raw, f_flags);
else
goto out;