Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…/git/bpf/bpf-next

Daniel Borkmann says:

====================
pull-request: bpf-next 2023-06-23

We've added 49 non-merge commits during the last 24 day(s) which contain
a total of 70 files changed, 1935 insertions(+), 442 deletions(-).

The main changes are:

1) Extend bpf_fib_lookup helper to allow passing the route table ID,
   from Louis DeLosSantos.

2) Fix regsafe() in verifier to call check_ids() for scalar registers,
   from Eduard Zingerman.

3) Extend the set of cpumask kfuncs with bpf_cpumask_first_and()
   and a rework of bpf_cpumask_any*() kfuncs. Additionally,
   add selftests, from David Vernet.

4) Fix socket lookup BPF helpers for tc/XDP to respect VRF bindings,
   from Gilad Sever.

5) Change bpf_link_put() to use workqueue unconditionally to fix it
   under PREEMPT_RT, from Sebastian Andrzej Siewior.

6) Follow-ups to address issues in the bpf_refcount shared ownership
   implementation, from Dave Marchevsky.

7) A few general refactorings to BPF map and program creation permissions
   checks which were part of the BPF token series, from Andrii Nakryiko.

8) Various fixes for benchmark framework and add a new benchmark
   for BPF memory allocator to BPF selftests, from Hou Tao.

9) Documentation improvements around iterators and trusted pointers,
   from Anton Protopopov.

10) Small cleanup in verifier to improve allocated object check,
    from Daniel T. Lee.

11) Improve performance of bpf_xdp_pointer() by avoiding access
    to shared_info when XDP packet does not have frags,
    from Jesper Dangaard Brouer.

12) Silence a harmless syzbot-reported warning in btf_type_id_size(),
    from Yonghong Song.

13) Remove duplicate bpfilter_umh_cleanup in favor of umd_cleanup_helper,
    from Jarkko Sakkinen.

14) Fix BPF selftests build for resolve_btfids under custom HOSTCFLAGS,
    from Viktor Malik.

* tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next: (49 commits)
  bpf, docs: Document existing macros instead of deprecated
  bpf, docs: BPF Iterator Document
  selftests/bpf: Fix compilation failure for prog vrf_socket_lookup
  selftests/bpf: Add vrf_socket_lookup tests
  bpf: Fix bpf socket lookup from tc/xdp to respect socket VRF bindings
  bpf: Call __bpf_sk_lookup()/__bpf_skc_lookup() directly via TC hookpoint
  bpf: Factor out socket lookup functions for the TC hookpoint.
  selftests/bpf: Set the default value of consumer_cnt as 0
  selftests/bpf: Ensure that next_cpu() returns a valid CPU number
  selftests/bpf: Output the correct error code for pthread APIs
  selftests/bpf: Use producer_cnt to allocate local counter array
  xsk: Remove unused inline function xsk_buff_discard()
  bpf: Keep BPF_PROG_LOAD permission checks clear of validations
  bpf: Centralize permissions checks for all BPF map types
  bpf: Inline map creation logic in map_create() function
  bpf: Move unprivileged checks into map_create() and bpf_prog_load()
  bpf: Remove in_atomic() from bpf_link_put().
  selftests/bpf: Verify that check_ids() is used for scalars in regsafe()
  bpf: Verify scalar ids mapping in regsafe() using check_ids()
  selftests/bpf: Check if mark_chain_precision() follows scalar ids
  ...
====================

Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
kuba-moo committed Jun 24, 2023
2 parents d1d29a4 + fbc5669 commit a685d0d
Show file tree
Hide file tree
Showing 70 changed files with 1,935 additions and 442 deletions.
7 changes: 2 additions & 5 deletions Documentation/bpf/bpf_iterators.rst
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,8 @@ The following is the breakdown for each field in struct ``bpf_iter_reg``.
that the kernel function cond_resched() is called to avoid other kernel
subsystem (e.g., rcu) misbehaving.
* - seq_info
- Specifies certain action requests in the kernel BPF iterator
infrastructure. Currently, only BPF_ITER_RESCHED is supported. This means
that the kernel function cond_resched() is called to avoid other kernel
subsystem (e.g., rcu) misbehaving.

- Specifies the set of seq operations for the BPF iterator and helpers to
initialize/free the private data for the corresponding ``seq_file``.

