Commit 30897832 authored by KP Singh's avatar KP Singh Committed by Alexei Starovoitov

bpf: Allow local storage to be used from LSM programs

Adds support for both bpf_{sk, inode}_storage_{get, delete} to be used
in LSM programs. These helpers are not used for tracing programs
(currently) as their usage is tied to the life-cycle of the object and
should only be used where the owning object won't be freed (when the
owning object is passed as an argument to the LSM hook). Thus, they
are safer to use in LSM hooks than tracing. Usage of local storage in
tracing programs will probably follow a per function based whitelist
approach.

Since the UAPI helper signature for bpf_sk_storage expect a bpf_sock,
it, leads to a compilation warning for LSM programs, it's also updated
to accept a void * pointer instead.
Signed-off-by: default avatarKP Singh <kpsingh@google.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarMartin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20200825182919.1118197-7-kpsingh@chromium.org
parent 8ea63684
...@@ -20,6 +20,8 @@ void bpf_sk_storage_free(struct sock *sk); ...@@ -20,6 +20,8 @@ void bpf_sk_storage_free(struct sock *sk);
extern const struct bpf_func_proto bpf_sk_storage_get_proto; extern const struct bpf_func_proto bpf_sk_storage_get_proto;
extern const struct bpf_func_proto bpf_sk_storage_delete_proto; extern const struct bpf_func_proto bpf_sk_storage_delete_proto;
extern const struct bpf_func_proto sk_storage_get_btf_proto;
extern const struct bpf_func_proto sk_storage_delete_btf_proto;
struct bpf_local_storage_elem; struct bpf_local_storage_elem;
struct bpf_sk_storage_diag; struct bpf_sk_storage_diag;
......
...@@ -2808,7 +2808,7 @@ union bpf_attr { ...@@ -2808,7 +2808,7 @@ union bpf_attr {
* *
* **-ERANGE** if resulting value was out of range. * **-ERANGE** if resulting value was out of range.
* *
* void *bpf_sk_storage_get(struct bpf_map *map, struct bpf_sock *sk, void *value, u64 flags) * void *bpf_sk_storage_get(struct bpf_map *map, void *sk, void *value, u64 flags)
* Description * Description
* Get a bpf-local-storage from a *sk*. * Get a bpf-local-storage from a *sk*.
* *
...@@ -2824,6 +2824,9 @@ union bpf_attr { ...@@ -2824,6 +2824,9 @@ union bpf_attr {
* "type". The bpf-local-storage "type" (i.e. the *map*) is * "type". The bpf-local-storage "type" (i.e. the *map*) is
* searched against all bpf-local-storages residing at *sk*. * searched against all bpf-local-storages residing at *sk*.
* *
* *sk* is a kernel **struct sock** pointer for LSM program.
* *sk* is a **struct bpf_sock** pointer for other program types.
*
* An optional *flags* (**BPF_SK_STORAGE_GET_F_CREATE**) can be * An optional *flags* (**BPF_SK_STORAGE_GET_F_CREATE**) can be
* used such that a new bpf-local-storage will be * used such that a new bpf-local-storage will be
* created if one does not exist. *value* can be used * created if one does not exist. *value* can be used
...@@ -2836,7 +2839,7 @@ union bpf_attr { ...@@ -2836,7 +2839,7 @@ union bpf_attr {
* **NULL** if not found or there was an error in adding * **NULL** if not found or there was an error in adding
* a new bpf-local-storage. * a new bpf-local-storage.
* *
* long bpf_sk_storage_delete(struct bpf_map *map, struct bpf_sock *sk) * long bpf_sk_storage_delete(struct bpf_map *map, void *sk)
* Description * Description
* Delete a bpf-local-storage from a *sk*. * Delete a bpf-local-storage from a *sk*.
* Return * Return
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <linux/bpf_lsm.h> #include <linux/bpf_lsm.h>
#include <linux/kallsyms.h> #include <linux/kallsyms.h>
#include <linux/bpf_verifier.h> #include <linux/bpf_verifier.h>
#include <net/bpf_sk_storage.h>
#include <linux/bpf_local_storage.h>
/* For every LSM hook that allows attachment of BPF programs, declare a nop /* For every LSM hook that allows attachment of BPF programs, declare a nop
* function where a BPF program can be attached. * function where a BPF program can be attached.
...@@ -45,10 +47,27 @@ int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog, ...@@ -45,10 +47,27 @@ int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog,
return 0; return 0;
} }
static const struct bpf_func_proto *
bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
switch (func_id) {
case BPF_FUNC_inode_storage_get:
return &bpf_inode_storage_get_proto;
case BPF_FUNC_inode_storage_delete:
return &bpf_inode_storage_delete_proto;
case BPF_FUNC_sk_storage_get:
return &sk_storage_get_btf_proto;
case BPF_FUNC_sk_storage_delete:
return &sk_storage_delete_btf_proto;
default:
return tracing_prog_func_proto(func_id, prog);
}
}
const struct bpf_prog_ops lsm_prog_ops = { const struct bpf_prog_ops lsm_prog_ops = {
}; };
const struct bpf_verifier_ops lsm_verifier_ops = { const struct bpf_verifier_ops lsm_verifier_ops = {
.get_func_proto = tracing_prog_func_proto, .get_func_proto = bpf_lsm_func_proto,
.is_valid_access = btf_ctx_access, .is_valid_access = btf_ctx_access,
}; };
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <net/sock.h> #include <net/sock.h>
#include <uapi/linux/sock_diag.h> #include <uapi/linux/sock_diag.h>
#include <uapi/linux/btf.h> #include <uapi/linux/btf.h>
#include <linux/btf_ids.h>
DEFINE_BPF_STORAGE_CACHE(sk_cache); DEFINE_BPF_STORAGE_CACHE(sk_cache);
...@@ -377,6 +378,30 @@ const struct bpf_func_proto bpf_sk_storage_delete_proto = { ...@@ -377,6 +378,30 @@ const struct bpf_func_proto bpf_sk_storage_delete_proto = {
.arg2_type = ARG_PTR_TO_SOCKET, .arg2_type = ARG_PTR_TO_SOCKET,
}; };
BTF_ID_LIST(sk_storage_btf_ids)
BTF_ID_UNUSED
BTF_ID(struct, sock)
const struct bpf_func_proto sk_storage_get_btf_proto = {
.func = bpf_sk_storage_get,
.gpl_only = false,
.ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL,
.arg1_type = ARG_CONST_MAP_PTR,
.arg2_type = ARG_PTR_TO_BTF_ID,
.arg3_type = ARG_PTR_TO_MAP_VALUE_OR_NULL,
.arg4_type = ARG_ANYTHING,
.btf_id = sk_storage_btf_ids,
};
const struct bpf_func_proto sk_storage_delete_btf_proto = {
.func = bpf_sk_storage_delete,
.gpl_only = false,
.ret_type = RET_INTEGER,
.arg1_type = ARG_CONST_MAP_PTR,
.arg2_type = ARG_PTR_TO_BTF_ID,
.btf_id = sk_storage_btf_ids,
};
struct bpf_sk_storage_diag { struct bpf_sk_storage_diag {
u32 nr_maps; u32 nr_maps;
struct bpf_map *maps[]; struct bpf_map *maps[];
......
...@@ -2808,7 +2808,7 @@ union bpf_attr { ...@@ -2808,7 +2808,7 @@ union bpf_attr {
* *
* **-ERANGE** if resulting value was out of range. * **-ERANGE** if resulting value was out of range.
* *
* void *bpf_sk_storage_get(struct bpf_map *map, struct bpf_sock *sk, void *value, u64 flags) * void *bpf_sk_storage_get(struct bpf_map *map, void *sk, void *value, u64 flags)
* Description * Description
* Get a bpf-local-storage from a *sk*. * Get a bpf-local-storage from a *sk*.
* *
...@@ -2824,6 +2824,9 @@ union bpf_attr { ...@@ -2824,6 +2824,9 @@ union bpf_attr {
* "type". The bpf-local-storage "type" (i.e. the *map*) is * "type". The bpf-local-storage "type" (i.e. the *map*) is
* searched against all bpf-local-storages residing at *sk*. * searched against all bpf-local-storages residing at *sk*.
* *
* *sk* is a kernel **struct sock** pointer for LSM program.
* *sk* is a **struct bpf_sock** pointer for other program types.
*
* An optional *flags* (**BPF_SK_STORAGE_GET_F_CREATE**) can be * An optional *flags* (**BPF_SK_STORAGE_GET_F_CREATE**) can be
* used such that a new bpf-local-storage will be * used such that a new bpf-local-storage will be
* created if one does not exist. *value* can be used * created if one does not exist. *value* can be used
...@@ -2836,7 +2839,7 @@ union bpf_attr { ...@@ -2836,7 +2839,7 @@ union bpf_attr {
* **NULL** if not found or there was an error in adding * **NULL** if not found or there was an error in adding
* a new bpf-local-storage. * a new bpf-local-storage.
* *
* long bpf_sk_storage_delete(struct bpf_map *map, struct bpf_sock *sk) * long bpf_sk_storage_delete(struct bpf_map *map, void *sk)
* Description * Description
* Delete a bpf-local-storage from a *sk*. * Delete a bpf-local-storage from a *sk*.
* Return * Return
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment