From 97bbad5aead725ca451bca29d06d7d4967dd71a8 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Wed, 26 Feb 2020 16:34:47 +0100 Subject: [PATCH] nova: avoid dying thread in platform.run Avoids timely interference by dying thread. Fixes #3670 --- repos/base-nova/src/test/platform/main.cc | 78 ++++++++++++---------- repos/base-nova/src/test/platform/server.h | 13 +--- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/repos/base-nova/src/test/platform/main.cc b/repos/base-nova/src/test/platform/main.cc index 0e535db1b..309ef64bc 100644 --- a/repos/base-nova/src/test/platform/main.cc +++ b/repos/base-nova/src/test/platform/main.cc @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2015-2017 Genode Labs GmbH + * Copyright (C) 2015-2020 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -266,8 +266,31 @@ void test_revoke(Genode::Env &env) } } +static void portal_entry() +{ + Genode::Thread &myself = *Genode::Thread::myself(); + Nova::Utcb &utcb = *reinterpret_cast(myself.utcb()); + + Nova::Crd const snd_crd(utcb.msg()[0]); + + enum { + HOTSPOT = 0, USER_PD = false, HOST_PGT = false, SOLELY_MAP = false, + NO_DMA = false, EVILLY_DONT_WRITE_COMBINE = false + }; + + utcb.set_msg_word(0); + bool ok = utcb.append_item(snd_crd, HOTSPOT, USER_PD, HOST_PGT, + SOLELY_MAP, NO_DMA, EVILLY_DONT_WRITE_COMBINE); + (void)ok; + + Nova::reply(myself.stack_top()); +} + void test_pat(Genode::Env &env) { + Genode::Thread &myself = *Genode::Thread::myself(); + Nova::Utcb &utcb = *reinterpret_cast(myself.utcb()); + /* read out the tsc frequenzy once */ Attached_rom_dataspace const platform_info (env, "platform_info"); Xml_node const hardware = platform_info.xml().sub_node("hardware"); @@ -283,10 +306,6 @@ void test_pat(Genode::Env &env) static Rpc_entrypoint ep(&env.pd(), STACK_SIZE, "rpc_ep_pat"); - Test::Component component; - Test::Capability session_cap = ep.manage(&component); - Test::Client client(session_cap); - Genode::Rm_connection rm(env); Genode::Region_map_client rm_free_area(rm.create(1 << (DS_ORDER + PAGE_4K))); addr_t remap_addr = env.rm().attach(rm_free_area.dataspace()); @@ -296,36 +315,32 @@ void test_pat(Genode::Env &env) touch_read(reinterpret_cast(map_addr)); /* - * Manipulate entrypoint + * Establish memory mapping with evilly wrong mapping attributes */ - Nova::Rights all(true, true, true); - Genode::addr_t utcb_ep_addr_t = client.leak_utcb_address(); - Nova::Utcb *utcb_ep = reinterpret_cast(utcb_ep_addr_t); - /* overwrite receive window of entrypoint */ - utcb_ep->crd_rcv = Nova::Mem_crd(remap_addr >> PAGE_4K, DS_ORDER, all); + Nova_native_pd_client native_pd { env.pd().native_pd() }; + Thread * thread = reinterpret_cast(&ep); + Native_capability const thread_cap + = Capability_space::import(thread->native_thread().ec_sel); - /* - * Set-up current (client) thread to delegate write-combined memory - */ - Nova::Mem_crd snd_crd(map_addr >> PAGE_4K, DS_ORDER, all); + Untyped_capability const pt = + native_pd.alloc_rpc_cap(thread_cap, (addr_t)portal_entry, 0 /* MTD */); - Nova::Utcb *utcb = reinterpret_cast(Thread::myself()->utcb()); - enum { - HOTSPOT = 0, USER_PD = false, HOST_PGT = false, SOLELY_MAP = false, - NO_DMA = false, EVILLY_DONT_WRITE_COMBINE = false - }; + Nova::Rights const all(true, true, true); + Nova::Mem_crd const rcv_crd(remap_addr >> PAGE_4K, DS_ORDER, all); + Nova::Mem_crd const snd_crd(map_addr >> PAGE_4K, DS_ORDER, all); + Nova::Crd const old_crd = utcb.crd_rcv; - Nova::Crd old = utcb->crd_rcv; + utcb.crd_rcv = rcv_crd; + utcb.set_msg_word(1); + utcb.msg()[0] = snd_crd.value(); - utcb->set_msg_word(0); - bool ok = utcb->append_item(snd_crd, HOTSPOT, USER_PD, HOST_PGT, - SOLELY_MAP, NO_DMA, EVILLY_DONT_WRITE_COMBINE); - (void)ok; + uint8_t const res = Nova::call(pt.local_name()); + utcb.crd_rcv = old_crd; - uint8_t res = Nova::call(session_cap.local_name()); - (void)res; - - utcb->crd_rcv = old; + if (res != Nova::NOVA_OK) { + Genode::error("establishing memory failed ", res); + failed++; + } /* sanity check - touch re-mapped area */ for (addr_t i = remap_addr; i < remap_addr + (1 << (DS_ORDER + PAGE_4K)); i += (1 << PAGE_4K)) @@ -358,11 +373,6 @@ void test_pat(Genode::Env &env) } Nova::revoke(Nova::Mem_crd(remap_addr >> PAGE_4K, DS_ORDER, all)); - - /* - * note: server entrypoint died because of unexpected receive window - * state - that is expected - */ } void test_server_oom(Genode::Env &env) diff --git a/repos/base-nova/src/test/platform/server.h b/repos/base-nova/src/test/platform/server.h index abd215ca0..cf0651e88 100644 --- a/repos/base-nova/src/test/platform/server.h +++ b/repos/base-nova/src/test/platform/server.h @@ -47,10 +47,7 @@ struct Test::Session : Genode::Session void_cap); GENODE_RPC(Rpc_cap_cap, Genode::Native_capability, cap_cap, Genode::addr_t); - GENODE_RPC(Rpc_leak_utcb_address, Genode::addr_t, leak_utcb_address); - - GENODE_RPC_INTERFACE(Rpc_cap_void, Rpc_void_cap, Rpc_cap_cap, - Rpc_leak_utcb_address); + GENODE_RPC_INTERFACE(Rpc_cap_void, Rpc_void_cap, Rpc_cap_cap); }; struct Test::Client : Genode::Rpc_client @@ -65,9 +62,6 @@ struct Test::Client : Genode::Rpc_client Genode::Native_capability cap_cap(Genode::addr_t cap) { return call(cap); } - - Genode::addr_t leak_utcb_address() { - return call(); } }; struct Test::Component : Genode::Rpc_object @@ -78,8 +72,6 @@ struct Test::Component : Genode::Rpc_object Genode::Native_capability void_cap(); /* Test to transfer a specific object capability during reply */ Genode::Native_capability cap_cap(Genode::addr_t); - /* Leak utcb address of entrypoint to manipulate utcb receive window */ - Genode::addr_t leak_utcb_address(); }; namespace Test { typedef Genode::Capability Capability; } @@ -114,8 +106,5 @@ inline Genode::Native_capability Test::Component::void_cap() { return send_cap; } -inline Genode::addr_t Test::Component::leak_utcb_address() { - return reinterpret_cast(Genode::Thread::myself()->utcb()); } - inline Genode::Native_capability Test::Component::cap_cap(Genode::addr_t cap) { return Genode::Capability_space::import(cap); }