Received: by 2002:ab2:6991:0:b0:1f7:f6c3:9cb1 with SMTP id v17csp402661lqo; Wed, 8 May 2024 03:29:03 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCUGonLPRu5Gnef1D5HF23/lLuVpAcg9ek95npm+qdJP/adCMuTC2+0YfPzEwkcUlyCB73Zw78M9Ab6rD5ZUE+9zOhMd/9PDIzUErW0gdg== X-Google-Smtp-Source: AGHT+IHJX+M0L+eMPlh3Nic7G5nhTO4si/OniUpccOnT+5bvhTG0/Vi8jYFz7qsgLye8XeK0QeFt X-Received: by 2002:a17:906:1110:b0:a59:b1cf:fea3 with SMTP id a640c23a62f3a-a59fb947c87mr125908766b.3.1715164143733; Wed, 08 May 2024 03:29:03 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1715164143; cv=pass; d=google.com; s=arc-20160816; b=gbWMiWd3pKTye+1Z7PPxc2woGzdyZNEy9BSniZRCTqIIvmlkeC/GWmiurfPh93izIr OC3z7n2yPKax2EHzwaZsOVhd4kUUvjygs/y69Hu9olgQPdCTFM4jMHcXwLAk/6r3B5s7 02UseQIumc0+cgqKZ5GcK+D4YiGuVMrHd5kg+Pv3e19u+bnqlpvL1rp04bjohhLkuv9D fiM/ti/t5IEs5TK/FyBelvJLzqMGytVxbyCFt6YYarpHobuoMll0SLrGSyPxRXVq00Hr YQRrSWyQHYLDoRH6OqjkUs0sTVu+I+9zj6PczHdEWHhjgYzg4oh38TZvw9cnmemCnezZ 8/0Q== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:list-unsubscribe:list-subscribe:list-id:precedence :subject:date:from:dkim-signature; bh=5PP9Qy81m18PnqXenWKEhrFy9eeoNa7YXJUUGfh2BvE=; fh=2Qfsg0WOtJrwq8299N4MaGAPw9hpNnc5g4i36eCtx0s=; b=fDKO19fAqEEJJJBnHATp4ChuXDrB+Ut3I627xQRZqj6V7TlGWrxU/zgI6QJ/kA+ZMP SNzuIi2+S+XYUgrg4wAtO60JGvF6KPcvAtqfgHV53898d+M1fgoN5WBk6i6XKfRFhffH Yajfp4eQxM6gJRVX3Si6EMEY/RYpEsLtR0OyZ2dWHU1u11js87oLn1io90VryLfNbfTy KsgttvfmTmPVL/XlyPpd9sMNFMz2Zn7+qNFWhOGKIJLoO734+OGDXAWxJx1+OMmrdoDZ cLd/U7k05rIxgvumuFkPC2ddFM1JjVf67y8zkJqs+19z3+Tk55mMEHdRZ2HNC+2RLHzY pPSg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=twAoqDhV; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-173063-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-173063-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id hr11-20020a1709073f8b00b00a59dd9955afsi2519970ejc.18.2024.05.08.03.29.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 May 2024 03:29:03 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-173063-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=twAoqDhV; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-173063-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-173063-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 4D7A61F21447 for ; Wed, 8 May 2024 10:29:03 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CF09980C16; Wed, 8 May 2024 10:27:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="twAoqDhV" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A913180BE3; Wed, 8 May 2024 10:27:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164043; cv=none; b=mT0Nw1tDFSKbbbgXPhH0m/208SMrOho6z4Dt51jng8mWVExDXTkLhl7QOxraMrTIeOj8c/WcJVHeQ8R/mGdt51F3iSALeUglm1AQM2NvDJ33mrolpknBdnAbfN7Oi5CPX8uffX9bLJjz490I7oztGjcS0MpV1vItTr7k8vFb0so= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715164043; c=relaxed/simple; bh=9waEZf/wX6l7KSv3TGWZ2a108xaQGTbk2eaVsTu2CFc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZQpotUruvX8iUNP6wd9/va9LAU2snu+fKPWwXlkQLM3CvRcRyi+sMr34mXEP7ANwStPu8dOlCB77DGBPZxN61Vv1DIv9x14jCQgD9W0ob2RtJi0geQ0Vaf29NF51kXLFZuTfZiRzjT5Sr/5D3GBiU3NIrdE4hgUIW8BGvWjjtzg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=twAoqDhV; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 45CCBC113CC; Wed, 8 May 2024 10:27:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1715164043; bh=9waEZf/wX6l7KSv3TGWZ2a108xaQGTbk2eaVsTu2CFc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=twAoqDhVc6j+5cG9bW/+SnuFXZ3pnTIo2y+Gk+ayDG0rjPn4uPRlGk2H9ojZ2RPHf jC5xlsET5/XMxYps4uA2N8IVhKu8/8S+H6n7qWZXavKTVQ8DLwNqB58gPV4xM3ebH/ iYuONRYgXYBbmhLI/pPziCOnwqiY9UL/salBWxBSoXJBH89rm0DpZNmREPoZS+XAti yKLp/URvcrbf/hs6PkyB8689xqahuHt4dDHjRz5b/oc3+FRjvu05k12cNTlUbY2R9p oZ/OspzoWTtshJiljk7jVX6+kxivQUE+QKyFd7Rpz21/hWYuCKbXPXdd7BYqxG5Ze5 xagE4OLoPb6jA== From: Benjamin Tissoires Date: Wed, 08 May 2024 12:26:41 +0200 Subject: [PATCH RFC HID 6/7] WIP: selftests/hid: add tests for hid_hw_raw_request HID-BPF hooks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20240508-hid_bpf_async_fun-v1-6-558375a25657@kernel.org> References: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> In-Reply-To: <20240508-hid_bpf_async_fun-v1-0-558375a25657@kernel.org> To: Benjamin Tissoires Cc: linux-kernel@vger.kernel.org, linux-input@vger.kernel.org, bpf@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.12.4 X-Developer-Signature: v=1; a=ed25519-sha256; t=1715164017; l=8381; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=9waEZf/wX6l7KSv3TGWZ2a108xaQGTbk2eaVsTu2CFc=; b=HYLnB3YF5tVYYctI5AVxJ0cl2CSHeXhATB4kXQdS4os/a2n8SPgf/9Ta30cNl2pc2X4p1Y5yK DshsY4hqrQHDCHCd0UR+0sFqMypD9zTVGD6HxnBy1EzEVrqUA7uFCNJ X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= Signed-off-by: Benjamin Tissoires --- tools/testing/selftests/hid/hid_bpf.c | 55 ++++++++++++++++++++++ tools/testing/selftests/hid/progs/hid.c | 51 ++++++++++++++++++++ .../testing/selftests/hid/progs/hid_bpf_helpers.h | 39 +++++++++------ 3 files changed, 130 insertions(+), 15 deletions(-) diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c index 7fed9f599b62..522fc32a5c38 100644 --- a/tools/testing/selftests/hid/hid_bpf.c +++ b/tools/testing/selftests/hid/hid_bpf.c @@ -469,6 +469,8 @@ static void detach_bpf(FIXTURE_DATA(hid_bpf) * self) close(self->hidraw_fd); self->hidraw_fd = 0; + // hid__detach(self->skel); + for (i = 0; i < ARRAY_SIZE(self->hid_links); i++) { if (self->hid_links[i]) close(self->hid_links[i]); @@ -572,6 +574,8 @@ static void load_programs(const struct test_program programs[], self->hid_links[i] = args.retval; } + // hid__attach(self->skel); + self->hidraw_fd = open_hidraw(self->dev_id); ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); } @@ -871,6 +875,57 @@ TEST_F(hid_bpf, test_hid_user_raw_request_call) ASSERT_EQ(args.data[1], 2); } +/* + * Call hid_hw_raw_request against the given uhid device, + * check that the program is called and does the expected. + */ +TEST_F(hid_bpf, test_hid_filter_raw_request_call) +{ + const struct test_program progs[] = { + { .name = "hid_test_filter_raw_request" }, + { .name = "hid_test_raw_request" }, + }; + __u8 buf[10] = {0}; + int err; + + LOAD_PROGRAMS(progs); + + /* first check that we did not attach to device_event */ + + /* inject one event */ + buf[0] = 1; + buf[1] = 42; + uhid_send_event(_metadata, self->uhid_fd, buf, 6); + + /* read the data from hidraw */ + memset(buf, 0, sizeof(buf)); + err = read(self->hidraw_fd, buf, sizeof(buf)); + ASSERT_EQ(err, 6) TH_LOG("read_hidraw"); + ASSERT_EQ(buf[0], 1); + ASSERT_EQ(buf[1], 42); + ASSERT_EQ(buf[2], 0) TH_LOG("leftovers_from_previous_test"); + + /* now check that our program is preventing hid_hw_raw_request() */ + + /* emit hid_hw_raw_request from hidraw */ + /* Get Feature */ + memset(buf, 0, sizeof(buf)); + buf[0] = 0x1; /* Report Number */ + err = ioctl(self->hidraw_fd, HIDIOCGFEATURE(sizeof(buf)), buf); + ASSERT_LT(err, 0) TH_LOG("unexpected success while reading HIDIOCGFEATURE: %d", err); + + /* remove our bpf program and check that we can now emit commands */ + + /* detach the program */ + detach_bpf(self); + + self->hidraw_fd = open_hidraw(self->dev_id); + ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); + + err = ioctl(self->hidraw_fd, HIDIOCGFEATURE(sizeof(buf)), buf); + ASSERT_GE(err, 0) TH_LOG("error while reading HIDIOCGFEATURE: %d", err); +} + /* * Attach hid_insert{0,1,2} to the given uhid device, * retrieve and open the matching hidraw node, diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selftests/hid/progs/hid.c index b721d1256836..64aaa279bec4 100644 --- a/tools/testing/selftests/hid/progs/hid.c +++ b/tools/testing/selftests/hid/progs/hid.c @@ -226,3 +226,54 @@ HID_BPF_DEVICE_EVENT(hid_test_insert3, struct hid_bpf_ctx *hid_ctx) return 0; } + +// SEC("fentry/hidraw_open") +// int BPF_PROG(hidraw_open, struct inode *inode, struct file *file) +// { +// bpf_printk("inode: %llx, file: %llx", (u64)inode, (u64)file); +// return 0; +// } + +HID_BPF_RAW_REQUEST(hid_test_filter_raw_request, struct hid_bpf_ctx *hctx) +{ + bpf_printk("in %s:%d", __func__, __LINE__); + return 0; +} + +HID_BPF_SLEEPABLE_RAW_REQUEST(hid_test_raw_request, struct hid_bpf_ctx *hctx) +{ + struct test_report buf = { + .data = {2, 3, 4, 5, 6, 7}, + }; + __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 2 /* size */); + int ret; + + bpf_printk("in %s, hctx: %llx source: %llx", __func__, (u64)hctx, hctx->source); + + if (!data) + return 0; /* EPERM check */ + bpf_printk("in %s:%d", __func__, __LINE__); + + if (hctx->source) { + hid_bpf_input_report(hctx, HID_INPUT_REPORT, buf.data, sizeof(buf.data)); + + /* still forward the request as-is to the device, hid-bpf will not + * call us again. + */ + + data[0] = hctx->reportnum; + + ret = hid_bpf_hw_request(hctx, + data, + 2, + hctx->report_type, + hctx->reqtype); + bpf_printk("ret: %d", ret); + if (ret) + return ret; + return -1; + } + + bpf_printk("in %s:%d", __func__, __LINE__); + return 0; +} diff --git a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h index 9826880e88d1..779ec151c717 100644 --- a/tools/testing/selftests/hid/progs/hid_bpf_helpers.h +++ b/tools/testing/selftests/hid/progs/hid_bpf_helpers.h @@ -56,17 +56,6 @@ enum hid_report_type { HID_REPORT_TYPES, }; -struct hid_bpf_ctx { - __u32 index; - const struct hid_device *hid; - __u32 allocated_size; - enum hid_report_type report_type; - union { - __s32 retval; - __s32 size; - }; -} __attribute__((preserve_access_index)); - enum hid_class_request { HID_REQ_GET_REPORT = 0x01, HID_REQ_GET_IDLE = 0x02, @@ -88,6 +77,20 @@ struct attach_prog_args { int insert_head; }; +struct hid_bpf_ctx { + __u32 index; + __u32 allocated_size; + __u64 source; + const struct hid_device *hid; + enum hid_report_type report_type; + enum hid_class_request reqtype; /* for HID_BPF_PROG_TYPE_RAW_REQUEST */ + union { + __s32 retval; + __s32 size; + }; + __u8 reportnum; +} __attribute__((preserve_access_index)); + /* following are kfuncs exported by HID for HID-BPF */ extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, @@ -96,6 +99,10 @@ extern int hid_bpf_attach_prog_impl(unsigned int hid_id, enum hid_bpf_prog_type type, int (prog_fn)(struct hid_bpf_ctx *hid_ctx), u32 flags, void *aux) __ksym; +extern int hid_bpf_attach_sleepable_prog_impl(unsigned int hid_id, + enum hid_bpf_prog_type type, + int (prog_fn)(struct hid_bpf_ctx *hid_ctx), + u32 flags, void *aux) __ksym; extern struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id) __ksym; extern void hid_bpf_release_context(struct hid_bpf_ctx *ctx) __ksym; extern int hid_bpf_hw_request(struct hid_bpf_ctx *ctx, @@ -110,12 +117,12 @@ extern int hid_bpf_input_report(struct hid_bpf_ctx *ctx, __u8 *data, size_t buf__sz) __ksym; -#define __HID_BPF_PROG(type, name, arg) \ +#define __HID_BPF_PROG(type, name, arg, sleepable) \ static int __##name(arg); \ SEC("syscall") \ int name(struct attach_prog_args *ctx) \ { \ - ctx->retval = hid_bpf_attach_prog_impl(ctx->hid, \ + ctx->retval = hid_bpf_attach_##sleepable##prog_impl(ctx->hid, \ type, \ __##name, \ ctx->insert_head ? HID_BPF_FLAG_INSERT_HEAD : \ @@ -125,7 +132,9 @@ extern int hid_bpf_input_report(struct hid_bpf_ctx *ctx, } \ static int __##name(arg) -#define HID_BPF_DEVICE_EVENT(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_DEVICE_EVENT, name, arg) -#define HID_BPF_RDESC_FIXUP(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RDESC_FIXUP, name, arg) +#define HID_BPF_DEVICE_EVENT(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_DEVICE_EVENT, name, arg, ) +#define HID_BPF_RDESC_FIXUP(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RDESC_FIXUP, name, arg, ) +#define HID_BPF_RAW_REQUEST(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RAW_REQUEST, name, arg, ) +#define HID_BPF_SLEEPABLE_RAW_REQUEST(name, arg) __HID_BPF_PROG(HID_BPF_PROG_TYPE_RAW_REQUEST, name, arg, sleepable_) #endif /* __HID_BPF_HELPERS_H */ -- 2.44.0