From e0492d672f76a3a90ff781dfc9f13c41ceebe855 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Mon, 11 Feb 2008 11:11:17 +0000 Subject: [PATCH] Kernel inspects and sets sender id instead of userspace. Modified ipc handling so that from now on the kernel inspects and sets the sender id if the receiver is receiving from L4_ANYTHREAD. This posed a security problem since the receiver could not trust the sender for sender information. --- include/l4/api/kip.h | 1 + include/l4/glue/arm/utcb.h | 4 ++++ src/api/ipc.c | 15 +++++++++++++-- src/arch/arm/exception.c | 9 --------- tasks/libl4/include/l4lib/arch-arm/syslib.h | 8 +------- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/include/l4/api/kip.h b/include/l4/api/kip.h index 60c31e8..7348a34 100644 --- a/include/l4/api/kip.h +++ b/include/l4/api/kip.h @@ -95,4 +95,5 @@ struct kip { extern struct kip kip; #endif /* __KERNEL__ */ + #endif /* __KIP_H__ */ diff --git a/include/l4/glue/arm/utcb.h b/include/l4/glue/arm/utcb.h index 8b0fad5..97f5285 100644 --- a/include/l4/glue/arm/utcb.h +++ b/include/l4/glue/arm/utcb.h @@ -8,6 +8,10 @@ #define MR_TOTAL 6 +#define MR_TAG 0 +#define MR_SENDER 1 +#define MR_UNUSED_START 2 + /* Compact utcb for now! 8-) */ struct utcb { u32 mr[MR_TOTAL]; diff --git a/src/api/ipc.c b/src/api/ipc.c index 2fec995..aa6389e 100644 --- a/src/api/ipc.c +++ b/src/api/ipc.c @@ -12,6 +12,7 @@ #include #include #include INC_API(syscall.h) +#include INC_GLUE(utcb.h) enum IPC_TYPE { IPC_INVALID = 0, @@ -22,8 +23,12 @@ enum IPC_TYPE { /* * Copies message registers from one ktcb stack to another. During the return - * from system call, the registers are popped from the stack. On fast ipc path - * they shouldn't even be pushed to the stack to avoid extra copying. + * from system call, the registers are popped from the stack. In the future + * this should be optimised so that they shouldn't even be pushed to the stack + * + * This also copies the sender into MR0 in case the receiver receives from + * L4_ANYTHREAD. This is done for security since the receiver cannot trust + * the sender info provided by the sender task. */ int ipc_msg_copy(struct ktcb *to, struct ktcb *from) { @@ -35,6 +40,10 @@ int ipc_msg_copy(struct ktcb *to, struct ktcb *from) */ memcpy(mr0_dst, mr0_src, MR_TOTAL * sizeof(unsigned int)); + /* Save the sender id in case of ANYTHREAD receiver */ + if (to->senderid == L4_ANYTHREAD) + mr0_dst[MR_SENDER] = from->tid; + return 0; } @@ -241,6 +250,8 @@ int sys_ipc(struct syscall_args *regs) ret = -EINVAL; goto error; } + + /* Cannot send to self, or receive from self */ if (from == current->tid || to == current->tid) { ret = -EINVAL; goto error; diff --git a/src/arch/arm/exception.c b/src/arch/arm/exception.c index 31322db..01aa427 100644 --- a/src/arch/arm/exception.c +++ b/src/arch/arm/exception.c @@ -16,15 +16,6 @@ #include INC_GLUE(utcb.h) #include INC_SUBARCH(mm.h) -/* - * NOTE: These are defined in libl4 headers for userspace. Syslib uses - * these as conventional mr offsets to store ipc-related data commonly needed - * for all ipc parties. - */ -#define MR_TAG 0 -#define MR_SENDER 1 -#define MR_UNUSED_START 2 - /* Send data fault ipc to the faulty task's pager */ void fault_ipc_to_pager(u32 faulty_pc, u32 fsr, u32 far) { diff --git a/tasks/libl4/include/l4lib/arch-arm/syslib.h b/tasks/libl4/include/l4lib/arch-arm/syslib.h index 4de46f5..bbfe77f 100644 --- a/tasks/libl4/include/l4lib/arch-arm/syslib.h +++ b/tasks/libl4/include/l4lib/arch-arm/syslib.h @@ -37,11 +37,6 @@ static inline l4id_t l4_get_sender(void) return (l4id_t)read_mr(MR_SENDER); } -static inline void l4_set_sender(l4id_t id) -{ - write_mr(MR_SENDER, (unsigned int)id); -} - static inline unsigned int l4_get_tag(void) { return read_mr(MR_TAG); @@ -63,7 +58,6 @@ static inline l4id_t self_tid(void) static inline int l4_send(l4id_t to, unsigned int tag) { l4_set_tag(tag); - l4_set_sender(self_tid()); return l4_ipc(to, L4_NILTHREAD); } @@ -72,7 +66,7 @@ static inline int l4_sendrecv(l4id_t to, l4id_t from, unsigned int tag) { BUG_ON(to == L4_NILTHREAD || from == L4_NILTHREAD); l4_set_tag(tag); - l4_set_sender(self_tid()); + return l4_ipc(to, from); }