mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
Merge branch 'for-7.4/core' into for-linus
- OOB fix in s32ton() (Alan Stern) - switch to named initializers for acpi_device_id (Pawel Zalewski) - UAF fix in hiddev (Yousef Alhouseen)
This commit is contained in:
commit
22434a272e
|
|
@ -71,8 +71,8 @@ static u32 s32ton(__s32 value, unsigned int n)
|
|||
if (!value || !n)
|
||||
return 0;
|
||||
|
||||
if (n > 32)
|
||||
n = 32;
|
||||
if (n >= 32)
|
||||
return (u32) value;
|
||||
|
||||
a = value >> (n - 1);
|
||||
if (a && a != -1)
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ static void cbas_ec_remove(struct platform_device *pdev)
|
|||
|
||||
#ifdef CONFIG_ACPI
|
||||
static const struct acpi_device_id cbas_ec_acpi_ids[] = {
|
||||
{ "GOOG000B", 0 },
|
||||
{ .id = "GOOG000B" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, cbas_ec_acpi_ids);
|
||||
|
|
|
|||
|
|
@ -39,12 +39,12 @@ static const struct acpi_device_id i2c_hid_acpi_blacklist[] = {
|
|||
* The CHPN0001 ACPI device, which is used to describe the Chipone
|
||||
* ICN8505 controller, has a _CID of PNP0C50 but is not HID compatible.
|
||||
*/
|
||||
{ "CHPN0001" },
|
||||
{ .id = "CHPN0001" },
|
||||
/*
|
||||
* The IDEA5002 ACPI device causes high interrupt usage and spurious
|
||||
* wakeups from suspend.
|
||||
*/
|
||||
{ "IDEA5002" },
|
||||
{ .id = "IDEA5002" },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
@ -93,8 +93,8 @@ static int i2c_hid_acpi_probe(struct i2c_client *client)
|
|||
}
|
||||
|
||||
static const struct acpi_device_id i2c_hid_acpi_match[] = {
|
||||
{ "ACPI0C50" },
|
||||
{ "PNP0C50" },
|
||||
{ .id = "ACPI0C50" },
|
||||
{ .id = "PNP0C50" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, i2c_hid_acpi_match);
|
||||
|
|
|
|||
|
|
@ -277,8 +277,8 @@ static void surface_kbd_remove(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static const struct acpi_device_id surface_kbd_match[] = {
|
||||
{ "MSHW0096" },
|
||||
{ },
|
||||
{ .id = "MSHW0096" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, surface_kbd_match);
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,12 @@ struct hiddev_list {
|
|||
struct mutex thread_lock;
|
||||
};
|
||||
|
||||
static void hiddev_put(struct hiddev *hiddev)
|
||||
{
|
||||
if (refcount_dec_and_test(&hiddev->refcount))
|
||||
kfree(hiddev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a report, given the report's type and ID. The ID can be specified
|
||||
* indirectly by REPORT_ID_FIRST (which returns the first report of the given
|
||||
|
|
@ -216,26 +222,21 @@ static int hiddev_fasync(int fd, struct file *file, int on)
|
|||
static int hiddev_release(struct inode * inode, struct file * file)
|
||||
{
|
||||
struct hiddev_list *list = file->private_data;
|
||||
struct hiddev *hiddev = list->hiddev;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&list->hiddev->list_lock, flags);
|
||||
spin_lock_irqsave(&hiddev->list_lock, flags);
|
||||
list_del(&list->node);
|
||||
spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
|
||||
spin_unlock_irqrestore(&hiddev->list_lock, flags);
|
||||
|
||||
mutex_lock(&list->hiddev->existancelock);
|
||||
if (!--list->hiddev->open) {
|
||||
if (list->hiddev->exist) {
|
||||
hid_hw_close(list->hiddev->hid);
|
||||
hid_hw_power(list->hiddev->hid, PM_HINT_NORMAL);
|
||||
} else {
|
||||
mutex_unlock(&list->hiddev->existancelock);
|
||||
kfree(list->hiddev);
|
||||
vfree(list);
|
||||
return 0;
|
||||
}
|
||||
mutex_lock(&hiddev->existancelock);
|
||||
if (!--hiddev->open && hiddev->exist) {
|
||||
hid_hw_close(hiddev->hid);
|
||||
hid_hw_power(hiddev->hid, PM_HINT_NORMAL);
|
||||
}
|
||||
|
||||
mutex_unlock(&list->hiddev->existancelock);
|
||||
mutex_unlock(&hiddev->existancelock);
|
||||
hiddev_put(hiddev);
|
||||
vfree(list);
|
||||
|
||||
return 0;
|
||||
|
|
@ -270,6 +271,7 @@ static int __hiddev_open(struct hiddev *hiddev, struct file *file)
|
|||
spin_unlock_irq(&hiddev->list_lock);
|
||||
|
||||
file->private_data = list;
|
||||
refcount_inc(&hiddev->refcount);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
@ -897,9 +899,12 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
|
|||
INIT_LIST_HEAD(&hiddev->list);
|
||||
spin_lock_init(&hiddev->list_lock);
|
||||
mutex_init(&hiddev->existancelock);
|
||||
refcount_set(&hiddev->refcount, 1);
|
||||
hid->hiddev = hiddev;
|
||||
hiddev->hid = hid;
|
||||
hiddev->exist = 1;
|
||||
/* Honor NO_INIT_REPORTS before the character device becomes visible. */
|
||||
hiddev->initialized = hid->quirks & HID_QUIRK_NO_INIT_REPORTS;
|
||||
retval = usb_register_dev(usbhid->intf, &hiddev_class);
|
||||
if (retval) {
|
||||
hid_err(hid, "Not able to get a minor for this device\n");
|
||||
|
|
@ -908,12 +913,6 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* If HID_QUIRK_NO_INIT_REPORTS is set, make sure we don't initialize
|
||||
* the reports.
|
||||
*/
|
||||
hiddev->initialized = hid->quirks & HID_QUIRK_NO_INIT_REPORTS;
|
||||
|
||||
hiddev->minor = usbhid->intf->minor;
|
||||
|
||||
return 0;
|
||||
|
|
@ -937,9 +936,7 @@ void hiddev_disconnect(struct hid_device *hid)
|
|||
if (hiddev->open) {
|
||||
hid_hw_close(hiddev->hid);
|
||||
wake_up_interruptible(&hiddev->wait);
|
||||
mutex_unlock(&hiddev->existancelock);
|
||||
} else {
|
||||
mutex_unlock(&hiddev->existancelock);
|
||||
kfree(hiddev);
|
||||
}
|
||||
mutex_unlock(&hiddev->existancelock);
|
||||
hiddev_put(hiddev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#ifndef _HIDDEV_H
|
||||
#define _HIDDEV_H
|
||||
|
||||
#include <linux/refcount.h>
|
||||
#include <uapi/linux/hiddev.h>
|
||||
|
||||
|
||||
|
|
@ -24,6 +25,7 @@ struct hiddev {
|
|||
int minor;
|
||||
int exist;
|
||||
int open;
|
||||
refcount_t refcount;
|
||||
struct mutex existancelock;
|
||||
wait_queue_head_t wait;
|
||||
struct hid_device *hid;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user