From patchwork Fri Aug 16 19:12:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13766776 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-yw1-f180.google.com (mail-yw1-f180.google.com [209.85.128.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E8C631C0DC5 for ; Fri, 16 Aug 2024 19:12:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723835541; cv=none; b=jdx5RKVCtdcf13s0Wvjw2/MqJDeCRyXOPMhB+2cyD5w+/OC8mbVmcJiRiPKdKozZqiyjzYJZx5NduKW4S89fW9vOkyeflJ5AKVDe2JgzyuIypKXLeCTwnUvZNoDNGZnk36laTfGyxTxdfpm68zK8GCmP6ZUaQbl/veT8OWx9WHs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723835541; c=relaxed/simple; bh=6uguzTwBipT1pGt4iZ9oV71qd0fpV8tMOJjn79NSbc8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Nq6ELS8Y071y3r8XHz7RbT3bGHE0ODSG7e+XFmqGOQjeFiDu5RgD3Z3G5TtP/+KZGFfsa/JjNpWSg0DoZ2aJZbnBbnmatDmy+CIEMORpFiODKp4cVdYHvQTHmyW335zt43Vv45p0OhCqSa5TBkFBF7xSqmODXozMAD8LsN+auZ0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=agLmOfbi; arc=none smtp.client-ip=209.85.128.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="agLmOfbi" Received: by mail-yw1-f180.google.com with SMTP id 00721157ae682-691c85525ebso21771977b3.0 for ; Fri, 16 Aug 2024 12:12:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723835539; x=1724440339; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=B4W3sp2O8bZa06ldyNi6Xkm8a0QLS7BrI4ar8WNRouE=; b=agLmOfbiyGviHVGqiUS/gaqCTWMZ99AexdqOsvSXBqGMHcBAyY4kbldEQRQxAy0XaV f2cEcbQmq2gyec/eLV1SKEGvH+6+VuW/bpULaykzAfpdPhCj037m7BcwEGwio7rsWzFK b8b0dSnBGLQUsNVDZis+iUBetmR+8gShC+R3O0c1d6/rUx7iQKHEuq1VQsDLnL41LAH7 xw8213rtBLYAJXZiI6u4iL8f9WsBngKQGDXpCsAdqWgc76AhSNmwHj+rRqr/OBkJ40Pl c49EsGUxbAWw0e1pmn8ayvr6r30aXGdTfDpIdhNM126NTufYE7cAH5FJaqt/ONea/BMD ozwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723835539; x=1724440339; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=B4W3sp2O8bZa06ldyNi6Xkm8a0QLS7BrI4ar8WNRouE=; b=xTS99aEMHhIL5/SHpB59ppQowAkyUa3lJ9AW6iQm7PKRlWYCVd3u6R98N6a57wIDAh 8UZb8gGpCt8ZaaUx+M/qkVG8DoUkt3xZqJu1lY5SPVwov+OF2Bnp0Bi4sNNTq9XRx+4v uW7nNKTtQOpVZJeq8WZE+4+JQ4rRZsmk92J+BGJUGlBkKvMNhMb2zHISh6KuFafY0PfS i0xtkwuQ881NqmUBAl2BWwyCBeoQme7QYFrk1ZP0OZDrIHhR0iAk6JWlLkvbLhgwaES2 TFfM/LILnSJdTu55GXypyuA7xSofDCbSoAqZECx2OGR20/i16RmqVFEkyNjIf4C+hJ0U a2yA== X-Gm-Message-State: AOJu0YxypRJXPxuqzv/WzYOmBpbq/hkskah7qNsNkljnFFmTJj2dHzUJ ap4lO0i0yPBl6E8ycwE5S3a+KOQd3LztVpKrive/ZL8Bvj0lXzRkEseEEKe+ X-Google-Smtp-Source: AGHT+IFH+nD0eKEMowN01UBhS8kXcuXYok70WwpicjgrHW4yiUDaCX8Aupl1o03bGMwY2MkHno/1ew== X-Received: by 2002:a05:690c:ec5:b0:62c:e6c0:e887 with SMTP id 00721157ae682-6b1b9b5aba8mr45138867b3.9.1723835538781; Fri, 16 Aug 2024 12:12:18 -0700 (PDT) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:ca12:c8db:5571:aa13]) by smtp.gmail.com with ESMTPSA id 00721157ae682-6af9cd7a50dsm7233327b3.94.2024.08.16.12.12.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2024 12:12:18 -0700 (PDT) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, andrii@kernel.org Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [RFC bpf-next v4 1/6] bpf: define BPF_UPTR a new enumerator of btf_field_type. Date: Fri, 16 Aug 2024 12:12:08 -0700 Message-Id: <20240816191213.35573-2-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240816191213.35573-1-thinker.li@gmail.com> References: <20240816191213.35573-1-thinker.li@gmail.com> 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 X-Patchwork-State: RFC Define BPF_UPTR, and modify functions that describe attributes of a field type. Signed-off-by: Kui-Feng Lee --- include/linux/bpf.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 9f35df07e86d..954e476b5605 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -203,6 +203,7 @@ enum btf_field_type { BPF_GRAPH_ROOT = BPF_RB_ROOT | BPF_LIST_HEAD, BPF_REFCOUNT = (1 << 9), BPF_WORKQUEUE = (1 << 10), + BPF_UPTR = (1 << 11), }; typedef void (*btf_dtor_kfunc_t)(void *); @@ -322,6 +323,8 @@ static inline const char *btf_field_type_name(enum btf_field_type type) return "kptr"; case BPF_KPTR_PERCPU: return "percpu_kptr"; + case BPF_UPTR: + return "uptr"; case BPF_LIST_HEAD: return "bpf_list_head"; case BPF_LIST_NODE: @@ -350,6 +353,7 @@ static inline u32 btf_field_type_size(enum btf_field_type type) case BPF_KPTR_UNREF: case BPF_KPTR_REF: case BPF_KPTR_PERCPU: + case BPF_UPTR: return sizeof(u64); case BPF_LIST_HEAD: return sizeof(struct bpf_list_head); @@ -379,6 +383,7 @@ static inline u32 btf_field_type_align(enum btf_field_type type) case BPF_KPTR_UNREF: case BPF_KPTR_REF: case BPF_KPTR_PERCPU: + case BPF_UPTR: return __alignof__(u64); case BPF_LIST_HEAD: return __alignof__(struct bpf_list_head); @@ -419,6 +424,7 @@ static inline void bpf_obj_init_field(const struct btf_field *field, void *addr) case BPF_KPTR_UNREF: case BPF_KPTR_REF: case BPF_KPTR_PERCPU: + case BPF_UPTR: break; default: WARN_ON_ONCE(1); From patchwork Fri Aug 16 19:12:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13766777 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-yw1-f174.google.com (mail-yw1-f174.google.com [209.85.128.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E40F31C2301 for ; Fri, 16 Aug 2024 19:12:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723835542; cv=none; b=prAPjYWswbHh1Lk3119R472qkJP+C1C2ArPAurqqz5Rlzm7JJRRXnU7vNORbd93GzbKrcqoB50bf6d7s0RL8DANjnJcjWCTF0gSKHIIa3bIkEUapfkpnwU+5i/jRcUAUbugebevXdgFJcXnbz6v+p5sCzVRr7FHGAT+yBVj9tDM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723835542; c=relaxed/simple; bh=LFmhqp7CM4KZmy4pBG8PtYOoX+RcQCP0uI3faYP4vs8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XXxHDm7Au4aJvkQP+QjIc2Q8/FGmBZ/4BSWfCWdRyuPvsBOOjk0EiIK20Aobot5Hz4ZQwwEW6nySW1bNm9JOvSAbzhH4kMWA4ls8mCd/Dlu3iC+uz4QXxiwsw5WXUvRilSd9MScVaxlM5eohPWPqZrU/+xlGLcnpzP9mYD6ImD0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=mC77JxIQ; arc=none smtp.client-ip=209.85.128.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="mC77JxIQ" Received: by mail-yw1-f174.google.com with SMTP id 00721157ae682-690b6cbce11so22597967b3.2 for ; Fri, 16 Aug 2024 12:12:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723835540; x=1724440340; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0jgepIhK5T8DMdWFDinGBiig4lDcTk0a45QhOnxHlkE=; b=mC77JxIQG8owl2izBXlsq7nEC3cNnJVG6MrcQD13r+J97h+j4ZNed58VzTgu0w0sLa Kqf3/mBY/Z9WosjuVSeDOAGQ87DZUSpCQZTipZHwB3vm+MX18a8xkMt8Evj44k5EUt7X skdUcqPzN+itIVZ8wqhw5k5V16DGVEbpQ3aq7t9FFQ11PtOsJoT9Kkia3ZXS99J9CB5U 2ry9IhPvnx0Mrf45WMZjyE7/fECNfSuHdC+kUAWz8h+mZADA2dSQZ78bNiRVzA7cIr+R ehAZ5a8CCXBz2TJ6NpNIwUKPBTgxXqJd4AocyVERYyJcyNzhvCWH2ZoGpHcJiiNEO/pz /Y6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723835540; x=1724440340; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0jgepIhK5T8DMdWFDinGBiig4lDcTk0a45QhOnxHlkE=; b=CGyFf4IQtUMrZh0GBvC641Bhp6CIiPRlLz0WfF4bduSWu/QvKqDYAJHP7EKvCmgcou hzZ5PisUKgqUL7a2idFTRMIYKYwclGpr3PguJdxlqayxpZm3C18QkvfME3fqIL5Q7fjV ruGUHz9EglWp76GBuD5S8lmPTu7+inp9/ruz4t+PjW3vNEiXgP08I3zkNZ7IXTvya1MA tNZnJzywHbz4IgKzrUYs5f1KNxUe+hIs8NcIIYBnbvlRXRhP3JDqwD9SUpOk9ES5Ly7l NMJsnGm7zTmmWqlP1W3OSY9nNqKt0qids/AYlxD7OHCZSwwVCs2JkGJBPTI8snRCJR/1 mq5A== X-Gm-Message-State: AOJu0YwrDXOLmvKB4ysj6IVC32F6avtf0uSdYR/WvtdTAem3pNSavRj+ VsC5gVQ2A0hyVPU92T2IfH+/UYEC42wxzNfcY5LU3keZ57uCktQZGmbixJG2 X-Google-Smtp-Source: AGHT+IHtIqBNhhNwagwYfVVCktw9YS3NkW9kWbfh/umLl+MSUR3PYWK/w7x3Qoj70Jeai3ORR/watg== X-Received: by 2002:a05:690c:5811:b0:6ad:219a:b687 with SMTP id 00721157ae682-6b1bcf8ec90mr33110177b3.39.1723835539718; Fri, 16 Aug 2024 12:12:19 -0700 (PDT) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:ca12:c8db:5571:aa13]) by smtp.gmail.com with ESMTPSA id 00721157ae682-6af9cd7a50dsm7233327b3.94.2024.08.16.12.12.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2024 12:12:19 -0700 (PDT) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, andrii@kernel.org Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [RFC bpf-next v4 2/6] bpf: Parse and support "uptr" tag. Date: Fri, 16 Aug 2024 12:12:09 -0700 Message-Id: <20240816191213.35573-3-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240816191213.35573-1-thinker.li@gmail.com> References: <20240816191213.35573-1-thinker.li@gmail.com> 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 X-Patchwork-State: RFC Parse "uptr" tag from BTF, map it to BPF_UPTR, and support it in related functions. "uptr" tag is used to annotate a field in a struct type is a uptr, which is used to share a block memory between user programs and BPF programs. Signed-off-by: Kui-Feng Lee --- kernel/bpf/btf.c | 5 +++++ kernel/bpf/syscall.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index ab3c9f592c9f..f61bad288385 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -3356,6 +3356,8 @@ static int btf_find_kptr(const struct btf *btf, const struct btf_type *t, type = BPF_KPTR_REF; else if (!strcmp("percpu_kptr", __btf_name_by_offset(btf, t->name_off))) type = BPF_KPTR_PERCPU; + else if (!strcmp("uptr", __btf_name_by_offset(btf, t->name_off))) + type = BPF_UPTR; else return -EINVAL; @@ -3533,6 +3535,7 @@ static int btf_repeat_fields(struct btf_field_info *info, case BPF_KPTR_UNREF: case BPF_KPTR_REF: case BPF_KPTR_PERCPU: + case BPF_UPTR: case BPF_LIST_HEAD: case BPF_RB_ROOT: break; @@ -3659,6 +3662,7 @@ static int btf_find_field_one(const struct btf *btf, case BPF_KPTR_UNREF: case BPF_KPTR_REF: case BPF_KPTR_PERCPU: + case BPF_UPTR: ret = btf_find_kptr(btf, var_type, off, sz, info_cnt ? &info[0] : &tmp); if (ret < 0) @@ -3983,6 +3987,7 @@ struct btf_record *btf_parse_fields(const struct btf *btf, const struct btf_type case BPF_KPTR_UNREF: case BPF_KPTR_REF: case BPF_KPTR_PERCPU: + case BPF_UPTR: ret = btf_parse_kptr(btf, &rec->fields[i], &info_arr[i]); if (ret < 0) goto end; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 65dcd92d0b2c..fed4a2145f81 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -548,6 +548,7 @@ void btf_record_free(struct btf_record *rec) case BPF_KPTR_UNREF: case BPF_KPTR_REF: case BPF_KPTR_PERCPU: + case BPF_UPTR: if (rec->fields[i].kptr.module) module_put(rec->fields[i].kptr.module); btf_put(rec->fields[i].kptr.btf); @@ -596,6 +597,7 @@ struct btf_record *btf_record_dup(const struct btf_record *rec) case BPF_KPTR_UNREF: case BPF_KPTR_REF: case BPF_KPTR_PERCPU: + case BPF_UPTR: btf_get(fields[i].kptr.btf); if (fields[i].kptr.module && !try_module_get(fields[i].kptr.module)) { ret = -ENXIO; From patchwork Fri Aug 16 19:12:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13766778 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-yb1-f171.google.com (mail-yb1-f171.google.com [209.85.219.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB51F1C3F25 for ; Fri, 16 Aug 2024 19:12:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723835543; cv=none; b=YloLQwj6OSjY5QDTeaP0CxsoL0V70psGzeNCQmEj4xvaacR73DagTslXdcAi6uOzyoJS6CAfehx6YqlGDuWo4OUFBwORoVrYBUAaGXVcCFmRBkQzOK6ttGZpLhQ0vp+R9Zpt7YQ69e8asgoSwq7f6X3FrZLO2bm5EfUJDS0V4z0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723835543; c=relaxed/simple; bh=2kOtRv7qB6Foh6TYAjMuRKyqQS09rtUXbv1HfzFhBpI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZO4RxPXjI50D5uuQ3/c3pHH4GphA0nRtb4atv7oiIgxsaP4ib/ki6a+ZakSXV7VoY917/27hc/1JVmrzwZPGag+DeEsCHbNEKPjwYWGDvucmrAnk3LRhx2BUNz+3wSw1AV+JDUfEYBPFVrCYGQULt8WSqV3fX3Mj0nQBrY/kDl8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bag+R0T3; arc=none smtp.client-ip=209.85.219.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bag+R0T3" Received: by mail-yb1-f171.google.com with SMTP id 3f1490d57ef6-e116d2f5f7fso1746657276.1 for ; Fri, 16 Aug 2024 12:12:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723835541; x=1724440341; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=yQuSW7ZjyolAixejdxlo5ouKzCwC+WVNTWhjPrUWT8U=; b=bag+R0T3fUtQWsJGqKdjEf5R6mkh29Y0zRbQYD5mMmIDbwf6hvg4HSeyIzhTaIjBc9 uS0eKw4eMjVMec4to9PaSkXi8NbaGchFTUYHbmHmMFC7CHBpfdvQC9qZO01CPsxFe3cf Z5xCeviOGYnqa9p95BPRtOpr5Qp+v/52im/GvXKm55nMeurU2BYRrCce8mOa+E2ubDuX 8VPj7QPl/rBeO7FVMlxQyyW1nFJ5X5lvJYFMSeOeP7caRBczk1QKdpSv6arx16Dn+2gh IpCTpYdllrVMvs6VL7bY8VtQ17UvdH2sbwq7BmOGQJp7RGIxscQ2V6lVJj0kq8CRCrJj WVVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723835541; x=1724440341; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=yQuSW7ZjyolAixejdxlo5ouKzCwC+WVNTWhjPrUWT8U=; b=DapNG6rBcw1vtVj8wE974bYmcFuE3VlGyHkkpJLLyB+vkmn3qz/Ym5CthdFO6JvfFT OL0Oei1Td2YV0iO0H+yWExeHpdm9+P38eiexS1G7PpjVQeUyxzkavw3ENnoqhSI4OEUe /nnfdihx8joMK4XZ+O2yD8xot7teNeiuibvzsScnpm5n4kH450o/5bgH7loYT/CT5NbO 9qGs88Qr1MMrJZCJIsgbbqrcfMkVihDBWj60kIe0yXxBCi3LjIXiYK6mZbV+pmsinAk5 R59iVCpQ1LcrnT77ZE+bvrca22bKJL0WGT9KI4cPdSfLwgVRaqbjNcROwVd3QqYkDbKq iLfg== X-Gm-Message-State: AOJu0YwiDzRQvLXn6P8shJnKofnRrZljBZNFpbziLmRQ6z325XtOqSyx qPqRfF4m2OMVKZi96PXWDUSr36H3qKEOIgON7YaYsbw6AyomPsW3iREJvkfz X-Google-Smtp-Source: AGHT+IEkfPIIznB4Ydy8J38+Y8OkTy3lpGHmET5INtt6TQ3VnufN5MXtb1mge7HcLwtBjmvvg6YOYA== X-Received: by 2002:a05:690c:318d:b0:6ac:3043:168a with SMTP id 00721157ae682-6b1eef8240cmr24740727b3.10.1723835540775; Fri, 16 Aug 2024 12:12:20 -0700 (PDT) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:ca12:c8db:5571:aa13]) by smtp.gmail.com with ESMTPSA id 00721157ae682-6af9cd7a50dsm7233327b3.94.2024.08.16.12.12.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2024 12:12:20 -0700 (PDT) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, andrii@kernel.org Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [RFC bpf-next v4 3/6] bpf: Handle BPF_UPTR in verifier. Date: Fri, 16 Aug 2024 12:12:10 -0700 Message-Id: <20240816191213.35573-4-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240816191213.35573-1-thinker.li@gmail.com> References: <20240816191213.35573-1-thinker.li@gmail.com> 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 X-Patchwork-State: RFC Give PTR_TO_MEM | PTR_MAYBE_NULL to the memory pointed by an uptr with the size of the pointed type to make them readable and writable. Signed-off-by: Kui-Feng Lee --- kernel/bpf/verifier.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index e3932f8ce10a..5bc5b37b63cc 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5340,6 +5340,10 @@ static int map_kptr_match_type(struct bpf_verifier_env *env, int perm_flags; const char *reg_name = ""; + if (kptr_field->type == BPF_UPTR) + /* BPF programs should not change any user kptr */ + return -EACCES; + if (btf_is_kernel(reg->btf)) { perm_flags = PTR_MAYBE_NULL | PTR_TRUSTED | MEM_RCU; @@ -5488,6 +5492,29 @@ static u32 btf_ld_kptr_type(struct bpf_verifier_env *env, struct btf_field *kptr return ret; } +static int mark_uptr_ld_reg(struct bpf_verifier_env *env, u32 regno, + struct btf_field *field) +{ + struct bpf_reg_state *val_reg; + const struct btf_type *t; + u32 type_id, tsz; + + val_reg = reg_state(env, regno); + type_id = field->kptr.btf_id; + t = btf_type_id_size(field->kptr.btf, &type_id, &tsz); + if (!t) { + verbose(env, "The type of uptr is invalid"); + return -EACCES; + } + + mark_reg_known_zero(env, cur_regs(env), regno); + val_reg->type = PTR_TO_MEM | PTR_MAYBE_NULL; + val_reg->mem_size = tsz; + val_reg->id = ++env->id_gen; + + return 0; +} + static int check_map_kptr_access(struct bpf_verifier_env *env, u32 regno, int value_regno, int insn_idx, struct btf_field *kptr_field) @@ -5516,9 +5543,16 @@ static int check_map_kptr_access(struct bpf_verifier_env *env, u32 regno, verbose(env, "store to referenced kptr disallowed\n"); return -EACCES; } + if (class != BPF_LDX && kptr_field->type == BPF_UPTR) { + verbose(env, "store to uptr disallowed\n"); + return -EACCES; + } if (class == BPF_LDX) { val_reg = reg_state(env, value_regno); + if (kptr_field->type == BPF_UPTR) + return mark_uptr_ld_reg(env, value_regno, kptr_field); + /* We can simply mark the value_regno receiving the pointer * value from map as PTR_TO_BTF_ID, with the correct type. */ @@ -5576,6 +5610,7 @@ static int check_map_access(struct bpf_verifier_env *env, u32 regno, case BPF_KPTR_UNREF: case BPF_KPTR_REF: case BPF_KPTR_PERCPU: + case BPF_UPTR: if (src != ACCESS_DIRECT) { verbose(env, "kptr cannot be accessed indirectly by helper\n"); return -EACCES; @@ -6956,7 +6991,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn return err; if (tnum_is_const(reg->var_off)) kptr_field = btf_record_find(reg->map_ptr->record, - off + reg->var_off.value, BPF_KPTR); + off + reg->var_off.value, BPF_KPTR | BPF_UPTR); if (kptr_field) { err = check_map_kptr_access(env, regno, value_regno, insn_idx, kptr_field); } else if (t == BPF_READ && value_regno >= 0) { From patchwork Fri Aug 16 19:12:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13766779 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-yw1-f174.google.com (mail-yw1-f174.google.com [209.85.128.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F253A1C3F34 for ; Fri, 16 Aug 2024 19:12:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723835544; cv=none; b=PnRiRygmRYWKO4dmA+AuUHP6AKq7LNbVdMUJsYuGcMaT1FGav10sqUUwnQ5QF3rwmeEz56H+4XhrL3ICYbuYPKMj4UwOMNgRk3B+90g2FhLv1mOvyXCOOMV+QSsEsed6Eoyqa2rJl2UTtGu5ZO5lxUHQ/SLyFK+EyF7FHrCwAJg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723835544; c=relaxed/simple; bh=8OfILoANnlA4uWJ3TonOkQifBlaYhK4kGVLvAMy/JGI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=hZIlJoDBHSGcd2igXDP+1bBdi25mtTNpLvLRg0RiQ3Pkr0vChQSXiHL+LmZq03frttyJxO3tBlByiX8gRMbhPmZXlo+CiDG6v4h2N0JB3x8WCO6g5GX7xXUuzbrE13ahGc8Rdp3qNt7Fi4Oh53lC2X/Q6LBhEeNTCs/G080yn/4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=FDYFuVMb; arc=none smtp.client-ip=209.85.128.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FDYFuVMb" Received: by mail-yw1-f174.google.com with SMTP id 00721157ae682-66c7aeac627so26274837b3.1 for ; Fri, 16 Aug 2024 12:12:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723835542; x=1724440342; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=C/I8iBRqpMYf74wgXxhVFGCiJEuxAMdQwnIxNEYMw1s=; b=FDYFuVMbm+zMS+vh9tLkp5MZ7NSVTmfQx01v1V0W5VJ5KKt2We4sih7RePEZK5kPvE Vt9KLkUAs1rcchAcYYVHKyOlGJEfZMvTRCWHeOGBl54FaBhSbsTinoefgihArUUthheA QkTlFiA8ALsCu/tbcR0w1e60hOK0wt3vok6d/jCjtoPPC5Us9ubT6mnq1LNVfpM1dWOD 45nUVycaX0aelrDr5H5WFot2kuXcKwpys0qbNH3rXfKIq9aFrUs7Cd+piWgrhciEnFCW 0daSY7EkxG4FSpL6R8xjnKITCB+DYn5UBkimG8sFFU8W/65F+sNyFuHJl/rDM+zcFXJE V09w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723835542; x=1724440342; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=C/I8iBRqpMYf74wgXxhVFGCiJEuxAMdQwnIxNEYMw1s=; b=eF4ZORy2so8EHdwiMTp6HmYfpdh8eLkRfjTQz1uT0hs1jAtvYT0Knomi9llDSNK0wl VT4npaMgyzZAaj5t6amtptVXGrazZdKuYxEC4R0rl4ukDSMFQX2erYa97JsJlGc/c43d OZlvmviZgyj66BasClsUjWHo3UOUaSJIf4/s7r4yeZpELJEwNMJBrtesDnGV47Hzh43v CYhdSM2D1NHni9EjXAHmn6c1aMecNoecS3Nw5Bb2M8Z+VZxyuSg/i6PREoIQpttT/U0V ewlmxFCTITOBARh3gWVocGs4Jw5ThDo23kDMz2kyjkplMxjmBabaBigFGEznkdaTX9o0 ryBg== X-Gm-Message-State: AOJu0Ywla7AoBvE/0mmYjt6pVUh8WxtiavyV41uMFQAYcjvR3PSDxMuE hfeTrBMgdoxm8YSyrk8E+EdsZlLLTT9yS/L1xsfwwSUosTIeDraC0T/A+oXw X-Google-Smtp-Source: AGHT+IHq4RA32ay93U1en6x8yYxt+dO0XGSRDyCHucRhFjmHGef+aIi+zyUNHVN/Mpu4qS4awr/g1w== X-Received: by 2002:a05:690c:4183:b0:66a:843c:4c58 with SMTP id 00721157ae682-6b1bb75e74bmr42271967b3.34.1723835541912; Fri, 16 Aug 2024 12:12:21 -0700 (PDT) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:ca12:c8db:5571:aa13]) by smtp.gmail.com with ESMTPSA id 00721157ae682-6af9cd7a50dsm7233327b3.94.2024.08.16.12.12.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2024 12:12:21 -0700 (PDT) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, andrii@kernel.org Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee , linux-mm@kvack.org Subject: [RFC bpf-next v4 4/6] bpf: pin, translate, and unpin __uptr from syscalls. Date: Fri, 16 Aug 2024 12:12:11 -0700 Message-Id: <20240816191213.35573-5-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240816191213.35573-1-thinker.li@gmail.com> References: <20240816191213.35573-1-thinker.li@gmail.com> 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 X-Patchwork-State: RFC When a user program updates a map value, every uptr will be pinned and translated to an address in the kernel. This process is initiated by calling bpf_map_update_elem() from user programs. To access uptrs in BPF programs, they are pinned using pin_user_pages_fast(), but the conversion to kernel addresses is actually done by page_address(). The uptrs can be unpinned using unpin_user_pages(). Currently, the memory block pointed to by a uptr must reside in a single memory page, as crossing multiple pages is not supported. uptr is only supported by task storage maps and can only be set by user programs through syscalls. When the value of an uptr is overwritten or destroyed, the memory pointed to by the old value must be unpinned. This is ensured by calling bpf_obj_uptrcpy() and copy_map_uptr_locked() when updating map value and by bpf_obj_free_fields() when destroying map value. Cc: linux-mm@kvack.org Signed-off-by: Kui-Feng Lee --- include/linux/bpf.h | 30 ++++++ kernel/bpf/bpf_local_storage.c | 23 ++++- kernel/bpf/helpers.c | 20 ++++ kernel/bpf/syscall.c | 172 ++++++++++++++++++++++++++++++++- 4 files changed, 237 insertions(+), 8 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 954e476b5605..886c818ff555 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -477,6 +477,8 @@ static inline void bpf_long_memcpy(void *dst, const void *src, u32 size) data_race(*ldst++ = *lsrc++); } +void bpf_obj_unpin_uptr(const struct btf_field *field, void *addr); + /* copy everything but bpf_spin_lock, bpf_timer, and kptrs. There could be one of each. */ static inline void bpf_obj_memcpy(struct btf_record *rec, void *dst, void *src, u32 size, @@ -503,6 +505,34 @@ static inline void bpf_obj_memcpy(struct btf_record *rec, memcpy(dst + curr_off, src + curr_off, size - curr_off); } +static inline void bpf_obj_uptrcpy(struct btf_record *rec, + void *dst, void *src) +{ + int i; + + if (IS_ERR_OR_NULL(rec)) + return; + + for (i = 0; i < rec->cnt; i++) { + u32 next_off = rec->fields[i].offset; + void *addr; + + if (rec->fields[i].type == BPF_UPTR) { + /* Unpin old address. + * + * Alignments are guaranteed by btf_find_field_one(). + */ + addr = *(void **)(dst + next_off); + if (addr) + bpf_obj_unpin_uptr(&rec->fields[i], addr); + + *(void **)(dst + next_off) = *(void **)(src + next_off); + } + } +} + +void copy_map_uptr_locked(struct bpf_map *map, void *dst, void *src, bool lock_src); + static inline void copy_map_value(struct bpf_map *map, void *dst, void *src) { bpf_obj_memcpy(map->record, dst, src, map->value_size, false); diff --git a/kernel/bpf/bpf_local_storage.c b/kernel/bpf/bpf_local_storage.c index c938dea5ddbf..2fafad53b9d9 100644 --- a/kernel/bpf/bpf_local_storage.c +++ b/kernel/bpf/bpf_local_storage.c @@ -99,8 +99,11 @@ bpf_selem_alloc(struct bpf_local_storage_map *smap, void *owner, } if (selem) { - if (value) + if (value) { copy_map_value(&smap->map, SDATA(selem)->data, value); + if (smap->map.map_type == BPF_MAP_TYPE_TASK_STORAGE) + bpf_obj_uptrcpy(smap->map.record, SDATA(selem)->data, value); + } /* No need to call check_and_init_map_value as memory is zero init */ return selem; } @@ -575,8 +578,13 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap, if (err) return ERR_PTR(err); if (old_sdata && selem_linked_to_storage_lockless(SELEM(old_sdata))) { - copy_map_value_locked(&smap->map, old_sdata->data, - value, false); + if (smap->map.map_type == BPF_MAP_TYPE_TASK_STORAGE && + btf_record_has_field(smap->map.record, BPF_UPTR)) + copy_map_uptr_locked(&smap->map, old_sdata->data, + value, false); + else + copy_map_value_locked(&smap->map, old_sdata->data, + value, false); return old_sdata; } } @@ -607,8 +615,13 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap, goto unlock; if (old_sdata && (map_flags & BPF_F_LOCK)) { - copy_map_value_locked(&smap->map, old_sdata->data, value, - false); + if (smap->map.map_type == BPF_MAP_TYPE_TASK_STORAGE && + btf_record_has_field(smap->map.record, BPF_UPTR)) + copy_map_uptr_locked(&smap->map, old_sdata->data, + value, false); + else + copy_map_value_locked(&smap->map, old_sdata->data, + value, false); selem = SELEM(old_sdata); goto unlock; } diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index d02ae323996b..d588b52605b9 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -388,6 +388,26 @@ void copy_map_value_locked(struct bpf_map *map, void *dst, void *src, preempt_enable(); } +/* Copy map value and uptr from src to dst, with lock_src indicating + * whether src or dst is locked. + */ +void copy_map_uptr_locked(struct bpf_map *map, void *src, void *dst, + bool lock_src) +{ + struct bpf_spin_lock *lock; + + if (lock_src) + lock = src + map->record->spin_lock_off; + else + lock = dst + map->record->spin_lock_off; + preempt_disable(); + __bpf_spin_lock_irqsave(lock); + copy_map_value(map, dst, src); + bpf_obj_uptrcpy(map->record, dst, src); + __bpf_spin_unlock_irqrestore(lock); + preempt_enable(); +} + BPF_CALL_0(bpf_jiffies64) { return get_jiffies_64(); diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index fed4a2145f81..1854aeb13ff7 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -155,8 +155,140 @@ static void maybe_wait_bpf_programs(struct bpf_map *map) synchronize_rcu(); } -static int bpf_map_update_value(struct bpf_map *map, struct file *map_file, - void *key, void *value, __u64 flags) +void bpf_obj_unpin_uptr(const struct btf_field *field, void *addr) +{ + struct page *pages[1]; + u32 size, type_id; + int npages; + void *ptr; + + type_id = field->kptr.btf_id; + btf_type_id_size(field->kptr.btf, &type_id, &size); + if (size == 0) + return; + + ptr = (void *)((intptr_t)addr & PAGE_MASK); + + npages = (((intptr_t)addr + size + ~PAGE_MASK) - (intptr_t)ptr) >> PAGE_SHIFT; + if (WARN_ON_ONCE(npages > 1)) + return; + + pages[0] = virt_to_page(ptr); + unpin_user_pages(pages, 1); +} + +/* Unpin uptr fields in the record up to cnt */ +static void bpf_obj_unpin_uptrs_cnt(struct btf_record *rec, int cnt, void *src) +{ + u32 next_off; + void **kaddr_ptr; + int i; + + for (i = 0; i < cnt; i++) { + if (rec->fields[i].type != BPF_UPTR) + continue; + + next_off = rec->fields[i].offset; + kaddr_ptr = src + next_off; + if (*kaddr_ptr) { + bpf_obj_unpin_uptr(&rec->fields[i], *kaddr_ptr); + *kaddr_ptr = NULL; + } + } +} + +/* Find all BPF_UPTR fields in the record, pin the user memory, map it + * to kernel space, and update the addresses in the source memory. + * + * The map value passing from userspace may contain user kptrs pointing to + * user memory. This function pins the user memory and maps it to kernel + * memory so that BPF programs can access it. + */ +static int bpf_obj_trans_pin_uptrs(struct btf_record *rec, void *src, u32 size) +{ + u32 type_id, tsz, npages, next_off; + void *uaddr, *kaddr, **uaddr_ptr; + const struct btf_type *t; + struct page *pages[1]; + int i, err; + + if (IS_ERR_OR_NULL(rec)) + return 0; + + if (!btf_record_has_field(rec, BPF_UPTR)) + return 0; + + for (i = 0; i < rec->cnt; i++) { + if (rec->fields[i].type != BPF_UPTR) + continue; + + next_off = rec->fields[i].offset; + if (next_off + sizeof(void *) > size) { + err = -EFAULT; + goto rollback; + } + uaddr_ptr = src + next_off; + uaddr = *uaddr_ptr; + if (!uaddr) + continue; + + /* Make sure the user memory takes up at most one page */ + type_id = rec->fields[i].kptr.btf_id; + t = btf_type_id_size(rec->fields[i].kptr.btf, &type_id, &tsz); + if (!t) { + err = -EFAULT; + goto rollback; + } + if (tsz == 0) { + *uaddr_ptr = NULL; + continue; + } + npages = (((intptr_t)uaddr + tsz + ~PAGE_MASK) - + ((intptr_t)uaddr & PAGE_MASK)) >> PAGE_SHIFT; + if (npages > 1) { + /* Allow only one page */ + err = -EFAULT; + goto rollback; + } + + /* Pin the user memory */ + err = pin_user_pages_fast((intptr_t)uaddr, 1, FOLL_LONGTERM | FOLL_WRITE, pages); + if (err < 0) + goto rollback; + + /* Map to kernel space */ + kaddr = page_address(pages[0]); + if (unlikely(!kaddr)) { + WARN_ON_ONCE(1); + unpin_user_pages(pages, 1); + err = -EFAULT; + goto rollback; + } + *uaddr_ptr = kaddr + ((intptr_t)uaddr & ~PAGE_MASK); + } + + return 0; + +rollback: + /* Unpin the user memory of earlier fields */ + bpf_obj_unpin_uptrs_cnt(rec, i, src); + + return err; +} + +static void bpf_obj_unpin_uptrs(struct btf_record *rec, void *src) +{ + if (IS_ERR_OR_NULL(rec)) + return; + + if (!btf_record_has_field(rec, BPF_UPTR)) + return; + + bpf_obj_unpin_uptrs_cnt(rec, rec->cnt, src); +} + +static int bpf_map_update_value_inner(struct bpf_map *map, struct file *map_file, + void *key, void *value, __u64 flags) { int err; @@ -208,6 +340,29 @@ static int bpf_map_update_value(struct bpf_map *map, struct file *map_file, return err; } +static int bpf_map_update_value(struct bpf_map *map, struct file *map_file, + void *key, void *value, __u64 flags) +{ + int err; + + if (map->map_type == BPF_MAP_TYPE_TASK_STORAGE) { + /* Pin user memory can lead to context switch, so we need + * to do it before potential RCU lock. + */ + err = bpf_obj_trans_pin_uptrs(map->record, value, + bpf_map_value_size(map)); + if (err) + return err; + } + + err = bpf_map_update_value_inner(map, map_file, key, value, flags); + + if (err && map->map_type == BPF_MAP_TYPE_TASK_STORAGE) + bpf_obj_unpin_uptrs(map->record, value); + + return err; +} + static int bpf_map_copy_value(struct bpf_map *map, void *key, void *value, __u64 flags) { @@ -714,6 +869,11 @@ void bpf_obj_free_fields(const struct btf_record *rec, void *obj) field->kptr.dtor(xchgd_field); } break; + case BPF_UPTR: + if (*(void **)field_ptr) + bpf_obj_unpin_uptr(field, *(void **)field_ptr); + *(void **)field_ptr = NULL; + break; case BPF_LIST_HEAD: if (WARN_ON_ONCE(rec->spin_lock_off < 0)) continue; @@ -1099,7 +1259,7 @@ static int map_check_btf(struct bpf_map *map, struct bpf_token *token, map->record = btf_parse_fields(btf, value_type, BPF_SPIN_LOCK | BPF_TIMER | BPF_KPTR | BPF_LIST_HEAD | - BPF_RB_ROOT | BPF_REFCOUNT | BPF_WORKQUEUE, + BPF_RB_ROOT | BPF_REFCOUNT | BPF_WORKQUEUE | BPF_UPTR, map->value_size); if (!IS_ERR_OR_NULL(map->record)) { int i; @@ -1155,6 +1315,12 @@ static int map_check_btf(struct bpf_map *map, struct bpf_token *token, goto free_map_tab; } break; + case BPF_UPTR: + if (map->map_type != BPF_MAP_TYPE_TASK_STORAGE) { + ret = -EOPNOTSUPP; + goto free_map_tab; + } + break; case BPF_LIST_HEAD: case BPF_RB_ROOT: if (map->map_type != BPF_MAP_TYPE_HASH && From patchwork Fri Aug 16 19:12:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13766780 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-yw1-f182.google.com (mail-yw1-f182.google.com [209.85.128.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C70D1C4601 for ; Fri, 16 Aug 2024 19:12:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723835545; cv=none; b=dRlUNOCu3HIEXv7/913n0QygjWQrUDlJp8GiTFLXdvYs3Y/de15PIVNvuA8xSkiaCXMrTkUW/QYVrVpsU13DHRn17D8oHiXUZkd4L8vmcWlrO7yCu2+kwOI5badxTRTygyyq0NvsuznobEJnuTPytJfXWSHOHJNBYFakgQx1PQY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723835545; c=relaxed/simple; bh=5nFJ7ehyCvQFnjG/IjO9tfwq3gab+NR0irsJ84qK06k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=DDkhYVT3IvxgIVxSfV61qnTUZtexTJt4rbMOcZxbV5bt4RopBWRI5sIa8STCYonlEFts/bLjsmV3M6zFn8H+iFTMKZW8aFvYcBiiSWSPMbsRVirGkromr3rQeYUlYLP7wOMhjq6E/84oaqvlJJqIAAv8ODQ5DLmDjfaFXcLo9HY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Ut+DvhLi; arc=none smtp.client-ip=209.85.128.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ut+DvhLi" Received: by mail-yw1-f182.google.com with SMTP id 00721157ae682-66ca5e8cc51so23308547b3.1 for ; Fri, 16 Aug 2024 12:12:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723835543; x=1724440343; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wA7s9K430JAGPCORlT7sLO0AYsuu7LQN2Z75vPP4SaA=; b=Ut+DvhLi59fOAw5hTHtEll0mNtRyAX9yj3U8ciZW0gWdMSiokXqktB2kCicP8W4HnW ptAcaHS5TnuHERwmYYt0yCfvfsNAjoWfr9WcbFx3dPAjoLKc749Mw0iIxvRYTaKeZHbk slojtvFmGNKTCKNjZXrjfPG5/JMV/B+iJKxUz9JtB0OMNV8qtpRZGlI0niD17j+cwXHP sWPFmqPm/odX0MVLpmTEERB0LMCKFyqUY6uShMRIa6GAyMq2eFtTd2Zq4EV/v+jEZJE1 lsw/9p6ja5HUV6WaLdBK9K4i69LAfeubdHZQIlrdTDFA3udVUxUHlZCoEBNgZx0vzgAa O7JA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723835543; x=1724440343; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wA7s9K430JAGPCORlT7sLO0AYsuu7LQN2Z75vPP4SaA=; b=M73lL9teBQb4SilZUsArROqdiUQVdB4LbQrSkKWIGZSVtmqfmj8ERpciTqJbo+RwXp dbYKXeRpWYqTGvHQeWlwwTWGfLv3dYMsCMfn801m9WLGUlBwf4iBE06270vW+euDVhf8 EqBK+8DNlXooOTbehMHtbBXeSobvnmMbk0RvU90bm54gO57Q6KDmUrvu4SsjwQ1746hU GVn8CoAFbHvxdKHtwehHo5E64JM54Txsam7ap9m/BIYU3o5VJxm81dfxXCbyva1WrvAN kHTTiTVsY8W4ON159/nOqtKu/4JVMFFLZyMfz5RdqjCDcu6CQmKmBo51kamMg4QOtHiq qbbQ== X-Gm-Message-State: AOJu0Yx+/jl86oOptjfPQ15ayJdBc5Y6tlKZ4XiARTcEq5MmBDone63U b5LXzVSKQ7HcVKChgHlHL1rIVHbQDKBVQW4+rWO8KwGYSQR1DNvdc9w4NsTK X-Google-Smtp-Source: AGHT+IHNrR6tMCvuQKUdc94Ciumm0MqCvSVUjFkJ8r4jjlvBFopJmdb964CTXmk5NvwKFMPSzQSFoQ== X-Received: by 2002:a05:690c:f01:b0:62f:f535:f38 with SMTP id 00721157ae682-6b1b9a64059mr54864367b3.8.1723835542909; Fri, 16 Aug 2024 12:12:22 -0700 (PDT) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:ca12:c8db:5571:aa13]) by smtp.gmail.com with ESMTPSA id 00721157ae682-6af9cd7a50dsm7233327b3.94.2024.08.16.12.12.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2024 12:12:22 -0700 (PDT) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, andrii@kernel.org Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [RFC bpf-next v4 5/6] libbpf: define __uptr. Date: Fri, 16 Aug 2024 12:12:12 -0700 Message-Id: <20240816191213.35573-6-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240816191213.35573-1-thinker.li@gmail.com> References: <20240816191213.35573-1-thinker.li@gmail.com> 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 X-Patchwork-State: RFC Make __uptr available to BPF programs to enable them to define uptrs. Signed-off-by: Kui-Feng Lee Acked-by: Andrii Nakryiko --- tools/lib/bpf/bpf_helpers.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h index 305c62817dd3..7ff9d947b976 100644 --- a/tools/lib/bpf/bpf_helpers.h +++ b/tools/lib/bpf/bpf_helpers.h @@ -185,6 +185,7 @@ enum libbpf_tristate { #define __kptr_untrusted __attribute__((btf_type_tag("kptr_untrusted"))) #define __kptr __attribute__((btf_type_tag("kptr"))) #define __percpu_kptr __attribute__((btf_type_tag("percpu_kptr"))) +#define __uptr __attribute__((btf_type_tag("uptr"))) #if defined (__clang__) #define bpf_ksym_exists(sym) ({ \ From patchwork Fri Aug 16 19:12:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kui-Feng Lee X-Patchwork-Id: 13766781 X-Patchwork-Delegate: bpf@iogearbox.net Received: from mail-ot1-f49.google.com (mail-ot1-f49.google.com [209.85.210.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 161001C460E for ; Fri, 16 Aug 2024 19:12:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723835546; cv=none; b=vBn57K9EOAC/+Y9Hv/vARQNy9Mfem42kwoxhpSdgzHMqL9oj6VO/gdA2pR3y1ThOdxlx8HI0+HsW/TbV3L+ZgRKNp6fT0eM6R1ecHKQQ59e72W1XFVkFV68NSwvCYOnnx1TJb5uj9mOGF0Asds/HGGwOBmH9GTTEo1/fJ+fHqSE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723835546; c=relaxed/simple; bh=D34mojUig8vZuHPyC8TaZRR0VKlsSdjtAlsD/lb7vLI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=RoRQ17HBhRrarC7r1mKm2jAAmTzhwz+ZCcgs+/FS6gbeIUXeBsS4ir7qRvVtHlYiqubRQ9u7HbLQ3uIMgwqo7AjC/pFAQKN0pqVqNx/K3MU7DTlAK1FlvLXGspyQcA7+XqMMfalHyuehATZ7AYFQKHEheHrNyzQPuSSsWzOHMW0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=QTpz1xca; arc=none smtp.client-ip=209.85.210.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QTpz1xca" Received: by mail-ot1-f49.google.com with SMTP id 46e09a7af769-7093705c708so2284810a34.1 for ; Fri, 16 Aug 2024 12:12:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723835544; x=1724440344; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=T3GlU5Fpsfnwd7Yq8PAloGm0P5P3SvGYUSsiYTJ2NW0=; b=QTpz1xcaNN3PB5uWv7rzBOFrL+R74Ck+CPkpngGxHekVJSh+cDfhYUQWeUb+njtqJF RNE0RmiS87s/4ajEBYuxeJzw1TiDOQK8yKs7qCByulXD1YBUw2dJ7QMxXu2wCui3yTaY RRMdeHasUxrmeDfYYKliB3O5tKGSmrTq+CEWRI21dQyCo7BhUanCrlOfZy5B8nANUI8q s1wNtcmjhR2w/DMDbZG42fpTQy7510ZdLZKT/GmIephF/SvqGQXO7EsK+YsH3jGZtxPT g4F0cmjtAxgVyNI3qNTBxtKGdNG90opZCEEAXRA2ZAFo5ugUleUIpzvAKFyEvrA980vw mWHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723835544; x=1724440344; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=T3GlU5Fpsfnwd7Yq8PAloGm0P5P3SvGYUSsiYTJ2NW0=; b=FQVzsyyrdMUzYhHyFH+e/14tg5RI+ZpnvLXjMZtZgs3iM8GZuI8Eh9m6AJpMd5HcqZ BCpNKjLtr7Ofbhg5cW1pQhRpPKjqyO6kJnX43IqM52k7W1fFNKuFY7QFl52nyDJdu8Sw knyfFO2UZKz3K/3Lo3DgjkX5yoe2Tk6e7DSWmKEispN+Q4xXrTR6K3oMWlUbdAymsIP/ wyUOn83lCD6Hz727kwd3JKtzPFrJqd1np78zlYZ5GAUUhy56NbSxkiCD/i5PW6794tWp wYs98DnDQRQt3lGJRrPOkiTVl9OhFCkwP8fsOuHmYVkwi8uMNl0CkCXe5KxAODW1XpuO RTiA== X-Gm-Message-State: AOJu0YzFubQgCV7zKuTtk1ptzKvG8Ebm556dgOX4Vl4/3WSO4KyFdgBA qZTAXIEHuEWLflzJZU5kMaRgmMkoWpXDzNwPcft4Q8DOI4LiJ7pmA3E+yv3U X-Google-Smtp-Source: AGHT+IFG0eHk/XknX8Q6i6RaxxBjk+vVrvyo01EDeczL+6d1mVSvCwFOaHuvC73naxjTTim9fxj2qA== X-Received: by 2002:a05:6830:d8c:b0:703:6e7e:3e18 with SMTP id 46e09a7af769-70cb329c998mr596488a34.26.1723835543962; Fri, 16 Aug 2024 12:12:23 -0700 (PDT) Received: from kickker.attlocal.net ([2600:1700:6cf8:1240:ca12:c8db:5571:aa13]) by smtp.gmail.com with ESMTPSA id 00721157ae682-6af9cd7a50dsm7233327b3.94.2024.08.16.12.12.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2024 12:12:23 -0700 (PDT) From: Kui-Feng Lee To: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev, andrii@kernel.org Cc: sinquersw@gmail.com, kuifeng@meta.com, Kui-Feng Lee Subject: [RFC bpf-next v4 6/6] selftests/bpf: test __uptr on the value of a task storage map. Date: Fri, 16 Aug 2024 12:12:13 -0700 Message-Id: <20240816191213.35573-7-thinker.li@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240816191213.35573-1-thinker.li@gmail.com> References: <20240816191213.35573-1-thinker.li@gmail.com> 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 X-Patchwork-State: RFC Make sure the memory of uptrs have been mapped to the kernel properly. Also ensure the values of uptrs in the kernel haven't been copied to userspace. Signed-off-by: Kui-Feng Lee --- .../bpf/prog_tests/task_local_storage.c | 106 ++++++++++++++++++ .../selftests/bpf/progs/task_ls_uptr.c | 65 +++++++++++ 2 files changed, 171 insertions(+) create mode 100644 tools/testing/selftests/bpf/progs/task_ls_uptr.c diff --git a/tools/testing/selftests/bpf/prog_tests/task_local_storage.c b/tools/testing/selftests/bpf/prog_tests/task_local_storage.c index c33c05161a9e..5709b083021c 100644 --- a/tools/testing/selftests/bpf/prog_tests/task_local_storage.c +++ b/tools/testing/selftests/bpf/prog_tests/task_local_storage.c @@ -5,6 +5,7 @@ #include #include #include +#include #include /* For SYS_xxx definitions */ #include #include @@ -14,6 +15,20 @@ #include "task_ls_recursion.skel.h" #include "task_storage_nodeadlock.skel.h" +struct user_data { + int a; + int b; + int result; +}; + +struct value_type { + struct user_data *udata; +}; + +#define MAGIC_VALUE 0xabcd1234 + +#include "task_ls_uptr.skel.h" + static void test_sys_enter_exit(void) { struct task_local_storage *skel; @@ -40,6 +55,95 @@ static void test_sys_enter_exit(void) task_local_storage__destroy(skel); } +static struct user_data user_data __attribute__((aligned(16))) = { + .a = 1, + .b = 2, +}; + +static void test_uptr(void) +{ + struct task_ls_uptr *skel = NULL; + int task_fd = -1, ev_fd = -1; + struct value_type value; + int err, wstatus; + __u64 dummy = 1; + pid_t pid; + + value.udata = &user_data; + + task_fd = sys_pidfd_open(getpid(), 0); + if (!ASSERT_NEQ(task_fd, -1, "sys_pidfd_open")) + goto out; + + ev_fd = eventfd(0, 0); + if (!ASSERT_NEQ(ev_fd, -1, "eventfd")) + goto out; + + skel = task_ls_uptr__open_and_load(); + if (!ASSERT_OK_PTR(skel, "skel_open_and_load")) + goto out; + + err = bpf_map_update_elem(bpf_map__fd(skel->maps.datamap), &task_fd, &value, 0); + if (!ASSERT_OK(err, "update_datamap")) + exit(1); + + err = task_ls_uptr__attach(skel); + if (!ASSERT_OK(err, "skel_attach")) + goto out; + + fflush(stdout); + fflush(stderr); + + pid = fork(); + if (pid < 0) + goto out; + + /* Call syscall in the child process, but access the map value of + * the parent process in the BPF program to check if the user kptr + * is translated/mapped correctly. + */ + if (pid == 0) { + /* child */ + + /* Overwrite the user_data in the child process to check if + * the BPF program accesses the user_data of the parent. + */ + user_data.a = 0; + user_data.b = 0; + + /* Wait for the parent to set child_pid */ + read(ev_fd, &dummy, sizeof(dummy)); + + exit(0); + } + + skel->bss->parent_pid = syscall(SYS_gettid); + skel->bss->child_pid = pid; + + write(ev_fd, &dummy, sizeof(dummy)); + + err = waitpid(pid, &wstatus, 0); + ASSERT_EQ(err, pid, "waitpid"); + skel->bss->child_pid = 0; + + ASSERT_EQ(MAGIC_VALUE + user_data.a + user_data.b, + user_data.result, "result"); + + /* Check if user programs can access the value of user kptrs + * through bpf_map_lookup_elem(). Make sure the kernel value is not + * leaked. + */ + err = bpf_map_lookup_elem(bpf_map__fd(skel->maps.datamap), &task_fd, &value); + if (!ASSERT_OK(err, "bpf_map_lookup_elem")) + goto out; + ASSERT_EQ(value.udata, NULL, "lookup_udata"); + +out: + task_ls_uptr__destroy(skel); + close(ev_fd); + close(task_fd); +} + static void test_exit_creds(void) { struct task_local_storage_exit_creds *skel; @@ -237,4 +341,6 @@ void test_task_local_storage(void) test_recursion(); if (test__start_subtest("nodeadlock")) test_nodeadlock(); + if (test__start_subtest("uptr")) + test_uptr(); } diff --git a/tools/testing/selftests/bpf/progs/task_ls_uptr.c b/tools/testing/selftests/bpf/progs/task_ls_uptr.c new file mode 100644 index 000000000000..473e6890d522 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/task_ls_uptr.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ + +#include "vmlinux.h" +#include +#include +#include "task_kfunc_common.h" + +char _license[] SEC("license") = "GPL"; + +struct user_data { + int a; + int b; + int result; +}; + +struct value_type { + struct user_data __uptr *udata; +}; + +struct { + __uint(type, BPF_MAP_TYPE_TASK_STORAGE); + __uint(map_flags, BPF_F_NO_PREALLOC); + __type(key, int); + __type(value, struct value_type); +} datamap SEC(".maps"); + +#define MAGIC_VALUE 0xabcd1234 + +/* This is a workaround to avoid clang generating a forward reference for + * struct user_data. This is a known issue and will be fixed in the future. + */ +struct user_data __dummy; + +pid_t child_pid = 0; +pid_t parent_pid = 0; + +SEC("tp_btf/sys_enter") +int BPF_PROG(on_enter, struct pt_regs *regs, long id) +{ + struct task_struct *task, *data_task; + struct value_type *ptr; + struct user_data *udata; + + task = bpf_get_current_task_btf(); + if (task->pid != child_pid) + return 0; + + data_task = bpf_task_from_pid(parent_pid); + if (!data_task) + return 0; + + ptr = bpf_task_storage_get(&datamap, data_task, 0, + BPF_LOCAL_STORAGE_GET_F_CREATE); + bpf_task_release(data_task); + if (!ptr) + return 0; + + udata = ptr->udata; + if (!udata) + return 0; + udata->result = MAGIC_VALUE + udata->a + udata->b; + + return 0; +}