`Click here
<https://lore.kernel.org/bpf/[email protected]/>`_
Expand Down
5 changes: 3 additions & 2 deletions Documentation/bpf/cpumasks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -351,14 +351,15 @@ In addition to the above kfuncs, there is also a set of read-only kfuncs that
can be used to query the contents of cpumasks.

.. kernel-doc:: kernel/bpf/cpumask.c
:identifiers: bpf_cpumask_first bpf_cpumask_first_zero bpf_cpumask_test_cpu
:identifiers: bpf_cpumask_first bpf_cpumask_first_zero bpf_cpumask_first_and
bpf_cpumask_test_cpu

.. kernel-doc:: kernel/bpf/cpumask.c
:identifiers: bpf_cpumask_equal bpf_cpumask_intersects bpf_cpumask_subset
bpf_cpumask_empty bpf_cpumask_full

.. kernel-doc:: kernel/bpf/cpumask.c
:identifiers: bpf_cpumask_any bpf_cpumask_any_and
:identifiers: bpf_cpumask_any_distribute bpf_cpumask_any_and_distribute

----

Expand Down
38 changes: 32 additions & 6 deletions Documentation/bpf/kfuncs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -227,23 +227,49 @@ absolutely no ABI stability guarantees.

As mentioned above, a nested pointer obtained from walking a trusted pointer is
no longer trusted, with one exception. If a struct type has a field that is
guaranteed to be valid as long as its parent pointer is trusted, the
``BTF_TYPE_SAFE_NESTED`` macro can be used to express that to the verifier as
follows:
guaranteed to be valid (trusted or rcu, as in KF_RCU description below) as long
as its parent pointer is valid, the following macros can be used to express
that to the verifier:

* ``BTF_TYPE_SAFE_TRUSTED``
* ``BTF_TYPE_SAFE_RCU``
* ``BTF_TYPE_SAFE_RCU_OR_NULL``

For example,

.. code-block:: c
BTF_TYPE_SAFE_TRUSTED(struct socket) {
struct sock *sk;
};
or

.. code-block:: c
BTF_TYPE_SAFE_NESTED(struct task_struct) {
BTF_TYPE_SAFE_RCU(struct task_struct) {
const cpumask_t *cpus_ptr;
struct css_set __rcu *cgroups;
struct task_struct __rcu *real_parent;
struct task_struct *group_leader;
};
In other words, you must:

1. Wrap the trusted pointer type in the ``BTF_TYPE_SAFE_NESTED`` macro.
1. Wrap the valid pointer type in a ``BTF_TYPE_SAFE_*`` macro.

2. Specify the type and name of the trusted nested field. This field must match
2. Specify the type and name of the valid nested field. This field must match
the field in the original type definition exactly.

A new type declared by a ``BTF_TYPE_SAFE_*`` macro also needs to be emitted so
that it appears in BTF. For example, ``BTF_TYPE_SAFE_TRUSTED(struct socket)``
is emitted in the ``type_is_trusted()`` function as follows:

.. code-block:: c
BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED(struct socket));
2.4.5 KF_SLEEPABLE flag
-----------------------

Expand Down
25 changes: 19 additions & 6 deletions include/linux/bpf_verifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,11 +313,6 @@ struct bpf_idx_pair {
u32 idx;
};

struct bpf_id_pair {
u32 old;
u32 cur;
};

#define MAX_CALL_FRAMES 8
/* Maximum number of register states that can exist at once */
#define BPF_ID_MAP_SIZE ((MAX_BPF_REG + MAX_BPF_STACK / BPF_REG_SIZE) * MAX_CALL_FRAMES)
Expand Down Expand Up @@ -557,6 +552,21 @@ struct backtrack_state {
u64 stack_masks[MAX_CALL_FRAMES];
};

struct bpf_id_pair {
u32 old;
u32 cur;
};

struct bpf_idmap {
u32 tmp_id_gen;
struct bpf_id_pair map[BPF_ID_MAP_SIZE];
};

struct bpf_idset {
u32 count;
u32 ids[BPF_ID_MAP_SIZE];
};

