l4_task_cap_equal broken?

Alexander Warg alexander.warg at os.inf.tu-dresden.de
Thu Apr 19 17:36:53 CEST 2012

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!


More information about the l4-hackers mailing list