lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20130319212511.GA7821@polaris.bitmath.org>
Date:	Tue, 19 Mar 2013 22:25:11 +0100
From:	"Henrik Rydberg" <rydberg@...omail.se>
To:	Benjamin Tissoires <benjamin.tissoires@...hat.com>
Cc:	Benjamin Tissoires <benjamin.tissoires@...il.com>,
	Jiri Kosina <jkosina@...e.cz>,
	Stephane Chatty <chatty@...c.fr>, linux-input@...r.kernel.org,
	linux-kernel@...r.kernel.org
Subject: Re: [PATCH 1/7] HID: input: don't register unmapped input devices

Hi Benjamin,

> There is no need to register an input device containing no events.
> This allows drivers using the quirk MULTI_INPUT to register one input
> per report effectively used.
> 
> For backward compatibility, we need to add a quirk to request
> this behavior.
> 
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@...hat.com>
> ---
>  drivers/hid/hid-input.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/hid.h     |  1 +
>  2 files changed, 78 insertions(+)
> 
> diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
> index 21b196c..7aaf7d3 100644
> --- a/drivers/hid/hid-input.c
> +++ b/drivers/hid/hid-input.c
> @@ -1198,6 +1198,67 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid)
>  	return hidinput;
>  }
>  
> +static bool hidinput_has_been_populated(struct hid_input *hidinput)
> +{
> +	int i;
> +	bool r = 0;
> +
> +	for (i = 0; i < BITS_TO_LONGS(EV_CNT); i++)
> +		r = r || hidinput->input->evbit[i];

I believe there is a bit count method that will do this for you (weight).

> +
> +	for (i = 0; i < BITS_TO_LONGS(KEY_CNT); i++)
> +		r = r || hidinput->input->keybit[i];
> +
> +	for (i = 0; i < BITS_TO_LONGS(REL_CNT); i++)
> +		r = r || hidinput->input->relbit[i];
> +
> +	for (i = 0; i < BITS_TO_LONGS(ABS_CNT); i++)
> +		r = r || hidinput->input->absbit[i];
> +
> +	for (i = 0; i < BITS_TO_LONGS(MSC_CNT); i++)
> +		r = r || hidinput->input->mscbit[i];
> +
> +	for (i = 0; i < BITS_TO_LONGS(LED_CNT); i++)
> +		r = r || hidinput->input->ledbit[i];
> +
> +	for (i = 0; i < BITS_TO_LONGS(SND_CNT); i++)
> +		r = r || hidinput->input->sndbit[i];
> +
> +	for (i = 0; i < BITS_TO_LONGS(FF_CNT); i++)
> +		r = r || hidinput->input->ffbit[i];
> +
> +	for (i = 0; i < BITS_TO_LONGS(SW_CNT); i++)
> +		r = r || hidinput->input->swbit[i];
> +
> +	return !!r;
> +}
> +
> +static void hidinput_cleanup_hidinput(struct hid_device *hid,
> +		struct hid_input *hidinput)
> +{
> +	struct hid_report *report;
> +	int i, k;
> +
> +	list_del(&hidinput->list);
> +	input_free_device(hidinput->input);
> +
> +	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
> +		if (k == HID_OUTPUT_REPORT &&
> +			hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
> +			continue;
> +
> +		list_for_each_entry(report, &hid->report_enum[k].report_list,
> +				    list) {
> +
> +			for (i = 0; i < report->maxfield; i++)
> +				if (report->field[i]->hidinput == hidinput)
> +					report->field[i]->hidinput = NULL;

Why test before clearing?

> +		}
> +	}
> +
> +	kfree(hidinput);
> +}
> +
>  /*
>   * Register the input device; print a message.
>   * Configure the input layer interface
> @@ -1249,6 +1310,10 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
>  					hidinput_configure_usage(hidinput, report->field[i],
>  								 report->field[i]->usage + j);
>  
> +			if ((hid->quirks & HID_QUIRK_NO_EMPTY_INPUT) &&
> +			    !hidinput_has_been_populated(hidinput))
> +				continue;
> +

Is there possibly a subset of input properties that may be populated
but still not duplicated? Or the other way around?

>  			if (hid->quirks & HID_QUIRK_MULTI_INPUT) {
>  				/* This will leave hidinput NULL, so that it
>  				 * allocates another one if we have more inputs on
> @@ -1265,6 +1330,18 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
>  		}
>  	}
>  
> +	if (hidinput && (hid->quirks & HID_QUIRK_NO_EMPTY_INPUT) &&
> +	    !hidinput_has_been_populated(hidinput)) {
> +		/* no need to register an input device not populated */
> +		hidinput_cleanup_hidinput(hid, hidinput);
> +		hidinput = NULL;
> +	}
> +
> +	if (list_empty(&hid->inputs)) {
> +		hid_err(hid, "No inputs registered, leaving\n");
> +		goto out_unwind;
> +	}
> +
>  	if (hidinput) {
>  		if (drv->input_configured)
>  			drv->input_configured(hid, hidinput);
> diff --git a/include/linux/hid.h b/include/linux/hid.h
> index 7071eb3..15b98a6 100644
> --- a/include/linux/hid.h
> +++ b/include/linux/hid.h
> @@ -282,6 +282,7 @@ struct hid_item {
>  #define HID_QUIRK_BADPAD			0x00000020
>  #define HID_QUIRK_MULTI_INPUT			0x00000040
>  #define HID_QUIRK_HIDINPUT_FORCE		0x00000080
> +#define HID_QUIRK_NO_EMPTY_INPUT		0x00000100
>  #define HID_QUIRK_SKIP_OUTPUT_REPORTS		0x00010000
>  #define HID_QUIRK_FULLSPEED_INTERVAL		0x10000000
>  #define HID_QUIRK_NO_INIT_REPORTS		0x20000000
> -- 
> 1.8.1.2
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