mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jinmo Yang <jinmo44.yang@gmail.com>
To: Jiri Kosina <jikos@kernel.org>, Benjamin Tissoires <bentiss@kernel.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	David Barksdale <dbarksdale@uplogix.com>,
	linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
	Jinmo Yang <jinmo44.yang@gmail.com>,
	stable@vger.kernel.org
Subject: [PATCH] HID: cp2112: don't dereference hdev->hidraw unconditionally
Date: Wed, 14 Oct 2026 10:38:47 +0000	[thread overview]
Message-ID: <20261014103849.1837692-1-jinmo44.yang@gmail.com> (raw)
In-Reply-To: <20261014051326.3784498-4-dmitry.torokhov@gmail.com>

cp2112_probe() builds the I2C adapter name from the hidraw minor:

	snprintf(dev->adap.name, sizeof(dev->adap.name),
		 "CP2112 SMBus Bridge on hidraw%d",
		 ((struct hidraw *)hdev->hidraw)->minor);

hdev->hidraw is set only when hidraw_connect() succeeds; on failure it
stays NULL and reading ->minor faults.  hidraw_connect() fails when all
HIDRAW_MAX_DEVICES minors are in use, or on allocation failure.

hid_hw_start() does not report that.  hid_connect() has

	if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev))
		hdev->claimed |= HID_CLAIMED_HIDRAW;
	...
	if (!hdev->claimed && !hdev->driver->raw_event) {
		hid_err(hdev, "device has no listeners, quitting\n");
		return -ENODEV;
	}

When hidraw_connect() fails, claimed stays 0 -- but that bail-out also
requires the driver to have no ->raw_event.  cp2112 sets
.raw_event = cp2112_raw_event, so the -ENODEV path is skipped,
hid_connect() returns 0, cp2112_probe() passes its "if (ret)" check, and
the dereference faults.

The minor is only used for the adapter name, so fall back to the device
name instead of failing the probe.

Found by coverage-guided fuzzing of the HID subsystem through /dev/uhid
(syzkaller with extended descriptions), arm64 with KASAN:

Unable to handle kernel paging request at virtual address dfff800000000000
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
pc : cp2112_probe+0x794/0xef0 drivers/hid/hid-cp2112.c:1333
Call trace:
 cp2112_probe
 __hid_device_probe
 hid_device_probe
 really_probe
 device_add
 hid_add_device
 uhid_device_add_worker
 process_one_work

hid-led.c and hid-u2fzero.c read hdev->hidraw the same way, but neither
sets ->raw_event, so for them hid_connect() does return -ENODEV and their
error checks catch it.  cp2112 is the only one of the three where the
bail-out is defeated.

Fixes: 42cb6b35b9e6 ("HID: cp2112: use proper hidraw name with minor number")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
---
This is the minimal, backportable fix.  Dmitry's series

  [PATCH 0/5] HID: hidraw: Encapsulate struct hidraw and make hidraw.h private
  https://lore.kernel.org/linux-input/20261014051326.3784498-1-dmitry.torokhov@gmail.com/

solves the same thing more thoroughly in mainline: 2/5 adds
hidraw_instance(), which performs this check in one place, 3/5 converts
cp2112 (and hid-led and hid-u2fzero) to it, and 5/5 makes the raw cast
impossible by moving hidraw.h out of include/linux.  That is the better
end state and I am not proposing an alternative to it.

I am sending this separately only because that series moves headers and
touches include/linux/hid.h, so it is not a stable candidate, while the
dereference itself has been reachable since v4.12.  If you would rather
tag 2/5 and 3/5 for stable instead, please drop this patch -- that works
equally well for me and I will not resend it.

Either way the oops is real and unprivileged; the trace above is from
/dev/uhid with no special capabilities.  I can test whichever way you go.

 drivers/hid/hid-cp2112.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c
index 04379db93571..8883023d432d 100644
--- a/drivers/hid/hid-cp2112.c
+++ b/drivers/hid/hid-cp2112.c
@@ -1330,9 +1330,13 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	dev->adap.algo		= &smbus_algorithm;
 	dev->adap.algo_data	= dev;
 	dev->adap.dev.parent	= &hdev->dev;
-	snprintf(dev->adap.name, sizeof(dev->adap.name),
-		 "CP2112 SMBus Bridge on hidraw%d",
-		 ((struct hidraw *)hdev->hidraw)->minor);
+	if (hdev->claimed & HID_CLAIMED_HIDRAW)
+		snprintf(dev->adap.name, sizeof(dev->adap.name),
+			 "CP2112 SMBus Bridge on hidraw%d",
+			 ((struct hidraw *)hdev->hidraw)->minor);
+	else
+		snprintf(dev->adap.name, sizeof(dev->adap.name),
+			 "CP2112 SMBus Bridge on %s", dev_name(&hdev->dev));
 	dev->hwversion = buf[2];
 	init_waitqueue_head(&dev->wait);
 
-- 
2.43.0


  reply	other threads:[~2026-10-14 10:41 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-14  5:13 [PATCH 0/5] HID: hidraw: Encapsulate struct hidraw and make hidraw.h private Dmitry Torokhov
2026-10-14  5:13 ` [PATCH 1/5] HID: core: Move internal declarations and drop unused exports Dmitry Torokhov
2026-10-14  5:13 ` [PATCH 2/5] HID: hidraw: Introduce hidraw_instance() helper Dmitry Torokhov
2026-10-14  5:13 ` [PATCH 3/5] HID: Use hidraw_instance() in drivers Dmitry Torokhov
2026-10-14 10:38   ` Jinmo Yang [this message]
2026-10-14 13:50     ` [PATCH] HID: cp2112: don't dereference hdev->hidraw unconditionally Benjamin Tissoires
2026-10-14  5:13 ` [PATCH 4/5] HID: Drop unused linux/hidraw.h includes Dmitry Torokhov
2026-10-14  5:13 ` [PATCH 5/5] HID: hidraw: Make hidraw.h private to HID subsystem Dmitry Torokhov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261014103849.1837692-1-jinmo44.yang@gmail.com \
    --to=jinmo44.yang@gmail.com \
    --cc=bentiss@kernel.org \
    --cc=dbarksdale@uplogix.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=jikos@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®