Received: by 2002:a05:6a10:9e8c:0:0:0:0 with SMTP id y12csp632944pxx; Mon, 26 Oct 2020 17:33:19 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy3wUT9NqLvnrvX26SsO6qb+3gG2sW/V7DM/53arJPrYcbjykW7Vi89LzrV3bGU6ytzry95 X-Received: by 2002:a05:6402:945:: with SMTP id h5mr18796137edz.6.1603758799595; Mon, 26 Oct 2020 17:33:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1603758799; cv=none; d=google.com; s=arc-20160816; b=JiyTDsAonQVwbC1GDJArLBbNS8BOS9xqzMfgXcPRSriiHFT0A0Cl/XT50rNoIp1J/P JkQHF1bilBwWuTR3eKNE/rCJRbM6OA+8uhgKKXbKFXaTNQuJHvwIVqlm+IeiN03kjs59 BeP9p2l5o4bT7An6ZoV29OlYNuQflbhqgZ0Hhrfbt4LBkmNALMs1D4hpKjj3f9+7O2yH /40e0qpjbLPOYvEocpxmiXBjqbw30ZPC3C4AcBaTjTpfPS0sdQYLROxxwU1hiFx1tcQ3 CT5TZR7LEpVU4a/o/pq9BqdXwwew1FgEPvw4RD68I0A1b7v4zyXYqpl8V8Tx4xjm4A2z kmyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=iA/hSLJXkWf8y0irnNMmY/tjJhPpsRRHR04Ny5kfqvo=; b=gjzTT8uIGtfCGGh3ttvTfBpBaKMnN09fgfF3aZXI/smS/h+0J5Qdy2VQrk95d+4y72 3UK41xSk5eS3goCs0BbI1Y2T7aYmlCOUL6oSUNQUd15FwGqIhfKMgz8iP2imNZmH9f5y PVPaNBSxShHQ5fM0WXFVEXsa/W4luoPZgbkksLKxYPbFIlOPIqlIvSLeWaixZTXZPgoa Q4sJt96dABeXGf0COwc1mWCzq3twmoVxmOpVp9mLgCH3irhYjqZ9GElhpa3W25+3SY1O Hm09ywi8fkLH5Injelht83kkvFHO5epWCxp5RApDAaB66u15HgadziEG860y+1DaC+aJ 5npQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="l1x/CFUH"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id h8si10217368ejj.512.2020.10.26.17.32.57; Mon, 26 Oct 2020 17:33:19 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="l1x/CFUH"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2441173AbgJ0AVW (ORCPT + 99 others); Mon, 26 Oct 2020 20:21:22 -0400 Received: from mail.kernel.org ([198.145.29.99]:34892 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2411006AbgJZXz5 (ORCPT ); Mon, 26 Oct 2020 19:55:57 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 63C7420B1F; Mon, 26 Oct 2020 23:55:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603756556; bh=G3kHGiJ0JFFbiwJJgYNWGLgRs+nYMiXmevdZJzjgM9E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=l1x/CFUHO1NOQU75MLr0WUIy4a0+ZnH+JkePJ8oxsGAPmhVbgEOav8E0laliP7AUl HtIqcmec2UqWkatl4iYt43dIZJ66FXlg0y9mnrWrjXmqCRUFYA1zUrIMjuw92ZMRpe Kfk3SRZedwjazYPkzqU9AOmj6xEDvDqZl1WCAZfY= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Yonghong Song , Alexei Starovoitov , Andrii Nakryiko , Sasha Levin , netdev@vger.kernel.org, bpf@vger.kernel.org, clang-built-linux@googlegroups.com Subject: [PATCH AUTOSEL 5.4 32/80] bpf: Permit map_ptr arithmetic with opcode add and offset 0 Date: Mon, 26 Oct 2020 19:54:28 -0400 Message-Id: <20201026235516.1025100-32-sashal@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201026235516.1025100-1-sashal@kernel.org> References: <20201026235516.1025100-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Yonghong Song [ Upstream commit 7c6967326267bd5c0dded0a99541357d70dd11ac ] Commit 41c48f3a98231 ("bpf: Support access to bpf map fields") added support to access map fields with CORE support. For example, struct bpf_map { __u32 max_entries; } __attribute__((preserve_access_index)); struct bpf_array { struct bpf_map map; __u32 elem_size; } __attribute__((preserve_access_index)); struct { __uint(type, BPF_MAP_TYPE_ARRAY); __uint(max_entries, 4); __type(key, __u32); __type(value, __u32); } m_array SEC(".maps"); SEC("cgroup_skb/egress") int cg_skb(void *ctx) { struct bpf_array *array = (struct bpf_array *)&m_array; /* .. array->map.max_entries .. */ } In kernel, bpf_htab has similar structure, struct bpf_htab { struct bpf_map map; ... } In the above cg_skb(), to access array->map.max_entries, with CORE, the clang will generate two builtin's. base = &m_array; /* access array.map */ map_addr = __builtin_preserve_struct_access_info(base, 0, 0); /* access array.map.max_entries */ max_entries_addr = __builtin_preserve_struct_access_info(map_addr, 0, 0); max_entries = *max_entries_addr; In the current llvm, if two builtin's are in the same function or in the same function after inlining, the compiler is smart enough to chain them together and generates like below: base = &m_array; max_entries = *(base + reloc_offset); /* reloc_offset = 0 in this case */ and we are fine. But if we force no inlining for one of functions in test_map_ptr() selftest, e.g., check_default(), the above two __builtin_preserve_* will be in two different functions. In this case, we will have code like: func check_hash(): reloc_offset_map = 0; base = &m_array; map_base = base + reloc_offset_map; check_default(map_base, ...) func check_default(map_base, ...): max_entries = *(map_base + reloc_offset_max_entries); In kernel, map_ptr (CONST_PTR_TO_MAP) does not allow any arithmetic. The above "map_base = base + reloc_offset_map" will trigger a verifier failure. ; VERIFY(check_default(&hash->map, map)); 0: (18) r7 = 0xffffb4fe8018a004 2: (b4) w1 = 110 3: (63) *(u32 *)(r7 +0) = r1 R1_w=invP110 R7_w=map_value(id=0,off=4,ks=4,vs=8,imm=0) R10=fp0 ; VERIFY_TYPE(BPF_MAP_TYPE_HASH, check_hash); 4: (18) r1 = 0xffffb4fe8018a000 6: (b4) w2 = 1 7: (63) *(u32 *)(r1 +0) = r2 R1_w=map_value(id=0,off=0,ks=4,vs=8,imm=0) R2_w=invP1 R7_w=map_value(id=0,off=4,ks=4,vs=8,imm=0) R10=fp0 8: (b7) r2 = 0 9: (18) r8 = 0xffff90bcb500c000 11: (18) r1 = 0xffff90bcb500c000 13: (0f) r1 += r2 R1 pointer arithmetic on map_ptr prohibited To fix the issue, let us permit map_ptr + 0 arithmetic which will result in exactly the same map_ptr. Signed-off-by: Yonghong Song Signed-off-by: Alexei Starovoitov Acked-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20200908175702.2463625-1-yhs@fb.com Signed-off-by: Sasha Levin --- kernel/bpf/verifier.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index ae27dd77a73cb..bd0a5ead2af0c 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -4398,6 +4398,10 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, dst, reg_type_str[ptr_reg->type]); return -EACCES; case CONST_PTR_TO_MAP: + /* smin_val represents the known value */ + if (known && smin_val == 0 && opcode == BPF_ADD) + break; + /* fall-through */ case PTR_TO_PACKET_END: case PTR_TO_SOCKET: case PTR_TO_SOCKET_OR_NULL: -- 2.25.1