From patchwork Mon Oct 23 16:03:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Song Liu X-Patchwork-Id: 13433101 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 059F51CA96; Mon, 23 Oct 2023 16:04:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="emogXKV6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4836EC433C7; Mon, 23 Oct 2023 16:04:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698077044; bh=0LBNy4jEmP3QOJLS/v9sSKJshgRUg6NsdZQVstUHGPY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=emogXKV6GbYRdSu1N+OovH3lb2oAUmm/F3dQ3CeIiorOls+O7tYeqryO0XAYDFku8 nwiJRAOljnwXYkcisOmhWwUwP7fq+asxjEacrsnVL8noshRJCTaFnjhMaoFH9OtuuI v8FbGho9/604nl67Qq+zjLaw1Kx19qRxdMMuD58S2o5VBG2QcwI41WvIhGDktca4cf PAsErxf9iXX9SAIGlDBX/iEDWzOrfjLZ3WFMQumydl/e9p+6wyk4hm6Ccg+YTw8pVx PnZnVzwhkzyza5wL7Y8Zu5fJGLwfmAuaVEbvWCnD/t0qWDwV6MhBBH9yAUfNoZCmmV D0pai9pzXukJw== From: Song Liu To: bpf@vger.kernel.org, fsverity@lists.linux.dev Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org, martin.lau@kernel.org, kernel-team@meta.com, ebiggers@kernel.org, tytso@mit.edu, roberto.sassu@huaweicloud.com, Song Liu Subject: [PATCH v3 bpf-next 2/9] bpf: Factor out helper check_reg_const_str() Date: Mon, 23 Oct 2023 09:03:42 -0700 Message-Id: <20231023160349.4161154-3-song@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231023160349.4161154-1-song@kernel.org> References: <20231023160349.4161154-1-song@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 This helper will be used to check whether a kfunc arg points to const string. Add a type check (PTR_TO_MAP_VALUE) in case the helper is misused in the future. Signed-off-by: Song Liu --- kernel/bpf/verifier.c | 85 +++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index e9bc5d4a25a1..6ce5f0fbad84 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -8265,6 +8265,54 @@ static enum bpf_dynptr_type dynptr_get_type(struct bpf_verifier_env *env, return state->stack[spi].spilled_ptr.dynptr.type; } +static int check_reg_const_str(struct bpf_verifier_env *env, + struct bpf_reg_state *reg, u32 regno) +{ + struct bpf_map *map = reg->map_ptr; + int err; + int map_off; + u64 map_addr; + char *str_ptr; + + if (WARN_ON_ONCE(reg->type != PTR_TO_MAP_VALUE)) + return -EINVAL; + + if (!bpf_map_is_rdonly(map)) { + verbose(env, "R%d does not point to a readonly map'\n", regno); + return -EACCES; + } + + if (!tnum_is_const(reg->var_off)) { + verbose(env, "R%d is not a constant address'\n", regno); + return -EACCES; + } + + if (!map->ops->map_direct_value_addr) { + verbose(env, "no direct value access support for this map type\n"); + return -EACCES; + } + + err = check_map_access(env, regno, reg->off, + map->value_size - reg->off, false, + ACCESS_HELPER); + if (err) + return err; + + map_off = reg->off + reg->var_off.value; + err = map->ops->map_direct_value_addr(map, &map_addr, map_off); + if (err) { + verbose(env, "direct value access on string failed\n"); + return err; + } + + str_ptr = (char *)(long)(map_addr); + if (!strnchr(str_ptr + map_off, map->value_size - map_off, 0)) { + verbose(env, "string is not zero-terminated\n"); + return -EINVAL; + } + return 0; +} + static int check_func_arg(struct bpf_verifier_env *env, u32 arg, struct bpf_call_arg_meta *meta, const struct bpf_func_proto *fn, @@ -8509,44 +8557,9 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg, } case ARG_PTR_TO_CONST_STR: { - struct bpf_map *map = reg->map_ptr; - int map_off; - u64 map_addr; - char *str_ptr; - - if (!bpf_map_is_rdonly(map)) { - verbose(env, "R%d does not point to a readonly map'\n", regno); - return -EACCES; - } - - if (!tnum_is_const(reg->var_off)) { - verbose(env, "R%d is not a constant address'\n", regno); - return -EACCES; - } - - if (!map->ops->map_direct_value_addr) { - verbose(env, "no direct value access support for this map type\n"); - return -EACCES; - } - - err = check_map_access(env, regno, reg->off, - map->value_size - reg->off, false, - ACCESS_HELPER); + err = check_reg_const_str(env, reg, regno); if (err) return err; - - map_off = reg->off + reg->var_off.value; - err = map->ops->map_direct_value_addr(map, &map_addr, map_off); - if (err) { - verbose(env, "direct value access on string failed\n"); - return err; - } - - str_ptr = (char *)(long)(map_addr); - if (!strnchr(str_ptr + map_off, map->value_size - map_off, 0)) { - verbose(env, "string is not zero-terminated\n"); - return -EINVAL; - } break; } case ARG_PTR_TO_KPTR: