From: Alex Williamson Date: Thu, 1 Nov 2007 14:50:03 +0000 (-0600) Subject: [IA64] Fix ia64_sal_get_state_info() emulation bug X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14827 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=626fecc46b40d622dc3e5290a3b47b1703db12fd;p=xen.git [IA64] Fix ia64_sal_get_state_info() emulation bug It is possible to double-free the sal queue entry when multiple ia64_sal_get_state_info() from Dom0 are called simultaniously. In the worst case, the kernel might panic. Signed-off-by: Kazuhiro Suzuki --- diff --git a/xen/arch/ia64/xen/fw_emul.c b/xen/arch/ia64/xen/fw_emul.c index 8b00e62ea4..b6e9f8754b 100644 --- a/xen/arch/ia64/xen/fw_emul.c +++ b/xen/arch/ia64/xen/fw_emul.c @@ -242,6 +242,8 @@ sal_emulator (long index, unsigned long in1, unsigned long in2, } e = list_entry(sal_queue[in1].next, sal_queue_entry_t, list); + + list_del(&e->list); spin_unlock_irqrestore(&sal_queue_lock, flags); IA64_SAL_DEBUG("SAL_GET_STATE_INFO(%s <= %s) " @@ -277,10 +279,12 @@ sal_emulator (long index, unsigned long in1, unsigned long in2, r9 = arg.ret; status = arg.status; if (r9 == 0) { + xfree(e); + } else { + /* Re-add the entry to sal_queue */ spin_lock_irqsave(&sal_queue_lock, flags); - list_del(&e->list); + list_add(&e->list, &sal_queue[in1]); spin_unlock_irqrestore(&sal_queue_lock, flags); - xfree(e); } } else { status = IA64_SAL_NO_INFORMATION_AVAILABLE; @@ -316,10 +320,10 @@ sal_emulator (long index, unsigned long in1, unsigned long in2, "on CPU#%d.\n", rec_name[e->sal_info_type], rec_name[in1], e->cpuid); - arg.type = e->sal_info_type; arg.status = 0; + if (e->cpuid == smp_processor_id()) { IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO: local\n"); clear_state_info_on(&arg);