From patchwork Thu Oct 10 13:27:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 13830115 X-Patchwork-Delegate: bpf@iogearbox.net Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 381C21C9DD5 for ; Thu, 10 Oct 2024 13:28:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728566884; cv=none; b=lg3+m3uREBeuyB5v5YLKA7ld3xxIEPT0ZTEqdCYFFP2533/3bs224USvGatWkumm/r2DK/Ld9nnJfmsie17oausTkdo593EKZ/nPlH1CpwwhGVWYDjmmWSmKCoVcVHFysz+icd5cqXOiCjhgO9SIhIHMgoAWrhx+UyT+bSzktK4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728566884; c=relaxed/simple; bh=M0zCY90Fb2hTp6ShOKR2m5jT/6bRMm1u3v6q53MlWnQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TEjQ7vEZ7/cJrtTQrUdSRrcIkTcnNOXpaSvs8dduZKlBGzWdrdS91DkHcogJXZDY4PPQuJD5Nw77UNMi/KpprCvcEpA7znm34AU/dGkdiPEATA4OyXEWy/UXGCDtfBVD/UbuFA4Z5afJQCHO+c/hWKVNZ8PR00ddelBRBpdAI/o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=QGj0Vpcc; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="QGj0Vpcc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728566882; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=24xFVhHpUbv0GxX3vB78a7ab9wcPKJu6tPdj/V0Z/DE=; b=QGj0Vpccwxc9KphIlWuIDgJlBTpNdvQsM1r7HpEa7wbwaLfBCLsSg5/qgZ7QLeP9h5pHfi l7MsynCD5WY6jhTUYXBDm7ISxmVQR9tPjvxjkjyIJ667ew9B8lQAZR5z2MpQdxZXdJhNkP AqCTs4k8EsaVJHRHhSna1jHaiJgU3eY= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-568-rqsC7n_MP16sEfEEvNa8Tg-1; Thu, 10 Oct 2024 09:28:01 -0400 X-MC-Unique: rqsC7n_MP16sEfEEvNa8Tg-1 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-42cb6dc3365so5836495e9.2 for ; Thu, 10 Oct 2024 06:28:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728566880; x=1729171680; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=24xFVhHpUbv0GxX3vB78a7ab9wcPKJu6tPdj/V0Z/DE=; b=jQ6z72RIYw66CzzM2mCY9ow63puKvHc7IFhx8ykhLbSQC0g6SkbI6tivvCVreotjle UHLMtL4bcOGL9xds84KntSpOn6s2gVw/NWfxWDM1SSUrQI8icYb6L55M/HLDuv7Wkcs5 bsFEbuktYvtYDHkjhTLch/5Cama62flvuDmRuCblsYkGz/Z2GXghmBx4x6DrMM3prEsO jotlVag3CCGbM8YxfgTgACaAS3jSY35nijjJ6QJzbK33poz5JBBOUWfFCwdJ8FuyvR5d yj+Yq0tNOeF0+F/dZerf8br9LBC3asSuZRIITuDeb0CW0TJ5SJLHXlrh2pnpvcATU2/z np+Q== X-Forwarded-Encrypted: i=1; AJvYcCUkFYRngGxrNKDFJMPwBKJ0Ho04HegVThTacV78GLjnhXLcrkpMAcHclOjy9uOHUq6q4XU=@vger.kernel.org X-Gm-Message-State: AOJu0YxyzLMDqmAVuYHOi4debWF+2vmnqX3eYBQJcolYVmAqp+AYiw+g 1Ql6vHWbxJdTdfLnIj7jbLhQvPEbRicTU/AAJCWi2IhgFU/Sb96YUWawN9y6H9sU/CtF9WZhcnr ceGHXJmYYSkaRaZOP1WbnQ78JZ5VGuzbBzVrZCwB1pXfLEq0OOg== X-Received: by 2002:a05:600c:1c23:b0:430:57f2:baf2 with SMTP id 5b1f17b1804b1-430d59b7873mr53577165e9.22.1728566879849; Thu, 10 Oct 2024 06:27:59 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFRcQowUIpMvvFM5df2r+5d4cDIMgcqXOBgEHWpeiYvZjV/0LhU38epcMkm/fXkByH0ybFumw== X-Received: by 2002:a05:600c:1c23:b0:430:57f2:baf2 with SMTP id 5b1f17b1804b1-430d59b7873mr53576895e9.22.1728566879373; Thu, 10 Oct 2024 06:27:59 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk ([45.145.92.2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4311835d8f6sm16592475e9.44.2024.10.10.06.27.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Oct 2024 06:27:58 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id 3F47515F3EA1; Thu, 10 Oct 2024 15:27:57 +0200 (CEST) From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= Date: Thu, 10 Oct 2024 15:27:07 +0200 Subject: [PATCH bpf v2 1/3] bpf: fix kfunc btf caching for modules Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241010-fix-kfunc-btf-caching-for-modules-v2-1-745af6c1af98@redhat.com> References: <20241010-fix-kfunc-btf-caching-for-modules-v2-0-745af6c1af98@redhat.com> In-Reply-To: <20241010-fix-kfunc-btf-caching-for-modules-v2-0-745af6c1af98@redhat.com> To: Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Kumar Kartikeya Dwivedi Cc: Simon Sundberg , bpf@vger.kernel.org, netdev@vger.kernel.org, =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Mailer: b4 0.14.2 X-Patchwork-Delegate: bpf@iogearbox.net The verifier contains a cache for looking up module BTF objects when calling kfuncs defined in modules. This cache uses a 'struct bpf_kfunc_btf_tab', which contains a sorted list of BTF objects that were already seen in the current verifier run, and the BTF objects are looked up by the offset stored in the relocated call instruction using bsearch(). The first time a given offset is seen, the module BTF is loaded from the file descriptor passed in by libbpf, and stored into the cache. However, there's a bug in the code storing the new entry: it stores a pointer to the new cache entry, then calls sort() to keep the cache sorted for the next lookup using bsearch(), and then returns the entry that was just stored through the stored pointer. However, because sort() modifies the list of entries in place *by value*, the stored pointer may no longer point to the right entry, in which case the wrong BTF object will be returned. The end result of this is an intermittent bug where, if a BPF program calls two functions with the same signature in two different modules, the function from the wrong module may sometimes end up being called. Whether this happens depends on the order of the calls in the BPF program (as that affects whether sort() reorders the array of BTF objects), making it especially hard to track down. Simon, credited as reporter below, spent significant effort analysing and creating a reproducer for this issue. The reproducer is added as a selftest in a subsequent patch. The fix is straight forward: simply don't use the stored pointer after calling sort(). Since we already have an on-stack pointer to the BTF object itself at the point where the function return, just use that, and populate it from the cache entry in the branch where the lookup succeeds. Fixes: 2357672c54c3 ("bpf: Introduce BPF support for kernel module function calls") Reported-by: Simon Sundberg Acked-by: Jiri Olsa Acked-by: Kumar Kartikeya Dwivedi Signed-off-by: Toke Høiland-Jørgensen --- kernel/bpf/verifier.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 633fd6da40c2460094b82ca7c2b9305eade05cf6..bf9996ea34fe1d80cef1c1ff3bbdb1030a976710 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2750,10 +2750,16 @@ static struct btf *__find_kfunc_desc_btf(struct bpf_verifier_env *env, b->module = mod; b->offset = offset; + /* sort() reorders entries by value, so b may no longer point + * to the right entry after this + */ sort(tab->descs, tab->nr_descs, sizeof(tab->descs[0]), kfunc_btf_cmp_by_off, NULL); + } else { + btf = b->btf; } - return b->btf; + + return btf; } void bpf_free_kfunc_btf_tab(struct bpf_kfunc_btf_tab *tab) From patchwork Thu Oct 10 13:27:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 13830113 X-Patchwork-Delegate: bpf@iogearbox.net Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 039341C9DCD for ; Thu, 10 Oct 2024 13:28:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728566884; cv=none; b=cXDMUG13r9pSCl9AjOB24bKFOZMHz6mhoevsopBLQpwD7QzqZBSy5mFta0waa1M+Dcsx9f2pMrShI0x3W2Pl7ls6zrL0UpAqdy3kPfBA4euOMw8wsxymEpy9LQpYmjiAT7IPzqAc8745t5EnjrkB1J100h+ACoRCSA9GglFbTCc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728566884; c=relaxed/simple; bh=4YDcFKqcFOptWI4+Ky226m4++Sy0wlebeGJk5kGSTGU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NTNquCARJx1dF5JMTVRwVgbGg1PRyR7KJlqcUa3kzaJEm4DdgSY4lZ95vXNM+kG9EUhzXDxdkSxDoNqvFFrlK/WoxzJV1IrD/yUdc8kbruhhIZD03lE4IGzT2xd8id2d/SdG6XZw7Jeqw7fagiQXw+Bl08wXB7eXOsba5m50azc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Q5Lf+YcL; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Q5Lf+YcL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728566881; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dcVLw7oVeKeWONINqyVyub+tBa9Z5YErFbIgINy4EE8=; b=Q5Lf+YcLtHt1J4wsbsWBWE3yg1lESD4FfKLdvwFmUNRz/6/Bk9j7S++YkWJqcrcSj2peod CknKOVtKjlMiph4AsT6ctt5Ez3Bjg2x2U+rbUCVrZgP/RSdUzJXn/+3aXaXZGMDy3UP2ts +bfoUYxn2rI7E+P7MPYuIa8vovaQ5jg= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-240-o9A5pK8rOEel96CeKKbsJw-1; Thu, 10 Oct 2024 09:28:00 -0400 X-MC-Unique: o9A5pK8rOEel96CeKKbsJw-1 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-42cceb06940so6022255e9.0 for ; Thu, 10 Oct 2024 06:28:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728566879; x=1729171679; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dcVLw7oVeKeWONINqyVyub+tBa9Z5YErFbIgINy4EE8=; b=e8Vzatx4uQG2T0zBgRmlZ/J/DOArBL7DW+cRjMAmc6F4FhWAUw8ZrffNjqI8fkfnEs K50gw8CNyd1NGvDKLp83hFZnykArMsCZKHjL4iLP1FwMoqqfl19ajk46KawUAAGYkNd9 t18a1AOKJVA6WOdeEyz60Zpnyxwo4fQLsVvLsnkHv2OVuwT5VLnnSjizjyKhvcQyfiRw Rwp7JL9Gpc26TkvpSjhZzHFz7XID7IWadtSpr65fTejaYtmjS5OzviSJI5+6XCAHSwKs PfyKWxGud/eNEKDaXWTZo6KYC8PBncI8Bd5+sJ0c9yGpaX/Xqf0Hl4Sw7xakmW1AbAbN 9Blw== X-Forwarded-Encrypted: i=1; AJvYcCWzAD8onEc3LzuGQkxtBypo99klunX8yBIzeQw5KYca25otzuG1aHVgbdTJuGUuvHfAU+s=@vger.kernel.org X-Gm-Message-State: AOJu0Yzn4DhKNMxPlMiOl7d4fxVIJibImdKipOqhNg0BJ2xagr2Pn8vm 2J8xlUxgGaqajPBSiz+gVFqV8cNIUzKkSu4dWl5VF/OjLF66E4Syzz17etuk2P1+LWKIP2logOm qnL2VHgR0iEoA3wB/EZnb0g99AxZQ1iI5z+8+QMQKGEamJaG2Eg== X-Received: by 2002:adf:fb87:0:b0:37c:d11f:c591 with SMTP id ffacd0b85a97d-37d3a9d90d5mr4093124f8f.17.1728566879330; Thu, 10 Oct 2024 06:27:59 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGguFz9WsMX+fsRXMX7/QsYuTAHffxv9qqM5rJFM3KQdJMFygKoVRN1jcOUpNhsN+omtwApyQ== X-Received: by 2002:adf:fb87:0:b0:37c:d11f:c591 with SMTP id ffacd0b85a97d-37d3a9d90d5mr4093093f8f.17.1728566878888; Thu, 10 Oct 2024 06:27:58 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk ([2a0c:4d80:42:443::2]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37d4b6ce6a7sm1560119f8f.46.2024.10.10.06.27.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Oct 2024 06:27:58 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id 419EB15F3EA3; Thu, 10 Oct 2024 15:27:57 +0200 (CEST) From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= Date: Thu, 10 Oct 2024 15:27:08 +0200 Subject: [PATCH bpf v2 2/3] selftests/bpf: Provide a generic [un]load_module helper Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241010-fix-kfunc-btf-caching-for-modules-v2-2-745af6c1af98@redhat.com> References: <20241010-fix-kfunc-btf-caching-for-modules-v2-0-745af6c1af98@redhat.com> In-Reply-To: <20241010-fix-kfunc-btf-caching-for-modules-v2-0-745af6c1af98@redhat.com> To: Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Kumar Kartikeya Dwivedi Cc: Simon Sundberg , bpf@vger.kernel.org, netdev@vger.kernel.org, =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Mailer: b4 0.14.2 X-Patchwork-Delegate: bpf@iogearbox.net From: Simon Sundberg Generalize the previous [un]load_bpf_testmod() helpers (in testing_helpers.c) to the more generic [un]load_module(), which can load an arbitrary kernel module by name. This allows future selftests to more easily load custom kernel modules other than bpf_testmod.ko. Refactor [un]load_bpf_testmod() to wrap this new helper. Signed-off-by: Simon Sundberg Acked-by: Jiri Olsa Acked-by: Kumar Kartikeya Dwivedi Signed-off-by: Toke Høiland-Jørgensen --- tools/testing/selftests/bpf/testing_helpers.c | 34 +++++++++++++++++---------- tools/testing/selftests/bpf/testing_helpers.h | 2 ++ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/tools/testing/selftests/bpf/testing_helpers.c b/tools/testing/selftests/bpf/testing_helpers.c index d3c3c3a24150f99abd13ecb7d7b11d8f7351560d..5e9f16683be5460b1a295fb9754df761cbd090ea 100644 --- a/tools/testing/selftests/bpf/testing_helpers.c +++ b/tools/testing/selftests/bpf/testing_helpers.c @@ -367,7 +367,7 @@ int delete_module(const char *name, int flags) return syscall(__NR_delete_module, name, flags); } -int unload_bpf_testmod(bool verbose) +int unload_module(const char *name, bool verbose) { int ret, cnt = 0; @@ -375,11 +375,11 @@ int unload_bpf_testmod(bool verbose) fprintf(stdout, "Failed to trigger kernel-side RCU sync!\n"); for (;;) { - ret = delete_module("bpf_testmod", 0); + ret = delete_module(name, 0); if (!ret || errno != EAGAIN) break; if (++cnt > 10000) { - fprintf(stdout, "Unload of bpf_testmod timed out\n"); + fprintf(stdout, "Unload of %s timed out\n", name); break; } usleep(100); @@ -388,41 +388,51 @@ int unload_bpf_testmod(bool verbose) if (ret) { if (errno == ENOENT) { if (verbose) - fprintf(stdout, "bpf_testmod.ko is already unloaded.\n"); + fprintf(stdout, "%s.ko is already unloaded.\n", name); return -1; } - fprintf(stdout, "Failed to unload bpf_testmod.ko from kernel: %d\n", -errno); + fprintf(stdout, "Failed to unload %s.ko from kernel: %d\n", name, -errno); return -1; } if (verbose) - fprintf(stdout, "Successfully unloaded bpf_testmod.ko.\n"); + fprintf(stdout, "Successfully unloaded %s.ko.\n", name); return 0; } -int load_bpf_testmod(bool verbose) +int load_module(const char *path, bool verbose) { int fd; if (verbose) - fprintf(stdout, "Loading bpf_testmod.ko...\n"); + fprintf(stdout, "Loading %s...\n", path); - fd = open("bpf_testmod.ko", O_RDONLY); + fd = open(path, O_RDONLY); if (fd < 0) { - fprintf(stdout, "Can't find bpf_testmod.ko kernel module: %d\n", -errno); + fprintf(stdout, "Can't find %s kernel module: %d\n", path, -errno); return -ENOENT; } if (finit_module(fd, "", 0)) { - fprintf(stdout, "Failed to load bpf_testmod.ko into the kernel: %d\n", -errno); + fprintf(stdout, "Failed to load %s into the kernel: %d\n", path, -errno); close(fd); return -EINVAL; } close(fd); if (verbose) - fprintf(stdout, "Successfully loaded bpf_testmod.ko.\n"); + fprintf(stdout, "Successfully loaded %s.\n", path); return 0; } +int unload_bpf_testmod(bool verbose) +{ + return unload_module("bpf_testmod", verbose); +} + +int load_bpf_testmod(bool verbose) +{ + return load_module("bpf_testmod.ko", verbose); +} + /* * Trigger synchronize_rcu() in kernel. */ diff --git a/tools/testing/selftests/bpf/testing_helpers.h b/tools/testing/selftests/bpf/testing_helpers.h index d55f6ab124338ccab33bc120ca7e3baa18264aea..46d7f7089f636b0d2476859fd0fa5e1c4b305419 100644 --- a/tools/testing/selftests/bpf/testing_helpers.h +++ b/tools/testing/selftests/bpf/testing_helpers.h @@ -38,6 +38,8 @@ int unload_bpf_testmod(bool verbose); int kern_sync_rcu(void); int finit_module(int fd, const char *param_values, int flags); int delete_module(const char *name, int flags); +int load_module(const char *path, bool verbose); +int unload_module(const char *name, bool verbose); static inline __u64 get_time_ns(void) { From patchwork Thu Oct 10 13:27:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Patchwork-Id: 13830116 X-Patchwork-Delegate: bpf@iogearbox.net Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 873E21C9DE6 for ; Thu, 10 Oct 2024 13:28:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728566885; cv=none; b=KC8b7nU8iOkk02d1BOmaqOkQBoVTXEzP5vH/hXOXn12OlfTgXMkppmbO62hvYTqppaxzamciLY+2618FLYabZgopBGeYVPYJzACSzofTgmVLxCw3QcKUuoBVYhiB/+FZeYdWsoTpmUfxeJ7ndw7kH0c8RFKbdfOVYEAHPicJAcM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728566885; c=relaxed/simple; bh=wFxPhISBn0FR+BysUNxXrED95b21s0IL5GZkJf5EAVg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=KEsfIf3iiasAte/yyEDbUQkIbdzPgiZIzipOuFRDsqV7y1D11Am0ENjsIUdkUpEINgrm0MFI7qjBdRLB7j+Jcdh+D2lCl55vf4FYdfRxXToOD1EF/i+EsIbjNE6fXhoLrk3tQ/gp5jcr+UyUJlRs30Veju9vvCn/ErotyfFq5vY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=KEqeB0UP; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="KEqeB0UP" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1728566882; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LNfEkhaEfnomZL+VVDTKqmTWRtfi6Sw1VjCoynxR+M4=; b=KEqeB0UPRZNAmM/ZGjmNljA58IbTvuV/cAqRxsqffTvmDE9+HXyAcdlbcODYL5d7p6C0B2 IncSaY0YOso06j+x4qsHWQkrzmapurE3nSBAqOSOqsLBaiYLxiO9Ebqd6rN6mP2J60Dpdg rAAMaHS006izY+Gswt2EzDbZnvqjsAA= Received: from mail-ej1-f70.google.com (mail-ej1-f70.google.com [209.85.218.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-240-sI9TUbBZNSW9jTJ27qIZMQ-1; Thu, 10 Oct 2024 09:28:01 -0400 X-MC-Unique: sI9TUbBZNSW9jTJ27qIZMQ-1 Received: by mail-ej1-f70.google.com with SMTP id a640c23a62f3a-a9940593476so71456666b.3 for ; Thu, 10 Oct 2024 06:28:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1728566880; x=1729171680; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LNfEkhaEfnomZL+VVDTKqmTWRtfi6Sw1VjCoynxR+M4=; b=Lrk8u0B5ebT3WTA81JCvXXOiJ6HxyJBKdp5GqyWrlDFY+ZMZ0k7l8l7vx8BBtwajgv vZJMoNSONnQZiA0yGhgZh5Ph6g/n5DktkGg3Mn/5XjcOYBwBVnaUJKtv7oiVt4qjSU+E THlrk1Saw7bArw2CSWEaaK9l8/YqSPz3Sxle/NIAvIw2kIBZLZw4e6YOQk++S/wuJDt7 bPvFqEJB1hrp0S5bIWtNgH/jWYDJyGdWdbtqYlSawqhFTJvFQpWUX18dTbM8jCboTfRy Z9FfSk/r9ZzVhxUL0LVvofmkj8ntBf/plB5b82d1ItvEeCfHdRNyyHMEG/aq3uk+3GxW BBWw== X-Forwarded-Encrypted: i=1; AJvYcCWl5HKgQHKOYhVP+gDd9cT1g9QOCSvFA5QMseqJEJ2BEqsU9xRotIQpQhzYBN7rPe+MmLE=@vger.kernel.org X-Gm-Message-State: AOJu0YzYo2C4u1Yx76nnURTgKQvQv3scZDoxogJH/YueaCVW2JyGQWP0 wwM2pxL3S3cJhhrsV9EI11dAVzIg573munVVDv4JT/RU6Tk8HsRCwbWPxU42FdDDoLY1OQ/FYU4 BTWx8NQsjk8AboMt4IS4LgGKEB6HL7mWJU8K4v5HDjwkNzzqDdw== X-Received: by 2002:a17:907:d14:b0:a99:4278:8df8 with SMTP id a640c23a62f3a-a998d218eedmr478419766b.34.1728566879613; Thu, 10 Oct 2024 06:27:59 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGLsIM+zWS3wCu58d2XA43gODSIjv5f1PFCiGxE5AQ3RR/LJDPMorLaMUl2+g+WzFHhZozN9w== X-Received: by 2002:a17:907:d14:b0:a99:4278:8df8 with SMTP id a640c23a62f3a-a998d218eedmr478417466b.34.1728566879149; Thu, 10 Oct 2024 06:27:59 -0700 (PDT) Received: from alrua-x1.borgediget.toke.dk ([45.145.92.2]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a99a80efb5bsm88330266b.192.2024.10.10.06.27.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 10 Oct 2024 06:27:58 -0700 (PDT) Received: by alrua-x1.borgediget.toke.dk (Postfix, from userid 1000) id 4418815F3EA5; Thu, 10 Oct 2024 15:27:57 +0200 (CEST) From: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= Date: Thu, 10 Oct 2024 15:27:09 +0200 Subject: [PATCH bpf v2 3/3] selftests/bpf: Add test for kfunc module order Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241010-fix-kfunc-btf-caching-for-modules-v2-3-745af6c1af98@redhat.com> References: <20241010-fix-kfunc-btf-caching-for-modules-v2-0-745af6c1af98@redhat.com> In-Reply-To: <20241010-fix-kfunc-btf-caching-for-modules-v2-0-745af6c1af98@redhat.com> To: Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Kumar Kartikeya Dwivedi Cc: Simon Sundberg , bpf@vger.kernel.org, netdev@vger.kernel.org, =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= X-Mailer: b4 0.14.2 X-Patchwork-Delegate: bpf@iogearbox.net From: Simon Sundberg Add a test case for kfuncs from multiple external modules, checking that the correct kfuncs are called regardless of which order they're called in. Specifically, check that calling the kfuncs in an order different from the one the modules' BTF are loaded in works. Signed-off-by: Simon Sundberg Acked-by: Kumar Kartikeya Dwivedi Signed-off-by: Toke Høiland-Jørgensen --- tools/testing/selftests/bpf/Makefile | 20 +++++++- .../selftests/bpf/bpf_test_modorder_x/Makefile | 19 ++++++++ .../bpf/bpf_test_modorder_x/bpf_test_modorder_x.c | 39 +++++++++++++++ .../selftests/bpf/bpf_test_modorder_y/Makefile | 19 ++++++++ .../bpf/bpf_test_modorder_y/bpf_test_modorder_y.c | 39 +++++++++++++++ .../selftests/bpf/prog_tests/kfunc_module_order.c | 55 ++++++++++++++++++++++ .../selftests/bpf/progs/kfunc_module_order.c | 30 ++++++++++++ 7 files changed, 220 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index f04af11df8eb5a1cecd75a4864d45c669433df61..6f9838a5dcc9a0a0e7cc249a4f93c87befafb699 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -157,7 +157,8 @@ TEST_GEN_PROGS_EXTENDED = \ flow_dissector_load test_flow_dissector test_tcp_check_syncookie_user \ test_lirc_mode2_user xdping test_cpp runqslower bench bpf_testmod.ko \ xskxceiver xdp_redirect_multi xdp_synproxy veristat xdp_hw_metadata \ - xdp_features bpf_test_no_cfi.ko + xdp_features bpf_test_no_cfi.ko bpf_test_modorder_x.ko \ + bpf_test_modorder_y.ko TEST_GEN_FILES += liburandom_read.so urandom_read sign-file uprobe_multi @@ -303,6 +304,19 @@ $(OUTPUT)/bpf_test_no_cfi.ko: $(VMLINUX_BTF) $(RESOLVE_BTFIDS) $(wildcard bpf_te $(Q)$(MAKE) $(submake_extras) RESOLVE_BTFIDS=$(RESOLVE_BTFIDS) -C bpf_test_no_cfi $(Q)cp bpf_test_no_cfi/bpf_test_no_cfi.ko $@ +$(OUTPUT)/bpf_test_modorder_x.ko: $(VMLINUX_BTF) $(RESOLVE_BTFIDS) $(wildcard bpf_test_modorder_x/Makefile bpf_test_modorder_x/*.[ch]) + $(call msg,MOD,,$@) + $(Q)$(RM) bpf_test_modorder_x/bpf_test_modorder_x.ko # force re-compilation + $(Q)$(MAKE) $(submake_extras) RESOLVE_BTFIDS=$(RESOLVE_BTFIDS) -C bpf_test_modorder_x + $(Q)cp bpf_test_modorder_x/bpf_test_modorder_x.ko $@ + +$(OUTPUT)/bpf_test_modorder_y.ko: $(VMLINUX_BTF) $(RESOLVE_BTFIDS) $(wildcard bpf_test_modorder_y/Makefile bpf_test_modorder_y/*.[ch]) + $(call msg,MOD,,$@) + $(Q)$(RM) bpf_test_modorder_y/bpf_test_modorder_y.ko # force re-compilation + $(Q)$(MAKE) $(submake_extras) RESOLVE_BTFIDS=$(RESOLVE_BTFIDS) -C bpf_test_modorder_y + $(Q)cp bpf_test_modorder_y/bpf_test_modorder_y.ko $@ + + DEFAULT_BPFTOOL := $(HOST_SCRATCH_DIR)/sbin/bpftool ifneq ($(CROSS_COMPILE),) CROSS_BPFTOOL := $(SCRATCH_DIR)/sbin/bpftool @@ -722,6 +736,8 @@ TRUNNER_EXTRA_SOURCES := test_progs.c \ ip_check_defrag_frags.h TRUNNER_EXTRA_FILES := $(OUTPUT)/urandom_read $(OUTPUT)/bpf_testmod.ko \ $(OUTPUT)/bpf_test_no_cfi.ko \ + $(OUTPUT)/bpf_test_modorder_x.ko \ + $(OUTPUT)/bpf_test_modorder_y.ko \ $(OUTPUT)/liburandom_read.so \ $(OUTPUT)/xdp_synproxy \ $(OUTPUT)/sign-file \ @@ -856,6 +872,8 @@ EXTRA_CLEAN := $(SCRATCH_DIR) $(HOST_SCRATCH_DIR) \ $(addprefix $(OUTPUT)/,*.o *.d *.skel.h *.lskel.h *.subskel.h \ no_alu32 cpuv4 bpf_gcc bpf_testmod.ko \ bpf_test_no_cfi.ko \ + bpf_test_modorder_x.ko \ + bpf_test_modorder_y.ko \ liburandom_read.so) \ $(OUTPUT)/FEATURE-DUMP.selftests diff --git a/tools/testing/selftests/bpf/bpf_test_modorder_x/Makefile b/tools/testing/selftests/bpf/bpf_test_modorder_x/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..40b25b98ad1b622c6a5c3c00d0625595349bb677 --- /dev/null +++ b/tools/testing/selftests/bpf/bpf_test_modorder_x/Makefile @@ -0,0 +1,19 @@ +BPF_TESTMOD_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))) +KDIR ?= $(abspath $(BPF_TESTMOD_DIR)/../../../../..) + +ifeq ($(V),1) +Q = +else +Q = @ +endif + +MODULES = bpf_test_modorder_x.ko + +obj-m += bpf_test_modorder_x.o + +all: + +$(Q)make -C $(KDIR) M=$(BPF_TESTMOD_DIR) modules + +clean: + +$(Q)make -C $(KDIR) M=$(BPF_TESTMOD_DIR) clean + diff --git a/tools/testing/selftests/bpf/bpf_test_modorder_x/bpf_test_modorder_x.c b/tools/testing/selftests/bpf/bpf_test_modorder_x/bpf_test_modorder_x.c new file mode 100644 index 0000000000000000000000000000000000000000..0cc747fa912fcd5b6738af15dc1b8dfb88c33f6b --- /dev/null +++ b/tools/testing/selftests/bpf/bpf_test_modorder_x/bpf_test_modorder_x.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include + +__bpf_kfunc_start_defs(); + +__bpf_kfunc int bpf_test_modorder_retx(void) +{ + return 'x'; +} + +__bpf_kfunc_end_defs(); + +BTF_KFUNCS_START(bpf_test_modorder_kfunc_x_ids) +BTF_ID_FLAGS(func, bpf_test_modorder_retx); +BTF_KFUNCS_END(bpf_test_modorder_kfunc_x_ids) + +static const struct btf_kfunc_id_set bpf_test_modorder_x_set = { + .owner = THIS_MODULE, + .set = &bpf_test_modorder_kfunc_x_ids, +}; + +static int __init bpf_test_modorder_x_init(void) +{ + return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, + &bpf_test_modorder_x_set); +} + +static void __exit bpf_test_modorder_x_exit(void) +{ +} + +module_init(bpf_test_modorder_x_init); +module_exit(bpf_test_modorder_x_exit); + +MODULE_DESCRIPTION("BPF selftest ordertest module X"); +MODULE_LICENSE("GPL"); diff --git a/tools/testing/selftests/bpf/bpf_test_modorder_y/Makefile b/tools/testing/selftests/bpf/bpf_test_modorder_y/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..52c3ab9d84e29c794f57c1f75be03b46d80d4a06 --- /dev/null +++ b/tools/testing/selftests/bpf/bpf_test_modorder_y/Makefile @@ -0,0 +1,19 @@ +BPF_TESTMOD_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))) +KDIR ?= $(abspath $(BPF_TESTMOD_DIR)/../../../../..) + +ifeq ($(V),1) +Q = +else +Q = @ +endif + +MODULES = bpf_test_modorder_y.ko + +obj-m += bpf_test_modorder_y.o + +all: + +$(Q)make -C $(KDIR) M=$(BPF_TESTMOD_DIR) modules + +clean: + +$(Q)make -C $(KDIR) M=$(BPF_TESTMOD_DIR) clean + diff --git a/tools/testing/selftests/bpf/bpf_test_modorder_y/bpf_test_modorder_y.c b/tools/testing/selftests/bpf/bpf_test_modorder_y/bpf_test_modorder_y.c new file mode 100644 index 0000000000000000000000000000000000000000..c627ee085d1305af98c5d7f66d99dcfbf98dc4e1 --- /dev/null +++ b/tools/testing/selftests/bpf/bpf_test_modorder_y/bpf_test_modorder_y.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include + +__bpf_kfunc_start_defs(); + +__bpf_kfunc int bpf_test_modorder_rety(void) +{ + return 'y'; +} + +__bpf_kfunc_end_defs(); + +BTF_KFUNCS_START(bpf_test_modorder_kfunc_y_ids) +BTF_ID_FLAGS(func, bpf_test_modorder_rety); +BTF_KFUNCS_END(bpf_test_modorder_kfunc_y_ids) + +static const struct btf_kfunc_id_set bpf_test_modorder_y_set = { + .owner = THIS_MODULE, + .set = &bpf_test_modorder_kfunc_y_ids, +}; + +static int __init bpf_test_modorder_y_init(void) +{ + return register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, + &bpf_test_modorder_y_set); +} + +static void __exit bpf_test_modorder_y_exit(void) +{ +} + +module_init(bpf_test_modorder_y_init); +module_exit(bpf_test_modorder_y_exit); + +MODULE_DESCRIPTION("BPF selftest ordertest module Y"); +MODULE_LICENSE("GPL"); diff --git a/tools/testing/selftests/bpf/prog_tests/kfunc_module_order.c b/tools/testing/selftests/bpf/prog_tests/kfunc_module_order.c new file mode 100644 index 0000000000000000000000000000000000000000..48c0560d398e2a14d0682e309cdfc99def244720 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/kfunc_module_order.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +#include "kfunc_module_order.skel.h" + +static int test_run_prog(const struct bpf_program *prog, + struct bpf_test_run_opts *opts) +{ + int err; + + err = bpf_prog_test_run_opts(bpf_program__fd(prog), opts); + if (!ASSERT_OK(err, "bpf_prog_test_run_opts")) + return err; + + if (!ASSERT_EQ((int)opts->retval, 0, bpf_program__name(prog))) + return -EINVAL; + + return 0; +} + +void test_kfunc_module_order(void) +{ + struct kfunc_module_order *skel; + char pkt_data[64] = {}; + int err = 0; + + DECLARE_LIBBPF_OPTS(bpf_test_run_opts, test_opts, .data_in = pkt_data, + .data_size_in = sizeof(pkt_data)); + + err = load_module("bpf_test_modorder_x.ko", + env_verbosity > VERBOSE_NONE); + if (!ASSERT_OK(err, "load bpf_test_modorder_x.ko")) + return; + + err = load_module("bpf_test_modorder_y.ko", + env_verbosity > VERBOSE_NONE); + if (!ASSERT_OK(err, "load bpf_test_modorder_y.ko")) + goto exit_modx; + + skel = kfunc_module_order__open_and_load(); + if (!ASSERT_OK_PTR(skel, "kfunc_module_order__open_and_load()")) { + err = -EINVAL; + goto exit_mods; + } + + test_run_prog(skel->progs.call_kfunc_xy, &test_opts); + test_run_prog(skel->progs.call_kfunc_yx, &test_opts); + + kfunc_module_order__destroy(skel); +exit_mods: + unload_module("bpf_test_modorder_y", env_verbosity > VERBOSE_NONE); +exit_modx: + unload_module("bpf_test_modorder_x", env_verbosity > VERBOSE_NONE); +} diff --git a/tools/testing/selftests/bpf/progs/kfunc_module_order.c b/tools/testing/selftests/bpf/progs/kfunc_module_order.c new file mode 100644 index 0000000000000000000000000000000000000000..76003d04c95f4eaef4c9f3ec640a0da2a20253e2 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/kfunc_module_order.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +extern int bpf_test_modorder_retx(void) __ksym; +extern int bpf_test_modorder_rety(void) __ksym; + +SEC("classifier") +int call_kfunc_xy(struct __sk_buff *skb) +{ + int ret1, ret2; + + ret1 = bpf_test_modorder_retx(); + ret2 = bpf_test_modorder_rety(); + + return ret1 == 'x' && ret2 == 'y' ? 0 : -1; +} + +SEC("classifier") +int call_kfunc_yx(struct __sk_buff *skb) +{ + int ret1, ret2; + + ret1 = bpf_test_modorder_rety(); + ret2 = bpf_test_modorder_retx(); + + return ret1 == 'y' && ret2 == 'x' ? 0 : -1; +} + +char _license[] SEC("license") = "GPL";