f9micro / f9-kernel

An efficient and secure microkernel built for ARM Cortex-M cores, inspired by L4
Other
679 stars 145 forks source link

Ipc_deliver didn't check from_thr intended to send. #138

Closed louisom closed 7 years ago

louisom commented 7 years ago

Code in kernel/ipc.c ipc_deliver switch case T_RECV_BLOCKED didn't check from_thr intended.

if (thr->ipc_from != L4_NILTHREAD &&
    thr->ipc_from != L4_ANYTHREAD &&
    thr->ipc_from != TID_TO_GLOBALID(THREAD_INTERRUPT)) {
    from_thr = thread_by_globalid(thr->ipc_from);
    /* BUG: Didn't check from_thr intend */
    if (from_thr->state == T_SEND_BLOCKED)
        do_ipc(from_thr, thr);
}

As pistachio ipc_tests Local destintation Id test case, if you provide a thread id that is not exist, you will still pass the test.

Which can see in kernel/ipc.c:275, it will setting intended_receiver, but not used in ipc_deliver

            /* No waiting, block myself */
            caller->state = T_SEND_BLOCKED;
            caller->utcb->intended_receiver = to_tid;

PoC for passing not passing test cases

void simple_ipc_t1_l {
    tag = L4_Receive_Timeout(ipc_t2, L4_TimePeriod(500 * 1000 * 1000));
    print_result("Local destination Id", L4_IpcSucceeded(tag));
    L4_Set_MsgTag(L4_Niltag);
    tag = L4_Send(ipc_t2);
}

void simple_ipc_t2_l {
    L4_ThreadId_t t;
    t.raw = 0xdeadbeaf;
    L4_Set_MsgTag(L4_Niltag);
    L4_Send(t);
    L4_Receive(ipc_t1);
}

Result

====================================================
 Copyright(C) 2013-2014 The F9 Microkernel Project  
====================================================
Git head: 6405ba6a269a6b604ac432d8a9870fd03d87d85a
Host: x86_64
Build: 2016-11-20T14:28:57+0800

Press '?' to print KDB menu

L4/Pistachio test suite starts

Simple IPC test (inter-as, only untyped words)
  Local destination Id:   OK