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