From patchwork Mon Feb 12 23:32:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13554157 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 932DA3A8C2 for ; Mon, 12 Feb 2024 23:32:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707780747; cv=none; b=lY4GSnq+9COHgcSvAznLRgh6cejYAOCmY7OjDITNHj3xlmVH/+PKkDQIu9VsVlUDDMofBdWc+SGBrfFpP7EjZruejcQsiKEGkKQTnVKrIhiMRNQuj1YM3NQr9DZlZyZRhAriWxouU5PvaBuR1b+6DZhJrj28Vom8OziJt5IVnuA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707780747; c=relaxed/simple; bh=ihcAai2OdKzaL/m+OGN1eDSJXOKdauw6wDzofwDqAWc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=th2uzH/zI15en8ztdnp+V9vCs0B2mm8gY7t54Rd0s0UAiT24o31xjkAjVV8tZpn6dwXsgaT65lBAAau8L8MTumXZTGs1RV0ZCYzkp4/YF/xMBLZa45c7QpYrbLulB0ekYFnUBJjfht3qHv5wYPHDXx2RFAqrjw/Qaw67miH3jOs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OU1Gingn; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="OU1Gingn" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 26579C433F1; Mon, 12 Feb 2024 23:32:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707780747; bh=ihcAai2OdKzaL/m+OGN1eDSJXOKdauw6wDzofwDqAWc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OU1Gingnnq5eZqfVjWeJWBTy3NHeUrqDN9+JcnZrA4Z1yqI8rKFhjmAttTOAGhznK Pi7FqPRcixkwPm86LVIzenRIISwKarIyZkQ+mldLAuOXMlfPdpbIAnfjwAv6CZuw5W gO7u6kjuhGzmumfpQZUQdOLMmeZmX9fbO9bTQ0zWhLpjV2nUvWnbVZZ4qnMtT2gYgr 5zx6ib1e7Qr9rOum0qUVO90CHIqXhRAYPPuMcIGFWbto7v17f1LEdz4UbEbexT0Clo 0e1DGpZgbCgTjjrIWOnVdyQ3tkYFR9dkkA5enV61PhMGaGrvlnehHwhVfJ7isbt2oX QxEDZTEKexLfg== From: Andrii Nakryiko To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, martin.lau@kernel.org Cc: andrii@kernel.org, kernel-team@meta.com Subject: [PATCH v2 bpf-next 1/4] bpf: simplify btf_get_prog_ctx_type() into btf_is_prog_ctx_type() Date: Mon, 12 Feb 2024 15:32:18 -0800 Message-Id: <20240212233221.2575350-2-andrii@kernel.org> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240212233221.2575350-1-andrii@kernel.org> References: <20240212233221.2575350-1-andrii@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Return result of btf_get_prog_ctx_type() is never used and callers only check NULL vs non-NULL case to determine if given type matches expected PTR_TO_CTX type. So rename function to `btf_is_prog_ctx_type()` and return a simple true/false. We'll use this simpler interface to handle kprobe program type's special typedef case in the next patch. Signed-off-by: Andrii Nakryiko --- include/linux/btf.h | 17 ++++++++--------- kernel/bpf/btf.c | 27 +++++++++++++-------------- kernel/bpf/verifier.c | 2 +- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/include/linux/btf.h b/include/linux/btf.h index 1ee8977b8c95..7cfccd7a851d 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -525,10 +525,9 @@ s32 btf_find_dtor_kfunc(struct btf *btf, u32 btf_id); int register_btf_id_dtor_kfuncs(const struct btf_id_dtor_kfunc *dtors, u32 add_cnt, struct module *owner); struct btf_struct_meta *btf_find_struct_meta(const struct btf *btf, u32 btf_id); -const struct btf_type * -btf_get_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, - const struct btf_type *t, enum bpf_prog_type prog_type, - int arg); +bool btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, + const struct btf_type *t, enum bpf_prog_type prog_type, + int arg); int get_kern_ctx_btf_id(struct bpf_verifier_log *log, enum bpf_prog_type prog_type); bool btf_types_are_same(const struct btf *btf1, u32 id1, const struct btf *btf2, u32 id2); @@ -568,12 +567,12 @@ static inline struct btf_struct_meta *btf_find_struct_meta(const struct btf *btf { return NULL; } -static inline const struct btf_member * -btf_get_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, - const struct btf_type *t, enum bpf_prog_type prog_type, - int arg) +static inline bool +btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, + const struct btf_type *t, enum bpf_prog_type prog_type, + int arg) { - return NULL; + return false; } static inline int get_kern_ctx_btf_id(struct bpf_verifier_log *log, enum bpf_prog_type prog_type) { diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 8e06d29961f1..f0ce384aa73e 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -5687,10 +5687,9 @@ static int find_kern_ctx_type_id(enum bpf_prog_type prog_type) return ctx_type->type; } -const struct btf_type * -btf_get_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, - const struct btf_type *t, enum bpf_prog_type prog_type, - int arg) +bool btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, + const struct btf_type *t, enum bpf_prog_type prog_type, + int arg) { const struct btf_type *ctx_type; const char *tname, *ctx_tname; @@ -5704,26 +5703,26 @@ btf_get_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, * is not supported yet. * BPF_PROG_TYPE_RAW_TRACEPOINT is fine. */ - return NULL; + return false; } tname = btf_name_by_offset(btf, t->name_off); if (!tname) { bpf_log(log, "arg#%d struct doesn't have a name\n", arg); - return NULL; + return false; } ctx_type = find_canonical_prog_ctx_type(prog_type); if (!ctx_type) { bpf_log(log, "btf_vmlinux is malformed\n"); /* should not happen */ - return NULL; + return false; } again: ctx_tname = btf_name_by_offset(btf_vmlinux, ctx_type->name_off); if (!ctx_tname) { /* should not happen */ bpf_log(log, "Please fix kernel include/linux/bpf_types.h\n"); - return NULL; + return false; } /* only compare that prog's ctx type name is the same as * kernel expects. No need to compare field by field. @@ -5733,20 +5732,20 @@ btf_get_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, * { // no fields of skb are ever used } */ if (strcmp(ctx_tname, "__sk_buff") == 0 && strcmp(tname, "sk_buff") == 0) - return ctx_type; + return true; if (strcmp(ctx_tname, "xdp_md") == 0 && strcmp(tname, "xdp_buff") == 0) - return ctx_type; + return true; if (strcmp(ctx_tname, tname)) { /* bpf_user_pt_regs_t is a typedef, so resolve it to * underlying struct and check name again */ if (!btf_type_is_modifier(ctx_type)) - return NULL; + return false; while (btf_type_is_modifier(ctx_type)) ctx_type = btf_type_by_id(btf_vmlinux, ctx_type->type); goto again; } - return ctx_type; + return true; } /* forward declarations for arch-specific underlying types of @@ -5898,7 +5897,7 @@ static int btf_translate_to_vmlinux(struct bpf_verifier_log *log, enum bpf_prog_type prog_type, int arg) { - if (!btf_get_prog_ctx_type(log, btf, t, prog_type, arg)) + if (!btf_is_prog_ctx_type(log, btf, t, prog_type, arg)) return -ENOENT; return find_kern_ctx_type_id(prog_type); } @@ -7184,7 +7183,7 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog) if (!btf_type_is_ptr(t)) goto skip_pointer; - if ((tags & ARG_TAG_CTX) || btf_get_prog_ctx_type(log, btf, t, prog_type, i)) { + if ((tags & ARG_TAG_CTX) || btf_is_prog_ctx_type(log, btf, t, prog_type, i)) { if (tags & ~ARG_TAG_CTX) { bpf_log(log, "arg#%d has invalid combination of tags\n", i); return -EINVAL; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index ddaf09db1175..0a6e047e4ee4 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -11033,7 +11033,7 @@ get_kfunc_ptr_arg_type(struct bpf_verifier_env *env, * type to our caller. When a set of conditions hold in the BTF type of * arguments, we resolve it to a known kfunc_ptr_arg_type. */ - if (btf_get_prog_ctx_type(&env->log, meta->btf, t, resolve_prog_type(env->prog), argno)) + if (btf_is_prog_ctx_type(&env->log, meta->btf, t, resolve_prog_type(env->prog), argno)) return KF_ARG_PTR_TO_CTX; if (is_kfunc_arg_alloc_obj(meta->btf, &args[argno])) From patchwork Mon Feb 12 23:32:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13554158 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C8F93A8C2 for ; Mon, 12 Feb 2024 23:32:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707780751; cv=none; b=GyxhQ43eXT73SNZzZrYnvR55Et/iaRo37zxDWNL7qel/yWSQwIwCOIqTiZYq7rm/KK/6kYGot7EjrfNY8UyvgWMeAIUySJBZqeZ52pfK2jjZP6UrpGroVxWJvEkYT0Aptd25kf2E1qs2+Eu2zj9LPhGKdIXbK/5xDNCbwp4wwQ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707780751; c=relaxed/simple; bh=hTePFMj87bd5J1h3gKIsd5JNLguhvEIR5DdTpXIpzyQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=UKzpxzsmC+HbGeFPGSLIjwN26FUHNTXR0r61meqCANM1Fc5PSRH/r9lCDV7l7YNOFrOrlfpEH22eZzxaFBsA0u1zoM5X4e6eN6wU0vLY1CBAc+uTmU59jAI7gRyBLcpd9Nug0SeEuB26Bh4/OhH7lBgUpE+Pwchl0/q0nJmQPiw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nGWddIQ7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="nGWddIQ7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 55430C43390; Mon, 12 Feb 2024 23:32:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707780750; bh=hTePFMj87bd5J1h3gKIsd5JNLguhvEIR5DdTpXIpzyQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nGWddIQ7KNE+XGdPA1AS+oulan+hVx0MBVsysPyfYAVOLqgBD8ZftPFEBjkiQeXLt Pk4ePLHTNRUosVB2p3yOKVHyhpmOOkp9sCFQojGCNvnWxRZUhMXkH3NrukxUTjOpXo Mkd7wH2RaCtV3ac4Z/D2ryK0ETtrdb+gGKF914PlvirGvIpZv6KCj7aixcF3HhajaI X4rXur3ocuKVhtH3MP3b4SZ4FQXfCzeGXiD+6UtGoZ1sTvOYCmMs+6N6x0Nsz9ei72 jWZzvyCC7HL7wusK9IXOMkMpIzYyvBNmyU31LZ1jehMaYEM7OGujqT+z1VAPqfvzr0 IuY71niGAp3hA== From: Andrii Nakryiko To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, martin.lau@kernel.org Cc: andrii@kernel.org, kernel-team@meta.com Subject: [PATCH v2 bpf-next 2/4] bpf: handle bpf_user_pt_regs_t typedef explicitly for PTR_TO_CTX global arg Date: Mon, 12 Feb 2024 15:32:19 -0800 Message-Id: <20240212233221.2575350-3-andrii@kernel.org> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240212233221.2575350-1-andrii@kernel.org> References: <20240212233221.2575350-1-andrii@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Expected canonical argument type for global function arguments representing PTR_TO_CTX is `bpf_user_pt_regs_t *ctx`. This currently works on s390x by accident because kernel resolves such typedef to underlying struct (which is anonymous on s390x), and erroneously accepting it as expected context type. We are fixing this problem next, which would break s390x arch, so we need to handle `bpf_user_pt_regs_t` case explicitly for KPROBE programs. Fixes: 91cc1a99740e ("bpf: Annotate context types") Signed-off-by: Andrii Nakryiko --- kernel/bpf/btf.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index f0ce384aa73e..da958092c969 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -5695,6 +5695,21 @@ bool btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, const char *tname, *ctx_tname; t = btf_type_by_id(btf, t->type); + + /* KPROBE programs allow bpf_user_pt_regs_t typedef, which we need to + * check before we skip all the typedef below. + */ + if (prog_type == BPF_PROG_TYPE_KPROBE) { + while (btf_type_is_modifier(t) && !btf_type_is_typedef(t)) + t = btf_type_by_id(btf, t->type); + + if (btf_type_is_typedef(t)) { + tname = btf_name_by_offset(btf, t->name_off); + if (tname && strcmp(tname, "bpf_user_pt_regs_t") == 0) + return true; + } + } + while (btf_type_is_modifier(t)) t = btf_type_by_id(btf, t->type); if (!btf_type_is_struct(t)) { From patchwork Mon Feb 12 23:32:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13554159 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 417623A8C2 for ; Mon, 12 Feb 2024 23:32:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707780754; cv=none; b=S+gd9G4BDTifwt/pyUfwvv5BORNbbKDmvq354kncMeuoIvKdEcbeYr1zrz59Rb1hIiZy5+cstW2E9fU9718CAJx3Y2x6fsd0LnmRk9uKEJ1Wg0W0hNaL+VgRRoBO1YsXFIlZkezV66zJ/3lan4xV3wHJkskySZlKGzxeCT7lBCc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707780754; c=relaxed/simple; bh=XH/M62z74kSPVa6XW93VnqBVlGXo/YIsCmSRdiS5Dsw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rGP7lqDjOPYbZ2KmAWK+Pgqqj6U1pq5NTIzxudb6Fbt2tnt3FmkL890g89juO+xzQ2oOEVjCHj4QS1562oKi1/8dURy+ArJPX0emyPha1yykS6PSqSEUhlNFQxVTvY36pN6koiHA32+0DCXcuTgb64YQZy/wPM/pmHaSleGCguw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=suI74l96; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="suI74l96" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 97DD3C433C7; Mon, 12 Feb 2024 23:32:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707780753; bh=XH/M62z74kSPVa6XW93VnqBVlGXo/YIsCmSRdiS5Dsw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=suI74l96m6rryUZnUMZVq9399XlFfZWaea/PetjvZ9oGA3jPervLIljxcY9qCjJ4Q O8q1d+l/1b4TjZViEVKRr4akHw+oQhfrZ9xeKCc3dVNYsd9tAghl1Rk+xPb+RG/v4Q gWhnEkMkz+dL6h+syiVRFvs7usgMJ7tchkyNQu2hj406/jjG/JkZ5cyJGpwSPxmtju 8sdrGfonybTuW3LX09CtOYxYnNJWm8tCe1c5ZQOIXFBmZIyQw4tiF8qeIOYOFO1HZk 1MLtPnFexzUaeXNjCwLGRWoArFdjo1KJWC9EnWz+0NXkWhfw6ffKa+QxPPeA5Hs7Fz mKzp2GT4PDZ+g== From: Andrii Nakryiko To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, martin.lau@kernel.org Cc: andrii@kernel.org, kernel-team@meta.com Subject: [PATCH v2 bpf-next 3/4] bpf: don't infer PTR_TO_CTX for programs with unnamed context type Date: Mon, 12 Feb 2024 15:32:20 -0800 Message-Id: <20240212233221.2575350-4-andrii@kernel.org> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240212233221.2575350-1-andrii@kernel.org> References: <20240212233221.2575350-1-andrii@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net For program types that don't have named context type name (e.g., BPF iterator programs or tracepoint programs), ctx_tname will be a non-NULL empty string. For such programs it shouldn't be possible to have PTR_TO_CTX argument for global subprogs based on type name alone. arg:ctx tag is the only way to have PTR_TO_CTX passed into global subprog for such program types. Fix this loophole, which currently would assume PTR_TO_CTX whenever user uses a pointer to anonymous struct as an argument to their global subprogs. This happens in practice with the following (quite common, in practice) approach: typedef struct { /* anonymous */ int x; } my_type_t; int my_subprog(my_type_t *arg) { ... } User's intent is to have PTR_TO_MEM argument for `arg`, but verifier will complain about expecting PTR_TO_CTX. This fix also closes unintended s390x-specific KPROBE handling of PTR_TO_CTX case. Selftest change is necessary to accommodate this. Fixes: 91cc1a99740e ("bpf: Annotate context types") Signed-off-by: Andrii Nakryiko --- kernel/bpf/btf.c | 3 +++ .../bpf/progs/test_global_func_ctx_args.c | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index da958092c969..13bd93efeed0 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -5739,6 +5739,9 @@ bool btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, bpf_log(log, "Please fix kernel include/linux/bpf_types.h\n"); return false; } + /* program types without named context types work only with arg:ctx tag */ + if (ctx_tname[0] == '\0') + return false; /* only compare that prog's ctx type name is the same as * kernel expects. No need to compare field by field. * It's ok for bpf prog to do: diff --git a/tools/testing/selftests/bpf/progs/test_global_func_ctx_args.c b/tools/testing/selftests/bpf/progs/test_global_func_ctx_args.c index 9a06e5eb1fbe..143c8a4852bf 100644 --- a/tools/testing/selftests/bpf/progs/test_global_func_ctx_args.c +++ b/tools/testing/selftests/bpf/progs/test_global_func_ctx_args.c @@ -26,6 +26,23 @@ int kprobe_typedef_ctx(void *ctx) return kprobe_typedef_ctx_subprog(ctx); } +/* s390x defines: + * + * typedef user_pt_regs bpf_user_pt_regs_t; + * typedef struct { ... } user_pt_regs; + * + * And so "canonical" underlying struct type is anonymous. + * So on s390x only valid ways to have PTR_TO_CTX argument in global subprogs + * are: + * - bpf_user_pt_regs_t *ctx (typedef); + * - struct bpf_user_pt_regs_t *ctx (backwards compatible struct hack); + * - void *ctx __arg_ctx (arg:ctx tag) + * + * Other architectures also allow using underlying struct types (e.g., + * `struct pt_regs *ctx` for x86-64) + */ +#ifndef bpf_target_s390 + #define pt_regs_struct_t typeof(*(__PT_REGS_CAST((struct pt_regs *)NULL))) __weak int kprobe_struct_ctx_subprog(pt_regs_struct_t *ctx) @@ -40,6 +57,8 @@ int kprobe_resolved_ctx(void *ctx) return kprobe_struct_ctx_subprog(ctx); } +#endif + /* this is current hack to make this work on old kernels */ struct bpf_user_pt_regs_t {}; From patchwork Mon Feb 12 23:32:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13554160 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C68C3A8C2 for ; Mon, 12 Feb 2024 23:32:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707780757; cv=none; b=YzCYLI1pfSEHqk4gWFxOfSNG60QyMPVO5GVPB8qSJKxoUCwrKUIDEL9t2GKtvQ/FNZ5BSmFvQhOFM3dSyslMPWuRLzazVH/5plQFCIl+mzusdohu8OvQ9GJt28xEqzETzcn9s2aLWHhoxctRFkPRSDsYf9rLzbkfCoRe2Ttk8u4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707780757; c=relaxed/simple; bh=N37XfCaS7bdcPg0qDrwSRW/oJljCUpgb2fdACke0c00=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=audKgeifA6zhL3cOn6x/Z8pJMmJU7erT5BJUwby6tL2xp1dwnbgjmbLsw5j4H/oje3r40OCAFCS1sdhRLZ9ku+5gyIuST5dQxM9dPBYOPkwxsg/F5X0/KWb0UtkDIW7B8+PyY8H94LcTP7zbZH206zttFesJ85ft8O1Gj9Ql6ks= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=uvKfARnI; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="uvKfARnI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C3713C433F1; Mon, 12 Feb 2024 23:32:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1707780756; bh=N37XfCaS7bdcPg0qDrwSRW/oJljCUpgb2fdACke0c00=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uvKfARnINcSypFMgI2SHm390tl3enQgUYFcDYSrdjaNAaB4jtluKuXA2g4o1qpzMW itXFj7oXgWP3sKqaW+CEDmurtQCMq9mj+rG1QuQZmgXl6yCPlDyxlAMDapjv9Krnyk ThdTKGHuDFwE9OL9lVIbzB7h1hDKIPY3nA9pOB4Pr1R/NB1fRn7tTBuFcHFYyjTRlO CVeEUJmvM8JwCnhxtA1wn4V2h89dqpWfEQ9hswqd8+PbC3fW5UPWdmBu/PboEXalwf z4RACQUM/6fuy3t5FTGCpPMLbqRvRk4ZyIuAIciMgRRaf0nt6BUodfm9htzf22oFs5 p6aA/29VfJ+OQ== From: Andrii Nakryiko To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, martin.lau@kernel.org Cc: andrii@kernel.org, kernel-team@meta.com Subject: [PATCH v2 bpf-next 4/4] selftests/bpf: add anonymous user struct as global subprog arg test Date: Mon, 12 Feb 2024 15:32:21 -0800 Message-Id: <20240212233221.2575350-5-andrii@kernel.org> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20240212233221.2575350-1-andrii@kernel.org> References: <20240212233221.2575350-1-andrii@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Add tests validating that kernel handles pointer to anonymous struct argument as PTR_TO_MEM case, not as PTR_TO_CTX case. Signed-off-by: Andrii Nakryiko --- .../bpf/progs/verifier_global_subprogs.c | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c b/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c index 67dddd941891..baff5ffe9405 100644 --- a/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c +++ b/tools/testing/selftests/bpf/progs/verifier_global_subprogs.c @@ -115,6 +115,35 @@ int arg_tag_nullable_ptr_fail(void *ctx) return subprog_nullable_ptr_bad(&x); } +typedef struct { + int x; +} user_struct_t; + +__noinline __weak int subprog_user_anon_mem(user_struct_t *t) +{ + return t ? t->x : 0; +} + +SEC("?tracepoint") +__failure __log_level(2) +__msg("invalid bpf_context access") +__msg("Caller passes invalid args into func#1 ('subprog_user_anon_mem')") +int anon_user_mem_invalid(void *ctx) +{ + /* can't pass PTR_TO_CTX as user memory */ + return subprog_user_anon_mem(ctx); +} + +SEC("?tracepoint") +__success __log_level(2) +__msg("Func#1 ('subprog_user_anon_mem') is safe for any args that match its prototype") +int anon_user_mem_valid(void *ctx) +{ + user_struct_t t = { .x = 42 }; + + return subprog_user_anon_mem(&t); +} + __noinline __weak int subprog_nonnull_ptr_good(int *p1 __arg_nonnull, int *p2 __arg_nonnull) { return (*p1) * (*p2); /* good, no need for NULL checks */