Linux v3.17.3
This commit is contained in:
parent
66f1128feb
commit
4e41491b2a
@ -1,98 +0,0 @@
|
||||
From: Johan Hovold <johan@kernel.org>
|
||||
Date: Fri, 5 Sep 2014 18:08:47 +0200
|
||||
Subject: [PATCH] HID: usbhid: add always-poll quirk
|
||||
|
||||
Add quirk to make sure that a device is always polled for input events
|
||||
even if it hasn't been opened.
|
||||
|
||||
This is needed for devices that disconnects from the bus unless the
|
||||
interrupt endpoint has been polled at least once or when not responding
|
||||
to an input event (e.g. after having shut down X).
|
||||
|
||||
Signed-off-by: Johan Hovold <johan@kernel.org>
|
||||
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
||||
---
|
||||
drivers/hid/usbhid/hid-core.c | 26 +++++++++++++++++++++++---
|
||||
include/linux/hid.h | 1 +
|
||||
2 files changed, 24 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
|
||||
index 79cf503e37bf..ddd547ad6d7e 100644
|
||||
--- a/drivers/hid/usbhid/hid-core.c
|
||||
+++ b/drivers/hid/usbhid/hid-core.c
|
||||
@@ -82,7 +82,7 @@ static int hid_start_in(struct hid_device *hid)
|
||||
struct usbhid_device *usbhid = hid->driver_data;
|
||||
|
||||
spin_lock_irqsave(&usbhid->lock, flags);
|
||||
- if (hid->open > 0 &&
|
||||
+ if ((hid->open > 0 || hid->quirks & HID_QUIRK_ALWAYS_POLL) &&
|
||||
!test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
|
||||
!test_bit(HID_SUSPENDED, &usbhid->iofl) &&
|
||||
!test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
|
||||
@@ -292,6 +292,8 @@ static void hid_irq_in(struct urb *urb)
|
||||
case 0: /* success */
|
||||
usbhid_mark_busy(usbhid);
|
||||
usbhid->retry_delay = 0;
|
||||
+ if ((hid->quirks & HID_QUIRK_ALWAYS_POLL) && !hid->open)
|
||||
+ break;
|
||||
hid_input_report(urb->context, HID_INPUT_REPORT,
|
||||
urb->transfer_buffer,
|
||||
urb->actual_length, 1);
|
||||
@@ -735,8 +737,10 @@ void usbhid_close(struct hid_device *hid)
|
||||
if (!--hid->open) {
|
||||
spin_unlock_irq(&usbhid->lock);
|
||||
hid_cancel_delayed_stuff(usbhid);
|
||||
- usb_kill_urb(usbhid->urbin);
|
||||
- usbhid->intf->needs_remote_wakeup = 0;
|
||||
+ if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL)) {
|
||||
+ usb_kill_urb(usbhid->urbin);
|
||||
+ usbhid->intf->needs_remote_wakeup = 0;
|
||||
+ }
|
||||
} else {
|
||||
spin_unlock_irq(&usbhid->lock);
|
||||
}
|
||||
@@ -1134,6 +1138,19 @@ static int usbhid_start(struct hid_device *hid)
|
||||
|
||||
set_bit(HID_STARTED, &usbhid->iofl);
|
||||
|
||||
+ if (hid->quirks & HID_QUIRK_ALWAYS_POLL) {
|
||||
+ ret = usb_autopm_get_interface(usbhid->intf);
|
||||
+ if (ret)
|
||||
+ goto fail;
|
||||
+ usbhid->intf->needs_remote_wakeup = 1;
|
||||
+ ret = hid_start_in(hid);
|
||||
+ if (ret) {
|
||||
+ dev_err(&hid->dev,
|
||||
+ "failed to start in urb: %d\n", ret);
|
||||
+ }
|
||||
+ usb_autopm_put_interface(usbhid->intf);
|
||||
+ }
|
||||
+
|
||||
/* Some keyboards don't work until their LEDs have been set.
|
||||
* Since BIOSes do set the LEDs, it must be safe for any device
|
||||
* that supports the keyboard boot protocol.
|
||||
@@ -1166,6 +1183,9 @@ static void usbhid_stop(struct hid_device *hid)
|
||||
if (WARN_ON(!usbhid))
|
||||
return;
|
||||
|
||||
+ if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
|
||||
+ usbhid->intf->needs_remote_wakeup = 0;
|
||||
+
|
||||
clear_bit(HID_STARTED, &usbhid->iofl);
|
||||
spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */
|
||||
set_bit(HID_DISCONNECTED, &usbhid->iofl);
|
||||
diff --git a/include/linux/hid.h b/include/linux/hid.h
|
||||
index f53c4a9cca1d..26ee25fced27 100644
|
||||
--- a/include/linux/hid.h
|
||||
+++ b/include/linux/hid.h
|
||||
@@ -287,6 +287,7 @@ struct hid_item {
|
||||
#define HID_QUIRK_HIDINPUT_FORCE 0x00000080
|
||||
#define HID_QUIRK_NO_EMPTY_INPUT 0x00000100
|
||||
#define HID_QUIRK_NO_INIT_INPUT_REPORTS 0x00000200
|
||||
+#define HID_QUIRK_ALWAYS_POLL 0x00000400
|
||||
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
|
||||
#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID 0x00020000
|
||||
#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP 0x00040000
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,37 +0,0 @@
|
||||
From: Adel Gadllah <adel.gadllah@gmail.com>
|
||||
Date: Mon, 6 Oct 2014 15:32:01 +0200
|
||||
Subject: [PATCH] HID: usbhid: always-poll quirk for Elan Touchscreen 009b
|
||||
|
||||
This device needs the quirk as well.
|
||||
---
|
||||
drivers/hid/hid-ids.h | 1 +
|
||||
drivers/hid/usbhid/hid-quirks.c | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
|
||||
index 0d2e07dd71d8..c293747f8c72 100644
|
||||
--- a/drivers/hid/hid-ids.h
|
||||
+++ b/drivers/hid/hid-ids.h
|
||||
@@ -298,6 +298,7 @@
|
||||
|
||||
#define USB_VENDOR_ID_ELAN 0x04f3
|
||||
#define USB_DEVICE_ID_ELAN_TOUCHSCREEN 0x0089
|
||||
+#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B 0x009b
|
||||
|
||||
#define USB_VENDOR_ID_ELECOM 0x056e
|
||||
#define USB_DEVICE_ID_ELECOM_BM084 0x0061
|
||||
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
|
||||
index ca18136ead15..2cdc1ecbf8e4 100644
|
||||
--- a/drivers/hid/usbhid/hid-quirks.c
|
||||
+++ b/drivers/hid/usbhid/hid-quirks.c
|
||||
@@ -71,6 +71,7 @@ static const struct hid_blacklist {
|
||||
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL },
|
||||
+ { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,39 +0,0 @@
|
||||
From: Adel Gadllah <adel.gadllah@gmail.com>
|
||||
Date: Tue, 7 Oct 2014 18:45:09 +0200
|
||||
Subject: [PATCH] HID: usbhid: always-poll quirk for Elan Touchscreen 016f
|
||||
|
||||
This device needs the quirk as well.
|
||||
|
||||
Signed-off-by: Adel Gadllah <adel.gadllah@gmail.com>
|
||||
---
|
||||
drivers/hid/hid-ids.h | 1 +
|
||||
drivers/hid/usbhid/hid-quirks.c | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
|
||||
index c293747f8c72..81bc10e0bba2 100644
|
||||
--- a/drivers/hid/hid-ids.h
|
||||
+++ b/drivers/hid/hid-ids.h
|
||||
@@ -299,6 +299,7 @@
|
||||
#define USB_VENDOR_ID_ELAN 0x04f3
|
||||
#define USB_DEVICE_ID_ELAN_TOUCHSCREEN 0x0089
|
||||
#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B 0x009b
|
||||
+#define USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F 0x016f
|
||||
|
||||
#define USB_VENDOR_ID_ELECOM 0x056e
|
||||
#define USB_DEVICE_ID_ELECOM_BM084 0x0061
|
||||
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
|
||||
index 2cdc1ecbf8e4..39a265df2909 100644
|
||||
--- a/drivers/hid/usbhid/hid-quirks.c
|
||||
+++ b/drivers/hid/usbhid/hid-quirks.c
|
||||
@@ -72,6 +72,7 @@ static const struct hid_blacklist {
|
||||
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B, HID_QUIRK_ALWAYS_POLL },
|
||||
+ { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_016F, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,52 +0,0 @@
|
||||
From: Johan Hovold <johan@kernel.org>
|
||||
Date: Fri, 5 Sep 2014 18:08:48 +0200
|
||||
Subject: [PATCH] HID: usbhid: enable always-poll quirk for Elan Touchscreen
|
||||
|
||||
Enable the always-poll quirk for Elan Touchscreens found on some recent
|
||||
Samsung laptops.
|
||||
|
||||
Without this quirk the device keeps disconnecting from the bus (and is
|
||||
re-enumerated) unless opened (and kept open, should an input event
|
||||
occur).
|
||||
|
||||
Note that while the device can be run-time suspended, the autosuspend
|
||||
timeout must be high enough to allow the device to be polled at least
|
||||
once before being suspended. Specifically, using autosuspend_delay_ms=0
|
||||
will still cause the device to disconnect on input events.
|
||||
|
||||
Signed-off-by: Johan Hovold <johan@kernel.org>
|
||||
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
||||
---
|
||||
drivers/hid/hid-ids.h | 3 +++
|
||||
drivers/hid/usbhid/hid-quirks.c | 1 +
|
||||
2 files changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
|
||||
index 25cd674d6064..0d2e07dd71d8 100644
|
||||
--- a/drivers/hid/hid-ids.h
|
||||
+++ b/drivers/hid/hid-ids.h
|
||||
@@ -296,6 +296,9 @@
|
||||
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7 0x73f7
|
||||
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001
|
||||
|
||||
+#define USB_VENDOR_ID_ELAN 0x04f3
|
||||
+#define USB_DEVICE_ID_ELAN_TOUCHSCREEN 0x0089
|
||||
+
|
||||
#define USB_VENDOR_ID_ELECOM 0x056e
|
||||
#define USB_DEVICE_ID_ELECOM_BM084 0x0061
|
||||
|
||||
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
|
||||
index 15225f3eaed1..ca18136ead15 100644
|
||||
--- a/drivers/hid/usbhid/hid-quirks.c
|
||||
+++ b/drivers/hid/usbhid/hid-quirks.c
|
||||
@@ -70,6 +70,7 @@ static const struct hid_blacklist {
|
||||
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
|
||||
+ { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL },
|
||||
{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
|
||||
{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,97 +0,0 @@
|
||||
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
|
||||
Date: Tue, 2 Sep 2014 09:49:18 -0700
|
||||
Subject: [PATCH] Input: synaptics - gate forcepad support by DMI check
|
||||
|
||||
Unfortunately, ForcePad capability is not actually exported over PS/2, so
|
||||
we have to resort to DMI checks.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Reported-by: Nicole Faerber <nicole.faerber@kernelconcepts.de>
|
||||
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
|
||||
---
|
||||
drivers/input/mouse/synaptics.c | 22 +++++++++++++++++++++-
|
||||
drivers/input/mouse/synaptics.h | 8 ++------
|
||||
2 files changed, 23 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
|
||||
index 6394d9b5bfd3..9031a0a28ea4 100644
|
||||
--- a/drivers/input/mouse/synaptics.c
|
||||
+++ b/drivers/input/mouse/synaptics.c
|
||||
@@ -607,6 +607,8 @@ static void synaptics_parse_agm(const unsigned char buf[],
|
||||
priv->agm_pending = true;
|
||||
}
|
||||
|
||||
+static bool is_forcepad;
|
||||
+
|
||||
static int synaptics_parse_hw_state(const unsigned char buf[],
|
||||
struct synaptics_data *priv,
|
||||
struct synaptics_hw_state *hw)
|
||||
@@ -636,7 +638,7 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
|
||||
hw->left = (buf[0] & 0x01) ? 1 : 0;
|
||||
hw->right = (buf[0] & 0x02) ? 1 : 0;
|
||||
|
||||
- if (SYN_CAP_FORCEPAD(priv->ext_cap_0c)) {
|
||||
+ if (is_forcepad) {
|
||||
/*
|
||||
* ForcePads, like Clickpads, use middle button
|
||||
* bits to report primary button clicks.
|
||||
@@ -1667,11 +1669,29 @@ static const struct dmi_system_id __initconst cr48_dmi_table[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
+static const struct dmi_system_id forcepad_dmi_table[] __initconst = {
|
||||
+#if defined(CONFIG_DMI) && defined(CONFIG_X86)
|
||||
+ {
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook Folio 1040 G1"),
|
||||
+ },
|
||||
+ },
|
||||
+#endif
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
void __init synaptics_module_init(void)
|
||||
{
|
||||
impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
|
||||
broken_olpc_ec = dmi_check_system(olpc_dmi_table);
|
||||
cr48_profile_sensor = dmi_check_system(cr48_dmi_table);
|
||||
+
|
||||
+ /*
|
||||
+ * Unfortunately ForcePad capability is not exported over PS/2,
|
||||
+ * so we have to resort to checking DMI.
|
||||
+ */
|
||||
+ is_forcepad = dmi_check_system(forcepad_dmi_table);
|
||||
}
|
||||
|
||||
static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
|
||||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
|
||||
index fb2e076738ae..1bd01f21783b 100644
|
||||
--- a/drivers/input/mouse/synaptics.h
|
||||
+++ b/drivers/input/mouse/synaptics.h
|
||||
@@ -77,12 +77,9 @@
|
||||
* for noise.
|
||||
* 2 0x08 image sensor image sensor tracks 5 fingers, but only
|
||||
* reports 2.
|
||||
+ * 2 0x01 uniform clickpad whole clickpad moves instead of being
|
||||
+ * hinged at the top.
|
||||
* 2 0x20 report min query 0x0f gives min coord reported
|
||||
- * 2 0x80 forcepad forcepad is a variant of clickpad that
|
||||
- * does not have physical buttons but rather
|
||||
- * uses pressure above certain threshold to
|
||||
- * report primary clicks. Forcepads also have
|
||||
- * clickpad bit set.
|
||||
*/
|
||||
#define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */
|
||||
#define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */
|
||||
@@ -91,7 +88,6 @@
|
||||
#define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000)
|
||||
#define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400)
|
||||
#define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800)
|
||||
-#define SYN_CAP_FORCEPAD(ex0c) ((ex0c) & 0x008000)
|
||||
|
||||
/* synaptics modes query bits */
|
||||
#define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7))
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,37 +0,0 @@
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Fri, 24 Oct 2014 17:07:21 +0200
|
||||
Subject: [PATCH] KVM: emulate: avoid accessing NULL ctxt->memopp
|
||||
|
||||
A failure to decode the instruction can cause a NULL pointer access.
|
||||
This is fixed simply by moving the "done" label as close as possible
|
||||
to the return.
|
||||
|
||||
This fixes CVE-2014-8481.
|
||||
|
||||
Reported-by: Andy Lutomirski <luto@amacapital.net>
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 41061cdb98a0bec464278b4db8e894a3121671f5
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/emulate.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
||||
index a0a04090d2ff..5669ed12f9ee 100644
|
||||
--- a/arch/x86/kvm/emulate.c
|
||||
+++ b/arch/x86/kvm/emulate.c
|
||||
@@ -4565,10 +4565,10 @@ done_prefixes:
|
||||
/* Decode and fetch the destination operand: register or memory. */
|
||||
rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask);
|
||||
|
||||
-done:
|
||||
if (ctxt->rip_relative)
|
||||
ctxt->memopp->addr.mem.ea += ctxt->_eip;
|
||||
|
||||
+done:
|
||||
return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK;
|
||||
}
|
||||
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,145 +0,0 @@
|
||||
From: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Date: Fri, 24 Oct 2014 17:07:12 +0200
|
||||
Subject: [PATCH] KVM: x86: Check non-canonical addresses upon WRMSR
|
||||
|
||||
Upon WRMSR, the CPU should inject #GP if a non-canonical value (address) is
|
||||
written to certain MSRs. The behavior is "almost" identical for AMD and Intel
|
||||
(ignoring MSRs that are not implemented in either architecture since they would
|
||||
anyhow #GP). However, IA32_SYSENTER_ESP and IA32_SYSENTER_EIP cause #GP if
|
||||
non-canonical address is written on Intel but not on AMD (which ignores the top
|
||||
32-bits).
|
||||
|
||||
Accordingly, this patch injects a #GP on the MSRs which behave identically on
|
||||
Intel and AMD. To eliminate the differences between the architecutres, the
|
||||
value which is written to IA32_SYSENTER_ESP and IA32_SYSENTER_EIP is turned to
|
||||
canonical value before writing instead of injecting a #GP.
|
||||
|
||||
Some references from Intel and AMD manuals:
|
||||
|
||||
According to Intel SDM description of WRMSR instruction #GP is expected on
|
||||
WRMSR "If the source register contains a non-canonical address and ECX
|
||||
specifies one of the following MSRs: IA32_DS_AREA, IA32_FS_BASE, IA32_GS_BASE,
|
||||
IA32_KERNEL_GS_BASE, IA32_LSTAR, IA32_SYSENTER_EIP, IA32_SYSENTER_ESP."
|
||||
|
||||
According to AMD manual instruction manual:
|
||||
LSTAR/CSTAR (SYSCALL): "The WRMSR instruction loads the target RIP into the
|
||||
LSTAR and CSTAR registers. If an RIP written by WRMSR is not in canonical
|
||||
form, a general-protection exception (#GP) occurs."
|
||||
IA32_GS_BASE and IA32_FS_BASE (WRFSBASE/WRGSBASE): "The address written to the
|
||||
base field must be in canonical form or a #GP fault will occur."
|
||||
IA32_KERNEL_GS_BASE (SWAPGS): "The address stored in the KernelGSbase MSR must
|
||||
be in canonical form."
|
||||
|
||||
This patch fixes CVE-2014-3610.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
arch/x86/include/asm/kvm_host.h | 14 ++++++++++++++
|
||||
arch/x86/kvm/svm.c | 2 +-
|
||||
arch/x86/kvm/vmx.c | 2 +-
|
||||
arch/x86/kvm/x86.c | 27 ++++++++++++++++++++++++++-
|
||||
4 files changed, 42 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
|
||||
index 7c492ed9087b..78d014c83ae3 100644
|
||||
--- a/arch/x86/include/asm/kvm_host.h
|
||||
+++ b/arch/x86/include/asm/kvm_host.h
|
||||
@@ -990,6 +990,20 @@ static inline void kvm_inject_gp(struct kvm_vcpu *vcpu, u32 error_code)
|
||||
kvm_queue_exception_e(vcpu, GP_VECTOR, error_code);
|
||||
}
|
||||
|
||||
+static inline u64 get_canonical(u64 la)
|
||||
+{
|
||||
+ return ((int64_t)la << 16) >> 16;
|
||||
+}
|
||||
+
|
||||
+static inline bool is_noncanonical_address(u64 la)
|
||||
+{
|
||||
+#ifdef CONFIG_X86_64
|
||||
+ return get_canonical(la) != la;
|
||||
+#else
|
||||
+ return false;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
#define TSS_IOPB_BASE_OFFSET 0x66
|
||||
#define TSS_BASE_SIZE 0x68
|
||||
#define TSS_IOPB_SIZE (65536 / 8)
|
||||
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
|
||||
index ddf742768ecf..e2de97daa03c 100644
|
||||
--- a/arch/x86/kvm/svm.c
|
||||
+++ b/arch/x86/kvm/svm.c
|
||||
@@ -3234,7 +3234,7 @@ static int wrmsr_interception(struct vcpu_svm *svm)
|
||||
msr.host_initiated = false;
|
||||
|
||||
svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
|
||||
- if (svm_set_msr(&svm->vcpu, &msr)) {
|
||||
+ if (kvm_set_msr(&svm->vcpu, &msr)) {
|
||||
trace_kvm_msr_write_ex(ecx, data);
|
||||
kvm_inject_gp(&svm->vcpu, 0);
|
||||
} else {
|
||||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
||||
index 6a118fa378b5..3a3e419780df 100644
|
||||
--- a/arch/x86/kvm/vmx.c
|
||||
+++ b/arch/x86/kvm/vmx.c
|
||||
@@ -5263,7 +5263,7 @@ static int handle_wrmsr(struct kvm_vcpu *vcpu)
|
||||
msr.data = data;
|
||||
msr.index = ecx;
|
||||
msr.host_initiated = false;
|
||||
- if (vmx_set_msr(vcpu, &msr) != 0) {
|
||||
+ if (kvm_set_msr(vcpu, &msr) != 0) {
|
||||
trace_kvm_msr_write_ex(ecx, data);
|
||||
kvm_inject_gp(vcpu, 0);
|
||||
return 1;
|
||||
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
|
||||
index 8f1e22d3b286..1f9a233d8624 100644
|
||||
--- a/arch/x86/kvm/x86.c
|
||||
+++ b/arch/x86/kvm/x86.c
|
||||
@@ -984,7 +984,6 @@ void kvm_enable_efer_bits(u64 mask)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_enable_efer_bits);
|
||||
|
||||
-
|
||||
/*
|
||||
* Writes msr value into into the appropriate "register".
|
||||
* Returns 0 on success, non-0 otherwise.
|
||||
@@ -992,8 +991,34 @@ EXPORT_SYMBOL_GPL(kvm_enable_efer_bits);
|
||||
*/
|
||||
int kvm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
|
||||
{
|
||||
+ switch (msr->index) {
|
||||
+ case MSR_FS_BASE:
|
||||
+ case MSR_GS_BASE:
|
||||
+ case MSR_KERNEL_GS_BASE:
|
||||
+ case MSR_CSTAR:
|
||||
+ case MSR_LSTAR:
|
||||
+ if (is_noncanonical_address(msr->data))
|
||||
+ return 1;
|
||||
+ break;
|
||||
+ case MSR_IA32_SYSENTER_EIP:
|
||||
+ case MSR_IA32_SYSENTER_ESP:
|
||||
+ /*
|
||||
+ * IA32_SYSENTER_ESP and IA32_SYSENTER_EIP cause #GP if
|
||||
+ * non-canonical address is written on Intel but not on
|
||||
+ * AMD (which ignores the top 32-bits, because it does
|
||||
+ * not implement 64-bit SYSENTER).
|
||||
+ *
|
||||
+ * 64-bit code should hence be able to write a non-canonical
|
||||
+ * value on AMD. Making the address canonical ensures that
|
||||
+ * vmentry does not fail on Intel after writing a non-canonical
|
||||
+ * value, and that something deterministic happens if the guest
|
||||
+ * invokes 64-bit SYSENTER.
|
||||
+ */
|
||||
+ msr->data = get_canonical(msr->data);
|
||||
+ }
|
||||
return kvm_x86_ops->set_msr(vcpu, msr);
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(kvm_set_msr);
|
||||
|
||||
/*
|
||||
* Adapt set_msr() to msr_io()'s calling convention
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,38 +0,0 @@
|
||||
From: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Date: Fri, 24 Oct 2014 17:07:20 +0200
|
||||
Subject: [PATCH] KVM: x86: Decoding guest instructions which cross page
|
||||
boundary may fail
|
||||
|
||||
Once an instruction crosses a page boundary, the size read from the second page
|
||||
disregards the common case that part of the operand resides on the first page.
|
||||
As a result, fetch of long insturctions may fail, and thereby cause the
|
||||
decoding to fail as well.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 5cfc7e0f5e5e1adf998df94f8e36edaf5d30d38e
|
||||
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/emulate.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
||||
index 1ac496349f39..a0a04090d2ff 100644
|
||||
--- a/arch/x86/kvm/emulate.c
|
||||
+++ b/arch/x86/kvm/emulate.c
|
||||
@@ -777,8 +777,10 @@ static int __do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, int op_size)
|
||||
static __always_inline int do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt,
|
||||
unsigned size)
|
||||
{
|
||||
- if (unlikely(ctxt->fetch.end - ctxt->fetch.ptr < size))
|
||||
- return __do_insn_fetch_bytes(ctxt, size);
|
||||
+ unsigned done_size = ctxt->fetch.end - ctxt->fetch.ptr;
|
||||
+
|
||||
+ if (unlikely(done_size < size))
|
||||
+ return __do_insn_fetch_bytes(ctxt, size - done_size);
|
||||
else
|
||||
return X86EMUL_CONTINUE;
|
||||
}
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,77 +0,0 @@
|
||||
From: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Date: Fri, 24 Oct 2014 17:07:22 +0200
|
||||
Subject: [PATCH] KVM: x86: Emulator does not decode clflush well
|
||||
|
||||
Currently, all group15 instructions are decoded as clflush (e.g., mfence,
|
||||
xsave). In addition, the clflush instruction requires no prefix (66/f2/f3)
|
||||
would exist. If prefix exists it may encode a different instruction (e.g.,
|
||||
clflushopt).
|
||||
|
||||
Creating a group for clflush, and different group for each prefix.
|
||||
|
||||
This has been the case forever, but the next patch needs the cflush group
|
||||
in order to fix a bug introduced in 3.17.
|
||||
|
||||
Fixes: 41061cdb98a0bec464278b4db8e894a3121671f5
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/emulate.c | 20 +++++++++++++++++---
|
||||
1 file changed, 17 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
||||
index 5669ed12f9ee..d1a19289d11a 100644
|
||||
--- a/arch/x86/kvm/emulate.c
|
||||
+++ b/arch/x86/kvm/emulate.c
|
||||
@@ -3458,6 +3458,12 @@ static int em_bswap(struct x86_emulate_ctxt *ctxt)
|
||||
return X86EMUL_CONTINUE;
|
||||
}
|
||||
|
||||
+static int em_clflush(struct x86_emulate_ctxt *ctxt)
|
||||
+{
|
||||
+ /* emulating clflush regardless of cpuid */
|
||||
+ return X86EMUL_CONTINUE;
|
||||
+}
|
||||
+
|
||||
static bool valid_cr(int nr)
|
||||
{
|
||||
switch (nr) {
|
||||
@@ -3790,6 +3796,16 @@ static const struct opcode group11[] = {
|
||||
X7(D(Undefined)),
|
||||
};
|
||||
|
||||
+static const struct gprefix pfx_0f_ae_7 = {
|
||||
+ I(0, em_clflush), N, N, N,
|
||||
+};
|
||||
+
|
||||
+static const struct group_dual group15 = { {
|
||||
+ N, N, N, N, N, N, N, GP(0, &pfx_0f_ae_7),
|
||||
+}, {
|
||||
+ N, N, N, N, N, N, N, N,
|
||||
+} };
|
||||
+
|
||||
static const struct gprefix pfx_0f_6f_0f_7f = {
|
||||
I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov),
|
||||
};
|
||||
@@ -4049,7 +4065,7 @@ static const struct opcode twobyte_table[256] = {
|
||||
F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
|
||||
F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
|
||||
F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
|
||||
- D(ModRM), F(DstReg | SrcMem | ModRM, em_imul),
|
||||
+ GD(0, &group15), F(DstReg | SrcMem | ModRM, em_imul),
|
||||
/* 0xB0 - 0xB7 */
|
||||
I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_cmpxchg),
|
||||
I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg),
|
||||
@@ -4976,8 +4992,6 @@ twobyte_insn:
|
||||
case 0x90 ... 0x9f: /* setcc r/m8 */
|
||||
ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags);
|
||||
break;
|
||||
- case 0xae: /* clflush */
|
||||
- break;
|
||||
case 0xb6 ... 0xb7: /* movzx */
|
||||
ctxt->dst.bytes = ctxt->op_bytes;
|
||||
ctxt->dst.val = (ctxt->src.bytes == 1) ? (u8) ctxt->src.val
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,234 +0,0 @@
|
||||
From: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Date: Fri, 24 Oct 2014 17:07:16 +0200
|
||||
Subject: [PATCH] KVM: x86: Emulator fixes for eip canonical checks on near
|
||||
branches
|
||||
|
||||
Before changing rip (during jmp, call, ret, etc.) the target should be asserted
|
||||
to be canonical one, as real CPUs do. During sysret, both target rsp and rip
|
||||
should be canonical. If any of these values is noncanonical, a #GP exception
|
||||
should occur. The exception to this rule are syscall and sysenter instructions
|
||||
in which the assigned rip is checked during the assignment to the relevant
|
||||
MSRs.
|
||||
|
||||
This patch fixes the emulator to behave as real CPUs do for near branches.
|
||||
Far branches are handled by the next patch.
|
||||
|
||||
This fixes CVE-2014-3647.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/emulate.c | 78 ++++++++++++++++++++++++++++++++++----------------
|
||||
1 file changed, 54 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
||||
index a85f438b6a47..e52e74feedb8 100644
|
||||
--- a/arch/x86/kvm/emulate.c
|
||||
+++ b/arch/x86/kvm/emulate.c
|
||||
@@ -563,7 +563,8 @@ static int emulate_nm(struct x86_emulate_ctxt *ctxt)
|
||||
return emulate_exception(ctxt, NM_VECTOR, 0, false);
|
||||
}
|
||||
|
||||
-static inline void assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst)
|
||||
+static inline int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst,
|
||||
+ int cs_l)
|
||||
{
|
||||
switch (ctxt->op_bytes) {
|
||||
case 2:
|
||||
@@ -573,16 +574,25 @@ static inline void assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst)
|
||||
ctxt->_eip = (u32)dst;
|
||||
break;
|
||||
case 8:
|
||||
+ if ((cs_l && is_noncanonical_address(dst)) ||
|
||||
+ (!cs_l && (dst & ~(u32)-1)))
|
||||
+ return emulate_gp(ctxt, 0);
|
||||
ctxt->_eip = dst;
|
||||
break;
|
||||
default:
|
||||
WARN(1, "unsupported eip assignment size\n");
|
||||
}
|
||||
+ return X86EMUL_CONTINUE;
|
||||
+}
|
||||
+
|
||||
+static inline int assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst)
|
||||
+{
|
||||
+ return assign_eip_far(ctxt, dst, ctxt->mode == X86EMUL_MODE_PROT64);
|
||||
}
|
||||
|
||||
-static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
|
||||
+static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
|
||||
{
|
||||
- assign_eip_near(ctxt, ctxt->_eip + rel);
|
||||
+ return assign_eip_near(ctxt, ctxt->_eip + rel);
|
||||
}
|
||||
|
||||
static u16 get_segment_selector(struct x86_emulate_ctxt *ctxt, unsigned seg)
|
||||
@@ -1989,13 +1999,15 @@ static int em_grp45(struct x86_emulate_ctxt *ctxt)
|
||||
case 2: /* call near abs */ {
|
||||
long int old_eip;
|
||||
old_eip = ctxt->_eip;
|
||||
- ctxt->_eip = ctxt->src.val;
|
||||
+ rc = assign_eip_near(ctxt, ctxt->src.val);
|
||||
+ if (rc != X86EMUL_CONTINUE)
|
||||
+ break;
|
||||
ctxt->src.val = old_eip;
|
||||
rc = em_push(ctxt);
|
||||
break;
|
||||
}
|
||||
case 4: /* jmp abs */
|
||||
- ctxt->_eip = ctxt->src.val;
|
||||
+ rc = assign_eip_near(ctxt, ctxt->src.val);
|
||||
break;
|
||||
case 5: /* jmp far */
|
||||
rc = em_jmp_far(ctxt);
|
||||
@@ -2030,10 +2042,14 @@ static int em_cmpxchg8b(struct x86_emulate_ctxt *ctxt)
|
||||
|
||||
static int em_ret(struct x86_emulate_ctxt *ctxt)
|
||||
{
|
||||
- ctxt->dst.type = OP_REG;
|
||||
- ctxt->dst.addr.reg = &ctxt->_eip;
|
||||
- ctxt->dst.bytes = ctxt->op_bytes;
|
||||
- return em_pop(ctxt);
|
||||
+ int rc;
|
||||
+ unsigned long eip;
|
||||
+
|
||||
+ rc = emulate_pop(ctxt, &eip, ctxt->op_bytes);
|
||||
+ if (rc != X86EMUL_CONTINUE)
|
||||
+ return rc;
|
||||
+
|
||||
+ return assign_eip_near(ctxt, eip);
|
||||
}
|
||||
|
||||
static int em_ret_far(struct x86_emulate_ctxt *ctxt)
|
||||
@@ -2314,7 +2330,7 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt)
|
||||
{
|
||||
const struct x86_emulate_ops *ops = ctxt->ops;
|
||||
struct desc_struct cs, ss;
|
||||
- u64 msr_data;
|
||||
+ u64 msr_data, rcx, rdx;
|
||||
int usermode;
|
||||
u16 cs_sel = 0, ss_sel = 0;
|
||||
|
||||
@@ -2330,6 +2346,9 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt)
|
||||
else
|
||||
usermode = X86EMUL_MODE_PROT32;
|
||||
|
||||
+ rcx = reg_read(ctxt, VCPU_REGS_RCX);
|
||||
+ rdx = reg_read(ctxt, VCPU_REGS_RDX);
|
||||
+
|
||||
cs.dpl = 3;
|
||||
ss.dpl = 3;
|
||||
ops->get_msr(ctxt, MSR_IA32_SYSENTER_CS, &msr_data);
|
||||
@@ -2347,6 +2366,9 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt)
|
||||
ss_sel = cs_sel + 8;
|
||||
cs.d = 0;
|
||||
cs.l = 1;
|
||||
+ if (is_noncanonical_address(rcx) ||
|
||||
+ is_noncanonical_address(rdx))
|
||||
+ return emulate_gp(ctxt, 0);
|
||||
break;
|
||||
}
|
||||
cs_sel |= SELECTOR_RPL_MASK;
|
||||
@@ -2355,8 +2377,8 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt)
|
||||
ops->set_segment(ctxt, cs_sel, &cs, 0, VCPU_SREG_CS);
|
||||
ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS);
|
||||
|
||||
- ctxt->_eip = reg_read(ctxt, VCPU_REGS_RDX);
|
||||
- *reg_write(ctxt, VCPU_REGS_RSP) = reg_read(ctxt, VCPU_REGS_RCX);
|
||||
+ ctxt->_eip = rdx;
|
||||
+ *reg_write(ctxt, VCPU_REGS_RSP) = rcx;
|
||||
|
||||
return X86EMUL_CONTINUE;
|
||||
}
|
||||
@@ -2897,10 +2919,13 @@ static int em_aad(struct x86_emulate_ctxt *ctxt)
|
||||
|
||||
static int em_call(struct x86_emulate_ctxt *ctxt)
|
||||
{
|
||||
+ int rc;
|
||||
long rel = ctxt->src.val;
|
||||
|
||||
ctxt->src.val = (unsigned long)ctxt->_eip;
|
||||
- jmp_rel(ctxt, rel);
|
||||
+ rc = jmp_rel(ctxt, rel);
|
||||
+ if (rc != X86EMUL_CONTINUE)
|
||||
+ return rc;
|
||||
return em_push(ctxt);
|
||||
}
|
||||
|
||||
@@ -2932,11 +2957,12 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt)
|
||||
static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
|
||||
{
|
||||
int rc;
|
||||
+ unsigned long eip;
|
||||
|
||||
- ctxt->dst.type = OP_REG;
|
||||
- ctxt->dst.addr.reg = &ctxt->_eip;
|
||||
- ctxt->dst.bytes = ctxt->op_bytes;
|
||||
- rc = emulate_pop(ctxt, &ctxt->dst.val, ctxt->op_bytes);
|
||||
+ rc = emulate_pop(ctxt, &eip, ctxt->op_bytes);
|
||||
+ if (rc != X86EMUL_CONTINUE)
|
||||
+ return rc;
|
||||
+ rc = assign_eip_near(ctxt, eip);
|
||||
if (rc != X86EMUL_CONTINUE)
|
||||
return rc;
|
||||
rsp_increment(ctxt, ctxt->src.val);
|
||||
@@ -3267,20 +3293,24 @@ static int em_lmsw(struct x86_emulate_ctxt *ctxt)
|
||||
|
||||
static int em_loop(struct x86_emulate_ctxt *ctxt)
|
||||
{
|
||||
+ int rc = X86EMUL_CONTINUE;
|
||||
+
|
||||
register_address_increment(ctxt, reg_rmw(ctxt, VCPU_REGS_RCX), -1);
|
||||
if ((address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) != 0) &&
|
||||
(ctxt->b == 0xe2 || test_cc(ctxt->b ^ 0x5, ctxt->eflags)))
|
||||
- jmp_rel(ctxt, ctxt->src.val);
|
||||
+ rc = jmp_rel(ctxt, ctxt->src.val);
|
||||
|
||||
- return X86EMUL_CONTINUE;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static int em_jcxz(struct x86_emulate_ctxt *ctxt)
|
||||
{
|
||||
+ int rc = X86EMUL_CONTINUE;
|
||||
+
|
||||
if (address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) == 0)
|
||||
- jmp_rel(ctxt, ctxt->src.val);
|
||||
+ rc = jmp_rel(ctxt, ctxt->src.val);
|
||||
|
||||
- return X86EMUL_CONTINUE;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static int em_in(struct x86_emulate_ctxt *ctxt)
|
||||
@@ -4728,7 +4758,7 @@ special_insn:
|
||||
break;
|
||||
case 0x70 ... 0x7f: /* jcc (short) */
|
||||
if (test_cc(ctxt->b, ctxt->eflags))
|
||||
- jmp_rel(ctxt, ctxt->src.val);
|
||||
+ rc = jmp_rel(ctxt, ctxt->src.val);
|
||||
break;
|
||||
case 0x8d: /* lea r16/r32, m */
|
||||
ctxt->dst.val = ctxt->src.addr.mem.ea;
|
||||
@@ -4758,7 +4788,7 @@ special_insn:
|
||||
break;
|
||||
case 0xe9: /* jmp rel */
|
||||
case 0xeb: /* jmp rel short */
|
||||
- jmp_rel(ctxt, ctxt->src.val);
|
||||
+ rc = jmp_rel(ctxt, ctxt->src.val);
|
||||
ctxt->dst.type = OP_NONE; /* Disable writeback. */
|
||||
break;
|
||||
case 0xf4: /* hlt */
|
||||
@@ -4881,7 +4911,7 @@ twobyte_insn:
|
||||
break;
|
||||
case 0x80 ... 0x8f: /* jnz rel, etc*/
|
||||
if (test_cc(ctxt->b, ctxt->eflags))
|
||||
- jmp_rel(ctxt, ctxt->src.val);
|
||||
+ rc = jmp_rel(ctxt, ctxt->src.val);
|
||||
break;
|
||||
case 0x90 ... 0x9f: /* setcc r/m8 */
|
||||
ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags);
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,64 +0,0 @@
|
||||
From: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Date: Fri, 24 Oct 2014 17:07:15 +0200
|
||||
Subject: [PATCH] KVM: x86: Fix wrong masking on relative jump/call
|
||||
|
||||
Relative jumps and calls do the masking according to the operand size, and not
|
||||
according to the address size as the KVM emulator does today.
|
||||
|
||||
This patch fixes KVM behavior.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/emulate.c | 27 ++++++++++++++++++++++-----
|
||||
1 file changed, 22 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
||||
index 03954f7900f5..a85f438b6a47 100644
|
||||
--- a/arch/x86/kvm/emulate.c
|
||||
+++ b/arch/x86/kvm/emulate.c
|
||||
@@ -504,11 +504,6 @@ static void rsp_increment(struct x86_emulate_ctxt *ctxt, int inc)
|
||||
masked_increment(reg_rmw(ctxt, VCPU_REGS_RSP), stack_mask(ctxt), inc);
|
||||
}
|
||||
|
||||
-static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
|
||||
-{
|
||||
- register_address_increment(ctxt, &ctxt->_eip, rel);
|
||||
-}
|
||||
-
|
||||
static u32 desc_limit_scaled(struct desc_struct *desc)
|
||||
{
|
||||
u32 limit = get_desc_limit(desc);
|
||||
@@ -568,6 +563,28 @@ static int emulate_nm(struct x86_emulate_ctxt *ctxt)
|
||||
return emulate_exception(ctxt, NM_VECTOR, 0, false);
|
||||
}
|
||||
|
||||
+static inline void assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst)
|
||||
+{
|
||||
+ switch (ctxt->op_bytes) {
|
||||
+ case 2:
|
||||
+ ctxt->_eip = (u16)dst;
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ ctxt->_eip = (u32)dst;
|
||||
+ break;
|
||||
+ case 8:
|
||||
+ ctxt->_eip = dst;
|
||||
+ break;
|
||||
+ default:
|
||||
+ WARN(1, "unsupported eip assignment size\n");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
|
||||
+{
|
||||
+ assign_eip_near(ctxt, ctxt->_eip + rel);
|
||||
+}
|
||||
+
|
||||
static u16 get_segment_selector(struct x86_emulate_ctxt *ctxt, unsigned seg)
|
||||
{
|
||||
u16 selector;
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,249 +0,0 @@
|
||||
From: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Date: Fri, 24 Oct 2014 17:07:17 +0200
|
||||
Subject: [PATCH] KVM: x86: Handle errors when RIP is set during far jumps
|
||||
|
||||
Far jmp/call/ret may fault while loading a new RIP. Currently KVM does not
|
||||
handle this case, and may result in failed vm-entry once the assignment is
|
||||
done. The tricky part of doing so is that loading the new CS affects the
|
||||
VMCS/VMCB state, so if we fail during loading the new RIP, we are left in
|
||||
unconsistent state. Therefore, this patch saves on 64-bit the old CS
|
||||
descriptor and restores it if loading RIP failed.
|
||||
|
||||
This fixes CVE-2014-3647.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/emulate.c | 118 ++++++++++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 88 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
||||
index e52e74feedb8..1ac496349f39 100644
|
||||
--- a/arch/x86/kvm/emulate.c
|
||||
+++ b/arch/x86/kvm/emulate.c
|
||||
@@ -1442,7 +1442,9 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt,
|
||||
|
||||
/* Does not support long mode */
|
||||
static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
|
||||
- u16 selector, int seg, u8 cpl, bool in_task_switch)
|
||||
+ u16 selector, int seg, u8 cpl,
|
||||
+ bool in_task_switch,
|
||||
+ struct desc_struct *desc)
|
||||
{
|
||||
struct desc_struct seg_desc, old_desc;
|
||||
u8 dpl, rpl;
|
||||
@@ -1574,6 +1576,8 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
|
||||
}
|
||||
load:
|
||||
ctxt->ops->set_segment(ctxt, selector, &seg_desc, base3, seg);
|
||||
+ if (desc)
|
||||
+ *desc = seg_desc;
|
||||
return X86EMUL_CONTINUE;
|
||||
exception:
|
||||
emulate_exception(ctxt, err_vec, err_code, true);
|
||||
@@ -1584,7 +1588,7 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
|
||||
u16 selector, int seg)
|
||||
{
|
||||
u8 cpl = ctxt->ops->cpl(ctxt);
|
||||
- return __load_segment_descriptor(ctxt, selector, seg, cpl, false);
|
||||
+ return __load_segment_descriptor(ctxt, selector, seg, cpl, false, NULL);
|
||||
}
|
||||
|
||||
static void write_register_operand(struct operand *op)
|
||||
@@ -1978,17 +1982,31 @@ static int em_iret(struct x86_emulate_ctxt *ctxt)
|
||||
static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
|
||||
{
|
||||
int rc;
|
||||
- unsigned short sel;
|
||||
+ unsigned short sel, old_sel;
|
||||
+ struct desc_struct old_desc, new_desc;
|
||||
+ const struct x86_emulate_ops *ops = ctxt->ops;
|
||||
+ u8 cpl = ctxt->ops->cpl(ctxt);
|
||||
+
|
||||
+ /* Assignment of RIP may only fail in 64-bit mode */
|
||||
+ if (ctxt->mode == X86EMUL_MODE_PROT64)
|
||||
+ ops->get_segment(ctxt, &old_sel, &old_desc, NULL,
|
||||
+ VCPU_SREG_CS);
|
||||
|
||||
memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2);
|
||||
|
||||
- rc = load_segment_descriptor(ctxt, sel, VCPU_SREG_CS);
|
||||
+ rc = __load_segment_descriptor(ctxt, sel, VCPU_SREG_CS, cpl, false,
|
||||
+ &new_desc);
|
||||
if (rc != X86EMUL_CONTINUE)
|
||||
return rc;
|
||||
|
||||
- ctxt->_eip = 0;
|
||||
- memcpy(&ctxt->_eip, ctxt->src.valptr, ctxt->op_bytes);
|
||||
- return X86EMUL_CONTINUE;
|
||||
+ rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l);
|
||||
+ if (rc != X86EMUL_CONTINUE) {
|
||||
+ WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64);
|
||||
+ /* assigning eip failed; restore the old cs */
|
||||
+ ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS);
|
||||
+ return rc;
|
||||
+ }
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static int em_grp45(struct x86_emulate_ctxt *ctxt)
|
||||
@@ -2055,21 +2073,34 @@ static int em_ret(struct x86_emulate_ctxt *ctxt)
|
||||
static int em_ret_far(struct x86_emulate_ctxt *ctxt)
|
||||
{
|
||||
int rc;
|
||||
- unsigned long cs;
|
||||
+ unsigned long eip, cs;
|
||||
+ u16 old_cs;
|
||||
int cpl = ctxt->ops->cpl(ctxt);
|
||||
+ struct desc_struct old_desc, new_desc;
|
||||
+ const struct x86_emulate_ops *ops = ctxt->ops;
|
||||
+
|
||||
+ if (ctxt->mode == X86EMUL_MODE_PROT64)
|
||||
+ ops->get_segment(ctxt, &old_cs, &old_desc, NULL,
|
||||
+ VCPU_SREG_CS);
|
||||
|
||||
- rc = emulate_pop(ctxt, &ctxt->_eip, ctxt->op_bytes);
|
||||
+ rc = emulate_pop(ctxt, &eip, ctxt->op_bytes);
|
||||
if (rc != X86EMUL_CONTINUE)
|
||||
return rc;
|
||||
- if (ctxt->op_bytes == 4)
|
||||
- ctxt->_eip = (u32)ctxt->_eip;
|
||||
rc = emulate_pop(ctxt, &cs, ctxt->op_bytes);
|
||||
if (rc != X86EMUL_CONTINUE)
|
||||
return rc;
|
||||
/* Outer-privilege level return is not implemented */
|
||||
if (ctxt->mode >= X86EMUL_MODE_PROT16 && (cs & 3) > cpl)
|
||||
return X86EMUL_UNHANDLEABLE;
|
||||
- rc = load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS);
|
||||
+ rc = __load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS, 0, false,
|
||||
+ &new_desc);
|
||||
+ if (rc != X86EMUL_CONTINUE)
|
||||
+ return rc;
|
||||
+ rc = assign_eip_far(ctxt, eip, new_desc.l);
|
||||
+ if (rc != X86EMUL_CONTINUE) {
|
||||
+ WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64);
|
||||
+ ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS);
|
||||
+ }
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2496,19 +2527,24 @@ static int load_state_from_tss16(struct x86_emulate_ctxt *ctxt,
|
||||
* Now load segment descriptors. If fault happens at this stage
|
||||
* it is handled in a context of new task
|
||||
*/
|
||||
- ret = __load_segment_descriptor(ctxt, tss->ldt, VCPU_SREG_LDTR, cpl, true);
|
||||
+ ret = __load_segment_descriptor(ctxt, tss->ldt, VCPU_SREG_LDTR, cpl,
|
||||
+ true, NULL);
|
||||
if (ret != X86EMUL_CONTINUE)
|
||||
return ret;
|
||||
- ret = __load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, cpl, true);
|
||||
+ ret = __load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, cpl,
|
||||
+ true, NULL);
|
||||
if (ret != X86EMUL_CONTINUE)
|
||||
return ret;
|
||||
- ret = __load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, cpl, true);
|
||||
+ ret = __load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, cpl,
|
||||
+ true, NULL);
|
||||
if (ret != X86EMUL_CONTINUE)
|
||||
return ret;
|
||||
- ret = __load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, cpl, true);
|
||||
+ ret = __load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, cpl,
|
||||
+ true, NULL);
|
||||
if (ret != X86EMUL_CONTINUE)
|
||||
return ret;
|
||||
- ret = __load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, cpl, true);
|
||||
+ ret = __load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, cpl,
|
||||
+ true, NULL);
|
||||
if (ret != X86EMUL_CONTINUE)
|
||||
return ret;
|
||||
|
||||
@@ -2633,25 +2669,32 @@ static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt,
|
||||
* Now load segment descriptors. If fault happenes at this stage
|
||||
* it is handled in a context of new task
|
||||
*/
|
||||
- ret = __load_segment_descriptor(ctxt, tss->ldt_selector, VCPU_SREG_LDTR, cpl, true);
|
||||
+ ret = __load_segment_descriptor(ctxt, tss->ldt_selector, VCPU_SREG_LDTR,
|
||||
+ cpl, true, NULL);
|
||||
if (ret != X86EMUL_CONTINUE)
|
||||
return ret;
|
||||
- ret = __load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, cpl, true);
|
||||
+ ret = __load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, cpl,
|
||||
+ true, NULL);
|
||||
if (ret != X86EMUL_CONTINUE)
|
||||
return ret;
|
||||
- ret = __load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, cpl, true);
|
||||
+ ret = __load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, cpl,
|
||||
+ true, NULL);
|
||||
if (ret != X86EMUL_CONTINUE)
|
||||
return ret;
|
||||
- ret = __load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, cpl, true);
|
||||
+ ret = __load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, cpl,
|
||||
+ true, NULL);
|
||||
if (ret != X86EMUL_CONTINUE)
|
||||
return ret;
|
||||
- ret = __load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, cpl, true);
|
||||
+ ret = __load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, cpl,
|
||||
+ true, NULL);
|
||||
if (ret != X86EMUL_CONTINUE)
|
||||
return ret;
|
||||
- ret = __load_segment_descriptor(ctxt, tss->fs, VCPU_SREG_FS, cpl, true);
|
||||
+ ret = __load_segment_descriptor(ctxt, tss->fs, VCPU_SREG_FS, cpl,
|
||||
+ true, NULL);
|
||||
if (ret != X86EMUL_CONTINUE)
|
||||
return ret;
|
||||
- ret = __load_segment_descriptor(ctxt, tss->gs, VCPU_SREG_GS, cpl, true);
|
||||
+ ret = __load_segment_descriptor(ctxt, tss->gs, VCPU_SREG_GS, cpl,
|
||||
+ true, NULL);
|
||||
if (ret != X86EMUL_CONTINUE)
|
||||
return ret;
|
||||
|
||||
@@ -2934,24 +2977,39 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt)
|
||||
u16 sel, old_cs;
|
||||
ulong old_eip;
|
||||
int rc;
|
||||
+ struct desc_struct old_desc, new_desc;
|
||||
+ const struct x86_emulate_ops *ops = ctxt->ops;
|
||||
+ int cpl = ctxt->ops->cpl(ctxt);
|
||||
|
||||
- old_cs = get_segment_selector(ctxt, VCPU_SREG_CS);
|
||||
old_eip = ctxt->_eip;
|
||||
+ ops->get_segment(ctxt, &old_cs, &old_desc, NULL, VCPU_SREG_CS);
|
||||
|
||||
memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2);
|
||||
- if (load_segment_descriptor(ctxt, sel, VCPU_SREG_CS))
|
||||
+ rc = __load_segment_descriptor(ctxt, sel, VCPU_SREG_CS, cpl, false,
|
||||
+ &new_desc);
|
||||
+ if (rc != X86EMUL_CONTINUE)
|
||||
return X86EMUL_CONTINUE;
|
||||
|
||||
- ctxt->_eip = 0;
|
||||
- memcpy(&ctxt->_eip, ctxt->src.valptr, ctxt->op_bytes);
|
||||
+ rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l);
|
||||
+ if (rc != X86EMUL_CONTINUE)
|
||||
+ goto fail;
|
||||
|
||||
ctxt->src.val = old_cs;
|
||||
rc = em_push(ctxt);
|
||||
if (rc != X86EMUL_CONTINUE)
|
||||
- return rc;
|
||||
+ goto fail;
|
||||
|
||||
ctxt->src.val = old_eip;
|
||||
- return em_push(ctxt);
|
||||
+ rc = em_push(ctxt);
|
||||
+ /* If we failed, we tainted the memory, but the very least we should
|
||||
+ restore cs */
|
||||
+ if (rc != X86EMUL_CONTINUE)
|
||||
+ goto fail;
|
||||
+ return rc;
|
||||
+fail:
|
||||
+ ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS);
|
||||
+ return rc;
|
||||
+
|
||||
}
|
||||
|
||||
static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,36 +0,0 @@
|
||||
From: Andy Honig <ahonig@google.com>
|
||||
Date: Fri, 24 Oct 2014 17:07:14 +0200
|
||||
Subject: [PATCH] KVM: x86: Improve thread safety in pit
|
||||
|
||||
There's a race condition in the PIT emulation code in KVM. In
|
||||
__kvm_migrate_pit_timer the pit_timer object is accessed without
|
||||
synchronization. If the race condition occurs at the wrong time this
|
||||
can crash the host kernel.
|
||||
|
||||
This fixes CVE-2014-3611.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Andrew Honig <ahonig@google.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/i8254.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
|
||||
index 518d86471b76..298781d4cfb4 100644
|
||||
--- a/arch/x86/kvm/i8254.c
|
||||
+++ b/arch/x86/kvm/i8254.c
|
||||
@@ -262,8 +262,10 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
|
||||
return;
|
||||
|
||||
timer = &pit->pit_state.timer;
|
||||
+ mutex_lock(&pit->pit_state.lock);
|
||||
if (hrtimer_cancel(timer))
|
||||
hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
|
||||
+ mutex_unlock(&pit->pit_state.lock);
|
||||
}
|
||||
|
||||
static void destroy_pit_timer(struct kvm_pit *pit)
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,51 +0,0 @@
|
||||
From: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Date: Fri, 24 Oct 2014 17:07:23 +0200
|
||||
Subject: [PATCH] KVM: x86: PREFETCH and HINT_NOP should have SrcMem flag
|
||||
|
||||
The decode phase of the x86 emulator assumes that every instruction with the
|
||||
ModRM flag, and which can be used with RIP-relative addressing, has either
|
||||
SrcMem or DstMem. This is not the case for several instructions - prefetch,
|
||||
hint-nop and clflush.
|
||||
|
||||
Adding SrcMem|NoAccess for prefetch and hint-nop and SrcMem for clflush.
|
||||
|
||||
This fixes CVE-2014-8480.
|
||||
|
||||
Fixes: 41061cdb98a0bec464278b4db8e894a3121671f5
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/emulate.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
||||
index d1a19289d11a..48daa1a097af 100644
|
||||
--- a/arch/x86/kvm/emulate.c
|
||||
+++ b/arch/x86/kvm/emulate.c
|
||||
@@ -3797,7 +3797,7 @@ static const struct opcode group11[] = {
|
||||
};
|
||||
|
||||
static const struct gprefix pfx_0f_ae_7 = {
|
||||
- I(0, em_clflush), N, N, N,
|
||||
+ I(SrcMem | ByteOp, em_clflush), N, N, N,
|
||||
};
|
||||
|
||||
static const struct group_dual group15 = { {
|
||||
@@ -4010,10 +4010,11 @@ static const struct opcode twobyte_table[256] = {
|
||||
N, I(ImplicitOps | EmulateOnUD, em_syscall),
|
||||
II(ImplicitOps | Priv, em_clts, clts), N,
|
||||
DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N,
|
||||
- N, D(ImplicitOps | ModRM), N, N,
|
||||
+ N, D(ImplicitOps | ModRM | SrcMem | NoAccess), N, N,
|
||||
/* 0x10 - 0x1F */
|
||||
N, N, N, N, N, N, N, N,
|
||||
- D(ImplicitOps | ModRM), N, N, N, N, N, N, D(ImplicitOps | ModRM),
|
||||
+ D(ImplicitOps | ModRM | SrcMem | NoAccess),
|
||||
+ N, N, N, N, N, N, D(ImplicitOps | ModRM | SrcMem | NoAccess),
|
||||
/* 0x20 - 0x2F */
|
||||
DIP(ModRM | DstMem | Priv | Op3264 | NoMod, cr_read, check_cr_read),
|
||||
DIP(ModRM | DstMem | Priv | Op3264 | NoMod, dr_read, check_dr_read),
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,89 +0,0 @@
|
||||
From: Andy Honig <ahonig@google.com>
|
||||
Date: Fri, 24 Oct 2014 17:07:13 +0200
|
||||
Subject: [PATCH] KVM: x86: Prevent host from panicking on shared MSR writes.
|
||||
|
||||
The previous patch blocked invalid writes directly when the MSR
|
||||
is written. As a precaution, prevent future similar mistakes by
|
||||
gracefulling handle GPs caused by writes to shared MSRs.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Andrew Honig <ahonig@google.com>
|
||||
[Remove parts obsoleted by Nadav's patch. - Paolo]
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
arch/x86/include/asm/kvm_host.h | 2 +-
|
||||
arch/x86/kvm/vmx.c | 7 +++++--
|
||||
arch/x86/kvm/x86.c | 11 ++++++++---
|
||||
3 files changed, 14 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
|
||||
index 78d014c83ae3..d16311f4099e 100644
|
||||
--- a/arch/x86/include/asm/kvm_host.h
|
||||
+++ b/arch/x86/include/asm/kvm_host.h
|
||||
@@ -1062,7 +1062,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
|
||||
void kvm_vcpu_reset(struct kvm_vcpu *vcpu);
|
||||
|
||||
void kvm_define_shared_msr(unsigned index, u32 msr);
|
||||
-void kvm_set_shared_msr(unsigned index, u64 val, u64 mask);
|
||||
+int kvm_set_shared_msr(unsigned index, u64 val, u64 mask);
|
||||
|
||||
bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip);
|
||||
|
||||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
||||
index 3a3e419780df..0881ec6154cc 100644
|
||||
--- a/arch/x86/kvm/vmx.c
|
||||
+++ b/arch/x86/kvm/vmx.c
|
||||
@@ -2632,12 +2632,15 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
||||
default:
|
||||
msr = find_msr_entry(vmx, msr_index);
|
||||
if (msr) {
|
||||
+ u64 old_msr_data = msr->data;
|
||||
msr->data = data;
|
||||
if (msr - vmx->guest_msrs < vmx->save_nmsrs) {
|
||||
preempt_disable();
|
||||
- kvm_set_shared_msr(msr->index, msr->data,
|
||||
- msr->mask);
|
||||
+ ret = kvm_set_shared_msr(msr->index, msr->data,
|
||||
+ msr->mask);
|
||||
preempt_enable();
|
||||
+ if (ret)
|
||||
+ msr->data = old_msr_data;
|
||||
}
|
||||
break;
|
||||
}
|
||||
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
|
||||
index 1f9a233d8624..9d292e8372d6 100644
|
||||
--- a/arch/x86/kvm/x86.c
|
||||
+++ b/arch/x86/kvm/x86.c
|
||||
@@ -229,20 +229,25 @@ static void kvm_shared_msr_cpu_online(void)
|
||||
shared_msr_update(i, shared_msrs_global.msrs[i]);
|
||||
}
|
||||
|
||||
-void kvm_set_shared_msr(unsigned slot, u64 value, u64 mask)
|
||||
+int kvm_set_shared_msr(unsigned slot, u64 value, u64 mask)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
struct kvm_shared_msrs *smsr = per_cpu_ptr(shared_msrs, cpu);
|
||||
+ int err;
|
||||
|
||||
if (((value ^ smsr->values[slot].curr) & mask) == 0)
|
||||
- return;
|
||||
+ return 0;
|
||||
smsr->values[slot].curr = value;
|
||||
- wrmsrl(shared_msrs_global.msrs[slot], value);
|
||||
+ err = wrmsrl_safe(shared_msrs_global.msrs[slot], value);
|
||||
+ if (err)
|
||||
+ return 1;
|
||||
+
|
||||
if (!smsr->registered) {
|
||||
smsr->urn.on_user_return = kvm_on_user_return;
|
||||
user_return_notifier_register(&smsr->urn);
|
||||
smsr->registered = true;
|
||||
}
|
||||
+ return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_set_shared_msr);
|
||||
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,75 +0,0 @@
|
||||
From eb79f6f7b7525c722e967480946cb78e77844cd7 Mon Sep 17 00:00:00 2001
|
||||
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
|
||||
Date: Mon, 20 Oct 2014 08:29:55 +0300
|
||||
Subject: [PATCH] Revert "iwlwifi: mvm: treat EAPOLs like mgmt frames wrt rate"
|
||||
|
||||
This reverts commit aa11bbf3df026d6b1c6b528bef634fd9de7c2619.
|
||||
This commit was causing connection issues and is not needed
|
||||
if IWL_MVM_RS_RSSI_BASED_INIT_RATE is set to false by default.
|
||||
|
||||
Regardless of the issues mentioned above, this patch added the
|
||||
following WARNING:
|
||||
|
||||
WARNING: CPU: 0 PID: 3946 at drivers/net/wireless/iwlwifi/mvm/tx.c:190 iwl_mvm_set_tx_params+0x60a/0x6f0 [iwlmvm]()
|
||||
Got an HT rate for a non data frame 0x8
|
||||
CPU: 0 PID: 3946 Comm: wpa_supplicant Tainted: G O 3.17.0+ #6
|
||||
Hardware name: LENOVO 20ANCTO1WW/20ANCTO1WW, BIOS GLET71WW (2.25 ) 07/02/2014
|
||||
0000000000000009 ffffffff814fa911 ffff8804288db8f8 ffffffff81064f52
|
||||
0000000000001808 ffff8804288db948 ffff88040add8660 ffff8804291b5600
|
||||
0000000000000000 ffffffff81064fb7 ffffffffa07b73d0 0000000000000020
|
||||
Call Trace:
|
||||
[<ffffffff814fa911>] ? dump_stack+0x41/0x51
|
||||
[<ffffffff81064f52>] ? warn_slowpath_common+0x72/0x90
|
||||
[<ffffffff81064fb7>] ? warn_slowpath_fmt+0x47/0x50
|
||||
[<ffffffffa07a39ea>] ? iwl_mvm_set_tx_params+0x60a/0x6f0 [iwlmvm]
|
||||
[<ffffffffa07a3cf8>] ? iwl_mvm_tx_skb+0x48/0x3c0 [iwlmvm]
|
||||
[<ffffffffa079cb9b>] ? iwl_mvm_mac_tx+0x7b/0x180 [iwlmvm]
|
||||
[<ffffffffa0746ce9>] ? __ieee80211_tx+0x2b9/0x3c0 [mac80211]
|
||||
[<ffffffffa07492f3>] ? ieee80211_tx+0xb3/0x100 [mac80211]
|
||||
[<ffffffffa0749c49>] ? ieee80211_subif_start_xmit+0x459/0xca0 [mac80211]
|
||||
[<ffffffff814116e7>] ? dev_hard_start_xmit+0x337/0x5f0
|
||||
[<ffffffff81430d46>] ? sch_direct_xmit+0x96/0x1f0
|
||||
[<ffffffff81411ba3>] ? __dev_queue_xmit+0x203/0x4f0
|
||||
[<ffffffff8142f670>] ? ether_setup+0x70/0x70
|
||||
[<ffffffff814e96a1>] ? packet_sendmsg+0xf81/0x1110
|
||||
[<ffffffff8140625c>] ? skb_free_datagram+0xc/0x40
|
||||
[<ffffffff813f7538>] ? sock_sendmsg+0x88/0xc0
|
||||
[<ffffffff813f7274>] ? move_addr_to_kernel.part.20+0x14/0x60
|
||||
[<ffffffff811c47c2>] ? __inode_wait_for_writeback+0x62/0xb0
|
||||
[<ffffffff813f7a91>] ? SYSC_sendto+0xf1/0x180
|
||||
[<ffffffff813f88f9>] ? __sys_recvmsg+0x39/0x70
|
||||
[<ffffffff8150066d>] ? system_call_fastpath+0x1a/0x1f
|
||||
---[ end trace cc19a150d311fc63 ]---
|
||||
|
||||
which was reported here: https://bugzilla.kernel.org/show_bug.cgi?id=85691
|
||||
|
||||
CC: <stable@vger.kernel.org> [3.13+]
|
||||
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
|
||||
---
|
||||
drivers/net/wireless/iwlwifi/mvm/tx.c | 8 ++------
|
||||
1 file changed, 2 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
|
||||
index 9ee410bf6da2..dbc870713882 100644
|
||||
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
|
||||
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
|
||||
@@ -168,14 +168,10 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
|
||||
|
||||
/*
|
||||
* for data packets, rate info comes from the table inside the fw. This
|
||||
- * table is controlled by LINK_QUALITY commands. Exclude ctrl port
|
||||
- * frames like EAPOLs which should be treated as mgmt frames. This
|
||||
- * avoids them being sent initially in high rates which increases the
|
||||
- * chances for completion of the 4-Way handshake.
|
||||
+ * table is controlled by LINK_QUALITY commands
|
||||
*/
|
||||
|
||||
- if (ieee80211_is_data(fc) && sta &&
|
||||
- !(info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) {
|
||||
+ if (ieee80211_is_data(fc) && sta) {
|
||||
tx_cmd->initial_rate_index = 0;
|
||||
tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE);
|
||||
return;
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,52 +0,0 @@
|
||||
From d3641b4838204c1257bd575f12ba9dc24a4bc707 Mon Sep 17 00:00:00 2001
|
||||
From: Johan Hovold <johan@kernel.org>
|
||||
Date: Mon, 25 Aug 2014 17:51:26 +0200
|
||||
Subject: [PATCH] USB: core: add device-qualifier quirk
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add new quirk for devices that cannot handle requests for the
|
||||
device_qualifier descriptor.
|
||||
|
||||
A USB-2.0 compliant device must respond to requests for the
|
||||
device_qualifier descriptor (even if it's with a request error), but at
|
||||
least one device is known to misbehave after such a request.
|
||||
|
||||
Suggested-by: Bjørn Mork <bjorn@mork.no>
|
||||
Signed-off-by: Johan Hovold <johan@kernel.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/core/hub.c | 3 +++
|
||||
include/linux/usb/quirks.h | 3 +++
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
|
||||
index 50e854509f55..8f9d142aaf4a 100644
|
||||
--- a/drivers/usb/core/hub.c
|
||||
+++ b/drivers/usb/core/hub.c
|
||||
@@ -4524,6 +4524,9 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
|
||||
struct usb_qualifier_descriptor *qual;
|
||||
int status;
|
||||
|
||||
+ if (udev->quirks & USB_QUIRK_DEVICE_QUALIFIER)
|
||||
+ return;
|
||||
+
|
||||
qual = kmalloc (sizeof *qual, GFP_KERNEL);
|
||||
if (qual == NULL)
|
||||
return;
|
||||
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
|
||||
index 52f944dfe2fd..4681e0fb1fac 100644
|
||||
--- a/include/linux/usb/quirks.h
|
||||
+++ b/include/linux/usb/quirks.h
|
||||
@@ -33,4 +33,7 @@
|
||||
/* device generates spurious wakeup, ignore remote wakeup capability */
|
||||
#define USB_QUIRK_IGNORE_REMOTE_WAKEUP 0x00000200
|
||||
|
||||
+/* device can't handle device_qualifier descriptor requests */
|
||||
+#define USB_QUIRK_DEVICE_QUALIFIER 0x00000100
|
||||
+
|
||||
#endif /* __LINUX_USB_QUIRKS_H */
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,46 +0,0 @@
|
||||
From: Johan Hovold <johan@kernel.org>
|
||||
Date: Mon, 25 Aug 2014 17:51:27 +0200
|
||||
Subject: [PATCH] USB: quirks: enable device-qualifier quirk for Elan
|
||||
Touchscreen
|
||||
|
||||
Enable device-qualifier quirk for Elan Touchscreen, which often fails to
|
||||
handle requests for the device_descriptor.
|
||||
|
||||
Note that the device sometimes do respond properly with a Request Error
|
||||
(three times as USB core retries), but usually fails to respond at all.
|
||||
When this happens any further descriptor requests also fails, for
|
||||
example:
|
||||
|
||||
[ 1528.688934] usb 2-7: new full-speed USB device number 4 using xhci_hcd
|
||||
[ 1530.945588] usb 2-7: unable to read config index 0 descriptor/start: -71
|
||||
[ 1530.945592] usb 2-7: can't read configurations, error -71
|
||||
|
||||
This has been observed repeating for over a minute before eventual
|
||||
successful enumeration.
|
||||
|
||||
Reported-by: Drew Von Spreecken <drewvs@gmail.com>
|
||||
Reported-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Signed-off-by: Johan Hovold <johan@kernel.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/core/quirks.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
|
||||
index bae636e2a1a3..a342a783d496 100644
|
||||
--- a/drivers/usb/core/quirks.c
|
||||
+++ b/drivers/usb/core/quirks.c
|
||||
@@ -93,6 +93,10 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
{ USB_DEVICE(0x04e8, 0x6601), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
+ /* Elan Touchscreen */
|
||||
+ { USB_DEVICE(0x04f3, 0x0089), .driver_info =
|
||||
+ USB_QUIRK_DEVICE_QUALIFIER },
|
||||
+
|
||||
/* Roland SC-8820 */
|
||||
{ USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,32 +0,0 @@
|
||||
From: Adel Gadllah <adel.gadllah-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
|
||||
Date: Sun, 5 Oct 2014 18:32:34 +0200
|
||||
Subject: [PATCH] USB: quirks: enable device-qualifier quirk for another Elan
|
||||
touchscreen
|
||||
|
||||
Currently this quirk is enabled for the model with the device id 0x0089, it
|
||||
is needed for the 0x009b model, which is found on the Fujitsu Lifebook u904
|
||||
as well.
|
||||
|
||||
Signed-off-by: Adel Gadllah <adel.gadllah-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
|
||||
---
|
||||
drivers/usb/core/quirks.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
|
||||
index a342a783d496..cac60d9b091b 100644
|
||||
--- a/drivers/usb/core/quirks.c
|
||||
+++ b/drivers/usb/core/quirks.c
|
||||
@@ -97,6 +97,10 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
{ USB_DEVICE(0x04f3, 0x0089), .driver_info =
|
||||
USB_QUIRK_DEVICE_QUALIFIER },
|
||||
|
||||
+ /* Elan Touchscreen */
|
||||
+ { USB_DEVICE(0x04f3, 0x009b), .driver_info =
|
||||
+ USB_QUIRK_DEVICE_QUALIFIER },
|
||||
+
|
||||
/* Roland SC-8820 */
|
||||
{ USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,34 +0,0 @@
|
||||
From 5af4aca31445b5c0a05ef7bf707493c1bff73db5 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Kozina <okozina@redhat.com>
|
||||
Date: Mon, 25 Aug 2014 11:49:54 +0200
|
||||
Subject: [PATCH] crypto: algif - avoid excessive use of socket buffer in
|
||||
skcipher
|
||||
|
||||
On archs with PAGE_SIZE >= 64 KiB the function skcipher_alloc_sgl()
|
||||
fails with -ENOMEM no matter what user space actually requested.
|
||||
This is caused by the fact sock_kmalloc call inside the function tried
|
||||
to allocate more memory than allowed by the default kernel socket buffer
|
||||
size (kernel param net.core.optmem_max).
|
||||
|
||||
Signed-off-by: Ondrej Kozina <okozina@redhat.com>
|
||||
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
||||
---
|
||||
crypto/algif_skcipher.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
|
||||
index a19c027b29bd..83187f497c7c 100644
|
||||
--- a/crypto/algif_skcipher.c
|
||||
+++ b/crypto/algif_skcipher.c
|
||||
@@ -49,7 +49,7 @@ struct skcipher_ctx {
|
||||
struct ablkcipher_request req;
|
||||
};
|
||||
|
||||
-#define MAX_SGL_ENTS ((PAGE_SIZE - sizeof(struct skcipher_sg_list)) / \
|
||||
+#define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_sg_list)) / \
|
||||
sizeof(struct scatterlist) - 1)
|
||||
|
||||
static inline int skcipher_sndbuf(struct sock *sk)
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,34 +0,0 @@
|
||||
From: Josh Boyer <jwboyer@fedoraproject.org>
|
||||
Date: Fri, 5 Sep 2014 13:19:59 -0400
|
||||
Subject: [PATCH] drm/vmwgfx: Fix drm.h include
|
||||
|
||||
The userspace drm.h include doesn't prefix the drm directory. This can lead
|
||||
to compile failures as /usr/include/drm/ isn't in the standard gcc include
|
||||
paths. Fix it to be <drm/drm.h>, which matches the rest of the driver drm
|
||||
header files that get installed into /usr/include/drm.
|
||||
|
||||
Red Hat Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1138759
|
||||
|
||||
Fixes: 1d7a5cbf8f74e
|
||||
Reported-by: Jeffrey Bastian <jbastian@redhat.com>
|
||||
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
|
||||
---
|
||||
include/uapi/drm/vmwgfx_drm.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/uapi/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h
|
||||
index 4fc66f6b12ce..c472bedbe38e 100644
|
||||
--- a/include/uapi/drm/vmwgfx_drm.h
|
||||
+++ b/include/uapi/drm/vmwgfx_drm.h
|
||||
@@ -29,7 +29,7 @@
|
||||
#define __VMWGFX_DRM_H__
|
||||
|
||||
#ifndef __KERNEL__
|
||||
-#include <drm.h>
|
||||
+#include <drm/drm.h>
|
||||
#endif
|
||||
|
||||
#define DRM_VMW_MAX_SURFACE_FACES 6
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,83 +0,0 @@
|
||||
From a41537e69b4aa43f0fea02498c2595a81267383b Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Monakhov <dmonakhov@openvz.org>
|
||||
Date: Thu, 30 Oct 2014 10:53:16 -0400
|
||||
Subject: [PATCH] ext4: prevent bugon on race between write/fcntl
|
||||
|
||||
O_DIRECT flags can be toggeled via fcntl(F_SETFL). But this value checked
|
||||
twice inside ext4_file_write_iter() and __generic_file_write() which
|
||||
result in BUG_ON inside ext4_direct_IO.
|
||||
|
||||
Let's initialize iocb->private unconditionally.
|
||||
|
||||
TESTCASE: xfstest:generic/036 https://patchwork.ozlabs.org/patch/402445/
|
||||
|
||||
#TYPICAL STACK TRACE:
|
||||
kernel BUG at fs/ext4/inode.c:2960!
|
||||
invalid opcode: 0000 [#1] SMP
|
||||
Modules linked in: brd iTCO_wdt lpc_ich mfd_core igb ptp dm_mirror dm_region_hash dm_log dm_mod
|
||||
CPU: 6 PID: 5505 Comm: aio-dio-fcntl-r Not tainted 3.17.0-rc2-00176-gff5c017 #161
|
||||
Hardware name: Intel Corporation W2600CR/W2600CR, BIOS SE5C600.86B.99.99.x028.061320111235 06/13/2011
|
||||
task: ffff88080e95a7c0 ti: ffff88080f908000 task.ti: ffff88080f908000
|
||||
RIP: 0010:[<ffffffff811fabf2>] [<ffffffff811fabf2>] ext4_direct_IO+0x162/0x3d0
|
||||
RSP: 0018:ffff88080f90bb58 EFLAGS: 00010246
|
||||
RAX: 0000000000000400 RBX: ffff88080fdb2a28 RCX: 00000000a802c818
|
||||
RDX: 0000040000080000 RSI: ffff88080d8aeb80 RDI: 0000000000000001
|
||||
RBP: ffff88080f90bbc8 R08: 0000000000000000 R09: 0000000000001581
|
||||
R10: 0000000000000000 R11: 0000000000000000 R12: ffff88080d8aeb80
|
||||
R13: ffff88080f90bbf8 R14: ffff88080fdb28c8 R15: ffff88080fdb2a28
|
||||
FS: 00007f23b2055700(0000) GS:ffff880818400000(0000) knlGS:0000000000000000
|
||||
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
CR2: 00007f23b2045000 CR3: 000000080cedf000 CR4: 00000000000407e0
|
||||
Stack:
|
||||
ffff88080f90bb98 0000000000000000 7ffffffffffffffe ffff88080fdb2c30
|
||||
0000000000000200 0000000000000200 0000000000000001 0000000000000200
|
||||
ffff88080f90bbc8 ffff88080fdb2c30 ffff88080f90be08 0000000000000200
|
||||
Call Trace:
|
||||
[<ffffffff8112ca9d>] generic_file_direct_write+0xed/0x180
|
||||
[<ffffffff8112f2b2>] __generic_file_write_iter+0x222/0x370
|
||||
[<ffffffff811f495b>] ext4_file_write_iter+0x34b/0x400
|
||||
[<ffffffff811bd709>] ? aio_run_iocb+0x239/0x410
|
||||
[<ffffffff811bd709>] ? aio_run_iocb+0x239/0x410
|
||||
[<ffffffff810990e5>] ? local_clock+0x25/0x30
|
||||
[<ffffffff810abd94>] ? __lock_acquire+0x274/0x700
|
||||
[<ffffffff811f4610>] ? ext4_unwritten_wait+0xb0/0xb0
|
||||
[<ffffffff811bd756>] aio_run_iocb+0x286/0x410
|
||||
[<ffffffff810990e5>] ? local_clock+0x25/0x30
|
||||
[<ffffffff810ac359>] ? lock_release_holdtime+0x29/0x190
|
||||
[<ffffffff811bc05b>] ? lookup_ioctx+0x4b/0xf0
|
||||
[<ffffffff811bde3b>] do_io_submit+0x55b/0x740
|
||||
[<ffffffff811bdcaa>] ? do_io_submit+0x3ca/0x740
|
||||
[<ffffffff811be030>] SyS_io_submit+0x10/0x20
|
||||
[<ffffffff815ce192>] system_call_fastpath+0x16/0x1b
|
||||
Code: 01 48 8b 80 f0 01 00 00 48 8b 18 49 8b 45 10 0f 85 f1 01 00 00 48 03 45 c8 48 3b 43 48 0f 8f e3 01 00 00 49 83 7c
|
||||
24 18 00 75 04 <0f> 0b eb fe f0 ff 83 ec 01 00 00 49 8b 44 24 18 8b 00 85 c0 89
|
||||
RIP [<ffffffff811fabf2>] ext4_direct_IO+0x162/0x3d0
|
||||
RSP <ffff88080f90bb58>
|
||||
|
||||
Reported-by: Sasha Levin <sasha.levin@oracle.com>
|
||||
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
|
||||
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
|
||||
Cc: stable@vger.kernel.org
|
||||
---
|
||||
fs/ext4/file.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
|
||||
index aca7b24a4432..8131be8c0af3 100644
|
||||
--- a/fs/ext4/file.c
|
||||
+++ b/fs/ext4/file.c
|
||||
@@ -137,10 +137,10 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||
iov_iter_truncate(from, sbi->s_bitmap_maxbytes - pos);
|
||||
}
|
||||
|
||||
+ iocb->private = &overwrite;
|
||||
if (o_direct) {
|
||||
blk_start_plug(&plug);
|
||||
|
||||
- iocb->private = &overwrite;
|
||||
|
||||
/* check whether we do a DIO overwrite or not */
|
||||
if (ext4_should_dioread_nolock(inode) && !aio_mutex &&
|
||||
--
|
||||
2.1.0
|
||||
|
102
kernel.spec
102
kernel.spec
@ -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
|
||||
@ -729,36 +729,14 @@ Patch26016: HID-wacom-Add-support-for-the-Cintiq-Companion.patch
|
||||
Patch26019: psmouse-Add-psmouse_matches_pnp_id-helper-function.patch
|
||||
Patch26020: psmouse-Add-support-for-detecting-FocalTech-PS-2-tou.patch
|
||||
|
||||
#rhbz 1138759
|
||||
Patch26021: drm-vmwgfx-Fix-drm.h-include.patch
|
||||
|
||||
#rhbz 1145318
|
||||
Patch26029: KEYS-Reinstate-EPERM-for-a-key-type-name-beginning-w.patch
|
||||
|
||||
Patch26030: GFS2-Make-rename-not-save-dirent-location.patch
|
||||
|
||||
#CVE-2014-7970 rhbz 1151095 1151484
|
||||
Patch26032: mnt-Prevent-pivot_root-from-creating-a-loop-in-the-m.patch
|
||||
|
||||
#rhbz 1149509
|
||||
Patch26034: USB-core-add-device-qualifier-quirk.patch
|
||||
Patch26035: USB-quirks-enable-device-qualifier-quirk-for-Elan-To.patch
|
||||
Patch26036: USB-quirks-enable-device-qualifier-quirk-for-another.patch
|
||||
Patch26037: HID-usbhid-add-always-poll-quirk.patch
|
||||
Patch26038: HID-usbhid-enable-always-poll-quirk-for-Elan-Touchsc.patch
|
||||
Patch26039: HID-usbhid-always-poll-quirk-for-Elan-Touchscreen-00.patch
|
||||
Patch26040: USB-quirks-device-qualifier-quirk-for-another-Elan-t.patch
|
||||
Patch26041: HID-usbhid-always-poll-quirk-for-Elan-Touchscreen-01.patch
|
||||
|
||||
#CVE-2014-8086 rhbz 1151353 1152608
|
||||
Patch26056: ext4-prevent-bugon-on-race-between-write-fcntl.patch
|
||||
|
||||
#rhbz 1089731
|
||||
Patch26058: asus-nb-wmi-Add-wapf4-quirk-for-the-X550VB.patch
|
||||
|
||||
#rhbz 1153381
|
||||
Patch26059: Input-synaptics-gate-forcepad-support-by-DMI-check.patch
|
||||
|
||||
#CVE-2014-3688 rhbz 1155745 1155751
|
||||
Patch26061: net-sctp-fix-skb_over_panic-when-receiving-malformed.patch
|
||||
|
||||
@ -771,39 +749,12 @@ Patch26063: net-sctp-fix-remote-memory-pressure-from-excessive-q.patch
|
||||
#rhbz 1111138
|
||||
Patch26064: i8042-Add-notimeout-quirk-for-Fujitsu-Lifebook-A544-.patch
|
||||
|
||||
# CVE-2014-3610 kvm: noncanonical MSR writes (rhbz 1144883 1156543)
|
||||
# CVE-2014-3611 kvm: PIT timer race condition (rhbz 1144878 1156537)
|
||||
# CVE-2014-3646 kvm: vmx: invvpid vm exit not handled (rhbz 1144825 1156534)
|
||||
# CVE-2014-8369 kvm: excessive pages un-pinning in kvm_iommu_map error path (rhbz 1156518 1156522)
|
||||
# CVE-2014-8480 CVE-2014-8481 kvm: NULL pointer dereference during rip relative instruction emulation (rhbz 1156615 1156616)
|
||||
Patch26070: KVM-x86-Check-non-canonical-addresses-upon-WRMSR.patch
|
||||
Patch26071: KVM-x86-Prevent-host-from-panicking-on-shared-MSR-wr.patch
|
||||
Patch26072: KVM-x86-Improve-thread-safety-in-pit.patch
|
||||
Patch26073: KVM-x86-Fix-wrong-masking-on-relative-jump-call.patch
|
||||
Patch26074: KVM-x86-Emulator-fixes-for-eip-canonical-checks-on-n.patch
|
||||
Patch26075: KVM-x86-Handle-errors-when-RIP-is-set-during-far-jum.patch
|
||||
Patch26076: kvm-vmx-handle-invvpid-vm-exit-gracefully.patch
|
||||
Patch26077: kvm-x86-don-t-kill-guest-on-unknown-exit-reason.patch
|
||||
Patch26078: KVM-x86-Decoding-guest-instructions-which-cross-page.patch
|
||||
Patch26079: KVM-emulate-avoid-accessing-NULL-ctxt-memopp.patch
|
||||
Patch26080: KVM-x86-Emulator-does-not-decode-clflush-well.patch
|
||||
Patch26081: KVM-x86-PREFETCH-and-HINT_NOP-should-have-SrcMem-fla.patch
|
||||
Patch26082: kvm-fix-excessive-pages-un-pinning-in-kvm_iommu_map-.patch
|
||||
|
||||
#rhbz 1157327
|
||||
Patch26083: quirk-for-Lenovo-Yoga-3-no-rfkill-switch.patch
|
||||
|
||||
#rhbz 1159592
|
||||
Patch26084: x86-microcode-AMD-Fix-early-ucode-loading-on-32-bit.patch
|
||||
|
||||
# CVE-2014-7826 CVE-2014-7825 rhbz 1161565 1161572
|
||||
Patch26085: tracing-syscalls-Ignore-numbers-outside-NR_syscalls-.patch
|
||||
|
||||
#rhbz 1151836
|
||||
Patch26086: Revert-iwlwifi-mvm-treat-EAPOLs-like-mgmt-frames-wrt.patch
|
||||
|
||||
Patch26087: crypto-algif-avoid-excessive-use-of-socket-buffer-in.patch
|
||||
|
||||
#rhbz 1161805
|
||||
Patch26066: ahci-disable-MSI-instead-of-NCQ-on-Samsung-pci-e-SSD.patch
|
||||
|
||||
@ -1519,36 +1470,15 @@ ApplyPatch HID-wacom-Add-support-for-the-Cintiq-Companion.patch
|
||||
ApplyPatch psmouse-Add-psmouse_matches_pnp_id-helper-function.patch
|
||||
ApplyPatch psmouse-Add-support-for-detecting-FocalTech-PS-2-tou.patch
|
||||
|
||||
#rhbz 1138759
|
||||
ApplyPatch drm-vmwgfx-Fix-drm.h-include.patch
|
||||
|
||||
#rhbz 1145318
|
||||
ApplyPatch KEYS-Reinstate-EPERM-for-a-key-type-name-beginning-w.patch
|
||||
|
||||
ApplyPatch GFS2-Make-rename-not-save-dirent-location.patch
|
||||
|
||||
#CVE-2014-7970 rhbz 1151095 1151484
|
||||
ApplyPatch mnt-Prevent-pivot_root-from-creating-a-loop-in-the-m.patch
|
||||
|
||||
#rhbz 1149509
|
||||
ApplyPatch USB-core-add-device-qualifier-quirk.patch
|
||||
ApplyPatch USB-quirks-enable-device-qualifier-quirk-for-Elan-To.patch
|
||||
ApplyPatch USB-quirks-enable-device-qualifier-quirk-for-another.patch
|
||||
ApplyPatch HID-usbhid-add-always-poll-quirk.patch
|
||||
ApplyPatch HID-usbhid-enable-always-poll-quirk-for-Elan-Touchsc.patch
|
||||
ApplyPatch HID-usbhid-always-poll-quirk-for-Elan-Touchscreen-00.patch
|
||||
ApplyPatch USB-quirks-device-qualifier-quirk-for-another-Elan-t.patch
|
||||
ApplyPatch HID-usbhid-always-poll-quirk-for-Elan-Touchscreen-01.patch
|
||||
|
||||
#CVE-2014-8086 rhbz 1151353 1152608
|
||||
ApplyPatch ext4-prevent-bugon-on-race-between-write-fcntl.patch
|
||||
|
||||
#rhbz 1089731
|
||||
ApplyPatch asus-nb-wmi-Add-wapf4-quirk-for-the-X550VB.patch
|
||||
|
||||
#rhbz 1153381
|
||||
ApplyPatch Input-synaptics-gate-forcepad-support-by-DMI-check.patch
|
||||
|
||||
#CVE-2014-3688 rhbz 1155745 1155751
|
||||
ApplyPatch net-sctp-fix-skb_over_panic-when-receiving-malformed.patch
|
||||
|
||||
@ -1561,39 +1491,12 @@ ApplyPatch net-sctp-fix-remote-memory-pressure-from-excessive-q.patch
|
||||
#rhbz 1111138
|
||||
ApplyPatch i8042-Add-notimeout-quirk-for-Fujitsu-Lifebook-A544-.patch
|
||||
|
||||
# CVE-2014-3610 kvm: noncanonical MSR writes (rhbz 1144883 1156543)
|
||||
# CVE-2014-3611 kvm: PIT timer race condition (rhbz 1144878 1156537)
|
||||
# CVE-2014-3646 kvm: vmx: invvpid vm exit not handled (rhbz 1144825 1156534)
|
||||
# CVE-2014-8369 kvm: excessive pages un-pinning in kvm_iommu_map error path (rhbz 1156518 1156522)
|
||||
# CVE-2014-8480 CVE-2014-8481 kvm: NULL pointer dereference during rip relative instruction emulation (rhbz 1156615 1156616)
|
||||
ApplyPatch KVM-x86-Check-non-canonical-addresses-upon-WRMSR.patch
|
||||
ApplyPatch KVM-x86-Prevent-host-from-panicking-on-shared-MSR-wr.patch
|
||||
ApplyPatch KVM-x86-Improve-thread-safety-in-pit.patch
|
||||
ApplyPatch KVM-x86-Fix-wrong-masking-on-relative-jump-call.patch
|
||||
ApplyPatch KVM-x86-Emulator-fixes-for-eip-canonical-checks-on-n.patch
|
||||
ApplyPatch KVM-x86-Handle-errors-when-RIP-is-set-during-far-jum.patch
|
||||
ApplyPatch kvm-vmx-handle-invvpid-vm-exit-gracefully.patch
|
||||
ApplyPatch kvm-x86-don-t-kill-guest-on-unknown-exit-reason.patch
|
||||
ApplyPatch KVM-x86-Decoding-guest-instructions-which-cross-page.patch
|
||||
ApplyPatch KVM-emulate-avoid-accessing-NULL-ctxt-memopp.patch
|
||||
ApplyPatch KVM-x86-Emulator-does-not-decode-clflush-well.patch
|
||||
ApplyPatch KVM-x86-PREFETCH-and-HINT_NOP-should-have-SrcMem-fla.patch
|
||||
ApplyPatch kvm-fix-excessive-pages-un-pinning-in-kvm_iommu_map-.patch
|
||||
|
||||
#rhbz 1157327
|
||||
ApplyPatch quirk-for-Lenovo-Yoga-3-no-rfkill-switch.patch
|
||||
|
||||
#rhbz 1159592
|
||||
ApplyPatch x86-microcode-AMD-Fix-early-ucode-loading-on-32-bit.patch
|
||||
|
||||
# CVE-2014-7826 CVE-2014-7825 rhbz 1161565 1161572
|
||||
ApplyPatch tracing-syscalls-Ignore-numbers-outside-NR_syscalls-.patch
|
||||
|
||||
#rhbz 1151836
|
||||
ApplyPatch Revert-iwlwifi-mvm-treat-EAPOLs-like-mgmt-frames-wrt.patch
|
||||
|
||||
ApplyPatch crypto-algif-avoid-excessive-use-of-socket-buffer-in.patch
|
||||
|
||||
#rhbz 1161805
|
||||
ApplyPatch ahci-disable-MSI-instead-of-NCQ-on-Samsung-pci-e-SSD.patch
|
||||
|
||||
@ -2427,6 +2330,9 @@ fi
|
||||
# ||----w |
|
||||
# || ||
|
||||
%changelog
|
||||
* Fri Nov 14 2014 Justin M. Forbes <jforbes@fedoraproject.org> - 3.17.3-200
|
||||
- Linux v3.17.3
|
||||
|
||||
* Fri Nov 14 2014 Josh Boyer <jwboyer@fedoraproject.org>
|
||||
- Quiet WARN in i915 edp VDD handling
|
||||
- Enable I40EVF driver (rhbz 1164029)
|
||||
|
@ -1,78 +0,0 @@
|
||||
From: Quentin Casasnovas <quentin.casasnovas@oracle.com>
|
||||
Date: Fri, 24 Oct 2014 17:07:24 +0200
|
||||
Subject: [PATCH] kvm: fix excessive pages un-pinning in kvm_iommu_map error
|
||||
path.
|
||||
|
||||
The third parameter of kvm_unpin_pages() when called from
|
||||
kvm_iommu_map_pages() is wrong, it should be the number of pages to un-pin
|
||||
and not the page size.
|
||||
|
||||
This error was facilitated with an inconsistent API: kvm_pin_pages() takes
|
||||
a size, but kvn_unpin_pages() takes a number of pages, so fix the problem
|
||||
by matching the two.
|
||||
|
||||
This was introduced by commit 350b8bd ("kvm: iommu: fix the third parameter
|
||||
of kvm_iommu_put_pages (CVE-2014-3601)"), which fixes the lack of
|
||||
un-pinning for pages intended to be un-pinned (i.e. memory leak) but
|
||||
unfortunately potentially aggravated the number of pages we un-pin that
|
||||
should have stayed pinned. As far as I understand though, the same
|
||||
practical mitigations apply.
|
||||
|
||||
This issue was found during review of Red Hat 6.6 patches to prepare
|
||||
Ksplice rebootless updates.
|
||||
|
||||
Thanks to Vegard for his time on a late Friday evening to help me in
|
||||
understanding this code.
|
||||
|
||||
Fixes: 350b8bd ("kvm: iommu: fix the third parameter of... (CVE-2014-3601)")
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Quentin Casasnovas <quentin.casasnovas@oracle.com>
|
||||
Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
|
||||
Signed-off-by: Jamie Iles <jamie.iles@oracle.com>
|
||||
Reviewed-by: Sasha Levin <sasha.levin@oracle.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
virt/kvm/iommu.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
|
||||
index 714b94932312..1f0dc1e5f1f0 100644
|
||||
--- a/virt/kvm/iommu.c
|
||||
+++ b/virt/kvm/iommu.c
|
||||
@@ -43,13 +43,13 @@ static void kvm_iommu_put_pages(struct kvm *kvm,
|
||||
gfn_t base_gfn, unsigned long npages);
|
||||
|
||||
static pfn_t kvm_pin_pages(struct kvm_memory_slot *slot, gfn_t gfn,
|
||||
- unsigned long size)
|
||||
+ unsigned long npages)
|
||||
{
|
||||
gfn_t end_gfn;
|
||||
pfn_t pfn;
|
||||
|
||||
pfn = gfn_to_pfn_memslot(slot, gfn);
|
||||
- end_gfn = gfn + (size >> PAGE_SHIFT);
|
||||
+ end_gfn = gfn + npages;
|
||||
gfn += 1;
|
||||
|
||||
if (is_error_noslot_pfn(pfn))
|
||||
@@ -119,7 +119,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
|
||||
* Pin all pages we are about to map in memory. This is
|
||||
* important because we unmap and unpin in 4kb steps later.
|
||||
*/
|
||||
- pfn = kvm_pin_pages(slot, gfn, page_size);
|
||||
+ pfn = kvm_pin_pages(slot, gfn, page_size >> PAGE_SHIFT);
|
||||
if (is_error_noslot_pfn(pfn)) {
|
||||
gfn += 1;
|
||||
continue;
|
||||
@@ -131,7 +131,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
|
||||
if (r) {
|
||||
printk(KERN_ERR "kvm_iommu_map_address:"
|
||||
"iommu failed to map pfn=%llx\n", pfn);
|
||||
- kvm_unpin_pages(kvm, pfn, page_size);
|
||||
+ kvm_unpin_pages(kvm, pfn, page_size >> PAGE_SHIFT);
|
||||
goto unmap_pages;
|
||||
}
|
||||
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,78 +0,0 @@
|
||||
From: Petr Matousek <pmatouse@redhat.com>
|
||||
Date: Fri, 24 Oct 2014 17:07:18 +0200
|
||||
Subject: [PATCH] kvm: vmx: handle invvpid vm exit gracefully
|
||||
|
||||
On systems with invvpid instruction support (corresponding bit in
|
||||
IA32_VMX_EPT_VPID_CAP MSR is set) guest invocation of invvpid
|
||||
causes vm exit, which is currently not handled and results in
|
||||
propagation of unknown exit to userspace.
|
||||
|
||||
Fix this by installing an invvpid vm exit handler.
|
||||
|
||||
This is CVE-2014-3646.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Petr Matousek <pmatouse@redhat.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
arch/x86/include/uapi/asm/vmx.h | 2 ++
|
||||
arch/x86/kvm/vmx.c | 9 ++++++++-
|
||||
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h
|
||||
index 0e79420376eb..990a2fe1588d 100644
|
||||
--- a/arch/x86/include/uapi/asm/vmx.h
|
||||
+++ b/arch/x86/include/uapi/asm/vmx.h
|
||||
@@ -67,6 +67,7 @@
|
||||
#define EXIT_REASON_EPT_MISCONFIG 49
|
||||
#define EXIT_REASON_INVEPT 50
|
||||
#define EXIT_REASON_PREEMPTION_TIMER 52
|
||||
+#define EXIT_REASON_INVVPID 53
|
||||
#define EXIT_REASON_WBINVD 54
|
||||
#define EXIT_REASON_XSETBV 55
|
||||
#define EXIT_REASON_APIC_WRITE 56
|
||||
@@ -114,6 +115,7 @@
|
||||
{ EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, \
|
||||
{ EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, \
|
||||
{ EXIT_REASON_INVD, "INVD" }, \
|
||||
+ { EXIT_REASON_INVVPID, "INVVPID" }, \
|
||||
{ EXIT_REASON_INVPCID, "INVPCID" }
|
||||
|
||||
#endif /* _UAPIVMX_H */
|
||||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
||||
index 0881ec6154cc..12dd2b2e655c 100644
|
||||
--- a/arch/x86/kvm/vmx.c
|
||||
+++ b/arch/x86/kvm/vmx.c
|
||||
@@ -6639,6 +6639,12 @@ static int handle_invept(struct kvm_vcpu *vcpu)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static int handle_invvpid(struct kvm_vcpu *vcpu)
|
||||
+{
|
||||
+ kvm_queue_exception(vcpu, UD_VECTOR);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* The exit handlers return 1 if the exit was handled fully and guest execution
|
||||
* may resume. Otherwise they set the kvm_run parameter to indicate what needs
|
||||
@@ -6684,6 +6690,7 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
|
||||
[EXIT_REASON_MWAIT_INSTRUCTION] = handle_mwait,
|
||||
[EXIT_REASON_MONITOR_INSTRUCTION] = handle_monitor,
|
||||
[EXIT_REASON_INVEPT] = handle_invept,
|
||||
+ [EXIT_REASON_INVVPID] = handle_invvpid,
|
||||
};
|
||||
|
||||
static const int kvm_vmx_max_exit_handlers =
|
||||
@@ -6917,7 +6924,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
|
||||
case EXIT_REASON_VMPTRST: case EXIT_REASON_VMREAD:
|
||||
case EXIT_REASON_VMRESUME: case EXIT_REASON_VMWRITE:
|
||||
case EXIT_REASON_VMOFF: case EXIT_REASON_VMON:
|
||||
- case EXIT_REASON_INVEPT:
|
||||
+ case EXIT_REASON_INVEPT: case EXIT_REASON_INVVPID:
|
||||
/*
|
||||
* VMX instructions trap unconditionally. This allows L1 to
|
||||
* emulate them for its L2 guest, i.e., allows 3-level nesting!
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,54 +0,0 @@
|
||||
From: "Michael S. Tsirkin" <mst@redhat.com>
|
||||
Date: Fri, 24 Oct 2014 17:07:19 +0200
|
||||
Subject: [PATCH] kvm: x86: don't kill guest on unknown exit reason
|
||||
|
||||
KVM_EXIT_UNKNOWN is a kvm bug, we don't really know whether it was
|
||||
triggered by a priveledged application. Let's not kill the guest: WARN
|
||||
and inject #UD instead.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
---
|
||||
arch/x86/kvm/svm.c | 6 +++---
|
||||
arch/x86/kvm/vmx.c | 6 +++---
|
||||
2 files changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
|
||||
index e2de97daa03c..78dadc36fc78 100644
|
||||
--- a/arch/x86/kvm/svm.c
|
||||
+++ b/arch/x86/kvm/svm.c
|
||||
@@ -3534,9 +3534,9 @@ static int handle_exit(struct kvm_vcpu *vcpu)
|
||||
|
||||
if (exit_code >= ARRAY_SIZE(svm_exit_handlers)
|
||||
|| !svm_exit_handlers[exit_code]) {
|
||||
- kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
|
||||
- kvm_run->hw.hardware_exit_reason = exit_code;
|
||||
- return 0;
|
||||
+ WARN_ONCE(1, "vmx: unexpected exit reason 0x%x\n", exit_code);
|
||||
+ kvm_queue_exception(vcpu, UD_VECTOR);
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
return svm_exit_handlers[exit_code](svm);
|
||||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
||||
index 12dd2b2e655c..41a5426c8edb 100644
|
||||
--- a/arch/x86/kvm/vmx.c
|
||||
+++ b/arch/x86/kvm/vmx.c
|
||||
@@ -7065,10 +7065,10 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu)
|
||||
&& kvm_vmx_exit_handlers[exit_reason])
|
||||
return kvm_vmx_exit_handlers[exit_reason](vcpu);
|
||||
else {
|
||||
- vcpu->run->exit_reason = KVM_EXIT_UNKNOWN;
|
||||
- vcpu->run->hw.hardware_exit_reason = exit_reason;
|
||||
+ WARN_ONCE(1, "vmx: unexpected exit reason 0x%x\n", exit_reason);
|
||||
+ kvm_queue_exception(vcpu, UD_VECTOR);
|
||||
+ return 1;
|
||||
}
|
||||
- return 0;
|
||||
}
|
||||
|
||||
static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
|
||||
--
|
||||
1.9.3
|
||||
|
@ -1,44 +0,0 @@
|
||||
From: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Date: Wed, 8 Oct 2014 10:42:27 -0700
|
||||
Subject: [PATCH] mnt: Prevent pivot_root from creating a loop in the mount
|
||||
tree
|
||||
|
||||
Andy Lutomirski recently demonstrated that when chroot is used to set
|
||||
the root path below the path for the new ``root'' passed to pivot_root
|
||||
the pivot_root system call succeeds and leaks mounts.
|
||||
|
||||
In examining the code I see that starting with a new root that is
|
||||
below the current root in the mount tree will result in a loop in the
|
||||
mount tree after the mounts are detached and then reattached to one
|
||||
another. Resulting in all kinds of ugliness including a leak of that
|
||||
mounts involved in the leak of the mount loop.
|
||||
|
||||
Prevent this problem by ensuring that the new mount is reachable from
|
||||
the current root of the mount tree.
|
||||
|
||||
Upstream-status: Submitted for 3.18
|
||||
Bugzilla: 1151095,1151484
|
||||
|
||||
Reported-by: Andy Lutomirski <luto@amacapital.net>
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
---
|
||||
fs/namespace.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/fs/namespace.c b/fs/namespace.c
|
||||
index ef42d9bee212..74647c2fe69c 100644
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -2820,6 +2820,9 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
||||
/* make sure we can reach put_old from new_root */
|
||||
if (!is_path_reachable(old_mnt, old.dentry, &new))
|
||||
goto out4;
|
||||
+ /* make certain new is below the root */
|
||||
+ if (!is_path_reachable(new_mnt, new.dentry, &root))
|
||||
+ goto out4;
|
||||
root_mp->m_count++; /* pin it so it won't go away */
|
||||
lock_mount_hash();
|
||||
detach_mnt(new_mnt, &parent_path);
|
||||
--
|
||||
1.9.3
|
||||
|
2
sources
2
sources
@ -1,3 +1,3 @@
|
||||
fb30d0f29214d75cddd2faa94f73d5cf linux-3.17.tar.xz
|
||||
159e969cbc27201d8e2fa0f609dc722f perf-man-3.17.tar.gz
|
||||
d694b8625f834791f5e02d7c9add1406 patch-3.17.2.xz
|
||||
13f495e3ce72ed6ccefb38591587a6ef patch-3.17.3.xz
|
||||
|
@ -1,88 +0,0 @@
|
||||
From c0dc842e68fe51dd4096d374159d38292c4aca61 Mon Sep 17 00:00:00 2001
|
||||
From: Rabin Vincent <rabin@rab.in>
|
||||
Date: Wed, 29 Oct 2014 23:06:58 +0100
|
||||
Subject: [PATCH] tracing/syscalls: Ignore numbers outside NR_syscalls' range
|
||||
|
||||
ARM has some private syscalls (for example, set_tls(2)) which lie
|
||||
outside the range of NR_syscalls. If any of these are called while
|
||||
syscall tracing is being performed, out-of-bounds array access will
|
||||
occur in the ftrace and perf sys_{enter,exit} handlers.
|
||||
|
||||
# trace-cmd record -e raw_syscalls:* true && trace-cmd report
|
||||
...
|
||||
true-653 [000] 384.675777: sys_enter: NR 192 (0, 1000, 3, 4000022, ffffffff, 0)
|
||||
true-653 [000] 384.675812: sys_exit: NR 192 = 1995915264
|
||||
true-653 [000] 384.675971: sys_enter: NR 983045 (76f74480, 76f74000, 76f74b28, 76f74480, 76f76f74, 1)
|
||||
true-653 [000] 384.675988: sys_exit: NR 983045 = 0
|
||||
...
|
||||
|
||||
# trace-cmd record -e syscalls:* true
|
||||
[ 17.289329] Unable to handle kernel paging request at virtual address aaaaaace
|
||||
[ 17.289590] pgd = 9e71c000
|
||||
[ 17.289696] [aaaaaace] *pgd=00000000
|
||||
[ 17.289985] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
|
||||
[ 17.290169] Modules linked in:
|
||||
[ 17.290391] CPU: 0 PID: 704 Comm: true Not tainted 3.18.0-rc2+ #21
|
||||
[ 17.290585] task: 9f4dab00 ti: 9e710000 task.ti: 9e710000
|
||||
[ 17.290747] PC is at ftrace_syscall_enter+0x48/0x1f8
|
||||
[ 17.290866] LR is at syscall_trace_enter+0x124/0x184
|
||||
|
||||
Fix this by ignoring out-of-NR_syscalls-bounds syscall numbers.
|
||||
|
||||
Commit cd0980fc8add "tracing: Check invalid syscall nr while tracing syscalls"
|
||||
added the check for less than zero, but it should have also checked
|
||||
for greater than NR_syscalls.
|
||||
|
||||
Link: http://lkml.kernel.org/p/1414620418-29472-1-git-send-email-rabin@rab.in
|
||||
|
||||
Fixes: cd0980fc8add "tracing: Check invalid syscall nr while tracing syscalls"
|
||||
Cc: stable@vger.kernel.org # 2.6.33+
|
||||
Signed-off-by: Rabin Vincent <rabin@rab.in>
|
||||
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
|
||||
---
|
||||
kernel/trace/trace_syscalls.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
|
||||
index 759d5e004517..7e3cd7aaec83 100644
|
||||
--- a/kernel/trace/trace_syscalls.c
|
||||
+++ b/kernel/trace/trace_syscalls.c
|
||||
@@ -313,7 +313,7 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
|
||||
int size;
|
||||
|
||||
syscall_nr = trace_get_syscall_nr(current, regs);
|
||||
- if (syscall_nr < 0)
|
||||
+ if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
|
||||
/* Here we're inside tp handler's rcu_read_lock_sched (__DO_TRACE) */
|
||||
@@ -360,7 +360,7 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
|
||||
int syscall_nr;
|
||||
|
||||
syscall_nr = trace_get_syscall_nr(current, regs);
|
||||
- if (syscall_nr < 0)
|
||||
+ if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
|
||||
/* Here we're inside tp handler's rcu_read_lock_sched (__DO_TRACE()) */
|
||||
@@ -567,7 +567,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
|
||||
int size;
|
||||
|
||||
syscall_nr = trace_get_syscall_nr(current, regs);
|
||||
- if (syscall_nr < 0)
|
||||
+ if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
if (!test_bit(syscall_nr, enabled_perf_enter_syscalls))
|
||||
return;
|
||||
@@ -641,7 +641,7 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
|
||||
int size;
|
||||
|
||||
syscall_nr = trace_get_syscall_nr(current, regs);
|
||||
- if (syscall_nr < 0)
|
||||
+ if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
if (!test_bit(syscall_nr, enabled_perf_exit_syscalls))
|
||||
return;
|
||||
--
|
||||
1.9.3
|
||||
|
Loading…
Reference in New Issue
Block a user