From 591c89a3ae841d9149299e053e2410d4f8e7a615 Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Mon, 21 Oct 2013 21:43:31 +0200 Subject: [PATCH] limit the exception reply thread state application Don't apply those parts of the thread state returned by the Genode exception handler which might have changed in the kernel in the meantime. Fixes ssumpf/foc#8. --- kernel/fiasco/src/kern/arm/thread-arm.cpp | 12 +++++++++++- kernel/fiasco/src/kern/ia32/32/thread-ia32-32.cpp | 8 ++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/kernel/fiasco/src/kern/arm/thread-arm.cpp b/kernel/fiasco/src/kern/arm/thread-arm.cpp index 4127551e..13041c49 100644 --- a/kernel/fiasco/src/kern/arm/thread-arm.cpp +++ b/kernel/fiasco/src/kern/arm/thread-arm.cpp @@ -505,7 +505,17 @@ Thread::copy_utcb_to_ts(L4_msg_tag const &tag, Thread *snd, Thread *rcv, } else { - Mem::memcpy_mwords (ts, snd_utcb->values, s > 19 ? 19 : s); + /* + * copy R0..R12,SP,LR,PC,PSR (UTCB Mwords 3..15,16,17,19,20) + * don't allow to overwrite pf_address, error_code, tpidruro, km_lr + * (these might have changed in the kernel without the Genode exception + * handler knowing about it, so it could try to restore outdated values) + */ + Mem::memcpy_mwords (&ts->r[0], &snd_utcb->values[3], s > 15 ? 13 : s); + if (EXPECT_TRUE(s > 16)) + ts->usp = snd_utcb->values[16]; + if (EXPECT_TRUE(s > 17)) + ts->ulr = snd_utcb->values[17]; if (EXPECT_TRUE(s > 19)) ts->pc = snd_utcb->values[19]; if (EXPECT_TRUE(s > 20)) diff --git a/kernel/fiasco/src/kern/ia32/32/thread-ia32-32.cpp b/kernel/fiasco/src/kern/ia32/32/thread-ia32-32.cpp index 60112269..4fe71213 100644 --- a/kernel/fiasco/src/kern/ia32/32/thread-ia32-32.cpp +++ b/kernel/fiasco/src/kern/ia32/32/thread-ia32-32.cpp @@ -79,6 +79,7 @@ Thread::copy_utcb_to_ts(L4_msg_tag const &tag, Thread *snd, Thread *rcv, Trap_state *ts = (Trap_state*)rcv->_utcb_handler; Mword s = tag.words(); Unsigned32 cs = ts->cs(); + Unsigned32 eflags_tf = ts->flags() & EFLAGS_TF; Utcb *snd_utcb = snd->utcb().access(); // XXX: check that gs and fs point to valid user_entry only, for gdt and @@ -110,6 +111,13 @@ Thread::copy_utcb_to_ts(L4_msg_tag const &tag, Thread *snd, Thread *rcv, // don't allow to overwrite the code selector! ts->cs(cs); + /* + * don't allow to overwrite the single-step flag + * (it might have changed in the kernel without the Genode exception handler + * knowing about it, so it could try to restore an outdated value) + */ + ts->flags((ts->flags() & ~EFLAGS_TF) | eflags_tf); + bool ret = transfer_msg_items(tag, snd, snd_utcb, rcv, rcv->utcb().access(), rights);