* [PATCH] hog: Fix report_value_cb()
@ 2014-05-09 1:40 Petri Gynther
2014-05-09 11:50 ` Johan Hedberg
0 siblings, 1 reply; 3+ messages in thread
From: Petri Gynther @ 2014-05-09 1:40 UTC (permalink / raw)
To: linux-bluetooth
1. Fix potential buffer overflow. It would happen in the case:
hogdev->has_report_id == TRUE && report_size == UHID_DATA_MAX
2. Adjust function signature to match GAttribNotifyFunc.
3. Adjust uHID error handling to mimic uhid_send_input_report() in
profiles/input/device.c
---
profiles/input/hog.c | 44 +++++++++++++++++++++++++++++---------------
1 file changed, 29 insertions(+), 15 deletions(-)
diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index 12bc19a..671dab5 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -76,6 +76,7 @@
#define HOG_REPORT_MAP_MAX_SIZE 512
#define HID_INFO_SIZE 4
+#define ATT_NOTIFICATION_HEADER_SIZE 3
struct hog_device {
uint16_t id;
@@ -105,38 +106,51 @@ struct report {
static gboolean suspend_supported = FALSE;
static GSList *devices = NULL;
-static void report_value_cb(const uint8_t *pdu, uint16_t len,
- gpointer user_data)
+static void report_value_cb(const guint8 *pdu, guint16 len, gpointer user_data)
{
struct report *report = user_data;
struct hog_device *hogdev = report->hogdev;
struct uhid_event ev;
- uint16_t report_size = len - 3;
uint8_t *buf;
+ ssize_t status;
- if (len < 3) { /* 1-byte opcode + 2-byte handle */
+ if (len < ATT_NOTIFICATION_HEADER_SIZE) {
error("Malformed ATT notification");
return;
}
+ pdu += ATT_NOTIFICATION_HEADER_SIZE;
+ len -= ATT_NOTIFICATION_HEADER_SIZE;
+
memset(&ev, 0, sizeof(ev));
ev.type = UHID_INPUT;
- ev.u.input.size = MIN(report_size, UHID_DATA_MAX);
-
buf = ev.u.input.data;
+
if (hogdev->has_report_id) {
- *buf = report->id;
- buf++;
- ev.u.input.size++;
+ buf[0] = report->id;
+ len = MIN(len, sizeof(ev.u.input.data) - 1);
+ memcpy(buf + 1, pdu, len);
+ ev.u.input.size = ++len;
+ } else {
+ len = MIN(len, sizeof(ev.u.input.data));
+ memcpy(buf, pdu, len);
+ ev.u.input.size = len;
+ }
+
+ status = write(hogdev->uhid_fd, &ev, sizeof(ev));
+ if (status < 0) {
+ error("uHID dev write error: %s (%d)", strerror(errno), errno);
+ return;
}
- memcpy(buf, &pdu[3], MIN(report_size, UHID_DATA_MAX));
+ /* uHID kernel driver does not handle partial writes */
+ if ((size_t) status < sizeof(ev)) {
+ error("uHID dev write error: partial write (%zd of %lu bytes)",
+ status, sizeof(ev));
+ return;
+ }
- if (write(hogdev->uhid_fd, &ev, sizeof(ev)) < 0)
- error("uHID write failed: %s", strerror(errno));
- else
- DBG("Report from HoG device 0x%04X written to uHID fd %d",
- hogdev->id, hogdev->uhid_fd);
+ DBG("HoG report (%u bytes) -> uHID fd %d", len, hogdev->uhid_fd);
}
static void report_ccc_written_cb(guint8 status, const guint8 *pdu,
--
1.9.1.423.g4596e3a
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] hog: Fix report_value_cb()
2014-05-09 1:40 [PATCH] hog: Fix report_value_cb() Petri Gynther
@ 2014-05-09 11:50 ` Johan Hedberg
2014-05-09 16:44 ` Petri Gynther
0 siblings, 1 reply; 3+ messages in thread
From: Johan Hedberg @ 2014-05-09 11:50 UTC (permalink / raw)
To: Petri Gynther; +Cc: linux-bluetooth
Hi Petri,
On Thu, May 08, 2014, Petri Gynther wrote:
> 1. Fix potential buffer overflow. It would happen in the case:
> hogdev->has_report_id == TRUE && report_size == UHID_DATA_MAX
>
> 2. Adjust function signature to match GAttribNotifyFunc.
>
> 3. Adjust uHID error handling to mimic uhid_send_input_report() in
> profiles/input/device.c
> ---
> profiles/input/hog.c | 44 +++++++++++++++++++++++++++++---------------
> 1 file changed, 29 insertions(+), 15 deletions(-)
Whenever I see a commit message like this it begs the question:
shouldn't these separate fixes be in separate patches? If at all
possible please split the patch into smaller ones so that each one
contains a single independent fix. That makes it much easier to track
exactly which code change maps to which described fix as well the
possibility to do some bisecting later in case one of the fixes
introduces a bug.
Johan
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] hog: Fix report_value_cb()
2014-05-09 11:50 ` Johan Hedberg
@ 2014-05-09 16:44 ` Petri Gynther
0 siblings, 0 replies; 3+ messages in thread
From: Petri Gynther @ 2014-05-09 16:44 UTC (permalink / raw)
To: Johan Hedberg, linux-bluetooth
Hi Johan,
On Fri, May 9, 2014 at 4:50 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Petri,
>
> On Thu, May 08, 2014, Petri Gynther wrote:
>> 1. Fix potential buffer overflow. It would happen in the case:
>> hogdev->has_report_id == TRUE && report_size == UHID_DATA_MAX
>>
>> 2. Adjust function signature to match GAttribNotifyFunc.
>>
>> 3. Adjust uHID error handling to mimic uhid_send_input_report() in
>> profiles/input/device.c
>> ---
>> profiles/input/hog.c | 44 +++++++++++++++++++++++++++++---------------
>> 1 file changed, 29 insertions(+), 15 deletions(-)
>
> Whenever I see a commit message like this it begs the question:
> shouldn't these separate fixes be in separate patches? If at all
> possible please split the patch into smaller ones so that each one
> contains a single independent fix. That makes it much easier to track
> exactly which code change maps to which described fix as well the
> possibility to do some bisecting later in case one of the fixes
> introduces a bug.
>
> Johan
Fair enough. I'll break this down to three commits and send a new
patch out shortly.
-- Petri
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-05-09 16:44 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-09 1:40 [PATCH] hog: Fix report_value_cb() Petri Gynther
2014-05-09 11:50 ` Johan Hedberg
2014-05-09 16:44 ` Petri Gynther
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox