1. 16 Feb, 2022 1 commit
  2. 04 Feb, 2022 1 commit
  3. 03 Feb, 2022 1 commit
    • Yonghong Song's avatar
      bpf: Fix a btf decl_tag bug when tagging a function · d7e7b42f
      Yonghong Song authored
      syzbot reported a btf decl_tag bug with stack trace below:
      
        general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN
        KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
        CPU: 0 PID: 3592 Comm: syz-executor914 Not tainted 5.16.0-syzkaller-11424-gb7892f7d #0
        Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
        RIP: 0010:btf_type_vlen include/linux/btf.h:231 [inline]
        RIP: 0010:btf_decl_tag_resolve+0x83e/0xaa0 kernel/bpf/btf.c:3910
        ...
        Call Trace:
         <TASK>
         btf_resolve+0x251/0x1020 kernel/bpf/btf.c:4198
         btf_check_all_types kernel/bpf/btf.c:4239 [inline]
         btf_parse_type_sec kernel/bpf/btf.c:4280 [inline]
         btf_parse kernel/bpf/btf.c:4513 [inline]
         btf_new_fd+0x19fe/0x2370 kernel/bpf/btf.c:6047
         bpf_btf_load kernel/bpf/syscall.c:4039 [inline]
         __sys_bpf+0x1cbb/0x5970 kernel/bpf/syscall.c:4679
         __do_sys_bpf kernel/bpf/syscall.c:4738 [inline]
         __se_sys_bpf kernel/bpf/syscall.c:4736 [inline]
         __x64_sys_bpf+0x75/0xb0 kernel/bpf/syscall.c:4736
         do_syscall_x64 arch/x86/entry/common.c:50 [inline]
         do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
         entry_SYSCALL_64_after_hwframe+0x44/0xae
      
      The kasan error is triggered with an illegal BTF like below:
         type 0: void
         type 1: int
         type 2: decl_tag to func type 3
         type 3: func to func_proto type 8
      The total number of types is 4 and the type 3 is illegal
      since its func_proto type is out of range.
      
      Currently, the target type of decl_tag can be struct/union, var or func.
      Both struct/union and var implemented their own 'resolve' callback functions
      and hence handled properly in kernel.
      But func type doesn't have 'resolve' callback function. When
      btf_decl_tag_resolve() tries to check func type, it tries to get
      vlen of its func_proto type, which triggered the above kasan error.
      
      To fix the issue, btf_decl_tag_resolve() needs to do btf_func_check()
      before trying to accessing func_proto type.
      In the current implementation, func type is checked with
      btf_func_check() in the main checking function btf_check_all_types().
      To fix the above kasan issue, let us implement 'resolve' callback
      func type properly. The 'resolve' callback will be also called
      in btf_check_all_types() for func types.
      
      Fixes: b5ea834d
      
       ("bpf: Support for new btf kind BTF_KIND_TAG")
      Reported-by: syzbot+53619be9444215e785ed@syzkaller.appspotmail.com
      Signed-off-by: default avatarYonghong Song <yhs@fb.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/20220203191727.741862-1-yhs@fb.com
      d7e7b42f
  4. 27 Jan, 2022 1 commit
    • Yonghong Song's avatar
      bpf: reject program if a __user tagged memory accessed in kernel way · c6f1bfe8
      Yonghong Song authored
      
      BPF verifier supports direct memory access for BPF_PROG_TYPE_TRACING type
      of bpf programs, e.g., a->b. If "a" is a pointer
      pointing to kernel memory, bpf verifier will allow user to write
      code in C like a->b and the verifier will translate it to a kernel
      load properly. If "a" is a pointer to user memory, it is expected
      that bpf developer should be bpf_probe_read_user() helper to
      get the value a->b. Without utilizing BTF __user tagging information,
      current verifier will assume that a->b is a kernel memory access
      and this may generate incorrect result.
      
      Now BTF contains __user information, it can check whether the
      pointer points to a user memory or not. If it is, the verifier
      can reject the program and force users to use bpf_probe_read_user()
      helper explicitly.
      
      In the future, we can easily extend btf_add_space for other
      address space tagging, for example, rcu/percpu etc.
      Signed-off-by: default avatarYonghong Song <yhs@fb.com>
      Link: https://lore.kernel.org/r/20220127154606.654961-1-yhs@fb.com
      
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      c6f1bfe8
  5. 26 Jan, 2022 1 commit
  6. 19 Jan, 2022 1 commit
  7. 18 Jan, 2022 5 commits
    • Kumar Kartikeya Dwivedi's avatar
      bpf: Add reference tracking support to kfunc · 5c073f26
      Kumar Kartikeya Dwivedi authored
      This patch adds verifier support for PTR_TO_BTF_ID return type of kfunc
      to be a reference, by reusing acquire_reference_state/release_reference
      support for existing in-kernel bpf helpers.
      
      We make use of the three kfunc types:
      
      - BTF_KFUNC_TYPE_ACQUIRE
        Return true if kfunc_btf_id is an acquire kfunc.  This will
        acquire_reference_state for the returned PTR_TO_BTF_ID (this is the
        only allow return value). Note that acquire kfunc must always return a
        PTR_TO_BTF_ID{_OR_NULL}, otherwise the program is rejected.
      
      - BTF_KFUNC_TYPE_RELEASE
        Return true if kfunc_btf_id is a release kfunc.  This will release the
        reference to the passed in PTR_TO_BTF_ID which has a reference state
        (from earlier acquire kfunc).
        The btf_check_func_arg_match returns the regno (of argument register,
        hence > 0) if the kfunc is a release kfunc, and a proper referenced
        PTR_TO_BTF_ID is being passed to it.
        This is similar to how helper call check uses bpf_call_arg_meta to
        store the ref_obj_id that is later used to release the reference.
        Similar to in-kernel helper, we only allow passing one referenced
        PTR_TO_BTF_ID as an argument. It can also be passed in to normal
        kfunc, but in case of release kfunc there must always be one
        PTR_TO_BTF_ID argument that is referenced.
      
      - BTF_KFUNC_TYPE_RET_NULL
        For kfunc returning PTR_TO_BTF_ID, tells if it can be NULL, hence
        force caller to mark the pointer not null (using check) before
        accessing it. Note that taking into account the case fixed by commit
        93c230e3
      
       ("bpf: Enforce id generation for all may-be-null register type")
        we assign a non-zero id for mark_ptr_or_null_reg logic. Later, if more
        return types are supported by kfunc, which have a _OR_NULL variant, it
        might be better to move this id generation under a common
        reg_type_may_be_null check, similar to the case in the commit.
      
      Referenced PTR_TO_BTF_ID is currently only limited to kfunc, but can be
      extended in the future to other BPF helpers as well.  For now, we can
      rely on the btf_struct_ids_match check to ensure we get the pointer to
      the expected struct type. In the future, care needs to be taken to avoid
      ambiguity for reference PTR_TO_BTF_ID passed to release function, in
      case multiple candidates can release same BTF ID.
      
      e.g. there might be two release kfuncs (or kfunc and helper):
      
      foo(struct abc *p);
      bar(struct abc *p);
      
      ... such that both release a PTR_TO_BTF_ID with btf_id of struct abc. In
      this case we would need to track the acquire function corresponding to
      the release function to avoid type confusion, and store this information
      in the register state so that an incorrect program can be rejected. This
      is not a problem right now, hence it is left as an exercise for the
      future patch introducing such a case in the kernel.
      Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
      Link: https://lore.kernel.org/r/20220114163953.1455836-6-memxor@gmail.com
      
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      5c073f26
    • Kumar Kartikeya Dwivedi's avatar
      bpf: Introduce mem, size argument pair support for kfunc · d583691c
      Kumar Kartikeya Dwivedi authored
      
      BPF helpers can associate two adjacent arguments together to pass memory
      of certain size, using ARG_PTR_TO_MEM and ARG_CONST_SIZE arguments.
      Since we don't use bpf_func_proto for kfunc, we need to leverage BTF to
      implement similar support.
      
      The ARG_CONST_SIZE processing for helpers is refactored into a common
      check_mem_size_reg helper that is shared with kfunc as well. kfunc
      ptr_to_mem support follows logic similar to global functions, where
      verification is done as if pointer is not null, even when it may be
      null.
      
      This leads to a simple to follow rule for writing kfunc: always check
      the argument pointer for NULL, except when it is PTR_TO_CTX. Also, the
      PTR_TO_CTX case is also only safe when the helper expecting pointer to
      program ctx is not exposed to other programs where same struct is not
      ctx type. In that case, the type check will fall through to other cases
      and would permit passing other types of pointers, possibly NULL at
      runtime.
      
      Currently, we require the size argument to be suffixed with "__sz" in
      the parameter name. This information is then recorded in kernel BTF and
      verified during function argument checking. In the future we can use BTF
      tagging instead, and modify the kernel function definitions. This will
      be a purely kernel-side change.
      
      This allows us to have some form of backwards compatibility for
      structures that are passed in to the kernel function with their size,
      and allow variable length structures to be passed in if they are
      accompanied by a size parameter.
      Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
      Link: https://lore.kernel.org/r/20220114163953.1455836-5-memxor@gmail.com
      
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      d583691c
    • Kumar Kartikeya Dwivedi's avatar
      bpf: Remove check_kfunc_call callback and old kfunc BTF ID API · b202d844
      Kumar Kartikeya Dwivedi authored
      
      Completely remove the old code for check_kfunc_call to help it work
      with modules, and also the callback itself.
      
      The previous commit adds infrastructure to register all sets and put
      them in vmlinux or module BTF, and concatenates all related sets
      organized by the hook and the type. Once populated, these sets remain
      immutable for the lifetime of the struct btf.
      
      Also, since we don't need the 'owner' module anywhere when doing
      check_kfunc_call, drop the 'btf_modp' module parameter from
      find_kfunc_desc_btf.
      Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
      Link: https://lore.kernel.org/r/20220114163953.1455836-4-memxor@gmail.com
      
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      b202d844
    • Kumar Kartikeya Dwivedi's avatar
      bpf: Populate kfunc BTF ID sets in struct btf · dee872e1
      Kumar Kartikeya Dwivedi authored
      
      This patch prepares the kernel to support putting all kinds of kfunc BTF
      ID sets in the struct btf itself. The various kernel subsystems will
      make register_btf_kfunc_id_set call in the initcalls (for built-in code
      and modules).
      
      The 'hook' is one of the many program types, e.g. XDP and TC/SCHED_CLS,
      STRUCT_OPS, and 'types' are check (allowed or not), acquire, release,
      and ret_null (with PTR_TO_BTF_ID_OR_NULL return type).
      
      A maximum of BTF_KFUNC_SET_MAX_CNT (32) kfunc BTF IDs are permitted in a
      set of certain hook and type for vmlinux sets, since they are allocated
      on demand, and otherwise set as NULL. Module sets can only be registered
      once per hook and type, hence they are directly assigned.
      
      A new btf_kfunc_id_set_contains function is exposed for use in verifier,
      this new method is faster than the existing list searching method, and
      is also automatic. It also lets other code not care whether the set is
      unallocated or not.
      
      Note that module code can only do single register_btf_kfunc_id_set call
      per hook. This is why sorting is only done for in-kernel vmlinux sets,
      because there might be multiple sets for the same hook and type that
      must be concatenated, hence sorting them is required to ensure bsearch
      in btf_id_set_contains continues to work correctly.
      
      Next commit will update the kernel users to make use of this
      infrastructure.
      
      Finally, add __maybe_unused annotation for BTF ID macros for the
      !CONFIG_DEBUG_INFO_BTF case, so that they don't produce warnings during
      build time.
      
      The previous patch is also needed to provide synchronization against
      initialization for module BTF's kfunc_set_tab introduced here, as
      described below:
      
        The kfunc_set_tab pointer in struct btf is write-once (if we consider
        the registration phase (comprised of multiple register_btf_kfunc_id_set
        calls) as a single operation). In this sense, once it has been fully
        prepared, it isn't modified, only used for lookup (from the verifier
        context).
      
        For btf_vmlinux, it is initialized fully during the do_initcalls phase,
        which happens fairly early in the boot process, before any processes are
        present. This also eliminates the possibility of bpf_check being called
        at that point, thus relieving us of ensuring any synchronization between
        the registration and lookup function (btf_kfunc_id_set_contains).
      
        However, the case for module BTF is a bit tricky. The BTF is parsed,
        prepared, and published from the MODULE_STATE_COMING notifier callback.
        After this, the module initcalls are invoked, where our registration
        function will be called to populate the kfunc_set_tab for module BTF.
      
        At this point, BTF may be available to userspace while its corresponding
        module is still intializing. A BTF fd can then be passed to verifier
        using bpf syscall (e.g. for kfunc call insn).
      
        Hence, there is a race window where verifier may concurrently try to
        lookup the kfunc_set_tab. To prevent this race, we must ensure the
        operations are serialized, or waiting for the __init functions to
        complete.
      
        In the earlier registration API, this race was alleviated as verifier
        bpf_check_mod_kfunc_call didn't find the kfunc BTF ID until it was added
        by the registration function (called usually at the end of module __init
        function after all module resources have been initialized). If the
        verifier made the check_kfunc_call before kfunc BTF ID was added to the
        list, it would fail verification (saying call isn't allowed). The
        access to list was protected using a mutex.
      
        Now, it would still fail verification, but for a different reason
        (returning ENXIO due to the failed btf_try_get_module call in
        add_kfunc_call), because if the __init call is in progress the module
        will be in the middle of MODULE_STATE_COMING -> MODULE_STATE_LIVE
        transition, and the BTF_MODULE_LIVE flag for btf_module instance will
        not be set, so the btf_try_get_module call will fail.
      Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
      Link: https://lore.kernel.org/r/20220114163953.1455836-3-memxor@gmail.com
      
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      dee872e1
    • Kumar Kartikeya Dwivedi's avatar
      bpf: Fix UAF due to race between btf_try_get_module and load_module · 18688de2
      Kumar Kartikeya Dwivedi authored
      While working on code to populate kfunc BTF ID sets for module BTF from
      its initcall, I noticed that by the time the initcall is invoked, the
      module BTF can already be seen by userspace (and the BPF verifier). The
      existing btf_try_get_module calls try_module_get which only fails if
      mod->state == MODULE_STATE_GOING, i.e. it can increment module reference
      when module initcall is happening in parallel.
      
      Currently, BTF parsing happens from MODULE_STATE_COMING notifier
      callback. At this point, the module initcalls have not been invoked.
      The notifier callback parses and prepares the module BTF, allocates an
      ID, which publishes it to userspace, and then adds it to the btf_modules
      list allowing the kernel to invoke btf_try_get_module for the BTF.
      
      However, at this point, the module has not been fully initialized (i.e.
      its initcalls have not finished). The code in module.c can still fail
      and free the module, without caring for other users. However, nothing
      stops btf_try_get_module from succeeding between the state transition
      from MODULE_STATE_COMING to MODULE_STATE_LIVE.
      
      This leads to a use-after-free issue when BPF program loads
      successfully in the state transition, load_module's do_init_module call
      fails and frees the module, and BPF program fd on close calls module_put
      for the freed module. Future patch has test case to verify we don't
      regress in this area in future.
      
      There are multiple points after prepare_coming_module (in load_module)
      where failure can occur and module loading can return error. We
      illustrate and test for the race using the last point where it can
      practically occur (in module __init function).
      
      An illustration of the race:
      
      CPU 0                           CPU 1
      			  load_module
      			    notifier_call(MODULE_STATE_COMING)
      			      btf_parse_module
      			      btf_alloc_id	// Published to userspace
      			      list_add(&btf_mod->list, btf_modules)
      			    mod->init(...)
      ...				^
      bpf_check		        |
      check_pseudo_btf_id             |
        btf_try_get_module            |
          returns true                |  ...
      ...                             |  module __init in progress
      return prog_fd                  |  ...
      ...                             V
      			    if (ret < 0)
      			      free_module(mod)
      			    ...
      close(prog_fd)
       ...
       bpf_prog_free_deferred
        module_put(used_btf.mod) // use-after-free
      
      We fix this issue by setting a flag BTF_MODULE_F_LIVE, from the notifier
      callback when MODULE_STATE_LIVE state is reached for the module, so that
      we return NULL from btf_try_get_module for modules that are not fully
      formed. Since try_module_get already checks that module is not in
      MODULE_STATE_GOING state, and that is the only transition a live module
      can make before being removed from btf_modules list, this is enough to
      close the race and prevent the bug.
      
      A later selftest patch crafts the race condition artifically to verify
      that it has been fixed, and that verifier fails to load program (with
      ENXIO).
      
      Lastly, a couple of comments:
      
       1. Even if this race didn't exist, it seems more appropriate to only
          access resources (ksyms and kfuncs) of a fully formed module which
          has been initialized completely.
      
       2. This patch was born out of need for synchronization against module
          initcall for the next patch, so it is needed for correctness even
          without the aforementioned race condition. The BTF resources
          initialized by module initcall are set up once and then only looked
          up, so just waiting until the initcall has finished ensures correct
          behavior.
      
      Fixes: 541c3bad
      
       ("bpf: Support BPF ksym variables in kernel modules")
      Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
      Link: https://lore.kernel.org/r/20220114163953.1455836-2-memxor@gmail.com
      
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      18688de2
  8. 19 Dec, 2021 1 commit
    • Kumar Kartikeya Dwivedi's avatar
      bpf: Extend kfunc with PTR_TO_CTX, PTR_TO_MEM argument support · 3363bd0c
      Kumar Kartikeya Dwivedi authored
      
      Allow passing PTR_TO_CTX, if the kfunc expects a matching struct type,
      and punt to PTR_TO_MEM block if reg->type does not fall in one of
      PTR_TO_BTF_ID or PTR_TO_SOCK* types. This will be used by future commits
      to get access to XDP and TC PTR_TO_CTX, and pass various data (flags,
      l4proto, netns_id, etc.) encoded in opts struct passed as pointer to
      kfunc.
      
      For PTR_TO_MEM support, arguments are currently limited to pointer to
      scalar, or pointer to struct composed of scalars. This is done so that
      unsafe scenarios (like passing PTR_TO_MEM where PTR_TO_BTF_ID of
      in-kernel valid structure is expected, which may have pointers) are
      avoided. Since the argument checking happens basd on argument register
      type, it is not easy to ascertain what the expected type is. In the
      future, support for PTR_TO_MEM for kfunc can be extended to serve other
      usecases. The struct type whose pointer is passed in may have maximum
      nesting depth of 4, all recursively composed of scalars or struct with
      scalars.
      
      Future commits will add negative tests that check whether these
      restrictions imposed for kfunc arguments are duly rejected by BPF
      verifier or not.
      Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20211217015031.1278167-4-memxor@gmail.com
      3363bd0c
  9. 18 Dec, 2021 4 commits
  10. 13 Dec, 2021 1 commit
    • Jiri Olsa's avatar
      bpf: Allow access to int pointer arguments in tracing programs · bb6728d7
      Jiri Olsa authored
      
      Adding support to access arguments with int pointer arguments
      in tracing programs.
      
      Currently we allow tracing programs to access only pointers to
      string (char pointer), void pointers and pointers to structs.
      
      If we try to access argument which is pointer to int, verifier
      will fail to load the program with;
      
        R1 type=ctx expected=fp
        ; int BPF_PROG(fmod_ret_test, int _a, __u64 _b, int _ret)
        0: (bf) r6 = r1
        ; int BPF_PROG(fmod_ret_test, int _a, __u64 _b, int _ret)
        1: (79) r9 = *(u64 *)(r6 +8)
        func 'bpf_modify_return_test' arg1 type INT is not a struct
      
      There is no harm for the program to access int pointer argument.
      We are already doing that for string pointer, which is pointer
      to int with 1 byte size.
      
      Changing the is_string_ptr to generic integer check and renaming
      it to btf_type_is_int.
      Signed-off-by: default avatarJiri Olsa <jolsa@kernel.org>
      Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20211208193245.172141-2-jolsa@kernel.org
      bb6728d7
  11. 12 Dec, 2021 2 commits
  12. 09 Dec, 2021 1 commit
  13. 07 Dec, 2021 1 commit
  14. 04 Dec, 2021 1 commit
  15. 03 Dec, 2021 1 commit
  16. 02 Dec, 2021 7 commits
  17. 12 Nov, 2021 3 commits
  18. 07 Nov, 2021 1 commit
  19. 23 Oct, 2021 1 commit
  20. 19 Oct, 2021 1 commit
  21. 06 Oct, 2021 3 commits
  22. 15 Sep, 2021 1 commit