From patchwork Tue Feb 14 04:33:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joanne Koong X-Patchwork-Id: 13139362 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 875E5C61DA4 for ; Tue, 14 Feb 2023 04:35:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230124AbjBNEfJ (ORCPT ); Mon, 13 Feb 2023 23:35:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229818AbjBNEfI (ORCPT ); Mon, 13 Feb 2023 23:35:08 -0500 Received: from 66-220-144-178.mail-mxout.facebook.com (66-220-144-178.mail-mxout.facebook.com [66.220.144.178]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BE05B1968E for ; Mon, 13 Feb 2023 20:35:06 -0800 (PST) Received: by devvm15675.prn0.facebook.com (Postfix, from userid 115148) id 3FCD065D6F98; Mon, 13 Feb 2023 20:34:54 -0800 (PST) From: Joanne Koong To: bpf@vger.kernel.org Cc: andrii@kernel.org, daniel@iogearbox.net, ast@kernel.org, martin.lau@linux.dev, memxor@gmail.com, kernel-team@fb.com, Joanne Koong Subject: [PATCH v1 bpf-next] bpf: Update kfunc __sz documentation Date: Mon, 13 Feb 2023 20:33:50 -0800 Message-Id: <20230214043350.3497406-1-joannelkoong@gmail.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net A bpf program calling a kfunc with a __sz-annotated arg must explicitly initialize the stack themselves if the pointer to the memory region is a pointer to the stack. This is because in the verifier, we do not explicitly initialize the stack space for reg type PTR_TO_STACK kfunc args. Thus, the verifier will reject the program with: invalid indirect read from stack arg#0 arg#1 memory, len pair leads to invalid memory access Alternatively, the verifier could support initializing the stack space on behalf of the program for KF_ARG_PTR_TO_MEM_SIZE args, but this has some drawbacks. For example this would not allow the verifier to reject a program for passing in an uninitialized PTR_TO_STACK for an arg that should have valid data. Another example is that since there's no current way in a kfunc to differentiate between whether the arg should be treated as uninitialized or not, additional check_mem_access calls would need to be called even on PTR_TO_STACKs that have been initialized, which is inefficient. Please note that non-kfuncs don't have this problem because of the MEM_UNINIT tag; only if the arg is tagged as MEM_UNINIT, then do we call check_mem_access byte-by-byte for the size of the buffer. Signed-off-by: Joanne Koong --- Documentation/bpf/kfuncs.rst | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst index ca96ef3f6896..97497a7879d6 100644 --- a/Documentation/bpf/kfuncs.rst +++ b/Documentation/bpf/kfuncs.rst @@ -71,10 +71,37 @@ An example is given below:: ... } -Here, the verifier will treat first argument as a PTR_TO_MEM, and second -argument as its size. By default, without __sz annotation, the size of the type -of the pointer is used. Without __sz annotation, a kfunc cannot accept a void -pointer. +Here, the verifier will treat first argument (KF_ARG_PTR_TO_MEM_SIZE) as a +pointer to the memory region and second argument as its size. By default, +without __sz annotation, the size of the type of the pointer is used. Without +__sz annotation, a kfunc cannot accept a void pointer. + +Please note that if the memory is on the stack, the stack space must be +explicitly initialized by the program. For example: + +.. code-block:: c + + SEC("tc") + int prog(struct __sk_buff *skb) + { + char buf[8]; + + bpf_memzero(buf, sizeof(buf)); + ... + } + +should be + +.. code-block:: c + + SEC("tc") + int prog(struct __sk_buff *skb) + { + char buf[8] = {}; + + bpf_memzero(buf, sizeof(buf)); + ... + } 2.2.2 __k Annotation --------------------