Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp2164575pxb; Fri, 25 Mar 2022 12:14:21 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzbrHEVW+09kXYW52IX6QovflwiXiwbw1qP09BFoRU6Cqw54xgEjuL/6uUIe6iiyt+9Tdme X-Received: by 2002:a17:90b:4a06:b0:1c7:2020:b5b9 with SMTP id kk6-20020a17090b4a0600b001c72020b5b9mr14425520pjb.58.1648235661330; Fri, 25 Mar 2022 12:14:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648235661; cv=none; d=google.com; s=arc-20160816; b=wcICJneKUlToVSW5s9IznrsfMEUs+v+dUrXjEImMxKD63sH/BMQQhhdEr3rS0Kc8qD AxlHyrL6/Aq5rICkmeDaXMilZa1FE4NNV8ubxRfr+/C/UL91PdtB7vrvjIrAX5xzy+/F 6jVFHA7C4XgmrsfJfAnRhx9cpE44DDqx6tjvtEN0wQ7DmBvF50zqN6gZj4bBT6CQLO/r uqagznrBo7JzEihBb33XARvrd/QzXYh3jadqcQnOZNoDtlXsg32QJpU5N4gqwk6OPk16 hqPVdPKzuRTWXyPYYJvr96vItQw+xYGKaNNvoCV7dCqoCwy2xO+BkFo5mYQVQ8J0H2jx UWfA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=jojw5f7wnm9EHe+O1hZXC5y0oSm+5NVhYv4rzpOxMAw=; b=Z839fOvgf+nuw5mFTqYGAsNeiXAfe09Oj9x6eqZSQXrAhjP0S1Im1JY7NhXAqM+N3G X0pN4od9Hu3JBfvrWa3Ds5X4em/bahglpiA928bhylCqD7ZPkYou9jgtl7tdPZPjsNCh +ro13vCV+8wQZS0n9CFxtuNwvcti0bTVGjL4OAC5uhCyMqsPqh18ZWu5ZZOlgKctjVO4 KPaLB5AGOBoW3xfLWuxlRMsqXEV7p4fEHnxnwJ5YFjnfIz7uDb4F3rfF0MspSiiPi8la RV0ZPUb2PxntJ8uNAKHRXwyQx5gwGLyD+9+4fI6oDf94KprAkxwQKcbyFcXUkkZ60R/8 IMOA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=WAsL+ZxA; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id v2-20020a634802000000b003829aca7f1asi3106501pga.637.2022.03.25.12.14.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Mar 2022 12:14:21 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=WAsL+ZxA; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 4EEEF21F75B; Fri, 25 Mar 2022 11:19:14 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238473AbiCWQKQ (ORCPT + 99 others); Wed, 23 Mar 2022 12:10:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46906 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238404AbiCWQKM (ORCPT ); Wed, 23 Mar 2022 12:10:12 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 813AE2DA95 for ; Wed, 23 Mar 2022 09:08:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1648051721; 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: in-reply-to:in-reply-to:references:references; bh=jojw5f7wnm9EHe+O1hZXC5y0oSm+5NVhYv4rzpOxMAw=; b=WAsL+ZxAp/hZtNdMQzdqqn81M3kM8Q39CKsv6a0mrL+itPboDXl0eXxWK6jMxnbGWxazVu jA00TR+i6H1S6gZRNZXgzF8wirGtMoXDqRL12DwKZKwTuLBPsVEnI5Nf/glujcdmhUBBem ISnbJWdElTb8aSD0EtNwY9jOKhR3ylw= Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-119-71qujBo9NyyC8uLJY4A1uA-1; Wed, 23 Mar 2022 12:08:39 -0400 X-MC-Unique: 71qujBo9NyyC8uLJY4A1uA-1 Received: by mail-pj1-f72.google.com with SMTP id mm2-20020a17090b358200b001bf529127dfso1332949pjb.6 for ; Wed, 23 Mar 2022 09:08:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=jojw5f7wnm9EHe+O1hZXC5y0oSm+5NVhYv4rzpOxMAw=; b=JaIQLBnBe2HYVpum4bPVHBNf17hUGvl+9+klFpJnmnG1iNfyPz3kEXcLmsYOp4krM9 E/FQzzY2bRyagam/pvF3SEGSa5k9aDifv3tDdEbJuDnWcDL3Pzro8b2WBm1eI3l8VYw7 tJ59Ub8rT41daGki6XeSfPVvPWlYry49rvRie2v6UfOZW7+RNqzgDffr1uvAFxyd3hD7 2WltIzgf5FV0pjraCV/sKg/OqOMQNCFCikr+4yknNH2o3fLusVqkbv6lqCWcFiwHfa5a o2jzdHvE8WTzx+zmiM5fhXf4y5o5CD2v8Ig8ykk2KwKxAg8gFvwpU//m4b7sk7SvYDyW 2GNg== X-Gm-Message-State: AOAM533uUVrZ8PJB+3uwxQKk3D8qRDPFJpEF3a6DaNTcb/m7YBnVv0sM /oz2z4/serc12/Epr3XyV2NGULZl4QDW/Ok1rxxepUDoNGtL7BsiGxwiFygM8tDVuFEVjem3m6b qxvt8VoHQW9Tb2L5k0eyTCLFO6ZhJ7w3kQ6vaa1TH X-Received: by 2002:a05:6a00:2182:b0:4fa:6d20:d95d with SMTP id h2-20020a056a00218200b004fa6d20d95dmr255512pfi.83.1648051717848; Wed, 23 Mar 2022 09:08:37 -0700 (PDT) X-Received: by 2002:a05:6a00:2182:b0:4fa:6d20:d95d with SMTP id h2-20020a056a00218200b004fa6d20d95dmr255474pfi.83.1648051717452; Wed, 23 Mar 2022 09:08:37 -0700 (PDT) MIME-Version: 1.0 References: <20220318161528.1531164-1-benjamin.tissoires@redhat.com> <20220318161528.1531164-7-benjamin.tissoires@redhat.com> In-Reply-To: From: Benjamin Tissoires Date: Wed, 23 Mar 2022 17:08:25 +0100 Message-ID: Subject: Re: [PATCH bpf-next v3 06/17] HID: allow to change the report descriptor from an eBPF program To: Alexei Starovoitov Cc: Greg KH , Jiri Kosina , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , Shuah Khan , Dave Marchevsky , Joe Stringer , Jonathan Corbet , Tero Kristo , LKML , "open list:HID CORE LAYER" , Network Development , bpf , "open list:KERNEL SELFTEST FRAMEWORK" , "open list:DOCUMENTATION" Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-3.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Alexei, On Tue, Mar 22, 2022 at 11:51 PM Alexei Starovoitov wrote: > > On Fri, Mar 18, 2022 at 9:16 AM Benjamin Tissoires > wrote: > > > > +u8 *hid_bpf_report_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *size) > > +{ > > + int ret; > > + struct hid_bpf_ctx_kern ctx = { > > + .type = HID_BPF_RDESC_FIXUP, > > + .hdev = hdev, > > + .size = *size, > > + }; > > + > > + if (bpf_hid_link_empty(&hdev->bpf, BPF_HID_ATTACH_RDESC_FIXUP)) > > + goto ignore_bpf; > > + > > + ctx.data = kmemdup(rdesc, HID_MAX_DESCRIPTOR_SIZE, GFP_KERNEL); > > + if (!ctx.data) > > + goto ignore_bpf; > > + > > + ctx.allocated_size = HID_MAX_DESCRIPTOR_SIZE; > > + > > + ret = hid_bpf_run_progs(hdev, &ctx); > > + if (ret) > > + goto ignore_bpf; > > + > > + if (ctx.size > ctx.allocated_size) > > + goto ignore_bpf; > > + > > + *size = ctx.size; > > + > > + if (*size) { > > + rdesc = krealloc(ctx.data, *size, GFP_KERNEL); > > + } else { > > + rdesc = NULL; > > + kfree(ctx.data); > > + } > > + > > + return rdesc; > > + > > + ignore_bpf: > > + kfree(ctx.data); > > + return kmemdup(rdesc, *size, GFP_KERNEL); > > +} > > + > > int __init hid_bpf_module_init(void) > > { > > struct bpf_hid_hooks hooks = { > > .hdev_from_fd = hid_bpf_fd_to_hdev, > > .pre_link_attach = hid_bpf_pre_link_attach, > > + .post_link_attach = hid_bpf_post_link_attach, > > .array_detach = hid_bpf_array_detach, > > }; > > > > diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c > > index 937fab7eb9c6..3182c39db006 100644 > > --- a/drivers/hid/hid-core.c > > +++ b/drivers/hid/hid-core.c > > @@ -1213,7 +1213,8 @@ int hid_open_report(struct hid_device *device) > > return -ENODEV; > > size = device->dev_rsize; > > > > - buf = kmemdup(start, size, GFP_KERNEL); > > + /* hid_bpf_report_fixup() ensures we work on a copy of rdesc */ > > + buf = hid_bpf_report_fixup(device, start, &size); > > Looking at this patch and the majority of other patches... > the code is doing a lot of work to connect HID side with bpf. > At the same time the evolution of the patch series suggests > that these hook points are not quite stable. More hooks and > helpers are being added. > It tells us that it's way too early to introduce a stable > interface between HID and bpf. I understand that you might be under the impression that the interface is changing a lot, but this is mostly due to my poor knowledge of all the arcanes of eBPF. The overall way HID-BPF works is to work on a single array, and we should pretty much be sorted out. There are a couple of helpers to be able to communicate with the device, but the API has been stable in the kernel for those for quite some time now. The variations in the hooks is mostly because I don't know what is the best representation we can use in eBPF for those, and the review process is changing that. > We suggest to use __weak global functions and unstable kfunc helpers > to achieve the same goal. > This way HID side and bpf side can evolve without introducing > stable uapi burden. > For example this particular patch can be compressed to: > __weak int hid_bpf_report_fixup(struct hid_device *hdev, u8 *rdesc, > unsigned int *size) > { > return 0; > } > ALLOW_ERROR_INJECTION(ALLOW_ERROR_INJECTION, ERRNO); > > - buf = kmemdup(start, size, GFP_KERNEL); > + if (!hid_bpf_report_fixup(device, start, &size)) > + buf = kmemdup(start, size, GFP_KERNEL); > > Then bpf program can replace hid_bpf_report_fixup function and adjust its > return value while reading args. I appreciate the suggestion and gave it a try, but AFAICT this doesn't work for HID (please correct me if I am wrong): - I tried to use __weak to replace the ugly struct bpf_hid_hooks This struct is in place simply because the HID module can be compiled in as a kernel module and we might not have the symbols available from kernel/bpf when it is a separate module. Either I did something wrong, but it seems that when we load the module in the kernel, there is no magic that overrides the weak symbols from the ones from the modules. - for hid_bpf_report_fixup(), this would mean that a BPF program could overwrite the function This is great, but I need to have one program per device, not one globally defined function. I can not have a generic report_fixup in the system, simply because you might need 2 different functions for 2 different devices. We could solve that by auto-generating the bpf program based on which devices are available, but that would mean that users will see a reconnect of all of their input devices when they plug in a new one, and will also require them to have LLVM installed, which I do not want. - for stuff like hid_bpf_raw_event(), I want to have multiple programs attached to the various devices, and not necessarily the same across devices. This is basically the same as above, except that I need to chain programs. For instance, we could have a program that "fixes" one device, but I also want to attach a tracing program on top of it to monitor what is happening. > > Similar approach can be done with all other hooks. > > Once api between HID and bpf stabilizes we can replace nop functions > with writeable tracepoints to make things a bit more stable > while still allowing for change of the interface in the future. > > The amount of bpf specific code in HID core will be close to zero > while bpf can be used to flexibly tweak it. Again, I like the idea, but I clearly don't see where you want to go. From what I see, this is incompatible with the use cases I have. > > kfunc is a corresponding mechanism to introduce unstable api > from bpf into the kernel instead of stable helpers. > Just whitelist some functions as unstable kfunc helpers and call them > from bpf progs. > See net/bpf/test_run.c and bpf_kfunc_call* for inspiration. > I also like this idea. However, for hid_hw_raw_request() I can not blindly enable that function in all program types. This function makes the kernel sleep, and so we can not use it while in IRQ context. I think I can detect if we are in IRQ or not, but is it really worth enabling it across all BPF program types when we know that only SEC("hid/user_event") will use it? Also, I am not sure how we can make bpf_hid_get_data() work with that. We need to teach the verifier how much memory is provided, and I do not see how you can do that with kfunc. Cheers, Benjamin