diff --git a/0001-skge-fix-broken-driver.patch b/0001-skge-fix-broken-driver.patch deleted file mode 100644 index 7ca3dec..0000000 --- a/0001-skge-fix-broken-driver.patch +++ /dev/null @@ -1,62 +0,0 @@ -From c194992cbe71c20bb3623a566af8d11b0bfaa721 Mon Sep 17 00:00:00 2001 -From: Mikulas Patocka -Date: Thu, 19 Sep 2013 14:13:17 -0400 -Subject: [PATCH] skge: fix broken driver - -The patch 136d8f377e1575463b47840bc5f1b22d94bf8f63 broke the skge driver. -Note this part of the patch: -+ if (skge_rx_setup(skge, e, nskb, skge->rx_buf_size) < 0) { -+ dev_kfree_skb(nskb); -+ goto resubmit; -+ } -+ - pci_unmap_single(skge->hw->pdev, - dma_unmap_addr(e, mapaddr), - dma_unmap_len(e, maplen), - PCI_DMA_FROMDEVICE); - skb = e->skb; - prefetch(skb->data); -- skge_rx_setup(skge, e, nskb, skge->rx_buf_size); - -The function skge_rx_setup modifies e->skb to point to the new skb. Thus, -after this change, the new buffer, not the old, is returned to the -networking stack. - -This bug is present in kernels 3.11, 3.11.1 and 3.12-rc1. The patch should -be queued for 3.11-stable. - -Signed-off-by: Mikulas Patocka -Reported-by: Mikulas Patocka -Reported-by: Vasiliy Glazov -Tested-by: Mikulas Patocka -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/marvell/skge.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c -index ef94a59..1a9c4f6 100644 ---- a/drivers/net/ethernet/marvell/skge.c -+++ b/drivers/net/ethernet/marvell/skge.c -@@ -3092,6 +3092,9 @@ static struct sk_buff *skge_rx_get(struct net_device *dev, - if (!nskb) - goto resubmit; - -+ skb = e->skb; -+ prefetch(skb->data); -+ - if (skge_rx_setup(skge, e, nskb, skge->rx_buf_size) < 0) { - dev_kfree_skb(nskb); - goto resubmit; -@@ -3101,8 +3104,6 @@ static struct sk_buff *skge_rx_get(struct net_device *dev, - dma_unmap_addr(e, mapaddr), - dma_unmap_len(e, maplen), - PCI_DMA_FROMDEVICE); -- skb = e->skb; -- prefetch(skb->data); - } - - skb_put(skb, len); --- -1.8.3.1 - diff --git a/HID-CVE-fixes-3.11.patch b/HID-CVE-fixes-3.11.patch deleted file mode 100644 index 4cdc594..0000000 --- a/HID-CVE-fixes-3.11.patch +++ /dev/null @@ -1,828 +0,0 @@ -From ba6d8d44eaeb0ee58082f4b4c95138416e1f58a5 Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Wed, 11 Sep 2013 21:56:50 +0200 -Subject: [PATCH 02/16] HID: provide a helper for validating hid reports - -Many drivers need to validate the characteristics of their HID report -during initialization to avoid misusing the reports. This adds a common -helper to perform validation of the report exisitng, the field existing, -and the expected number of values within the field. - -Signed-off-by: Kees Cook -Cc: stable@vger.kernel.org -Reviewed-by: Benjamin Tissoires ---- - drivers/hid/hid-core.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ - include/linux/hid.h | 4 ++++ - 2 files changed, 62 insertions(+) - -diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c -index 5ea7d51..65ee459 100644 ---- a/drivers/hid/hid-core.c -+++ b/drivers/hid/hid-core.c -@@ -759,6 +759,64 @@ int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size) - } - EXPORT_SYMBOL_GPL(hid_parse_report); - -+static const char * const hid_report_names[] = { -+ "HID_INPUT_REPORT", -+ "HID_OUTPUT_REPORT", -+ "HID_FEATURE_REPORT", -+}; -+/** -+ * hid_validate_values - validate existing device report's value indexes -+ * -+ * @device: hid device -+ * @type: which report type to examine -+ * @id: which report ID to examine (0 for first) -+ * @field_index: which report field to examine -+ * @report_counts: expected number of values -+ * -+ * Validate the number of values in a given field of a given report, after -+ * parsing. -+ */ -+struct hid_report *hid_validate_values(struct hid_device *hid, -+ unsigned int type, unsigned int id, -+ unsigned int field_index, -+ unsigned int report_counts) -+{ -+ struct hid_report *report; -+ -+ if (type > HID_FEATURE_REPORT) { -+ hid_err(hid, "invalid HID report type %u\n", type); -+ return NULL; -+ } -+ -+ if (id >= HID_MAX_IDS) { -+ hid_err(hid, "invalid HID report id %u\n", id); -+ return NULL; -+ } -+ -+ /* -+ * Explicitly not using hid_get_report() here since it depends on -+ * ->numbered being checked, which may not always be the case when -+ * drivers go to access report values. -+ */ -+ report = hid->report_enum[type].report_id_hash[id]; -+ if (!report) { -+ hid_err(hid, "missing %s %u\n", hid_report_names[type], id); -+ return NULL; -+ } -+ if (report->maxfield <= field_index) { -+ hid_err(hid, "not enough fields in %s %u\n", -+ hid_report_names[type], id); -+ return NULL; -+ } -+ if (report->field[field_index]->report_count < report_counts) { -+ hid_err(hid, "not enough values in %s %u field %u\n", -+ hid_report_names[type], id, field_index); -+ return NULL; -+ } -+ return report; -+} -+EXPORT_SYMBOL_GPL(hid_validate_values); -+ - /** - * hid_open_report - open a driver-specific device report - * -diff --git a/include/linux/hid.h b/include/linux/hid.h -index ff545cc..6e18550 100644 ---- a/include/linux/hid.h -+++ b/include/linux/hid.h -@@ -749,6 +749,10 @@ void hid_output_report(struct hid_report *report, __u8 *data); - struct hid_device *hid_allocate_device(void); - struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); - int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); -+struct hid_report *hid_validate_values(struct hid_device *hid, -+ unsigned int type, unsigned int id, -+ unsigned int field_index, -+ unsigned int report_counts); - int hid_open_report(struct hid_device *device); - int hid_check_keys_pressed(struct hid_device *hid); - int hid_connect(struct hid_device *hid, unsigned int connect_mask); --- -1.8.3.1 - - -From 51bc0244e9e62b25e4f64f7cb87764a0c0692131 Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Wed, 11 Sep 2013 21:56:51 +0200 -Subject: [PATCH 03/16] HID: zeroplus: validate output report details - -The zeroplus HID driver was not checking the size of allocated values -in fields it used. A HID device could send a malicious output report -that would cause the driver to write beyond the output report allocation -during initialization, causing a heap overflow: - -[ 1442.728680] usb 1-1: New USB device found, idVendor=0c12, idProduct=0005 -... -[ 1466.243173] BUG kmalloc-192 (Tainted: G W ): Redzone overwritten - -CVE-2013-2889 - -Signed-off-by: Kees Cook -Cc: stable@vger.kernel.org -Reviewed-by: Benjamin Tissoires ---- - drivers/hid/hid-zpff.c | 18 +++++------------- - 1 file changed, 5 insertions(+), 13 deletions(-) - -diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c -index 6ec28a3..a29756c 100644 ---- a/drivers/hid/hid-zpff.c -+++ b/drivers/hid/hid-zpff.c -@@ -68,21 +68,13 @@ static int zpff_init(struct hid_device *hid) - struct hid_report *report; - struct hid_input *hidinput = list_entry(hid->inputs.next, - struct hid_input, list); -- struct list_head *report_list = -- &hid->report_enum[HID_OUTPUT_REPORT].report_list; - struct input_dev *dev = hidinput->input; -- int error; -+ int i, error; - -- if (list_empty(report_list)) { -- hid_err(hid, "no output report found\n"); -- return -ENODEV; -- } -- -- report = list_entry(report_list->next, struct hid_report, list); -- -- if (report->maxfield < 4) { -- hid_err(hid, "not enough fields in report\n"); -- return -ENODEV; -+ for (i = 0; i < 4; i++) { -+ report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1); -+ if (!report) -+ return -ENODEV; - } - - zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL); --- -1.8.3.1 - - -From 0d998969132672bab9942e3308058d212574a2f8 Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Wed, 11 Sep 2013 21:56:52 +0200 -Subject: [PATCH 04/16] HID: sony: validate HID output report details - -This driver must validate the availability of the HID output report and -its size before it can write LED states via buzz_set_leds(). This stops -a heap overflow that is possible if a device provides a malicious HID -output report: - -[ 108.171280] usb 1-1: New USB device found, idVendor=054c, idProduct=0002 -... -[ 117.507877] BUG kmalloc-192 (Not tainted): Redzone overwritten - -CVE-2013-2890 - -Signed-off-by: Kees Cook -Cc: stable@vger.kernel.org -Reviewed-by: Benjamin Tissoires ---- - drivers/hid/hid-sony.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c -index 87fbe29..334a4b5 100644 ---- a/drivers/hid/hid-sony.c -+++ b/drivers/hid/hid-sony.c -@@ -537,6 +537,10 @@ static int buzz_init(struct hid_device *hdev) - drv_data = hid_get_drvdata(hdev); - BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER)); - -+ /* Validate expected report characteristics. */ -+ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7)) -+ return -ENODEV; -+ - buzz = kzalloc(sizeof(*buzz), GFP_KERNEL); - if (!buzz) { - hid_err(hdev, "Insufficient memory, cannot allocate driver data\n"); --- -1.8.3.1 - - -From 5b029acf571f94193ff8a757340fd37a7f88ae0b Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Wed, 11 Sep 2013 21:56:53 +0200 -Subject: [PATCH 05/16] HID: steelseries: validate output report details - -A HID device could send a malicious output report that would cause the -steelseries HID driver to write beyond the output report allocation -during initialization, causing a heap overflow: - -[ 167.981534] usb 1-1: New USB device found, idVendor=1038, idProduct=1410 -... -[ 182.050547] BUG kmalloc-256 (Tainted: G W ): Redzone overwritten - -CVE-2013-2891 - -Signed-off-by: Kees Cook -Cc: stable@vger.kernel.org -Reviewed-by: Benjamin Tissoires ---- - drivers/hid/hid-steelseries.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/hid/hid-steelseries.c b/drivers/hid/hid-steelseries.c -index d164911..29f328f 100644 ---- a/drivers/hid/hid-steelseries.c -+++ b/drivers/hid/hid-steelseries.c -@@ -249,6 +249,11 @@ static int steelseries_srws1_probe(struct hid_device *hdev, - goto err_free; - } - -+ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 16)) { -+ ret = -ENODEV; -+ goto err_free; -+ } -+ - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (ret) { - hid_err(hdev, "hw start failed\n"); --- -1.8.3.1 - - -From e846e9b33d65246ed807156a114c65cdfece0d12 Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Wed, 11 Sep 2013 21:56:54 +0200 -Subject: [PATCH 06/16] HID: LG: validate HID output report details - -A HID device could send a malicious output report that would cause the -lg, lg3, and lg4 HID drivers to write beyond the output report allocation -during an event, causing a heap overflow: - -[ 325.245240] usb 1-1: New USB device found, idVendor=046d, idProduct=c287 -... -[ 414.518960] BUG kmalloc-4096 (Not tainted): Redzone overwritten - -Additionally, while lg2 did correctly validate the report details, it was -cleaned up and shortened. - -CVE-2013-2893 - -Signed-off-by: Kees Cook -Cc: stable@vger.kernel.org -Reviewed-by: Benjamin Tissoires ---- - drivers/hid/hid-lg2ff.c | 19 +++---------------- - drivers/hid/hid-lg3ff.c | 29 ++++++----------------------- - drivers/hid/hid-lg4ff.c | 20 +------------------- - drivers/hid/hid-lgff.c | 17 ++--------------- - 4 files changed, 12 insertions(+), 73 deletions(-) - -diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c -index b3cd150..1a42eaa 100644 ---- a/drivers/hid/hid-lg2ff.c -+++ b/drivers/hid/hid-lg2ff.c -@@ -64,26 +64,13 @@ int lg2ff_init(struct hid_device *hid) - struct hid_report *report; - struct hid_input *hidinput = list_entry(hid->inputs.next, - struct hid_input, list); -- struct list_head *report_list = -- &hid->report_enum[HID_OUTPUT_REPORT].report_list; - struct input_dev *dev = hidinput->input; - int error; - -- if (list_empty(report_list)) { -- hid_err(hid, "no output report found\n"); -+ /* Check that the report looks ok */ -+ report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7); -+ if (!report) - return -ENODEV; -- } -- -- report = list_entry(report_list->next, struct hid_report, list); -- -- if (report->maxfield < 1) { -- hid_err(hid, "output report is empty\n"); -- return -ENODEV; -- } -- if (report->field[0]->report_count < 7) { -- hid_err(hid, "not enough values in the field\n"); -- return -ENODEV; -- } - - lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL); - if (!lg2ff) -diff --git a/drivers/hid/hid-lg3ff.c b/drivers/hid/hid-lg3ff.c -index e52f181..8c2da18 100644 ---- a/drivers/hid/hid-lg3ff.c -+++ b/drivers/hid/hid-lg3ff.c -@@ -66,10 +66,11 @@ static int hid_lg3ff_play(struct input_dev *dev, void *data, - int x, y; - - /* -- * Maxusage should always be 63 (maximum fields) -- * likely a better way to ensure this data is clean -+ * Available values in the field should always be 63, but we only use up to -+ * 35. Instead, clear the entire area, however big it is. - */ -- memset(report->field[0]->value, 0, sizeof(__s32)*report->field[0]->maxusage); -+ memset(report->field[0]->value, 0, -+ sizeof(__s32) * report->field[0]->report_count); - - switch (effect->type) { - case FF_CONSTANT: -@@ -129,32 +130,14 @@ static const signed short ff3_joystick_ac[] = { - int lg3ff_init(struct hid_device *hid) - { - struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); -- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; - struct input_dev *dev = hidinput->input; -- struct hid_report *report; -- struct hid_field *field; - const signed short *ff_bits = ff3_joystick_ac; - int error; - int i; - -- /* Find the report to use */ -- if (list_empty(report_list)) { -- hid_err(hid, "No output report found\n"); -- return -1; -- } -- - /* Check that the report looks ok */ -- report = list_entry(report_list->next, struct hid_report, list); -- if (!report) { -- hid_err(hid, "NULL output report\n"); -- return -1; -- } -- -- field = report->field[0]; -- if (!field) { -- hid_err(hid, "NULL field\n"); -- return -1; -- } -+ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 35)) -+ return -ENODEV; - - /* Assume single fixed device G940 */ - for (i = 0; ff_bits[i] >= 0; i++) -diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c -index 0ddae2a..8782fe1 100644 ---- a/drivers/hid/hid-lg4ff.c -+++ b/drivers/hid/hid-lg4ff.c -@@ -484,34 +484,16 @@ static enum led_brightness lg4ff_led_get_brightness(struct led_classdev *led_cde - int lg4ff_init(struct hid_device *hid) - { - struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); -- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; - struct input_dev *dev = hidinput->input; -- struct hid_report *report; -- struct hid_field *field; - struct lg4ff_device_entry *entry; - struct lg_drv_data *drv_data; - struct usb_device_descriptor *udesc; - int error, i, j; - __u16 bcdDevice, rev_maj, rev_min; - -- /* Find the report to use */ -- if (list_empty(report_list)) { -- hid_err(hid, "No output report found\n"); -- return -1; -- } -- - /* Check that the report looks ok */ -- report = list_entry(report_list->next, struct hid_report, list); -- if (!report) { -- hid_err(hid, "NULL output report\n"); -+ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) - return -1; -- } -- -- field = report->field[0]; -- if (!field) { -- hid_err(hid, "NULL field\n"); -- return -1; -- } - - /* Check what wheel has been connected */ - for (i = 0; i < ARRAY_SIZE(lg4ff_devices); i++) { -diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c -index d7ea8c8..e1394af 100644 ---- a/drivers/hid/hid-lgff.c -+++ b/drivers/hid/hid-lgff.c -@@ -128,27 +128,14 @@ static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude) - int lgff_init(struct hid_device* hid) - { - struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); -- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; - struct input_dev *dev = hidinput->input; -- struct hid_report *report; -- struct hid_field *field; - const signed short *ff_bits = ff_joystick; - int error; - int i; - -- /* Find the report to use */ -- if (list_empty(report_list)) { -- hid_err(hid, "No output report found\n"); -- return -1; -- } -- - /* Check that the report looks ok */ -- report = list_entry(report_list->next, struct hid_report, list); -- field = report->field[0]; -- if (!field) { -- hid_err(hid, "NULL field\n"); -- return -1; -- } -+ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) -+ return -ENODEV; - - for (i = 0; i < ARRAY_SIZE(devices); i++) { - if (dev->id.vendor == devices[i].idVendor && --- -1.8.3.1 - - -From 0317e971d90e3e2e312074386a2349b2ef48d1d0 Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Wed, 11 Sep 2013 21:56:55 +0200 -Subject: [PATCH 07/16] HID: lenovo-tpkbd: validate output report details - -From: Kees Cook - -A HID device could send a malicious output report that would cause the -lenovo-tpkbd HID driver to write just beyond the output report allocation -during initialization, causing a heap overflow: - -[ 76.109807] usb 1-1: New USB device found, idVendor=17ef, idProduct=6009 -... -[ 80.462540] BUG kmalloc-192 (Tainted: G W ): Redzone overwritten - -CVE-2013-2894 - -Signed-off-by: Kees Cook -Cc: stable@vger.kernel.org -Signed-off-by: Benjamin Tissoires ---- - drivers/hid/hid-lenovo-tpkbd.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/drivers/hid/hid-lenovo-tpkbd.c b/drivers/hid/hid-lenovo-tpkbd.c -index 07837f5..762d988 100644 ---- a/drivers/hid/hid-lenovo-tpkbd.c -+++ b/drivers/hid/hid-lenovo-tpkbd.c -@@ -339,7 +339,15 @@ static int tpkbd_probe_tp(struct hid_device *hdev) - struct tpkbd_data_pointer *data_pointer; - size_t name_sz = strlen(dev_name(dev)) + 16; - char *name_mute, *name_micmute; -- int ret; -+ int i, ret; -+ -+ /* Validate required reports. */ -+ for (i = 0; i < 4; i++) { -+ if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1)) -+ return -ENODEV; -+ } -+ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2)) -+ return -ENODEV; - - if (sysfs_create_group(&hdev->dev.kobj, - &tpkbd_attr_group_pointer)) { --- -1.8.3.1 - - -From 978474c73af6764f1c2c5409585221e6d438b16c Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Wed, 11 Sep 2013 21:56:56 +0200 -Subject: [PATCH 08/16] HID: logitech-dj: validate output report details - -A HID device could send a malicious output report that would cause the -logitech-dj HID driver to leak kernel memory contents to the device, or -trigger a NULL dereference during initialization: - -[ 304.424553] usb 1-1: New USB device found, idVendor=046d, idProduct=c52b -... -[ 304.780467] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028 -[ 304.781409] IP: [] logi_dj_recv_send_report.isra.11+0x1a/0x90 - -CVE-2013-2895 - -Signed-off-by: Kees Cook -Cc: stable@vger.kernel.org -Signed-off-by: Benjamin Tissoires ---- - drivers/hid/hid-logitech-dj.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c -index cd33084..a2469b5 100644 ---- a/drivers/hid/hid-logitech-dj.c -+++ b/drivers/hid/hid-logitech-dj.c -@@ -461,7 +461,7 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, - struct hid_report *report; - struct hid_report_enum *output_report_enum; - u8 *data = (u8 *)(&dj_report->device_index); -- int i; -+ unsigned int i; - - output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT]; - report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT]; -@@ -471,7 +471,7 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, - return -ENODEV; - } - -- for (i = 0; i < report->field[0]->report_count; i++) -+ for (i = 0; i < DJREPORT_SHORT_LENGTH - 1; i++) - report->field[0]->value[i] = data[i]; - - hid_hw_request(hdev, report, HID_REQ_SET_REPORT); -@@ -783,6 +783,12 @@ static int logi_dj_probe(struct hid_device *hdev, - goto hid_parse_fail; - } - -+ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, REPORT_ID_DJ_SHORT, -+ 0, DJREPORT_SHORT_LENGTH - 1)) { -+ retval = -ENODEV; -+ goto hid_parse_fail; -+ } -+ - /* Starts the usb device and connects to upper interfaces hiddev and - * hidraw */ - retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); --- -1.8.3.1 - - -From 9445e3a28eb6365c54dae729d184c4c3b6b43d60 Mon Sep 17 00:00:00 2001 -From: Benjamin Tissoires -Date: Wed, 11 Sep 2013 21:56:57 +0200 -Subject: [PATCH 09/16] HID: validate feature and input report details - -When dealing with usage_index, be sure to properly use unsigned instead of -int to avoid overflows. - -When working on report fields, always validate that their report_counts are -in bounds. -Without this, a HID device could report a malicious feature report that -could trick the driver into a heap overflow: - -[ 634.885003] usb 1-1: New USB device found, idVendor=0596, idProduct=0500 -... -[ 676.469629] BUG kmalloc-192 (Tainted: G W ): Redzone overwritten - -CVE-2013-2897 - -Cc: stable@vger.kernel.org -Signed-off-by: Benjamin Tissoires ---- - drivers/hid/hid-core.c | 16 +++++++--------- - drivers/hid/hid-input.c | 11 ++++++++++- - 2 files changed, 17 insertions(+), 10 deletions(-) - -diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c -index 65ee459..08500bc 100644 ---- a/drivers/hid/hid-core.c -+++ b/drivers/hid/hid-core.c -@@ -94,7 +94,6 @@ EXPORT_SYMBOL_GPL(hid_register_report); - static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) - { - struct hid_field *field; -- int i; - - if (report->maxfield == HID_MAX_FIELDS) { - hid_err(report->device, "too many fields in report\n"); -@@ -113,9 +112,6 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned - field->value = (s32 *)(field->usage + usages); - field->report = report; - -- for (i = 0; i < usages; i++) -- field->usage[i].usage_index = i; -- - return field; - } - -@@ -226,9 +222,9 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign - { - struct hid_report *report; - struct hid_field *field; -- int usages; -+ unsigned usages; - unsigned offset; -- int i; -+ unsigned i; - - report = hid_register_report(parser->device, report_type, parser->global.report_id); - if (!report) { -@@ -255,7 +251,8 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign - if (!parser->local.usage_index) /* Ignore padding fields */ - return 0; - -- usages = max_t(int, parser->local.usage_index, parser->global.report_count); -+ usages = max_t(unsigned, parser->local.usage_index, -+ parser->global.report_count); - - field = hid_register_field(report, usages, parser->global.report_count); - if (!field) -@@ -266,13 +263,14 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign - field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); - - for (i = 0; i < usages; i++) { -- int j = i; -+ unsigned j = i; - /* Duplicate the last usage we parsed if we have excess values */ - if (i >= parser->local.usage_index) - j = parser->local.usage_index - 1; - field->usage[i].hid = parser->local.usage[j]; - field->usage[i].collection_index = - parser->local.collection_index[j]; -+ field->usage[i].usage_index = i; - } - - field->maxusage = usages; -@@ -1290,7 +1288,7 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, - goto out; - } - -- if (hid->claimed != HID_CLAIMED_HIDRAW) { -+ if (hid->claimed != HID_CLAIMED_HIDRAW && report->maxfield) { - for (a = 0; a < report->maxfield; a++) - hid_input_field(hid, report->field[a], cdata, interrupt); - hdrv = hid->driver; -diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c -index 7480799..3ac2138 100644 ---- a/drivers/hid/hid-input.c -+++ b/drivers/hid/hid-input.c -@@ -477,6 +477,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel - if (field->flags & HID_MAIN_ITEM_CONSTANT) - goto ignore; - -+ /* Ignore if report count is out of bounds. */ -+ if (field->report_count < 1) -+ goto ignore; -+ - /* only LED usages are supported in output fields */ - if (field->report_type == HID_OUTPUT_REPORT && - (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) { -@@ -1160,7 +1164,11 @@ static void report_features(struct hid_device *hid) - - rep_enum = &hid->report_enum[HID_FEATURE_REPORT]; - list_for_each_entry(rep, &rep_enum->report_list, list) -- for (i = 0; i < rep->maxfield; i++) -+ for (i = 0; i < rep->maxfield; i++) { -+ /* Ignore if report count is out of bounds. */ -+ if (rep->field[i]->report_count < 1) -+ continue; -+ - for (j = 0; j < rep->field[i]->maxusage; j++) { - /* Verify if Battery Strength feature is available */ - hidinput_setup_battery(hid, HID_FEATURE_REPORT, rep->field[i]); -@@ -1169,6 +1177,7 @@ static void report_features(struct hid_device *hid) - drv->feature_mapping(hid, rep->field[i], - rep->field[i]->usage + j); - } -+ } - } - - static struct hid_input *hidinput_allocate(struct hid_device *hid) --- -1.8.3.1 - - -From cc8d6c5e14fbffc3349dcd35c21fa46f1143070d Mon Sep 17 00:00:00 2001 -From: Benjamin Tissoires -Date: Wed, 11 Sep 2013 21:56:58 +0200 -Subject: [PATCH 10/16] HID: multitouch: validate indexes details - -When working on report indexes, always validate that they are in bounds. -Without this, a HID device could report a malicious feature report that -could trick the driver into a heap overflow: - -[ 634.885003] usb 1-1: New USB device found, idVendor=0596, idProduct=0500 -... -[ 676.469629] BUG kmalloc-192 (Tainted: G W ): Redzone overwritten - -Note that we need to change the indexes from s8 to s16 as they can -be between -1 and 255. - -CVE-2013-2897 - -Cc: stable@vger.kernel.org -Signed-off-by: Benjamin Tissoires ---- - drivers/hid/hid-multitouch.c | 26 ++++++++++++++------------ - 1 file changed, 14 insertions(+), 12 deletions(-) - -diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c -index cb0e361..2d3677c 100644 ---- a/drivers/hid/hid-multitouch.c -+++ b/drivers/hid/hid-multitouch.c -@@ -101,9 +101,9 @@ struct mt_device { - unsigned last_slot_field; /* the last field of a slot */ - unsigned mt_report_id; /* the report ID of the multitouch device */ - unsigned pen_report_id; /* the report ID of the pen device */ -- __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ -- __s8 inputmode_index; /* InputMode HID feature index in the report */ -- __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, -+ __s16 inputmode; /* InputMode HID feature, -1 if non-existent */ -+ __s16 inputmode_index; /* InputMode HID feature index in the report */ -+ __s16 maxcontact_report_id; /* Maximum Contact Number HID feature, - -1 if non-existent */ - __u8 num_received; /* how many contacts we received */ - __u8 num_expected; /* expected last contact index */ -@@ -317,20 +317,18 @@ static void mt_feature_mapping(struct hid_device *hdev, - struct hid_field *field, struct hid_usage *usage) - { - struct mt_device *td = hid_get_drvdata(hdev); -- int i; - - switch (usage->hid) { - case HID_DG_INPUTMODE: -- td->inputmode = field->report->id; -- td->inputmode_index = 0; /* has to be updated below */ -- -- for (i=0; i < field->maxusage; i++) { -- if (field->usage[i].hid == usage->hid) { -- td->inputmode_index = i; -- break; -- } -+ /* Ignore if value index is out of bounds. */ -+ if (usage->usage_index >= field->report_count) { -+ dev_err(&hdev->dev, "HID_DG_INPUTMODE out of range\n"); -+ break; - } - -+ td->inputmode = field->report->id; -+ td->inputmode_index = usage->usage_index; -+ - break; - case HID_DG_CONTACTMAX: - td->maxcontact_report_id = field->report->id; -@@ -536,6 +534,10 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, - mt_store_field(usage, td, hi); - return 1; - case HID_DG_CONTACTCOUNT: -+ /* Ignore if indexes are out of bounds. */ -+ if (field->index >= field->report->maxfield || -+ usage->usage_index >= field->report_count) -+ return 1; - td->cc_index = field->index; - td->cc_value_index = usage->usage_index; - return 1; --- -1.8.3.1 - - -From 01b52229ddc746c56b2a7756eed46b1f98673bea Mon Sep 17 00:00:00 2001 -From: Benjamin Tissoires -Date: Wed, 11 Sep 2013 21:56:59 +0200 -Subject: [PATCH 11/16] HID: lenovo-tpkbd: fix leak if tpkbd_probe_tp fails - -If tpkbd_probe_tp() bails out, the probe() function return an error, -but hid_hw_stop() is never called. - -fixes: -https://bugzilla.redhat.com/show_bug.cgi?id=1003998 - -Cc: stable@vger.kernel.org -Signed-off-by: Benjamin Tissoires ---- - drivers/hid/hid-lenovo-tpkbd.c | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) - -diff --git a/drivers/hid/hid-lenovo-tpkbd.c b/drivers/hid/hid-lenovo-tpkbd.c -index 762d988..31cf29a 100644 ---- a/drivers/hid/hid-lenovo-tpkbd.c -+++ b/drivers/hid/hid-lenovo-tpkbd.c -@@ -414,22 +414,27 @@ static int tpkbd_probe(struct hid_device *hdev, - ret = hid_parse(hdev); - if (ret) { - hid_err(hdev, "hid_parse failed\n"); -- goto err_free; -+ goto err; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (ret) { - hid_err(hdev, "hid_hw_start failed\n"); -- goto err_free; -+ goto err; - } - - uhdev = (struct usbhid_device *) hdev->driver_data; - -- if (uhdev->ifnum == 1) -- return tpkbd_probe_tp(hdev); -+ if (uhdev->ifnum == 1) { -+ ret = tpkbd_probe_tp(hdev); -+ if (ret) -+ goto err_hid; -+ } - - return 0; --err_free: -+err_hid: -+ hid_hw_stop(hdev); -+err: - return ret; - } - --- -1.8.3.1 diff --git a/kernel.spec b/kernel.spec index 9c6b24a..26db752 100644 --- a/kernel.spec +++ b/kernel.spec @@ -62,7 +62,7 @@ Summary: The Linux kernel # For non-released -rc kernels, this will be appended after the rcX and # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3" # -%global baserelease 301 +%global baserelease 300 %global fedora_build %{baserelease} # base_sublevel is the kernel version we're starting with and patching @@ -74,7 +74,7 @@ Summary: The Linux kernel %if 0%{?released_kernel} # Do we have a -stable update to apply? -%define stable_update 2 +%define stable_update 3 # Is it a -stable RC? %define stable_rc 0 # Set rpm version accordingly @@ -766,16 +766,6 @@ Patch25057: iwl4965-better-skb-management-in-rx-path.patch #rhbz 963715 Patch25077: media-cx23885-Fix-TeVii-S471-regression-since-introduction-of-ts2020.patch -#rhbz 1000679 -Patch25078: rt2800-rearrange-bbp-rfcsr-initialization.patch - -#CVE-2013-2888 rhbz 1000451 1002543 CVE-2013-2889 rhbz 999890 1002548 -#CVE-2013-2891 rhbz 999960 1002555 CVE-2013-2892 rhbz 1000429 1002570 -#CVE-2013-2893 rhbz 1000414 1002575 CVE-2013-2894 rhbz 1000137 1002579 -#CVE-2013-2895 rhbz 1000360 1002581 CVE-2013-2896 rhbz 1000494 1002594 -#CVE-2013-2897 rhbz 1000536 1002600 CVE-2013-2899 rhbz 1000373 1002604 -Patch25099: HID-CVE-fixes-3.11.patch - #CVE-2013-4343 rhbz 1007733 1007741 Patch25101: tuntap-correctly-handle-error-in-tun_set_iff.patch @@ -786,7 +776,6 @@ Patch25102: net-sctp-fix-ipv6-ipsec-encryption-bug-in-sctp_v6_xmit.patch Patch25104: ansi_cprng-Fix-off-by-one-error-in-non-block-size-request.patch #rhbz 1008323 -Patch25106: 0001-skge-fix-broken-driver.patch Patch25120: skge-fix-invalid-value-passed-to-pci_unmap_sigle.patch #rhbz 985522 @@ -798,12 +787,6 @@ Patch25108: Revert-rt2x00pci-Use-PCI-MSIs-whenever-possible.patch #rhbz 971893 Patch25109: bonding-driver-alb-learning.patch -#rhbz 997705 -Patch25110: rpc-clean-up-decoding-of-gssproxy-linux-creds.patch -Patch25111: rpc-comment-on-linux_cred-encoding-treat-all-as-unsigned.patch -Patch25112: rpc-fix-huge-kmallocs-in-gss-proxy.patch -Patch25113: rpc-let-xdr-layer-allocate-gssproxy-receieve-pages.patch - #rhbz 902012 Patch25114: elevator-Fix-a-race-in-elevator-switching-and-md.patch Patch25115: elevator-acquire-q-sysfs_lock-in-elevator_change.patch @@ -1538,16 +1521,6 @@ ApplyPatch iwl4965-better-skb-management-in-rx-path.patch #rhbz 963715 ApplyPatch media-cx23885-Fix-TeVii-S471-regression-since-introduction-of-ts2020.patch -#CVE-2013-2888 rhbz 1000451 1002543 CVE-2013-2889 rhbz 999890 1002548 -#CVE-2013-2891 rhbz 999960 1002555 CVE-2013-2892 rhbz 1000429 1002570 -#CVE-2013-2893 rhbz 1000414 1002575 CVE-2013-2894 rhbz 1000137 1002579 -#CVE-2013-2895 rhbz 1000360 1002581 CVE-2013-2896 rhbz 1000494 1002594 -#CVE-2013-2897 rhbz 1000536 1002600 CVE-2013-2899 rhbz 1000373 1002604 -ApplyPatch HID-CVE-fixes-3.11.patch - -#rhbz 1000679 -ApplyPatch rt2800-rearrange-bbp-rfcsr-initialization.patch - #CVE-2013-4343 rhbz 1007733 1007741 ApplyPatch tuntap-correctly-handle-error-in-tun_set_iff.patch @@ -1566,14 +1539,7 @@ ApplyPatch Revert-rt2x00pci-Use-PCI-MSIs-whenever-possible.patch #rhbz 971893 ApplyPatch bonding-driver-alb-learning.patch -#rhbz 997705 -ApplyPatch rpc-clean-up-decoding-of-gssproxy-linux-creds.patch -ApplyPatch rpc-comment-on-linux_cred-encoding-treat-all-as-unsigned.patch -ApplyPatch rpc-fix-huge-kmallocs-in-gss-proxy.patch -ApplyPatch rpc-let-xdr-layer-allocate-gssproxy-receieve-pages.patch - #rhbz 1008323 -ApplyPatch 0001-skge-fix-broken-driver.patch ApplyPatch skge-fix-invalid-value-passed-to-pci_unmap_sigle.patch #rhbz 902012 @@ -2388,6 +2354,9 @@ fi # ||----w | # || || %changelog +* Wed Oct 2 2013 Justin M. Forbes - 3.11.3-300 +- Linux v3.11.3 + * Mon Sep 30 2013 Josh Boyer - Add support for rf3070 devices from Stanislaw Gruszka (rhbz 974072) - Drop VC_MUTE patch (rhbz 859485) diff --git a/rpc-clean-up-decoding-of-gssproxy-linux-creds.patch b/rpc-clean-up-decoding-of-gssproxy-linux-creds.patch deleted file mode 100644 index ffafde8..0000000 --- a/rpc-clean-up-decoding-of-gssproxy-linux-creds.patch +++ /dev/null @@ -1,110 +0,0 @@ -From: "J. Bruce Fields" - -commit 778e512bb1d3315c6b55832248cd30c566c081d7 upstream. - -We can use the normal coding infrastructure here. - -Two minor behavior changes: - - - we're assuming no wasted space at the end of the linux cred. - That seems to match gss-proxy's behavior, and I can't see why - it would need to do differently in the future. - - - NGROUPS_MAX check added: note groups_alloc doesn't do this, - this is the caller's responsibility. - -Tested-by: Simo Sorce -Signed-off-by: J. Bruce Fields ---- - net/sunrpc/auth_gss/gss_rpc_xdr.c | 32 +++++++++++++------------------- - 1 file changed, 13 insertions(+), 19 deletions(-) - -diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c -index 3c85d1c..f5067b2 100644 ---- a/net/sunrpc/auth_gss/gss_rpc_xdr.c -+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c -@@ -166,14 +166,14 @@ static int dummy_dec_opt_array(struct xdr_stream *xdr, - return 0; - } - --static int get_s32(void **p, void *max, s32 *res) -+static int get_s32(struct xdr_stream *xdr, s32 *res) - { -- void *base = *p; -- void *next = (void *)((char *)base + sizeof(s32)); -- if (unlikely(next > max || next < base)) -+ __be32 *p; -+ -+ p = xdr_inline_decode(xdr, 4); -+ if (!p) - return -EINVAL; -- memcpy(res, base, sizeof(s32)); -- *p = next; -+ memcpy(res, p, sizeof(s32)); - return 0; - } - -@@ -182,7 +182,6 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr, - { - u32 length; - __be32 *p; -- void *q, *end; - s32 tmp; - int N, i, err; - -@@ -192,33 +191,28 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr, - - length = be32_to_cpup(p); - -- /* FIXME: we do not want to use the scratch buffer for this one -- * may need to use functions that allows us to access an io vector -- * directly */ -- p = xdr_inline_decode(xdr, length); -- if (unlikely(p == NULL)) -+ if (length > (3 + NGROUPS_MAX) * sizeof(u32)) - return -ENOSPC; - -- q = p; -- end = q + length; -- - /* uid */ -- err = get_s32(&q, end, &tmp); -+ err = get_s32(xdr, &tmp); - if (err) - return err; - creds->cr_uid = make_kuid(&init_user_ns, tmp); - - /* gid */ -- err = get_s32(&q, end, &tmp); -+ err = get_s32(xdr, &tmp); - if (err) - return err; - creds->cr_gid = make_kgid(&init_user_ns, tmp); - - /* number of additional gid's */ -- err = get_s32(&q, end, &tmp); -+ err = get_s32(xdr, &tmp); - if (err) - return err; - N = tmp; -+ if ((3 + N) * sizeof(u32) != length) -+ return -EINVAL; - creds->cr_group_info = groups_alloc(N); - if (creds->cr_group_info == NULL) - return -ENOMEM; -@@ -226,7 +220,7 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr, - /* gid's */ - for (i = 0; i < N; i++) { - kgid_t kgid; -- err = get_s32(&q, end, &tmp); -+ err = get_s32(xdr, &tmp); - if (err) - goto out_free_groups; - err = -EINVAL; --- -1.7.9.5 - --- -To unsubscribe from this list: send the line "unsubscribe linux-nfs" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html \ No newline at end of file diff --git a/rpc-comment-on-linux_cred-encoding-treat-all-as-unsigned.patch b/rpc-comment-on-linux_cred-encoding-treat-all-as-unsigned.patch deleted file mode 100644 index b4f9291..0000000 --- a/rpc-comment-on-linux_cred-encoding-treat-all-as-unsigned.patch +++ /dev/null @@ -1,90 +0,0 @@ -From: "J. Bruce Fields" - -commit 6a36978e6931e6601be586eb313375335f2cfaa3 upstream. - -The encoding of linux creds is a bit confusing. - -Also: I think in practice it doesn't really matter whether we treat any -of these things as signed or unsigned, but unsigned seems more -straightforward: uid_t/gid_t are unsigned and it simplifies the ngroups -overflow check. - -Tested-by: Simo Sorce -Signed-off-by: J. Bruce Fields ---- - net/sunrpc/auth_gss/gss_rpc_xdr.c | 18 ++++++++++-------- - 1 file changed, 10 insertions(+), 8 deletions(-) - -diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c -index f5067b2..3c19c7d 100644 ---- a/net/sunrpc/auth_gss/gss_rpc_xdr.c -+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c -@@ -166,14 +166,15 @@ static int dummy_dec_opt_array(struct xdr_stream *xdr, - return 0; - } - --static int get_s32(struct xdr_stream *xdr, s32 *res) -+static int get_host_u32(struct xdr_stream *xdr, u32 *res) - { - __be32 *p; - - p = xdr_inline_decode(xdr, 4); - if (!p) - return -EINVAL; -- memcpy(res, p, sizeof(s32)); -+ /* Contents of linux creds are all host-endian: */ -+ memcpy(res, p, sizeof(u32)); - return 0; - } - -@@ -182,8 +183,9 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr, - { - u32 length; - __be32 *p; -- s32 tmp; -- int N, i, err; -+ u32 tmp; -+ u32 N; -+ int i, err; - - p = xdr_inline_decode(xdr, 4); - if (unlikely(p == NULL)) -@@ -195,19 +197,19 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr, - return -ENOSPC; - - /* uid */ -- err = get_s32(xdr, &tmp); -+ err = get_host_u32(xdr, &tmp); - if (err) - return err; - creds->cr_uid = make_kuid(&init_user_ns, tmp); - - /* gid */ -- err = get_s32(xdr, &tmp); -+ err = get_host_u32(xdr, &tmp); - if (err) - return err; - creds->cr_gid = make_kgid(&init_user_ns, tmp); - - /* number of additional gid's */ -- err = get_s32(xdr, &tmp); -+ err = get_host_u32(xdr, &tmp); - if (err) - return err; - N = tmp; -@@ -220,7 +222,7 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr, - /* gid's */ - for (i = 0; i < N; i++) { - kgid_t kgid; -- err = get_s32(xdr, &tmp); -+ err = get_host_u32(xdr, &tmp); - if (err) - goto out_free_groups; - err = -EINVAL; --- -1.7.9.5 - --- -To unsubscribe from this list: send the line "unsubscribe linux-nfs" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html \ No newline at end of file diff --git a/rpc-fix-huge-kmallocs-in-gss-proxy.patch b/rpc-fix-huge-kmallocs-in-gss-proxy.patch deleted file mode 100644 index 6257f45..0000000 --- a/rpc-fix-huge-kmallocs-in-gss-proxy.patch +++ /dev/null @@ -1,113 +0,0 @@ -From: "J. Bruce Fields" - -commit 9dfd87da1aeb0fd364167ad199f40fe96a6a87be upstream. - -The reply to a gssproxy can include up to NGROUPS_MAX gid's, which will -take up more than a page. We therefore need to allocate an array of -pages to hold the reply instead of trying to allocate a single huge -buffer. - -Tested-by: Simo Sorce -Signed-off-by: J. Bruce Fields ---- - net/sunrpc/auth_gss/gss_rpc_upcall.c | 30 ++++++++++++++++++++++++++++++ - net/sunrpc/auth_gss/gss_rpc_xdr.c | 3 +++ - net/sunrpc/auth_gss/gss_rpc_xdr.h | 5 ++++- - 3 files changed, 37 insertions(+), 1 deletion(-) - -diff --git a/net/sunrpc/auth_gss/gss_rpc_upcall.c b/net/sunrpc/auth_gss/gss_rpc_upcall.c -index af7ffd4..be95af3 100644 ---- a/net/sunrpc/auth_gss/gss_rpc_upcall.c -+++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c -@@ -213,6 +213,30 @@ static int gssp_call(struct net *net, struct rpc_message *msg) - return status; - } - -+static void gssp_free_receive_pages(struct gssx_arg_accept_sec_context *arg) -+{ -+ int i; -+ -+ for (i = 0; i < arg->npages && arg->pages[i]; i++) -+ __free_page(arg->pages[i]); -+} -+ -+static int gssp_alloc_receive_pages(struct gssx_arg_accept_sec_context *arg) -+{ -+ int i; -+ -+ arg->npages = DIV_ROUND_UP(NGROUPS_MAX * 4, PAGE_SIZE); -+ arg->pages = kzalloc(arg->npages * sizeof(struct page *), GFP_KERNEL); -+ -+ for (i=0; i < arg->npages; i++) { -+ arg->pages[i] = alloc_page(GFP_KERNEL); -+ if (arg->pages[i] == NULL) { -+ gssp_free_receive_pages(arg); -+ return -ENOMEM; -+ } -+ } -+ return 0; -+} - - /* - * Public functions -@@ -261,10 +285,16 @@ int gssp_accept_sec_context_upcall(struct net *net, - arg.context_handle = &ctxh; - res.output_token->len = GSSX_max_output_token_sz; - -+ ret = gssp_alloc_receive_pages(&arg); -+ if (ret) -+ return ret; -+ - /* use nfs/ for targ_name ? */ - - ret = gssp_call(net, &msg); - -+ gssp_free_receive_pages(&arg); -+ - /* we need to fetch all data even in case of error so - * that we can free special strctures is they have been allocated */ - data->major_status = res.status.major_status; -diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c -index 3c19c7d..f0f78c5 100644 ---- a/net/sunrpc/auth_gss/gss_rpc_xdr.c -+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c -@@ -780,6 +780,9 @@ void gssx_enc_accept_sec_context(struct rpc_rqst *req, - /* arg->options */ - err = dummy_enc_opt_array(xdr, &arg->options); - -+ xdr_inline_pages(&req->rq_rcv_buf, -+ PAGE_SIZE/2 /* pretty arbitrary */, -+ arg->pages, 0 /* page base */, arg->npages * PAGE_SIZE); - done: - if (err) - dprintk("RPC: gssx_enc_accept_sec_context: %d\n", err); -diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.h b/net/sunrpc/auth_gss/gss_rpc_xdr.h -index 1c98b27..685a688 100644 ---- a/net/sunrpc/auth_gss/gss_rpc_xdr.h -+++ b/net/sunrpc/auth_gss/gss_rpc_xdr.h -@@ -147,6 +147,8 @@ struct gssx_arg_accept_sec_context { - struct gssx_cb *input_cb; - u32 ret_deleg_cred; - struct gssx_option_array options; -+ struct page **pages; -+ unsigned int npages; - }; - - struct gssx_res_accept_sec_context { -@@ -240,7 +242,8 @@ int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp, - 2 * GSSX_max_princ_sz + \ - 8 + 8 + 4 + 4 + 4) - #define GSSX_max_output_token_sz 1024 --#define GSSX_max_creds_sz (4 + 4 + 4 + NGROUPS_MAX * 4) -+/* grouplist not included; we allocate separate pages for that: */ -+#define GSSX_max_creds_sz (4 + 4 + 4 /* + NGROUPS_MAX*4 */) - #define GSSX_RES_accept_sec_context_sz (GSSX_default_status_sz + \ - GSSX_default_ctx_sz + \ - GSSX_max_output_token_sz + \ --- -1.7.9.5 - --- -To unsubscribe from this list: send the line "unsubscribe linux-nfs" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html \ No newline at end of file diff --git a/rpc-let-xdr-layer-allocate-gssproxy-receieve-pages.patch b/rpc-let-xdr-layer-allocate-gssproxy-receieve-pages.patch deleted file mode 100644 index fae0dcd..0000000 --- a/rpc-let-xdr-layer-allocate-gssproxy-receieve-pages.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: "J. Bruce Fields" - -commit d4a516560fc96a9d486a9939bcb567e3fdce8f49 upstream. - -In theory the linux cred in a gssproxy reply can include up to -NGROUPS_MAX data, 256K of data. In the common case we expect it to be -shorter. So do as the nfsv3 ACL code does and let the xdr code allocate -the pages as they come in, instead of allocating a lot of pages that -won't typically be used. - -Tested-by: Simo Sorce -Signed-off-by: J. Bruce Fields ---- - net/sunrpc/auth_gss/gss_rpc_upcall.c | 16 ++++++---------- - 1 file changed, 6 insertions(+), 10 deletions(-) - -diff --git a/net/sunrpc/auth_gss/gss_rpc_upcall.c b/net/sunrpc/auth_gss/gss_rpc_upcall.c -index be95af3..f1eb0d1 100644 ---- a/net/sunrpc/auth_gss/gss_rpc_upcall.c -+++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c -@@ -223,18 +223,14 @@ static void gssp_free_receive_pages(struct gssx_arg_accept_sec_context *arg) - - static int gssp_alloc_receive_pages(struct gssx_arg_accept_sec_context *arg) - { -- int i; -- - arg->npages = DIV_ROUND_UP(NGROUPS_MAX * 4, PAGE_SIZE); - arg->pages = kzalloc(arg->npages * sizeof(struct page *), GFP_KERNEL); -- -- for (i=0; i < arg->npages; i++) { -- arg->pages[i] = alloc_page(GFP_KERNEL); -- if (arg->pages[i] == NULL) { -- gssp_free_receive_pages(arg); -- return -ENOMEM; -- } -- } -+ /* -+ * XXX: actual pages are allocated by xdr layer in -+ * xdr_partial_copy_from_skb. -+ */ -+ if (!arg->pages) -+ return -ENOMEM; - return 0; - } - --- -1.7.9.5 - --- -To unsubscribe from this list: send the line "unsubscribe linux-nfs" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html \ No newline at end of file diff --git a/rt2800-rearrange-bbp-rfcsr-initialization.patch b/rt2800-rearrange-bbp-rfcsr-initialization.patch deleted file mode 100644 index 5b1e27c..0000000 --- a/rt2800-rearrange-bbp-rfcsr-initialization.patch +++ /dev/null @@ -1,69 +0,0 @@ -My commit - -commit c630ccf1a127578421a928489d51e99c05037054 -Author: Stanislaw Gruszka -Date: Sat Mar 16 19:19:46 2013 +0100 - - rt2800: rearrange bbp/rfcsr initialization - -make Maxim machine freeze when try to start wireless device. - -Initialization order and sending MCU_BOOT_SIGNAL request, changed in -above commit, is important. Doing things incorrectly make PCIe bus -problems, which can froze the machine. - -This patch change initialization sequence like vendor driver do: -function NICInitializeAsic() from -2011_1007_RT5390_RT5392_Linux_STA_V2.5.0.3_DPO (PCI devices) and -DPO_RT5572_LinuxSTA_2.6.1.3_20121022 (according Mediatek, latest driver -for RT8070/RT3070/RT3370/RT3572/RT5370/RT5372/RT5572 USB devices). -It fixes freezes on Maxim system. - -Resolve: -https://bugzilla.redhat.com/show_bug.cgi?id=1000679 - -Reported-and-tested-by: Maxim Polyakov -Bisected-by: Igor Gnatenko -Cc: stable@vger.kernel.org # 3.10+ -Signed-off-by: Stanislaw Gruszka ---- - drivers/net/wireless/rt2x00/rt2800lib.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c -index d217c9e..8f6820a 100644 ---- a/drivers/net/wireless/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/rt2x00/rt2800lib.c -@@ -6631,19 +6631,20 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) - rt2800_init_registers(rt2x00dev))) - return -EIO; - -+ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev))) -+ return -EIO; -+ - /* - * Send signal to firmware during boot time. - */ - rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); - rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); -- if (rt2x00_is_usb(rt2x00dev)) { -+ if (rt2x00_is_usb(rt2x00dev)) - rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); -- rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); -- } -+ rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); - msleep(1); - -- if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev) || -- rt2800_wait_bbp_ready(rt2x00dev))) -+ if (unlikely(rt2800_wait_bbp_ready(rt2x00dev))) - return -EIO; - - rt2800_init_bbp(rt2x00dev); --- -1.7.11.7 - --- -To unsubscribe from this list: send the line "unsubscribe linux-wireless" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html \ No newline at end of file diff --git a/sources b/sources index 9c3b879..447f35f 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ fea363551ff45fbe4cb88497b863b261 linux-3.11.tar.xz -5aa3286dcc7d70ceb50c3cbc64bc1cd8 patch-3.11.2.xz +b098457c2d9e9626faacfda931deefb6 patch-3.11.3.xz