lkml.org 
[lkml]   [2000]   [Nov]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch] Input drivers critical fixes, try #2.
Hello,

attached is a patch that fixes some critical and some less critical, but
still harmful bugs in the input drivers. It's against 2.4.0-test11-pre6.

Joysticks:

drivers/joystick/adi.c:
Fix X/Y axes on Logitech gamepads.
drivers/joystick/ns558.c:
Fix module impossible to load for ISA devices unless
CONFIG_HOTPLUG - bug added in test11-pre6. [critical]
Fix oops on unload if PCI gameports present. [critical]
Fix oops on unload if PCI gameports not present,
- bug added in test11-pre6. [critical]
Fix memory leak on unload. [critical]
drivers/char/joystick/sidewinder.c
Fix missing button on MS FF Wheel.

Input [USB+Joystick]:

drivers/input/input.c:
Fix a possible race at open - fix by Oliver Neukum. [critical]
drivers/input/evdev.c:
Fix possible overflows in connect and open. [critical]
drivers/input/joydev.c:
Fix possible overflows in connect and open. [critical]
drivers/input/mousedev.c:
Fix possible overflows in connect and open. [critical]
Add missing randomness reporting.

Please apply it.
Thanks.

--
Vojtech Pavlik
SuSE Labs
diff -urN linux-2.4.0-test11-pre6/drivers/char/joystick/adi.c linux/drivers/char/joystick/adi.c
--- linux-2.4.0-test11-pre6/drivers/char/joystick/adi.c Thu Jun 22 15:59:58 2000
+++ linux/drivers/char/joystick/adi.c Fri Nov 17 16:20:09 2000
@@ -418,7 +418,7 @@
adi->dev.private = port;
adi->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);

- for (i = 0; i < adi->axes10 + adi->axes8 + adi->hats * 2; i++)
+ for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad > 0)) * 2; i++)
set_bit(adi->abs[i], &adi->dev.absbit);

for (i = 0; i < adi->buttons; i++)
@@ -431,7 +431,7 @@

if (!adi->length) return;

- for (i = 0; i < adi->axes10 + adi->axes8 + adi->hats * 2; i++) {
+ for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad > 0)) * 2; i++) {

t = adi->abs[i];
x = adi->dev.abs[t];
diff -urN linux-2.4.0-test11-pre6/drivers/char/joystick/ns558.c linux/drivers/char/joystick/ns558.c
--- linux-2.4.0-test11-pre6/drivers/char/joystick/ns558.c Fri Nov 17 16:13:41 2000
+++ linux/drivers/char/joystick/ns558.c Fri Nov 17 16:20:51 2000
@@ -58,6 +58,7 @@
};

static struct ns558 *ns558;
+static int ns558_pci;

/*
* ns558_isa_probe() tries to find an isa gameport at the
@@ -187,12 +188,10 @@
}
memset(port, 0, sizeof(struct ns558));

- port->next = ns558;
port->type = NS558_PCI;
port->gameport.io = ioport;
port->gameport.size = iolen;
port->dev = pdev;
- ns558 = port;

pdev->driver_data = port;

@@ -315,8 +314,7 @@
* it is the least-invasive probe.
*/

- i = pci_register_driver(&ns558_pci_driver);
- if (i < 0) return i;
+ ns558_pci = !pci_module_init(&ns558_pci_driver);

