Dear Fiasco.OC developers, while working with Genode on top of Fiasco.OC, I've encountered the following problem. When I transfer ipc-gates via ipc between tasks, it comes to the point where a task receives a gate it already owns. These duplicates are detected due to an additional identifier that is transfered together with the gate. To detect fraud (whether somebody has send an invalid gate/id combination) the received gate gets compared with the locally available one via "l4_task_cap_equal". Now, the problem is "l4_task_cap_equal" often fails even when both capabilities point to the same ipc-gate. The following code-snippet demonstrates this issue:
... tag = l4_task_cap_equal(L4_BASE_TASK_CAP, i->kcap(), rcv_cap); if (!l4_msgtag_label(tag)) { unsigned long id1 = l4_debugger_global_id(i->kcap()), id2 = l4_debugger_global_id(rcv_cap); printf("my_cap=%lx (id=%lx) rcv_cap=%lx (id=%lx)", i->kcap(), id1, rcv_cap, id2); if (id1 == id2) enter_kdebug("FAIL"); } ... This snippet is executed after a thread in the roottask received from another thread of the same task a capability via IPC. Thereby rcv_cap is the cap that was received via ipc and i->kcap() is the cap that was retrieved via the additional transfered identifier. When executed I get the following output: ... my_cap=20f000 (id=12) rcv_cap=205000 (id=12) --------------------------------------------------------------------- CPU 0 [00145e81]: FAIL [ entrypoint] jdb: The debugger's global id (here: 12) indicates that both capabilities reference the same object. Nevertheless, the equality test fails. Can you confirm that this is undesired syscall's behaviour, or do I miss something important? The attached kernel patch fixes the problem for me, but may introduce other problems (e.g.: not sure whether obj() returns always valid pointers). Regards Stefan
Index: src/kern/task.cpp =================================================================== --- src/kern/task.cpp (revision 38) +++ src/kern/task.cpp (working copy) @@ -511,7 +511,8 @@ Obj_space::Capability c_a = obj_space()->lookup(obj_a.cap()); Obj_space::Capability c_b = obj_space()->lookup(obj_b.cap()); - return commit_result(c_a == c_b); + return commit_result(c_a.obj()->kobject_start_addr() == + c_b.obj()->kobject_start_addr()); } PRIVATE inline NOEXPORT
_______________________________________________ l4-hackers mailing list l4-hackers@os.inf.tu-dresden.de http://os.inf.tu-dresden.de/mailman/listinfo/l4-hackers