Skip to content

Commit 6fd1e39

Browse files
blitzsean-jc
authored andcommitted
KVM: x86: Clean up partially uninitialized integer in emulate_pop()
Explicitly zero out variables passed to emulate_pop() as output params to harden against consuming uninitialized data, and to make sanitizers happy. Many flows that use emulate_pop() pass an "unsigned long" so as to be able to hold the largest possible operand, but the actual number of bytes written is usually the word with of the vCPU. E.g. if the vCPU is in 16-bit or 32-bit mode (on a 64-bit host), the upper portion of the output param will be uninitialized. Passing around the uninitialized data is benign, as actual KVM usage of the output is also tied to the word width, but passing around uninitialized data makes some sanitizers rightly complain. Note, initializing the data in emulate_pop() is not a safe alternative, e.g. it would result in em_leave() clobbering RBP[31:16] if LEAVE were emulated with a 16-bit stack. Signed-off-by: Julian Stecklina <julian.stecklina@cyberus-technology.de> Link: https://lore.kernel.org/r/20231009092054.556935-1-julian.stecklina@cyberus-technology.de [sean: massage changelog, drop em_popa() variable size change]] Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 03f6298 commit 6fd1e39

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

arch/x86/kvm/emulate.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1863,7 +1863,8 @@ static int emulate_popf(struct x86_emulate_ctxt *ctxt,
18631863
void *dest, int len)
18641864
{
18651865
int rc;
1866-
unsigned long val, change_mask;
1866+
unsigned long val = 0;
1867+
unsigned long change_mask;
18671868
int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> X86_EFLAGS_IOPL_BIT;
18681869
int cpl = ctxt->ops->cpl(ctxt);
18691870

@@ -1954,7 +1955,7 @@ static int em_push_sreg(struct x86_emulate_ctxt *ctxt)
19541955
static int em_pop_sreg(struct x86_emulate_ctxt *ctxt)
19551956
{
19561957
int seg = ctxt->src2.val;
1957-
unsigned long selector;
1958+
unsigned long selector = 0;
19581959
int rc;
19591960

19601961
rc = emulate_pop(ctxt, &selector, 2);
@@ -2000,7 +2001,7 @@ static int em_popa(struct x86_emulate_ctxt *ctxt)
20002001
{
20012002
int rc = X86EMUL_CONTINUE;
20022003
int reg = VCPU_REGS_RDI;
2003-
u32 val;
2004+
u32 val = 0;
20042005

20052006
while (reg >= VCPU_REGS_RAX) {
20062007
if (reg == VCPU_REGS_RSP) {
@@ -2229,7 +2230,7 @@ static int em_cmpxchg8b(struct x86_emulate_ctxt *ctxt)
22292230
static int em_ret(struct x86_emulate_ctxt *ctxt)
22302231
{
22312232
int rc;
2232-
unsigned long eip;
2233+
unsigned long eip = 0;
22332234

22342235
rc = emulate_pop(ctxt, &eip, ctxt->op_bytes);
22352236
if (rc != X86EMUL_CONTINUE)
@@ -2241,7 +2242,8 @@ static int em_ret(struct x86_emulate_ctxt *ctxt)
22412242
static int em_ret_far(struct x86_emulate_ctxt *ctxt)
22422243
{
22432244
int rc;
2244-
unsigned long eip, cs;
2245+
unsigned long eip = 0;
2246+
unsigned long cs = 0;
22452247
int cpl = ctxt->ops->cpl(ctxt);
22462248
struct desc_struct new_desc;
22472249

@@ -3184,7 +3186,7 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt)
31843186
static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
31853187
{
31863188
int rc;
3187-
unsigned long eip;
3189+
unsigned long eip = 0;
31883190

31893191
rc = emulate_pop(ctxt, &eip, ctxt->op_bytes);
31903192
if (rc != X86EMUL_CONTINUE)

0 commit comments

Comments
 (0)