/* single container for all structs
* one verifier_env per bpf_check() call
*/
Expand Down Expand Up @@ -588,7 +598,10 @@ struct bpf_verifier_env {
const struct bpf_line_info *prev_linfo;
struct bpf_verifier_log log;
struct bpf_subprog_info subprog_info[BPF_MAX_SUBPROGS + 1];
struct bpf_id_pair idmap_scratch[BPF_ID_MAP_SIZE];
union {
struct bpf_idmap idmap_scratch;
struct bpf_idset idset_scratch;
};
struct {
int *insn_state;
int *insn_stack;
Expand Down
1 change: 0 additions & 1 deletion include/linux/bpfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ int bpfilter_ip_set_sockopt(struct sock *sk, int optname, sockptr_t optval,
unsigned int optlen);
int bpfilter_ip_get_sockopt(struct sock *sk, int optname, char __user *optval,
int __user *optlen);
void bpfilter_umh_cleanup(struct umd_info *info);

struct bpfilter_umh_ops {
struct umd_info info;
Expand Down
1 change: 0 additions & 1 deletion include/linux/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,6 @@ void bpf_prog_free(struct bpf_prog *fp);

bool bpf_opcode_in_insntable(u8 code);

void bpf_prog_free_linfo(struct bpf_prog *prog);
void bpf_prog_fill_jited_linfo(struct bpf_prog *prog,
const u32 *insn_to_jit_off);
int bpf_prog_alloc_jited_linfo(struct bpf_prog *prog);
Expand Down
9 changes: 9 additions & 0 deletions include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -5073,6 +5073,15 @@ static inline bool netif_is_l3_slave(const struct net_device *dev)
return dev->priv_flags & IFF_L3MDEV_SLAVE;
}

static inline int dev_sdif(const struct net_device *dev)
{
#ifdef CONFIG_NET_L3_MASTER_DEV
if (netif_is_l3_slave(dev))
return dev->ifindex;
#endif
return 0;
}

static inline bool netif_is_bridge_master(const struct net_device *dev)
{
return dev->priv_flags & IFF_EBRIDGE;
Expand Down
4 changes: 0 additions & 4 deletions include/net/xdp_sock_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,6 @@ static inline void xsk_buff_free(struct xdp_buff *xdp)
{
}

static inline void xsk_buff_discard(struct xdp_buff *xdp)
{
}

static inline void xsk_buff_set_size(struct xdp_buff *xdp, u32 size)
{
}
Expand Down
21 changes: 18 additions & 3 deletions include/uapi/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -3178,6 +3178,10 @@ union bpf_attr {
* **BPF_FIB_LOOKUP_DIRECT**
* Do a direct table lookup vs full lookup using FIB
* rules.
* **BPF_FIB_LOOKUP_TBID**
* Used with BPF_FIB_LOOKUP_DIRECT.
* Use the routing table ID present in *params*->tbid
* for the fib lookup.
* **BPF_FIB_LOOKUP_OUTPUT**
* Perform lookup from an egress perspective (default is
* ingress).
Expand Down Expand Up @@ -6832,6 +6836,7 @@ enum {
BPF_FIB_LOOKUP_DIRECT = (1U << 0),
BPF_FIB_LOOKUP_OUTPUT = (1U << 1),
BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2),
BPF_FIB_LOOKUP_TBID = (1U << 3),
};

enum {
Expand Down Expand Up @@ -6892,9 +6897,19 @@ struct bpf_fib_lookup {
__u32 ipv6_dst[4]; /* in6_addr; network order */
};

/* output */
__be16 h_vlan_proto;
__be16 h_vlan_TCI;
union {
struct {
/* output */
__be16 h_vlan_proto;
__be16 h_vlan_TCI;
};
/* input: when accompanied with the
* 'BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_TBID` flags, a
* specific routing table to use for the fib lookup.
*/
__u32 tbid;
};

__u8 smac[6]; /* ETH_ALEN */
__u8 dmac[6]; /* ETH_ALEN */
};
Expand Down
3 changes: 0 additions & 3 deletions kernel/bpf/bloom_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,6 @@ static struct bpf_map *bloom_map_alloc(union bpf_attr *attr)
int numa_node = bpf_map_attr_numa_node(attr);
struct bpf_bloom_filter *bloom;

if (!bpf_capable())
return ERR_PTR(-EPERM);

if (attr->key_size != 0 || attr->value_size == 0 ||
attr->max_entries == 0 ||
attr->map_flags & ~BLOOM_CREATE_FLAG_MASK ||
Expand Down
3 changes: 0 additions & 3 deletions kernel/bpf/bpf_local_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,9 +723,6 @@ int bpf_local_storage_map_alloc_check(union bpf_attr *attr)
!attr->btf_key_type_id || !attr->btf_value_type_id)
return -EINVAL;

if (!bpf_capable())
return -EPERM;

if (attr->value_size > BPF_LOCAL_STORAGE_MAX_VALUE_SIZE)
return -E2BIG;

Expand Down
3 changes: 0 additions & 3 deletions kernel/bpf/bpf_struct_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,9 +655,6 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
const struct btf_type *t, *vt;
struct bpf_map *map;

if (!bpf_capable())
return ERR_PTR(-EPERM);

st_ops = bpf_struct_ops_find_value(attr->btf_vmlinux_value_type_id);
if (!st_ops)
return ERR_PTR(-ENOTSUPP);
Expand Down
19 changes: 10 additions & 9 deletions kernel/bpf/btf.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,25 +492,26 @@ static bool btf_type_is_fwd(const struct btf_type *t)
return BTF_INFO_KIND(t->info) == BTF_KIND_FWD;
}

static bool btf_type_nosize(const struct btf_type *t)
static bool btf_type_is_datasec(const struct btf_type *t)
{
return btf_type_is_void(t) || btf_type_is_fwd(t) ||
btf_type_is_func(t) || btf_type_is_func_proto(t);
return BTF_INFO_KIND(t->info) == BTF_KIND_DATASEC;
}

static bool btf_type_nosize_or_null(const struct btf_type *t)
static bool btf_type_is_decl_tag(const struct btf_type *t)
{
return !t || btf_type_nosize(t);
return BTF_INFO_KIND(t->info) == BTF_KIND_DECL_TAG;
}

static bool btf_type_is_datasec(const struct btf_type *t)
static bool btf_type_nosize(const struct btf_type *t)
{
return BTF_INFO_KIND(t->info) == BTF_KIND_DATASEC;
return btf_type_is_void(t) || btf_type_is_fwd(t) ||
btf_type_is_func(t) || btf_type_is_func_proto(t) ||
btf_type_is_decl_tag(t);
}

static bool btf_type_is_decl_tag(const struct btf_type *t)
static bool btf_type_nosize_or_null(const struct btf_type *t)
{
return BTF_INFO_KIND(t->info) == BTF_KIND_DECL_TAG;
return !t || btf_type_nosize(t);
}

static bool btf_type_is_decl_tag_target(const struct btf_type *t)
Expand Down
8 changes: 5 additions & 3 deletions kernel/bpf/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2064,14 +2064,16 @@ EVAL4(PROG_NAME_LIST, 416, 448, 480, 512)
};
#undef PROG_NAME_LIST
#define PROG_NAME_LIST(stack_size) PROG_NAME_ARGS(stack_size),
static u64 (*interpreters_args[])(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5,
const struct bpf_insn *insn) = {
static __maybe_unused
u64 (*interpreters_args[])(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5,
const struct bpf_insn *insn) = {
EVAL6(PROG_NAME_LIST, 32, 64, 96, 128, 160, 192)
EVAL6(PROG_NAME_LIST, 224, 256, 288, 320, 352, 384)
EVAL4(PROG_NAME_LIST, 416, 448, 480, 512)
};
#undef PROG_NAME_LIST

#ifdef CONFIG_BPF_SYSCALL
void bpf_patch_call_args(struct bpf_insn *insn, u32 stack_depth)
{
stack_depth = max_t(u32, stack_depth, 1);
Expand All @@ -2080,7 +2082,7 @@ void bpf_patch_call_args(struct bpf_insn *insn, u32 stack_depth)
__bpf_call_base_args;
insn->code = BPF_JMP | BPF_CALL_ARGS;
}

#endif
#else
static unsigned int __bpf_prog_ret0_warn(const void *ctx,
const struct bpf_insn *insn)
Expand Down
4 changes: 0 additions & 4 deletions kernel/bpf/cpumap.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#include <linux/sched.h>
#include <linux/workqueue.h>
#include <linux/kthread.h>
#include <linux/capability.h>
#include <trace/events/xdp.h>
#include <linux/btf_ids.h>

Expand Down Expand Up @@ -89,9 +88,6 @@ static struct bpf_map *cpu_map_alloc(union bpf_attr *attr)
u32 value_size = attr->value_size;
struct bpf_cpu_map *cmap;

if (!bpf_capable())
return ERR_PTR(-EPERM);

/* check sanity of attributes */
if (attr->max_entries == 0 || attr->key_size != 4 ||
(value_size != offsetofend(struct bpf_cpumap_val, qsize) &&
Expand Down
Loading

0 comments on commit a685d0d

Please sign in to comment.