2021-03-22 20:19:02

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH BlueZ] hog-lib: Fix crash when receiving UHID_GET_REPORT

From: Luiz Augusto von Dentz <[email protected]>

If UHID_GET_REPORT is received but a report cannot be found, etc, the
would pass bt_hog as user_data instead of report to get_report_cb
leading to a crash.

Fixes https://github.com/bluez/bluez/issues/112
---
profiles/input/hog-lib.c | 49 ++++++++++++++++++++++++----------------
1 file changed, 30 insertions(+), 19 deletions(-)

diff --git a/profiles/input/hog-lib.c b/profiles/input/hog-lib.c
index 6ac14e401..e5e3d3e7f 100644
--- a/profiles/input/hog-lib.c
+++ b/profiles/input/hog-lib.c
@@ -786,11 +786,9 @@ fail:
set_report_cb(err, NULL, 0, hog);
}

-static void get_report_cb(guint8 status, const guint8 *pdu, guint16 len,
- gpointer user_data)
+static void report_reply(struct bt_hog *hog, uint8_t status, uint8_t id,
+ uint16_t len, const uint8_t *data)
{
- struct report *report = user_data;
- struct bt_hog *hog = report->hog;
struct uhid_event rsp;
int err;

@@ -800,6 +798,31 @@ static void get_report_cb(guint8 status, const guint8 *pdu, guint16 len,
rsp.type = UHID_GET_REPORT_REPLY;
rsp.u.get_report_reply.id = hog->getrep_id;

+ if (status)
+ goto done;
+
+ if (hog->has_report_id && len > 0) {
+ rsp.u.get_report_reply.size = len + 1;
+ rsp.u.get_report_reply.data[0] = id;
+ memcpy(&rsp.u.get_report_reply.data[1], data, len);
+ } else {
+ rsp.u.get_report_reply.size = len;
+ memcpy(rsp.u.get_report_reply.data, data, len);
+ }
+
+done:
+ rsp.u.get_report_reply.err = status;
+ err = bt_uhid_send(hog->uhid, &rsp);
+ if (err < 0)
+ error("bt_uhid_send: %s", strerror(-err));
+}
+
+static void get_report_cb(guint8 status, const guint8 *pdu, guint16 len,
+ gpointer user_data)
+{
+ struct report *report = user_data;
+ struct bt_hog *hog = report->hog;
+
if (status != 0) {
error("Error reading Report value: %s", att_ecode2str(status));
goto exit;
@@ -820,20 +843,8 @@ static void get_report_cb(guint8 status, const guint8 *pdu, guint16 len,
--len;
++pdu;

- if (hog->has_report_id && len > 0) {
- rsp.u.get_report_reply.size = len + 1;
- rsp.u.get_report_reply.data[0] = report->id;
- memcpy(&rsp.u.get_report_reply.data[1], pdu, len);
- } else {
- rsp.u.get_report_reply.size = len;
- memcpy(rsp.u.get_report_reply.data, pdu, len);
- }
-
exit:
- rsp.u.get_report_reply.err = status;
- err = bt_uhid_send(hog->uhid, &rsp);
- if (err < 0)
- error("bt_uhid_send: %s", strerror(-err));
+ report_reply(hog, status, report->id, len, pdu);
}

static void get_report(struct uhid_event *ev, void *user_data)
@@ -868,8 +879,8 @@ static void get_report(struct uhid_event *ev, void *user_data)
return;

fail:
- /* cancel the request on failure */
- get_report_cb(err, NULL, 0, hog);
+ /* reply with an error on failure */
+ report_reply(hog, err, 0, 0, NULL);
}

static bool get_descriptor_item_info(uint8_t *buf, ssize_t blen, ssize_t *len,
--
2.30.2


2021-03-22 20:37:20

by bluez.test.bot

[permalink] [raw]
Subject: RE: [BlueZ] hog-lib: Fix crash when receiving UHID_GET_REPORT

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=453251

---Test result---

##############################
Test: CheckPatch - PASS

##############################
Test: CheckGitLint - PASS

##############################
Test: CheckBuild - FAIL
Output:
configure.ac:21: installing './compile'
configure.ac:33: installing './config.guess'
configure.ac:33: installing './config.sub'
configure.ac:5: installing './install-sh'
configure.ac:5: installing './missing'
Makefile.am: installing './depcomp'
parallel-tests: installing './test-driver'
configure: error: Embedded Linux library >= 0.37 is required


##############################
Test: MakeCheck - SKIPPED
Output:
checkbuild not success



---
Regards,
Linux Bluetooth

2021-03-31 21:54:54

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH BlueZ] hog-lib: Fix crash when receiving UHID_GET_REPORT

Hi,

On Mon, Mar 22, 2021 at 1:16 PM Luiz Augusto von Dentz
<[email protected]> wrote:
>
> From: Luiz Augusto von Dentz <[email protected]>
>
> If UHID_GET_REPORT is received but a report cannot be found, etc, the
> would pass bt_hog as user_data instead of report to get_report_cb
> leading to a crash.
>
> Fixes https://github.com/bluez/bluez/issues/112
> ---
> profiles/input/hog-lib.c | 49 ++++++++++++++++++++++++----------------
> 1 file changed, 30 insertions(+), 19 deletions(-)
>
> diff --git a/profiles/input/hog-lib.c b/profiles/input/hog-lib.c
> index 6ac14e401..e5e3d3e7f 100644
> --- a/profiles/input/hog-lib.c
> +++ b/profiles/input/hog-lib.c
> @@ -786,11 +786,9 @@ fail:
> set_report_cb(err, NULL, 0, hog);
> }
>
> -static void get_report_cb(guint8 status, const guint8 *pdu, guint16 len,
> - gpointer user_data)
> +static void report_reply(struct bt_hog *hog, uint8_t status, uint8_t id,
> + uint16_t len, const uint8_t *data)
> {
> - struct report *report = user_data;
> - struct bt_hog *hog = report->hog;
> struct uhid_event rsp;
> int err;
>
> @@ -800,6 +798,31 @@ static void get_report_cb(guint8 status, const guint8 *pdu, guint16 len,
> rsp.type = UHID_GET_REPORT_REPLY;
> rsp.u.get_report_reply.id = hog->getrep_id;
>
> + if (status)
> + goto done;
> +
> + if (hog->has_report_id && len > 0) {
> + rsp.u.get_report_reply.size = len + 1;
> + rsp.u.get_report_reply.data[0] = id;
> + memcpy(&rsp.u.get_report_reply.data[1], data, len);
> + } else {
> + rsp.u.get_report_reply.size = len;
> + memcpy(rsp.u.get_report_reply.data, data, len);
> + }
> +
> +done:
> + rsp.u.get_report_reply.err = status;
> + err = bt_uhid_send(hog->uhid, &rsp);
> + if (err < 0)
> + error("bt_uhid_send: %s", strerror(-err));
> +}
> +
> +static void get_report_cb(guint8 status, const guint8 *pdu, guint16 len,
> + gpointer user_data)
> +{
> + struct report *report = user_data;
> + struct bt_hog *hog = report->hog;
> +
> if (status != 0) {
> error("Error reading Report value: %s", att_ecode2str(status));
> goto exit;
> @@ -820,20 +843,8 @@ static void get_report_cb(guint8 status, const guint8 *pdu, guint16 len,
> --len;
> ++pdu;
>
> - if (hog->has_report_id && len > 0) {
> - rsp.u.get_report_reply.size = len + 1;
> - rsp.u.get_report_reply.data[0] = report->id;
> - memcpy(&rsp.u.get_report_reply.data[1], pdu, len);
> - } else {
> - rsp.u.get_report_reply.size = len;
> - memcpy(rsp.u.get_report_reply.data, pdu, len);
> - }
> -
> exit:
> - rsp.u.get_report_reply.err = status;
> - err = bt_uhid_send(hog->uhid, &rsp);
> - if (err < 0)
> - error("bt_uhid_send: %s", strerror(-err));
> + report_reply(hog, status, report->id, len, pdu);
> }
>
> static void get_report(struct uhid_event *ev, void *user_data)
> @@ -868,8 +879,8 @@ static void get_report(struct uhid_event *ev, void *user_data)
> return;
>
> fail:
> - /* cancel the request on failure */
> - get_report_cb(err, NULL, 0, hog);
> + /* reply with an error on failure */
> + report_reply(hog, err, 0, 0, NULL);
> }
>
> static bool get_descriptor_item_info(uint8_t *buf, ssize_t blen, ssize_t *len,
> --
> 2.30.2

Applied.

--
Luiz Augusto von Dentz