Fixed error with ipc transfer type checking.

Tested test0 mutex ipc successfully rejecting to occur when given
different micro-capabilities than the actual transfer type.
This commit is contained in:
Bahadir Balban
2009-11-09 22:50:21 +02:00
parent 8b12db741f
commit da8b0a90f3
2 changed files with 19 additions and 14 deletions

View File

@@ -90,7 +90,7 @@ int user_mutex_test(void)
} }
cap.type = CAP_TYPE_IPC | CAP_RTYPE_THREAD; cap.type = CAP_TYPE_IPC | CAP_RTYPE_THREAD;
cap.access = CAP_IPC_EXTENDED | CAP_IPC_SEND | CAP_IPC_RECV; cap.access = CAP_IPC_SHORT | CAP_IPC_SEND | CAP_IPC_RECV;
if ((err = cap_request_pager(&cap)) < 0) { if ((err = cap_request_pager(&cap)) < 0) {
printf("Ipc capability request failed. " printf("Ipc capability request failed. "
"err = %d\n", err); "err = %d\n", err);
@@ -131,7 +131,7 @@ int user_mutex_test(void)
} }
/* Sync with the parent */ /* Sync with the parent */
if ((err = l4_send_full(parent, L4_IPC_TAG_SYNC)) < 0) { if ((err = l4_send(parent, L4_IPC_TAG_SYNC)) < 0) {
printf("Error: l4_send() failed with %d\n", err); printf("Error: l4_send() failed with %d\n", err);
goto out_err; goto out_err;
} }
@@ -169,7 +169,7 @@ int user_mutex_test(void)
l4_thread_switch(0); l4_thread_switch(0);
} }
/* Sync with the child */ /* Sync with the child */
if ((err = l4_receive_full(child)) < 0) { if ((err = l4_receive(child)) < 0) {
printf("Error: l4_receive() failed with %d\n", err); printf("Error: l4_receive() failed with %d\n", err);
goto out_err; goto out_err;
} }

View File

@@ -16,6 +16,7 @@
#include <l4/api/exregs.h> #include <l4/api/exregs.h>
#include <l4/api/ipc.h> #include <l4/api/ipc.h>
#include INC_GLUE(message.h) #include INC_GLUE(message.h)
#include INC_GLUE(ipc.h)
void capability_init(struct capability *cap) void capability_init(struct capability *cap)
{ {
@@ -338,11 +339,15 @@ cap_match_capctrl(struct capability *cap, void *args_ptr)
struct sys_ipc_args { struct sys_ipc_args {
struct ktcb *task; struct ktcb *task;
unsigned int ipc_type; unsigned int ipc_type;
unsigned int flags; unsigned int xfer_type;
}; };
/* /*
* In an ipc, we could look for access bits, resource type and target id * Matches ipc direction, transfer type and target resource.
*
* Currently, receives are not checked as only sends have
* a solid target id. Receives can be from any thread with
* no particular target.
*/ */
struct capability * struct capability *
cap_match_ipc(struct capability *cap, void *args_ptr) cap_match_ipc(struct capability *cap, void *args_ptr)
@@ -351,20 +356,20 @@ cap_match_ipc(struct capability *cap, void *args_ptr)
struct ktcb *target = args->task; struct ktcb *target = args->task;
/* Check operation privileges */ /* Check operation privileges */
if (args->flags & IPC_FLAGS_SHORT) if (args->xfer_type == IPC_FLAGS_SHORT)
if (!(cap->access & CAP_IPC_SHORT)) if (!(cap->access & CAP_IPC_SHORT))
return 0; return 0;
if (args->flags & IPC_FLAGS_FULL) if (args->xfer_type == IPC_FLAGS_FULL)
if (!(cap->access & CAP_IPC_FULL)) if (!(cap->access & CAP_IPC_FULL))
return 0; return 0;
if (args->flags & IPC_FLAGS_EXTENDED) if (args->xfer_type == IPC_FLAGS_EXTENDED)
if (!(cap->access & CAP_IPC_EXTENDED)) if (!(cap->access & CAP_IPC_EXTENDED))
return 0; return 0;
/* Assume we have both send and receive unconditionally */ /* NOTE: We only check on send capability */
if (!((cap->access & CAP_IPC_SEND) && if (args->ipc_type & IPC_SEND)
(cap->access & CAP_IPC_RECV))) if (!(cap->access & CAP_IPC_SEND))
return 0; return 0;
/* /*
* We have a target thread, check if capability match * We have a target thread, check if capability match
@@ -711,7 +716,7 @@ int cap_ipc_check(l4id_t to, l4id_t from,
struct ktcb *target; struct ktcb *target;
struct sys_ipc_args args; struct sys_ipc_args args;
/* Receivers can get away from us (for now) */ /* TODO: Receivers can get away from us (for now) */
if (ipc_type != IPC_SEND && ipc_type != IPC_SENDRECV) if (ipc_type != IPC_SEND && ipc_type != IPC_SENDRECV)
return 0; return 0;
@@ -723,7 +728,7 @@ int cap_ipc_check(l4id_t to, l4id_t from,
return -ESRCH; return -ESRCH;
/* Set up other args */ /* Set up other args */
args.flags = flags; args.xfer_type = ipc_flags_get_type(flags);
args.ipc_type = ipc_type; args.ipc_type = ipc_type;
args.task = target; args.task = target;