/*
* Probe for ISA ports.
@@ -337,12 +335,12 @@
}
#endif

- return 0;
+ return (ns558 || ns558_pci) ? 0 : -ENODEV;
}

void __exit ns558_exit(void)
{
- struct ns558 *port = ns558;
+ struct ns558 *next, *port = ns558;

while (port) {
gameport_unregister_port(&port->gameport);
@@ -363,10 +361,13 @@
break;
}

- port = port->next;
+ next = port->next;
+ kfree(port);
+ port = next;
}

- pci_unregister_driver(&ns558_pci_driver);
+ if (ns558_pci)
+ pci_unregister_driver(&ns558_pci_driver);
}

module_init(ns558_init);
diff -urN linux-2.4.0-test11-pre6/drivers/char/joystick/sidewinder.c linux/drivers/char/joystick/sidewinder.c
--- linux-2.4.0-test11-pre6/drivers/char/joystick/sidewinder.c Mon Aug 14 22:55:01 2000
+++ linux/drivers/char/joystick/sidewinder.c Fri Nov 17 16:20:09 2000
@@ -102,7 +102,7 @@
{ BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_SELECT },
{ BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_SELECT },
{ BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START, BTN_MODE, BTN_SELECT },
- { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_THUMB2, BTN_BASE, BTN_BASE2, BTN_BASE3 }};
+ { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_THUMB2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4 }};

static struct {
int x;
diff -urN linux-2.4.0-test11-pre6/drivers/input/evdev.c linux/drivers/input/evdev.c
--- linux-2.4.0-test11-pre6/drivers/input/evdev.c Fri Jul 28 03:36:54 2000
+++ linux/drivers/input/evdev.c Fri Nov 17 16:20:12 2000
@@ -123,7 +123,7 @@
struct evdev_list *list;
int i = MINOR(inode->i_rdev) - EVDEV_MINOR_BASE;

- if (i > EVDEV_MINORS || !evdev_table[i])
+ if (i >= EVDEV_MINORS || !evdev_table[i])
return -ENODEV;

if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL)))
@@ -288,7 +288,7 @@
int minor;

for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++);
- if (evdev_table[minor]) {
+ if (minor == EVDEV_MINORS) {
printk(KERN_ERR "evdev: no more free evdev devices\n");
return NULL;
}
diff -urN linux-2.4.0-test11-pre6/drivers/input/input.c linux/drivers/input/input.c
--- linux-2.4.0-test11-pre6/drivers/input/input.c Wed Nov 15 11:03:35 2000
+++ linux/drivers/input/input.c Fri Nov 17 16:20:12 2000
@@ -29,6 +29,8 @@
*/

#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/random.h>
@@ -378,7 +380,11 @@
}
old_fops = file->f_op;
file->f_op = new_fops;
+
+ lock_kernel();
err = new_fops->open(inode, file);
+ unlock_kernel();
+
if (err) {
fops_put(file->f_op);
file->f_op = fops_get(old_fops);
diff -urN linux-2.4.0-test11-pre6/drivers/input/joydev.c linux/drivers/input/joydev.c
--- linux-2.4.0-test11-pre6/drivers/input/joydev.c Tue Aug 22 18:06:31 2000
+++ linux/drivers/input/joydev.c Fri Nov 17 16:20:12 2000
@@ -193,7 +193,7 @@
struct joydev_list *list;
int i = MINOR(inode->i_rdev) - JOYDEV_MINOR_BASE;

- if (i > JOYDEV_MINORS || !joydev_table[i])
+ if (i >= JOYDEV_MINORS || !joydev_table[i])
return -ENODEV;

if (!(list = kmalloc(sizeof(struct joydev_list), GFP_KERNEL)))
@@ -395,7 +395,7 @@
|| test_bit(BTN_1, dev->keybit)))) return NULL;

for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
- if (joydev_table[minor]) {
+ if (minor == JOYDEV_MINORS) {
printk(KERN_ERR "joydev: no more free joydev devices\n");
return NULL;
}
diff -urN linux-2.4.0-test11-pre6/drivers/input/mousedev.c linux/drivers/input/mousedev.c
--- linux-2.4.0-test11-pre6/drivers/input/mousedev.c Tue Aug 22 18:06:31 2000
+++ linux/drivers/input/mousedev.c Fri Nov 17 16:20:12 2000
@@ -39,6 +39,7 @@
#include <linux/input.h>
#include <linux/config.h>
#include <linux/smp_lock.h>
+#include <linux/random.h>

#ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X
#define CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024
@@ -86,6 +87,8 @@
struct mousedev_list *list;
int index, size;

+ add_mouse_randomness((type << 4) ^ code ^ (code >> 4) ^ value);
+
while (*mousedev) {
list = (*mousedev)->list;
while (list) {
@@ -213,7 +216,7 @@
struct mousedev_list *list;
int i = MINOR(inode->i_rdev) - MOUSEDEV_MINOR_BASE;

- if (i > MOUSEDEV_MINORS || !mousedev_table[i])
+ if (i >= MOUSEDEV_MINORS || !mousedev_table[i])
return -ENODEV;

if (!(list = kmalloc(sizeof(struct mousedev_list), GFP_KERNEL)))
@@ -407,7 +410,7 @@
return NULL;

for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
- if (mousedev_table[minor]) {
+ if (minor == MOUSEDEV_MINORS) {
printk(KERN_ERR "mousedev: no more free mousedev devices\n");
return NULL;
}
\
 
 \ /
  Last update: 2005-03-22 12:47    [W:0.024 / U:4.200 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site