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: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 27 Nov 2006 12:56:51 -0600
From:	linas@...tin.ibm.com (Linas Vepstas)
To:	juanslayton@...extreme.com
Cc:	linux-hotplug-devel@...ts.sourceforge.net,
	Vojtech Pavlik <vojtech@...e.cz>, linux-kernel@...r.kernel.org,
	Alan Cox <alan@...rguk.ukuu.org.uk>
Subject: [RFC/PATCH] Uncap max number of evdev devices [was: Re: need more events]

On Fri, Nov 24, 2006 at 05:09:52PM -0800, juanslayton@...extreme.com wrote:
> 
>      The object is to poll 20 usb keyboards in an elementary school
> classroom, each of which generates 2
> events (one keyboard and one mouse).  The stock kernel maxes out at event
> 31, leaving me 4
> keyboards short.
>      I thought to fix this by changing the definition of EVDEV_MINORS
> (line 12, evdev.c) from 32 to 64.  It almost worked.  The extra
> events showed up in /dev/input/* and /proc/bus/input/devices.
> However, attempting to access the new events in the application
> program only yields a segmentation fault.  Obviously I've got to change
> something else.

The problem is in input_register_handler() in drivers/input/input.c
which does things like 
if (input_table[handler->minor >> 5])
 and 
input_table[handler->minor >> 5] = handler;

which implicitly makes 32 the max. 

The kernel path below removes this limitation. Does it fix your problem?

--linas


The evdev code is limited to 32 input devices max, because
the generic input layer puts a 32-device cap on the number
of minor device numbers that a device driver can register.

This patch hacks around the 32-device limitation for 
the number of evdev drivers. Not clear to me if this
this is the best solution. 

Not-even-compile-tested.

Signed-off-by: Linas Vepstas <linas@...tin.ibm.com>

----
 drivers/input/input.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

Index: linux-2.6.19-rc4-git3/drivers/input/input.c
===================================================================
--- linux-2.6.19-rc4-git3.orig/drivers/input/input.c	2006-11-01 16:15:19.000000000 -0600
+++ linux-2.6.19-rc4-git3/drivers/input/input.c	2006-11-27 12:50:12.000000000 -0600
@@ -28,12 +28,16 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@s
 MODULE_DESCRIPTION("Input core");
 MODULE_LICENSE("GPL");
 
-#define INPUT_DEVICES	256
+#define INPUT_MINOR_BITS   8
+#define INPUT_DEVICES      (1<<INPUT_MINOR_BITS)
+#define MINOR_RANGE_BITS   6
+#define MINOR_RANGES       (1<<(INPUT_MINOR_BITS-MINOR_RANGE_BITS))
+#define TABLE_OFFSET(minor) ((minor)>>MINOR_RANGE_BITS)
 
 static LIST_HEAD(input_dev_list);
 static LIST_HEAD(input_handler_list);
 
-static struct input_handler *input_table[8];
+static struct input_handler *input_table[MINOR_RANGES];
 
 /**
  * input_event() - report new input event
@@ -1046,10 +1050,10 @@ int input_register_handler(struct input_
 	INIT_LIST_HEAD(&handler->h_list);
 
 	if (handler->fops != NULL) {
-		if (input_table[handler->minor >> 5])
+		if (input_table[TABLE_OFFSET(handler->minor)])
 			return -EBUSY;
 
-		input_table[handler->minor >> 5] = handler;
+		input_table[TABLE_OFFSET(handler->minor)] = handler;
 	}
 
 	list_add_tail(&handler->node, &input_handler_list);
@@ -1082,7 +1086,7 @@ void input_unregister_handler(struct inp
 	list_del_init(&handler->node);
 
 	if (handler->fops != NULL)
-		input_table[handler->minor >> 5] = NULL;
+		input_table[TABLE_OFFSET(handler->minor)] = NULL;
 
 	input_wakeup_procfs_readers();
 }
@@ -1090,7 +1094,7 @@ EXPORT_SYMBOL(input_unregister_handler);
 
 static int input_open_file(struct inode *inode, struct file *file)
 {
-	struct input_handler *handler = input_table[iminor(inode) >> 5];
+	struct input_handler *handler = input_table[TABLE_OFFSET(iminor(inode))];
 	const struct file_operations *old_fops, *new_fops = NULL;
 	int err;
 
-
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