diff mbox series

Use after free in dispatch_hid_bpf_output_report()

Message ID 20250509113905.34947e78@meshulam.tesarici.cz
State New
Headers show
Series Use after free in dispatch_hid_bpf_output_report() | expand

Commit Message

Petr Tesařík May 9, 2025, 9:39 a.m. UTC
Hi all,

after installing v6.15-rc5 on my laptop, I'm running into an invalid
pointer dereference in dispatch_hid_bpf_output_report() on suspend. I
added some debugging messages (see patch below), and I can see this
sequence of events:

[ 1568.571776] [   T7420] PM: suspend entry (deep)
[ 1568.602245] [   T7420] Filesystems sync: 0.030 seconds
[ 1568.613183] [   T1704] hid-generic 0005:04F2:182A.0004: CLEANED UP srcu 00000000b7570e01
[ 1568.613348] [    T724] hid-generic 0005:04F2:182A.0004: UAF srcu 00000000b7570e01
[ 1568.616215] [   T7420] Freezing user space processes

The HID device is a Bluetooth keyboard (using bluez 5.79), which
(presumably) gets disconnected on suspend.

FTR I didn't encounter any such issues with v6.14.

Petr T

Comments

Benjamin Tissoires May 12, 2025, 2:47 p.m. UTC | #1
Hi Petr,


On May 09 2025, Petr Tesařík wrote:
> Hi all,
> 
> after installing v6.15-rc5 on my laptop, I'm running into an invalid
> pointer dereference in dispatch_hid_bpf_output_report() on suspend. I
> added some debugging messages (see patch below), and I can see this
> sequence of events:
> 
> [ 1568.571776] [   T7420] PM: suspend entry (deep)
> [ 1568.602245] [   T7420] Filesystems sync: 0.030 seconds
> [ 1568.613183] [   T1704] hid-generic 0005:04F2:182A.0004: CLEANED UP srcu 00000000b7570e01
> [ 1568.613348] [    T724] hid-generic 0005:04F2:182A.0004: UAF srcu 00000000b7570e01
> [ 1568.616215] [   T7420] Freezing user space processes
> 
> The HID device is a Bluetooth keyboard (using bluez 5.79), which
> (presumably) gets disconnected on suspend.
> 
> FTR I didn't encounter any such issues with v6.14.

Thanks for the patch. I already cc-ed you to the other debugging
thread[0], because I am slightly in favor of the other approach, based
on ->destroyed. Also that other patch prevents the race in other hooks.

Cheers,
Benjamin

[0] https://lore.kernel.org/linux-input/xyfdjeijtdt4sgb4zjmlibdbbvaaly3m3wiqhk7tu35cb2bpip@axziyhfcqx6w/T/#t

> 
> Petr T
> 
> diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
> index 2e96ec6a3073..f284175e8b0b 100644
> --- a/drivers/hid/bpf/hid_bpf_dispatch.c
> +++ b/drivers/hid/bpf/hid_bpf_dispatch.c
> @@ -130,6 +130,11 @@ int dispatch_hid_bpf_output_report(struct hid_device *hdev,
>  	struct hid_bpf_ops *e;
>  	int ret, idx;
>  
> +	if (unlikely(!hdev->bpf.srcu.sda)) {
> +		hid_warn(hdev, "UAF srcu %p", &hdev->bpf.srcu);
> +		return 0;
> +	}
> +
>  	idx = srcu_read_lock(&hdev->bpf.srcu);
>  	list_for_each_entry_srcu(e, &hdev->bpf.prog_list, list,
>  				 srcu_read_lock_held(&hdev->bpf.srcu)) {
> @@ -143,6 +148,8 @@ int dispatch_hid_bpf_output_report(struct hid_device *hdev,
>  	ret = 0;
>  
>  out:
> +	if (unlikely(!hdev->bpf.srcu.sda))
> +		hid_warn(hdev, "RACE srcu %p", &hdev->bpf.srcu);
>  	srcu_read_unlock(&hdev->bpf.srcu, idx);
>  	return ret;
>  }
> @@ -631,6 +638,7 @@ void hid_bpf_destroy_device(struct hid_device *hdev)
>  
>  	synchronize_srcu(&hdev->bpf.srcu);
>  	cleanup_srcu_struct(&hdev->bpf.srcu);
> +	hid_info(hdev, "CLEANED UP srcu %p", &hdev->bpf.srcu);
>  }
>  EXPORT_SYMBOL_GPL(hid_bpf_destroy_device);
>
Petr Tesařík May 12, 2025, 6:28 p.m. UTC | #2
On Mon, 12 May 2025 16:47:12 +0200
Benjamin Tissoires <bentiss@kernel.org> wrote:

> Hi Petr,
> 
> 
> On May 09 2025, Petr Tesařík wrote:
> > Hi all,
> > 
> > after installing v6.15-rc5 on my laptop, I'm running into an invalid
> > pointer dereference in dispatch_hid_bpf_output_report() on suspend. I
> > added some debugging messages (see patch below), and I can see this
> > sequence of events:
> > 
> > [ 1568.571776] [   T7420] PM: suspend entry (deep)
> > [ 1568.602245] [   T7420] Filesystems sync: 0.030 seconds
> > [ 1568.613183] [   T1704] hid-generic 0005:04F2:182A.0004: CLEANED UP srcu 00000000b7570e01
> > [ 1568.613348] [    T724] hid-generic 0005:04F2:182A.0004: UAF srcu 00000000b7570e01
> > [ 1568.616215] [   T7420] Freezing user space processes
> > 
> > The HID device is a Bluetooth keyboard (using bluez 5.79), which
> > (presumably) gets disconnected on suspend.
> > 
> > FTR I didn't encounter any such issues with v6.14.  
> 
> Thanks for the patch. I already cc-ed you to the other debugging
> thread[0], because I am slightly in favor of the other approach, based
> on ->destroyed. Also that other patch prevents the race in other hooks.

Oh, sure thing. My patch was not intended as a fix, rather as a way to
debug the issue, and I included it only for reference.

Thank you for your quick fix!

Petr T
diff mbox series

Patch

diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index 2e96ec6a3073..f284175e8b0b 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -130,6 +130,11 @@  int dispatch_hid_bpf_output_report(struct hid_device *hdev,
 	struct hid_bpf_ops *e;
 	int ret, idx;
 
+	if (unlikely(!hdev->bpf.srcu.sda)) {
+		hid_warn(hdev, "UAF srcu %p", &hdev->bpf.srcu);
+		return 0;
+	}
+
 	idx = srcu_read_lock(&hdev->bpf.srcu);
 	list_for_each_entry_srcu(e, &hdev->bpf.prog_list, list,
 				 srcu_read_lock_held(&hdev->bpf.srcu)) {
@@ -143,6 +148,8 @@  int dispatch_hid_bpf_output_report(struct hid_device *hdev,
 	ret = 0;
 
 out:
+	if (unlikely(!hdev->bpf.srcu.sda))
+		hid_warn(hdev, "RACE srcu %p", &hdev->bpf.srcu);
 	srcu_read_unlock(&hdev->bpf.srcu, idx);
 	return ret;
 }
@@ -631,6 +638,7 @@  void hid_bpf_destroy_device(struct hid_device *hdev)
 
 	synchronize_srcu(&hdev->bpf.srcu);
 	cleanup_srcu_struct(&hdev->bpf.srcu);
+	hid_info(hdev, "CLEANED UP srcu %p", &hdev->bpf.srcu);
 }
 EXPORT_SYMBOL_GPL(hid_bpf_destroy_device);