Skip to content

Commit 3089783

Browse files
sinkapAlexei Starovoitov
authored andcommitted
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: KP Singh <kpsingh@google.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Martin KaFai Lau <kafai@fb.com> Link: https://lore.kernel.org/bpf/20200825182919.1118197-7-kpsingh@chromium.org
1 parent 8ea6368 commit 3089783

File tree

5 files changed

+57
-5
lines changed

5 files changed

+57
-5
lines changed

include/net/bpf_sk_storage.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ void bpf_sk_storage_free(struct sock *sk);
2020

2121
extern const struct bpf_func_proto bpf_sk_storage_get_proto;
2222
extern const struct bpf_func_proto bpf_sk_storage_delete_proto;
23+
extern const struct bpf_func_proto sk_storage_get_btf_proto;
24+
extern const struct bpf_func_proto sk_storage_delete_btf_proto;
2325

2426
struct bpf_local_storage_elem;
2527
struct bpf_sk_storage_diag;

include/uapi/linux/bpf.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2808,7 +2808,7 @@ union bpf_attr {
28082808
*
28092809
* **-ERANGE** if resulting value was out of range.
28102810
*
2811-
* void *bpf_sk_storage_get(struct bpf_map *map, struct bpf_sock *sk, void *value, u64 flags)
2811+
* void *bpf_sk_storage_get(struct bpf_map *map, void *sk, void *value, u64 flags)
28122812
* Description
28132813
* Get a bpf-local-storage from a *sk*.
28142814
*
@@ -2824,6 +2824,9 @@ union bpf_attr {
28242824
* "type". The bpf-local-storage "type" (i.e. the *map*) is
28252825
* searched against all bpf-local-storages residing at *sk*.
28262826
*
2827+
* *sk* is a kernel **struct sock** pointer for LSM program.
2828+
* *sk* is a **struct bpf_sock** pointer for other program types.
2829+
*
28272830
* An optional *flags* (**BPF_SK_STORAGE_GET_F_CREATE**) can be
28282831
* used such that a new bpf-local-storage will be
28292832
* created if one does not exist. *value* can be used
@@ -2836,7 +2839,7 @@ union bpf_attr {
28362839
* **NULL** if not found or there was an error in adding
28372840
* a new bpf-local-storage.
28382841
*
2839-
* long bpf_sk_storage_delete(struct bpf_map *map, struct bpf_sock *sk)
2842+
* long bpf_sk_storage_delete(struct bpf_map *map, void *sk)
28402843
* Description
28412844
* Delete a bpf-local-storage from a *sk*.
28422845
* Return

kernel/bpf/bpf_lsm.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include <linux/bpf_lsm.h>
1212
#include <linux/kallsyms.h>
1313
#include <linux/bpf_verifier.h>
14+
#include <net/bpf_sk_storage.h>
15+
#include <linux/bpf_local_storage.h>
1416

1517
/* For every LSM hook that allows attachment of BPF programs, declare a nop
1618
* function where a BPF program can be attached.
@@ -45,10 +47,27 @@ int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog,
4547
return 0;
4648
}
4749

50+
static const struct bpf_func_proto *
51+
bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
52+
{
53+
switch (func_id) {
54+
case BPF_FUNC_inode_storage_get:
55+
return &bpf_inode_storage_get_proto;
56+
case BPF_FUNC_inode_storage_delete:
57+
return &bpf_inode_storage_delete_proto;
58+
case BPF_FUNC_sk_storage_get:
59+
return &sk_storage_get_btf_proto;
60+
case BPF_FUNC_sk_storage_delete:
61+
return &sk_storage_delete_btf_proto;
62+
default:
63+
return tracing_prog_func_proto(func_id, prog);
64+
}
65+
}
66+
4867
const struct bpf_prog_ops lsm_prog_ops = {
4968
};
5069

5170
const struct bpf_verifier_ops lsm_verifier_ops = {
52-
.get_func_proto = tracing_prog_func_proto,
71+
.get_func_proto = bpf_lsm_func_proto,
5372
.is_valid_access = btf_ctx_access,
5473
};

net/core/bpf_sk_storage.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <net/sock.h>
1313
#include <uapi/linux/sock_diag.h>
1414
#include <uapi/linux/btf.h>
15+
#include <linux/btf_ids.h>
1516

1617
DEFINE_BPF_STORAGE_CACHE(sk_cache);
1718

@@ -377,6 +378,30 @@ const struct bpf_func_proto bpf_sk_storage_delete_proto = {
377378
.arg2_type = ARG_PTR_TO_SOCKET,
378379
};
379380

381+
BTF_ID_LIST(sk_storage_btf_ids)
382+
BTF_ID_UNUSED
383+
BTF_ID(struct, sock)
384+
385+
const struct bpf_func_proto sk_storage_get_btf_proto = {
386+
.func = bpf_sk_storage_get,
387+
.gpl_only = false,
388+
.ret_type = RET_PTR_TO_MAP_VALUE_OR_NULL,
389+
.arg1_type = ARG_CONST_MAP_PTR,
390+
.arg2_type = ARG_PTR_TO_BTF_ID,
391+
.arg3_type = ARG_PTR_TO_MAP_VALUE_OR_NULL,
392+
.arg4_type = ARG_ANYTHING,
393+
.btf_id = sk_storage_btf_ids,
394+
};
395+
396+
const struct bpf_func_proto sk_storage_delete_btf_proto = {
397+
.func = bpf_sk_storage_delete,
398+
.gpl_only = false,
399+
.ret_type = RET_INTEGER,
400+
.arg1_type = ARG_CONST_MAP_PTR,
401+
.arg2_type = ARG_PTR_TO_BTF_ID,
402+
.btf_id = sk_storage_btf_ids,
403+
};
404+
380405
struct bpf_sk_storage_diag {
381406
u32 nr_maps;
382407
struct bpf_map *maps[];

tools/include/uapi/linux/bpf.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2808,7 +2808,7 @@ union bpf_attr {
28082808
*
28092809
* **-ERANGE** if resulting value was out of range.
28102810
*
2811-
* void *bpf_sk_storage_get(struct bpf_map *map, struct bpf_sock *sk, void *value, u64 flags)
2811+
* void *bpf_sk_storage_get(struct bpf_map *map, void *sk, void *value, u64 flags)
28122812
* Description
28132813
* Get a bpf-local-storage from a *sk*.
28142814
*
@@ -2824,6 +2824,9 @@ union bpf_attr {
28242824
* "type". The bpf-local-storage "type" (i.e. the *map*) is
28252825
* searched against all bpf-local-storages residing at *sk*.
28262826
*
2827+
* *sk* is a kernel **struct sock** pointer for LSM program.
2828+
* *sk* is a **struct bpf_sock** pointer for other program types.
2829+
*
28272830
* An optional *flags* (**BPF_SK_STORAGE_GET_F_CREATE**) can be
28282831
* used such that a new bpf-local-storage will be
28292832
* created if one does not exist. *value* can be used
@@ -2836,7 +2839,7 @@ union bpf_attr {
28362839
* **NULL** if not found or there was an error in adding
28372840
* a new bpf-local-storage.
28382841
*
2839-
* long bpf_sk_storage_delete(struct bpf_map *map, struct bpf_sock *sk)
2842+
* long bpf_sk_storage_delete(struct bpf_map *map, void *sk)
28402843
* Description
28412844
* Delete a bpf-local-storage from a *sk*.
28422845
* Return

0 commit comments

Comments
 (0)