linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] HID: rmi: check sanity of the incoming report
@ 2014-09-05 13:57 Benjamin Tissoires
  2014-09-08  8:13 ` Jiri Kosina
  2014-09-09  0:39 ` Andrew Duggan
  0 siblings, 2 replies; 5+ messages in thread
From: Benjamin Tissoires @ 2014-09-05 13:57 UTC (permalink / raw)
  To: Jiri Kosina, Andrew Duggan; +Cc: linux-input, linux-kernel

In the Dell XPS 13 9333, it appears that sometimes the bus get confused
and corrupts the incoming data. It fills the input report with the
sentinel value "ff". Synaptics told us that such behavior does not comes
from the touchpad itself, so we filter out such reports here.

Unfortunately, we can not simply discard the incoming data because they
may contain useful information. Most of the time, the misbehavior is
quite near the end of the report, so we can still use the valid part of
it.

Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=1123584

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-rmi.c | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
index 8389e81..db92c3b 100644
--- a/drivers/hid/hid-rmi.c
+++ b/drivers/hid/hid-rmi.c
@@ -320,9 +320,6 @@ static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data,
 	int offset;
 	int i;
 
-	if (size < hdata->f11.report_size)
-		return 0;
-
 	if (!(irq & hdata->f11.irq_mask))
 		return 0;
 
@@ -332,9 +329,13 @@ static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data,
 		int fs_bit_position = (i & 0x3) << 1;
 		int finger_state = (data[fs_byte_position] >> fs_bit_position) &
 					0x03;
+		int position = offset + 5 * i;
+
+		if (position + 5 > size)
+			/* partial report, go on with what we received */
+			break;
 
-		rmi_f11_process_touch(hdata, i, finger_state,
-				&data[offset + 5 * i]);
+		rmi_f11_process_touch(hdata, i, finger_state, &data[position]);
 	}
 	input_mt_sync_frame(hdata->input);
 	input_sync(hdata->input);
@@ -412,9 +413,29 @@ static int rmi_read_data_event(struct hid_device *hdev, u8 *data, int size)
 	return 1;
 }
 
