[kernel] r22030 - in dists/sid/linux/debian: . patches patches/bugfix/x86
Ben Hutchings
benh at moszumanska.debian.org
Tue Nov 4 00:19:39 UTC 2014
Author: benh
Date: Tue Nov 4 00:19:39 2014
New Revision: 22030
Log:
[x86] KVM: Fix far-jump to non-canonical check
Fixes bug in the original fix for CVE-2014-3647.
Also fix ordering of the previous patches.
Added:
dists/sid/linux/debian/patches/bugfix/x86/kvm-x86-fix-far-jump-to-non-canonical-check.patch
Modified:
dists/sid/linux/debian/changelog
dists/sid/linux/debian/patches/bugfix/x86/KVM-x86-Emulator-fixes-for-eip-canonical-checks-on-n.patch
dists/sid/linux/debian/patches/bugfix/x86/KVM-x86-Handle-errors-when-RIP-is-set-during-far-jum.patch
dists/sid/linux/debian/patches/series
Modified: dists/sid/linux/debian/changelog
==============================================================================
--- dists/sid/linux/debian/changelog Tue Nov 4 00:06:12 2014 (r22029)
+++ dists/sid/linux/debian/changelog Tue Nov 4 00:19:39 2014 (r22030)
@@ -142,6 +142,7 @@
* [x86] KVM: Emulator fixes for eip canonical checks on near branches
(CVE-2014-3647)
* [x86] KVM: Handle errors when RIP is set during far jumps (CVE-2014-3647)
+ * [x86] KVM: Fix far-jump to non-canonical check
* net: sctp: fix skb_over_panic when receiving malformed ASCONF chunks
(CVE-2014-3673)
* net: sctp: fix panic on duplicate ASCONF chunks (CVE-2014-3687)
Modified: dists/sid/linux/debian/patches/bugfix/x86/KVM-x86-Emulator-fixes-for-eip-canonical-checks-on-n.patch
==============================================================================
--- dists/sid/linux/debian/patches/bugfix/x86/KVM-x86-Emulator-fixes-for-eip-canonical-checks-on-n.patch Tue Nov 4 00:06:12 2014 (r22029)
+++ dists/sid/linux/debian/patches/bugfix/x86/KVM-x86-Emulator-fixes-for-eip-canonical-checks-on-n.patch Tue Nov 4 00:19:39 2014 (r22030)
@@ -62,7 +62,7 @@
}
static u16 get_segment_selector(struct x86_emulate_ctxt *ctxt, unsigned seg)
-@@ -2004,13 +2014,15 @@ static int em_grp45(struct x86_emulate_c
+@@ -1986,13 +1996,15 @@ static int em_grp45(struct x86_emulate_c
case 2: /* call near abs */ {
long int old_eip;
old_eip = ctxt->_eip;
@@ -80,7 +80,7 @@
break;
case 5: /* jmp far */
rc = em_jmp_far(ctxt);
-@@ -2042,10 +2054,14 @@ static int em_cmpxchg8b(struct x86_emula
+@@ -2024,10 +2036,14 @@ static int em_cmpxchg8b(struct x86_emula
static int em_ret(struct x86_emulate_ctxt *ctxt)
{
@@ -99,7 +99,7 @@
}
static int em_ret_far(struct x86_emulate_ctxt *ctxt)
-@@ -2336,7 +2352,7 @@ static int em_sysexit(struct x86_emulate
+@@ -2305,7 +2321,7 @@ static int em_sysexit(struct x86_emulate
{
const struct x86_emulate_ops *ops = ctxt->ops;
struct desc_struct cs, ss;
@@ -108,7 +108,7 @@
int usermode;
u16 cs_sel = 0, ss_sel = 0;
-@@ -2352,6 +2368,9 @@ static int em_sysexit(struct x86_emulate
+@@ -2321,6 +2337,9 @@ static int em_sysexit(struct x86_emulate
else
usermode = X86EMUL_MODE_PROT32;
@@ -118,7 +118,7 @@
cs.dpl = 3;
ss.dpl = 3;
ops->get_msr(ctxt, MSR_IA32_SYSENTER_CS, &msr_data);
-@@ -2369,6 +2388,9 @@ static int em_sysexit(struct x86_emulate
+@@ -2338,6 +2357,9 @@ static int em_sysexit(struct x86_emulate
ss_sel = cs_sel + 8;
cs.d = 0;
cs.l = 1;
@@ -128,7 +128,7 @@
break;
}
cs_sel |= SELECTOR_RPL_MASK;
-@@ -2377,8 +2399,8 @@ static int em_sysexit(struct x86_emulate
+@@ -2346,8 +2368,8 @@ static int em_sysexit(struct x86_emulate
ops->set_segment(ctxt, cs_sel, &cs, 0, VCPU_SREG_CS);
ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS);
@@ -139,7 +139,7 @@
return X86EMUL_CONTINUE;
}
-@@ -2931,10 +2953,13 @@ static int em_aad(struct x86_emulate_ctx
+@@ -2888,10 +2910,13 @@ static int em_aad(struct x86_emulate_ctx
static int em_call(struct x86_emulate_ctxt *ctxt)
{
@@ -154,7 +154,7 @@
return em_push(ctxt);
}
-@@ -2981,11 +3006,12 @@ fail:
+@@ -2923,11 +2948,12 @@ static int em_call_far(struct x86_emulat
static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
{
int rc;
@@ -171,7 +171,7 @@
if (rc != X86EMUL_CONTINUE)
return rc;
rsp_increment(ctxt, ctxt->src.val);
-@@ -3315,20 +3341,24 @@ static int em_lmsw(struct x86_emulate_ct
+@@ -3257,20 +3283,24 @@ static int em_lmsw(struct x86_emulate_ct
static int em_loop(struct x86_emulate_ctxt *ctxt)
{
@@ -200,7 +200,7 @@
}
static int em_in(struct x86_emulate_ctxt *ctxt)
-@@ -4729,7 +4759,7 @@ special_insn:
+@@ -4671,7 +4701,7 @@ special_insn:
break;
case 0x70 ... 0x7f: /* jcc (short) */
if (test_cc(ctxt->b, ctxt->eflags))
@@ -209,7 +209,7 @@
break;
case 0x8d: /* lea r16/r32, m */
ctxt->dst.val = ctxt->src.addr.mem.ea;
-@@ -4758,7 +4788,7 @@ special_insn:
+@@ -4700,7 +4730,7 @@ special_insn:
break;
case 0xe9: /* jmp rel */
case 0xeb: /* jmp rel short */
@@ -218,7 +218,7 @@
ctxt->dst.type = OP_NONE; /* Disable writeback. */
break;
case 0xf4: /* hlt */
-@@ -4878,7 +4908,7 @@ twobyte_insn:
+@@ -4820,7 +4850,7 @@ twobyte_insn:
break;
case 0x80 ... 0x8f: /* jnz rel, etc*/
if (test_cc(ctxt->b, ctxt->eflags))
Modified: dists/sid/linux/debian/patches/bugfix/x86/KVM-x86-Handle-errors-when-RIP-is-set-during-far-jum.patch
==============================================================================
--- dists/sid/linux/debian/patches/bugfix/x86/KVM-x86-Handle-errors-when-RIP-is-set-during-far-jum.patch Tue Nov 4 00:06:12 2014 (r22029)
+++ dists/sid/linux/debian/patches/bugfix/x86/KVM-x86-Handle-errors-when-RIP-is-set-during-far-jum.patch Tue Nov 4 00:19:39 2014 (r22030)
@@ -22,7 +22,7 @@
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
-@@ -1429,7 +1429,9 @@ static int write_segment_descriptor(stru
+@@ -1439,7 +1439,9 @@ static int write_segment_descriptor(stru
/* Does not support long mode */
static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
@@ -33,7 +33,7 @@
{
struct desc_struct seg_desc, old_desc;
u8 dpl, rpl;
-@@ -1558,6 +1560,8 @@ static int __load_segment_descriptor(str
+@@ -1568,6 +1570,8 @@ static int __load_segment_descriptor(str
}
load:
ctxt->ops->set_segment(ctxt, selector, &seg_desc, 0, seg);
@@ -42,7 +42,7 @@
return X86EMUL_CONTINUE;
exception:
emulate_exception(ctxt, err_vec, err_code, true);
-@@ -1568,7 +1572,7 @@ static int load_segment_descriptor(struc
+@@ -1578,7 +1582,7 @@ static int load_segment_descriptor(struc
u16 selector, int seg)
{
u8 cpl = ctxt->ops->cpl(ctxt);
@@ -51,7 +51,7 @@
}
static void write_register_operand(struct operand *op)
-@@ -1965,17 +1969,31 @@ static int em_iret(struct x86_emulate_ct
+@@ -1975,17 +1979,31 @@ static int em_iret(struct x86_emulate_ct
static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
{
int rc;
@@ -88,7 +88,7 @@
}
static int em_grp45(struct x86_emulate_ctxt *ctxt)
-@@ -2033,21 +2051,34 @@ static int em_ret(struct x86_emulate_ctx
+@@ -2049,21 +2067,34 @@ static int em_ret(struct x86_emulate_ctx
static int em_ret_far(struct x86_emulate_ctxt *ctxt)
{
int rc;
@@ -98,12 +98,12 @@
int cpl = ctxt->ops->cpl(ctxt);
+ struct desc_struct old_desc, new_desc;
+ const struct x86_emulate_ops *ops = ctxt->ops;
-
-- rc = emulate_pop(ctxt, &ctxt->_eip, ctxt->op_bytes);
++
+ 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;
@@ -128,7 +128,7 @@
return rc;
}
-@@ -2465,19 +2496,24 @@ static int load_state_from_tss16(struct
+@@ -2487,19 +2518,24 @@ static int load_state_from_tss16(struct
* Now load segment descriptors. If fault happens at this stage
* it is handled in a context of new task
*/
@@ -158,7 +158,7 @@
if (ret != X86EMUL_CONTINUE)
return ret;
-@@ -2602,25 +2638,32 @@ static int load_state_from_tss32(struct
+@@ -2624,25 +2660,32 @@ static int load_state_from_tss32(struct
* Now load segment descriptors. If fault happenes at this stage
* it is handled in a context of new task
*/
@@ -198,7 +198,7 @@
if (ret != X86EMUL_CONTINUE)
return ret;
-@@ -2900,24 +2943,39 @@ static int em_call_far(struct x86_emulat
+@@ -2925,24 +2968,39 @@ static int em_call_far(struct x86_emulat
u16 sel, old_cs;
ulong old_eip;
int rc;
Added: dists/sid/linux/debian/patches/bugfix/x86/kvm-x86-fix-far-jump-to-non-canonical-check.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/bugfix/x86/kvm-x86-fix-far-jump-to-non-canonical-check.patch Tue Nov 4 00:19:39 2014 (r22030)
@@ -0,0 +1,58 @@
+From: Nadav Amit <namit at cs.technion.ac.il>
+Date: Tue, 28 Oct 2014 00:03:43 +0200
+Subject: KVM: x86: Fix far-jump to non-canonical check
+Origin: https://git.kernel.org/linus/7e46dddd6f6cd5dbf3c7bd04a7e75d19475ac9f2
+
+Commit d1442d85cc30 ("KVM: x86: Handle errors when RIP is set during far
+jumps") introduced a bug that caused the fix to be incomplete. Due to
+incorrect evaluation, far jump to segment with L bit cleared (i.e., 32-bit
+segment) and RIP with any of the high bits set (i.e, RIP[63:32] != 0) set may
+not trigger #GP. As we know, this imposes a security problem.
+
+In addition, the condition for two warnings was incorrect.
+
+Fixes: d1442d85cc30ea75f7d399474ca738e0bc96f715
+Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
+Signed-off-by: Nadav Amit <namit at cs.technion.ac.il>
+[Add #ifdef CONFIG_X86_64 to avoid complaints of undefined behavior. - Paolo]
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+---
+ arch/x86/kvm/emulate.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -582,12 +582,14 @@ static inline int assign_eip_far(struct
+ case 4:
+ ctxt->_eip = (u32)dst;
+ break;
++#ifdef CONFIG_X86_64
+ case 8:
+ if ((cs_l && is_noncanonical_address(dst)) ||
+- (!cs_l && (dst & ~(u32)-1)))
++ (!cs_l && (dst >> 32) != 0))
+ return emulate_gp(ctxt, 0);
+ ctxt->_eip = dst;
+ break;
++#endif
+ default:
+ WARN(1, "unsupported eip assignment size\n");
+ }
+@@ -1998,7 +2000,7 @@ static int em_jmp_far(struct x86_emulate
+
+ rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l);
+ if (rc != X86EMUL_CONTINUE) {
+- WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64);
++ 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;
+@@ -2092,7 +2094,7 @@ static int em_ret_far(struct x86_emulate
+ return rc;
+ rc = assign_eip_far(ctxt, eip, new_desc.l);
+ if (rc != X86EMUL_CONTINUE) {
+- WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64);
++ WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64);
+ ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS);
+ }
+ return rc;
Modified: dists/sid/linux/debian/patches/series
==============================================================================
--- dists/sid/linux/debian/patches/series Tue Nov 4 00:06:12 2014 (r22029)
+++ dists/sid/linux/debian/patches/series Tue Nov 4 00:19:39 2014 (r22030)
@@ -412,8 +412,9 @@
bugfix/x86/KVM-x86-Improve-thread-safety-in-pit.patch
bugfix/x86/KVM-x86-Fix-wrong-masking-on-relative-jump-call.patch
bugfix/x86/kvm-vmx-handle-invvpid-vm-exit-gracefully.patch
-bugfix/x86/KVM-x86-Handle-errors-when-RIP-is-set-during-far-jum.patch
bugfix/x86/KVM-x86-Emulator-fixes-for-eip-canonical-checks-on-n.patch
+bugfix/x86/KVM-x86-Handle-errors-when-RIP-is-set-during-far-jum.patch
+bugfix/x86/kvm-x86-fix-far-jump-to-non-canonical-check.patch
bugfix/all/net-sctp-fix-skb_over_panic-when-receiving-malformed.patch
bugfix/all/net-sctp-fix-panic-on-duplicate-ASCONF-chunks.patch
bugfix/all/net-sctp-fix-remote-memory-pressure-from-excessive-q.patch
More information about the Kernel-svn-changes
mailing list