On Wed, 2012-04-18 at 15:01 +0200, Stefan kalkowski wrote:
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?
Yes, you missed the rights assigned to the capabilities. Two capabilities are equal if they are exactly equal. This means they must point to the same object and have exactly the same rights.
The attached kernel patch fixes the problem for me, but may introduce other problems (e.g.: not sure whether obj() returns always valid pointers).
The patch uses a debugging feature of the Kobject class and additionally removes the rights check. Note, the object pointers in two capabilities may also differ if they point to the same kernel object but have different rights!