+static int rmi_check_sanity(struct hid_device *hdev, u8 *data, int size)
+{
+	int valid_size = size;
+	/*
+	 * On the Dell XPS 13 9333, the bus sometimes get confused and fills
+	 * the report with a sentinel value "ff". Synaptics told us that such
+	 * behavior does not comes from the touchpad itself, so we filter out
+	 * such reports here.
+	 */
+
+	while ((data[valid_size - 1] == 0xff) && valid_size > 0)
+		valid_size--;
+
+	return valid_size;
+}
+
 static int rmi_raw_event(struct hid_device *hdev,
 		struct hid_report *report, u8 *data, int size)
 {
+	size = rmi_check_sanity(hdev, data, size);
+	if (size < 2)
+		return 0;
+
 	switch (data[0]) {
 	case RMI_READ_DATA_REPORT_ID:
 		return rmi_read_data_event(hdev, data, size);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] HID: rmi: check sanity of the incoming report
  2014-09-05 13:57 [PATCH] HID: rmi: check sanity of the incoming report Benjamin Tissoires
@ 2014-09-08  8:13 ` Jiri Kosina
  2014-09-09 14:11   ` Benjamin Tissoires
  2014-09-09  0:39 ` Andrew Duggan
  1 sibling, 1 reply; 5+ messages in thread
From: Jiri Kosina @ 2014-09-08  8:13 UTC (permalink / raw)
  To: Benjamin Tissoires; +Cc: Andrew Duggan, linux-input, linux-kernel

On Fri, 5 Sep 2014, Benjamin Tissoires wrote:

> In the Dell XPS 13 9333, it appears that sometimes the bus get confused
> and corrupts the incoming data. It fills the input report with the
> sentinel value "ff". Synaptics told us that such behavior does not comes
> from the touchpad itself, so we filter out such reports here.
> 
> Unfortunately, we can not simply discard the incoming data because they
> may contain useful information. Most of the time, the misbehavior is
> quite near the end of the report, so we can still use the valid part of
> it.
> 
> Fixes:
> https://bugzilla.redhat.com/show_bug.cgi?id=1123584
> 
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> ---
>  drivers/hid/hid-rmi.c | 31 ++++++++++++++++++++++++++-----
>  1 file changed, 26 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
> index 8389e81..db92c3b 100644
> --- a/drivers/hid/hid-rmi.c
> +++ b/drivers/hid/hid-rmi.c
> @@ -320,9 +320,6 @@ static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data,
>  	int offset;
>  	int i;
>  
> -	if (size < hdata->f11.report_size)
> -		return 0;
> -
>  	if (!(irq & hdata->f11.irq_mask))
>  		return 0;
>  
> @@ -332,9 +329,13 @@ static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data,
>  		int fs_bit_position = (i & 0x3) << 1;
>  		int finger_state = (data[fs_byte_position] >> fs_bit_position) &
>  					0x03;
> +		int position = offset + 5 * i;
> +
> +		if (position + 5 > size)
> +			/* partial report, go on with what we received */
> +			break;

Do you perhaps want to warn the user here, so that he knows that things 
are getting a little bit hairy? Or is this happening so often that it 
makes no sense to warn about it?

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] HID: rmi: check sanity of the incoming report
  2014-09-05 13:57 [PATCH] HID: rmi: check sanity of the incoming report Benjamin Tissoires
  2014-09-08  8:13 ` Jiri Kosina
@ 2014-09-09  0:39 ` Andrew Duggan
  2014-09-09 14:06   ` Benjamin Tissoires
  1 sibling, 1 reply; 5+ messages in thread
From: Andrew Duggan @ 2014-09-09  0:39 UTC (permalink / raw)
  To: Benjamin Tissoires, Jiri Kosina; +Cc: linux-input, linux-kernel

On 09/05/2014 06:57 AM, Benjamin Tissoires wrote:
> In the Dell XPS 13 9333, it appears that sometimes the bus get confused
> and corrupts the incoming data. It fills the input report with the
> sentinel value "ff". Synaptics told us that such behavior does not comes
> from the touchpad itself, so we filter out such reports here.
>
> Unfortunately, we can not simply discard the incoming data because they
> may contain useful information. Most of the time, the misbehavior is
> quite near the end of the report, so we can still use the valid part of
> it.
>
> Fixes:
> https://bugzilla.redhat.com/show_bug.cgi?id=1123584
>
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> ---
>   drivers/hid/hid-rmi.c | 31 ++++++++++++++++++++++++++-----
>   1 file changed, 26 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
> index 8389e81..db92c3b 100644
> --- a/drivers/hid/hid-rmi.c
> +++ b/drivers/hid/hid-rmi.c
> @@ -320,9 +320,6 @@ static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data,
>   	int offset;
>   	int i;
>   
> -	if (size < hdata->f11.report_size)
> -		return 0;
> -
>   	if (!(irq & hdata->f11.irq_mask))
>   		return 0;
>   
> @@ -332,9 +329,13 @@ static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data,
>   		int fs_bit_position = (i & 0x3) << 1;
>   		int finger_state = (data[fs_byte_position] >> fs_bit_position) &
>   					0x03;
> +		int position = offset + 5 * i;
> +
> +		if (position + 5 > size)
> +			/* partial report, go on with what we received */
> +			break;
>   
> -		rmi_f11_process_touch(hdata, i, finger_state,
> -				&data[offset + 5 * i]);
> +		rmi_f11_process_touch(hdata, i, finger_state, &data[position]);
>   	}
>   	input_mt_sync_frame(hdata->input);
>   	input_sync(hdata->input);
> @@ -412,9 +413,29 @@ static int rmi_read_data_event(struct hid_device *hdev, u8 *data, int size)
>   	return 1;
>   }
>   
> +static int rmi_check_sanity(struct hid_device *hdev, u8 *data, int size)
> +{
> +	int valid_size = size;
> +	/*
> +	 * On the Dell XPS 13 9333, the bus sometimes get confused and fills
> +	 * the report with a sentinel value "ff". Synaptics told us that such
> +	 * behavior does not comes from the touchpad itself, so we filter out
> +	 * such reports here.
> +	 */
> +
> +	while ((data[valid_size - 1] == 0xff) && valid_size > 0)
> +		valid_size--;
> +
> +	return valid_size;
> +}
> +
>   static int rmi_raw_event(struct hid_device *hdev,
>   		struct hid_report *report, u8 *data, int size)
>   {
> +	size = rmi_check_sanity(hdev, data, size);
> +	if (size < 2)
> +		return 0;
> +
>   	switch (data[0]) {
>   	case RMI_READ_DATA_REPORT_ID:
>   		return rmi_read_data_event(hdev, data, size);
I think there should also be a check in rmi_f30_input_event to make sure 
that the F30 data is also valid. The F30 data is at the end of the HID 
report so if the F30 interrupt bit is set, but the value in the report 
is FF then there might be some unintended button events. I think 
checking that size > 0 would be sufficient to make sure the F30 data is 
valid.

Other then that, the sanity check and validation in rmi_f11_input_event 
look good to me.

Andrew

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] HID: rmi: check sanity of the incoming report
  2014-09-09  0:39 ` Andrew Duggan
@ 2014-09-09 14:06   ` Benjamin Tissoires
  0 siblings, 0 replies; 5+ messages in thread
From: Benjamin Tissoires @ 2014-09-09 14:06 UTC (permalink / raw)
  To: Andrew Duggan; +Cc: Jiri Kosina, linux-input, linux-kernel

On Sep 08 2014 or thereabouts, Andrew Duggan wrote:
> On 09/05/2014 06:57 AM, Benjamin Tissoires wrote:
> >In the Dell XPS 13 9333, it appears that sometimes the bus get confused
> >and corrupts the incoming data. It fills the input report with the
> >sentinel value "ff". Synaptics told us that such behavior does not comes
> >from the touchpad itself, so we filter out such reports here.
> >
> >Unfortunately, we can not simply discard the incoming data because they
> >may contain useful information. Most of the time, the misbehavior is
> >quite near the end of the report, so we can still use the valid part of
> >it.
> >
> >Fixes:
> >https://bugzilla.redhat.com/show_bug.cgi?id=1123584
> >
> >Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> >---
> >  drivers/hid/hid-rmi.c | 31 ++++++++++++++++++++++++++-----
> >  1 file changed, 26 insertions(+), 5 deletions(-)
> >
> >diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
> >index 8389e81..db92c3b 100644
> >--- a/drivers/hid/hid-rmi.c
> >+++ b/drivers/hid/hid-rmi.c
> >@@ -320,9 +320,6 @@ static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data,
> >  	int offset;
> >  	int i;
> >-	if (size < hdata->f11.report_size)
> >-		return 0;
> >-
> >  	if (!(irq & hdata->f11.irq_mask))
> >  		return 0;
> >@@ -332,9 +329,13 @@ static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data,
> >  		int fs_bit_position = (i & 0x3) << 1;
> >  		int finger_state = (data[fs_byte_position] >> fs_bit_position) &
> >  					0x03;
> >+		int position = offset + 5 * i;
> >+
> >+		if (position + 5 > size)
> >+			/* partial report, go on with what we received */
> >+			break;
> >-		rmi_f11_process_touch(hdata, i, finger_state,
> >-				&data[offset + 5 * i]);
> >+		rmi_f11_process_touch(hdata, i, finger_state, &data[position]);
> >  	}
> >  	input_mt_sync_frame(hdata->input);
> >  	input_sync(hdata->input);
> >@@ -412,9 +413,29 @@ static int rmi_read_data_event(struct hid_device *hdev, u8 *data, int size)
> >  	return 1;
> >  }
> >+static int rmi_check_sanity(struct hid_device *hdev, u8 *data, int size)
> >+{
> >+	int valid_size = size;
> >+	/*
> >+	 * On the Dell XPS 13 9333, the bus sometimes get confused and fills
> >+	 * the report with a sentinel value "ff". Synaptics told us that such
> >+	 * behavior does not comes from the touchpad itself, so we filter out
> >+	 * such reports here.
> >+	 */
> >+
> >+	while ((data[valid_size - 1] == 0xff) && valid_size > 0)
> >+		valid_size--;
> >+
> >+	return valid_size;
> >+}
> >+
> >  static int rmi_raw_event(struct hid_device *hdev,
> >  		struct hid_report *report, u8 *data, int size)
> >  {
> >+	size = rmi_check_sanity(hdev, data, size);
> >+	if (size < 2)
> >+		return 0;
> >+
> >  	switch (data[0]) {
> >  	case RMI_READ_DATA_REPORT_ID:
> >  		return rmi_read_data_event(hdev, data, size);
> I think there should also be a check in rmi_f30_input_event to make sure
> that the F30 data is also valid. The F30 data is at the end of the HID
> report so if the F30 interrupt bit is set, but the value in the report is FF
> then there might be some unintended button events. I think checking that
> size > 0 would be sufficient to make sure the F30 data is valid.

Yeah :(
Actually, I am missing too checks in f11 and f30. If the size is <= 0,
then bail out before doing anything.

> 
> Other then that, the sanity check and validation in rmi_f11_input_event look
> good to me.
> 
> Andrew

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] HID: rmi: check sanity of the incoming report
  2014-09-08  8:13 ` Jiri Kosina
@ 2014-09-09 14:11   ` Benjamin Tissoires
  0 siblings, 0 replies; 5+ messages in thread
From: Benjamin Tissoires @ 2014-09-09 14:11 UTC (permalink / raw)
  To: Jiri Kosina; +Cc: Andrew Duggan, linux-input, linux-kernel

On Sep 08 2014 or thereabouts, Jiri Kosina wrote:
> On Fri, 5 Sep 2014, Benjamin Tissoires wrote:
> 
> > In the Dell XPS 13 9333, it appears that sometimes the bus get confused
> > and corrupts the incoming data. It fills the input report with the
> > sentinel value "ff". Synaptics told us that such behavior does not comes
> > from the touchpad itself, so we filter out such reports here.
> > 
> > Unfortunately, we can not simply discard the incoming data because they
> > may contain useful information. Most of the time, the misbehavior is
> > quite near the end of the report, so we can still use the valid part of
> > it.
> > 
> > Fixes:
> > https://bugzilla.redhat.com/show_bug.cgi?id=1123584
> > 
> > Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> > ---
> >  drivers/hid/hid-rmi.c | 31 ++++++++++++++++++++++++++-----
> >  1 file changed, 26 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
> > index 8389e81..db92c3b 100644
> > --- a/drivers/hid/hid-rmi.c
> > +++ b/drivers/hid/hid-rmi.c
> > @@ -320,9 +320,6 @@ static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data,
> >  	int offset;
> >  	int i;
> >  
> > -	if (size < hdata->f11.report_size)
> > -		return 0;
> > -
> >  	if (!(irq & hdata->f11.irq_mask))
> >  		return 0;
> >  
> > @@ -332,9 +329,13 @@ static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data,
> >  		int fs_bit_position = (i & 0x3) << 1;
> >  		int finger_state = (data[fs_byte_position] >> fs_bit_position) &
> >  					0x03;
> > +		int position = offset + 5 * i;
> > +
> > +		if (position + 5 > size)
> > +			/* partial report, go on with what we received */
> > +			break;
> 
> Do you perhaps want to warn the user here, so that he knows that things 
> are getting a little bit hairy? Or is this happening so often that it 
> makes no sense to warn about it?
> 

I wanted to check on that yesterday, but I have been side tracked quite
a lot. So:
I think there might be too much messages to unconditionally notify the
user here. I do not see a better way than limiting the number to 10 or
so before giving up the notifications. Ideally, I would love to notify
the user when useful information is lost, but I did not came up with a
solution quickly.

On the other hand, not having the coordinates is not that much of a
problem I think. But, missing a f30 message (button event) is much more
of a problem, and I think we should notify the user there unconditionally
because there will be stuck pointers if the failure happens during a
release.

v2 should be on its way something like next week unless somebody else
wants to take over.

Cheers,
Benjamin


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-09-09 14:11 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-05 13:57 [PATCH] HID: rmi: check sanity of the incoming report Benjamin Tissoires
2014-09-08  8:13 ` Jiri Kosina
2014-09-09 14:11   ` Benjamin Tissoires
2014-09-09  0:39 ` Andrew Duggan
2014-09-09 14:06   ` Benjamin Tissoires

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).