diff --git a/debian/changelog b/debian/changelog index 957aba8c2..909a28f9a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -142,6 +142,7 @@ linux (3.16.7-1) UNRELEASED; urgency=medium * [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) diff --git a/debian/patches/bugfix/x86/KVM-x86-Emulator-fixes-for-eip-canonical-checks-on-n.patch b/debian/patches/bugfix/x86/KVM-x86-Emulator-fixes-for-eip-canonical-checks-on-n.patch index c2b3891b5..21a789a8b 100644 --- a/debian/patches/bugfix/x86/KVM-x86-Emulator-fixes-for-eip-canonical-checks-on-n.patch +++ b/debian/patches/bugfix/x86/KVM-x86-Emulator-fixes-for-eip-canonical-checks-on-n.patch @@ -62,7 +62,7 @@ Signed-off-by: Paolo Bonzini } 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 @@ Signed-off-by: Paolo Bonzini 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 @@ Signed-off-by: Paolo Bonzini } 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 @@ Signed-off-by: Paolo Bonzini 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 @@ Signed-off-by: Paolo Bonzini 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 @@ Signed-off-by: Paolo Bonzini 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 @@ Signed-off-by: Paolo Bonzini 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 @@ Signed-off-by: Paolo Bonzini 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 @@ Signed-off-by: Paolo Bonzini 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 @@ Signed-off-by: Paolo Bonzini } 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 @@ Signed-off-by: Paolo Bonzini 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 @@ Signed-off-by: Paolo Bonzini 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)) diff --git a/debian/patches/bugfix/x86/KVM-x86-Handle-errors-when-RIP-is-set-during-far-jum.patch b/debian/patches/bugfix/x86/KVM-x86-Handle-errors-when-RIP-is-set-during-far-jum.patch index ce90e355d..944d7851b 100644 --- a/debian/patches/bugfix/x86/KVM-x86-Handle-errors-when-RIP-is-set-during-far-jum.patch +++ b/debian/patches/bugfix/x86/KVM-x86-Handle-errors-when-RIP-is-set-during-far-jum.patch @@ -22,7 +22,7 @@ Signed-off-by: Paolo Bonzini --- 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 @@ Signed-off-by: Paolo Bonzini { 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 @@ Signed-off-by: Paolo Bonzini 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 @@ Signed-off-by: Paolo Bonzini } 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 @@ Signed-off-by: Paolo Bonzini } 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 @@ Signed-off-by: Paolo Bonzini 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 @@ Signed-off-by: Paolo Bonzini 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 @@ Signed-off-by: Paolo Bonzini 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 @@ Signed-off-by: Paolo Bonzini 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; diff --git a/debian/patches/bugfix/x86/kvm-x86-fix-far-jump-to-non-canonical-check.patch b/debian/patches/bugfix/x86/kvm-x86-fix-far-jump-to-non-canonical-check.patch new file mode 100644 index 000000000..5b151a4b8 --- /dev/null +++ b/debian/patches/bugfix/x86/kvm-x86-fix-far-jump-to-non-canonical-check.patch @@ -0,0 +1,58 @@ +From: Nadav Amit +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 +Signed-off-by: Nadav Amit +[Add #ifdef CONFIG_X86_64 to avoid complaints of undefined behavior. - Paolo] +Signed-off-by: Paolo Bonzini +--- + 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; diff --git a/debian/patches/series b/debian/patches/series index a54a31e02..4e5fca179 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -412,8 +412,9 @@ bugfix/x86/KVM-x86-Prevent-host-from-panicking-on-shared-MSR-wr.patch 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