A better implementation of right carried by messages. We now correctly create
the right in the destination process. This is a small step backward for functionnality: vi does not work anymore because our right checks cause some spurious errors, but this will be fixed later.
This commit is contained in:
parent
050140988d
commit
2c04ce0604
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mach_bootstrap.c,v 1.3 2002/12/17 18:42:55 manu Exp $ */
|
||||
/* $NetBSD: mach_bootstrap.c,v 1.4 2003/01/02 12:46:06 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_bootstrap.c,v 1.3 2002/12/17 18:42:55 manu Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_bootstrap.c,v 1.4 2003/01/02 12:46:06 manu Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@ -47,6 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: mach_bootstrap.c,v 1.3 2002/12/17 18:42:55 manu Exp
|
||||
|
||||
#include <compat/mach/mach_types.h>
|
||||
#include <compat/mach/mach_message.h>
|
||||
#include <compat/mach/mach_port.h>
|
||||
#include <compat/mach/mach_bootstrap.h>
|
||||
#include <compat/mach/mach_errno.h>
|
||||
|
||||
@ -56,9 +57,11 @@ mach_bootstrap_look_up(args)
|
||||
{
|
||||
mach_bootstrap_look_up_request_t *req = args->smsg;
|
||||
mach_bootstrap_look_up_reply_t *rep = args->rmsg;
|
||||
struct proc *p = args->p;
|
||||
size_t *msglen = args->rsize;
|
||||
const char service_name[] = "lookup\21"; /* XXX Why */
|
||||
int service_name_len;
|
||||
struct mach_right *mr;
|
||||
|
||||
/* The trailer is word aligned */
|
||||
service_name_len = (sizeof(service_name) + 1) & ~0x7UL;
|
||||
@ -66,6 +69,8 @@ mach_bootstrap_look_up(args)
|
||||
sizeof(rep->rep_bootstrap_port) + service_name_len *
|
||||
sizeof(rep->rep_trailer);
|
||||
|
||||
mr = mach_right_get(NULL, p, MACH_PORT_TYPE_DEAD_NAME, 0);
|
||||
|
||||
rep->rep_msgh.msgh_bits =
|
||||
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE) |
|
||||
MACH_MSGH_BITS_COMPLEX;
|
||||
@ -73,7 +78,7 @@ mach_bootstrap_look_up(args)
|
||||
rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port;
|
||||
rep->rep_msgh.msgh_id = req->req_msgh.msgh_id + 100;
|
||||
rep->rep_count = 1; /* XXX Why? */
|
||||
rep->rep_bootstrap_port = 0x21b; /* XXX Why? */
|
||||
rep->rep_bootstrap_port = mr->mr_name;
|
||||
strcpy((char *)&rep->rep_service_name, service_name);
|
||||
/* XXX This is the trailer. We should find something better */
|
||||
rep->rep_service_name[service_name_len + 7] = 8;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mach_exec.c,v 1.22 2003/01/01 15:18:25 manu Exp $ */
|
||||
/* $NetBSD: mach_exec.c,v 1.23 2003/01/02 12:46:06 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001-2003 The NetBSD Foundation, Inc.
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.22 2003/01/01 15:18:25 manu Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_exec.c,v 1.23 2003/01/02 12:46:06 manu Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -231,7 +231,13 @@ mach_e_proc_init(p, vmspace)
|
||||
med->med_p = 0;
|
||||
|
||||
LIST_INIT(&med->med_right);
|
||||
med->med_nextright = 0x60b;
|
||||
/*
|
||||
* For debugging purpose, it's convenient to have each process
|
||||
* using distinct port names, so we prefix the first port name
|
||||
* by the PID. Darwin does not do that, but we can remove it
|
||||
* when we want, it will not hurt.
|
||||
*/
|
||||
med->med_nextright = p->p_pid << 16;
|
||||
|
||||
med->med_kernel = mach_port_get();
|
||||
med->med_host = mach_port_get();
|
||||
@ -261,7 +267,7 @@ mach_e_proc_exit(p)
|
||||
|
||||
lockmgr(&mach_right_list_lock, LK_EXCLUSIVE, NULL);
|
||||
while ((mr = LIST_FIRST(&med->med_right)) != NULL)
|
||||
mach_right_put_exclocked(mr);
|
||||
mach_right_put_exclocked(mr, MACH_PORT_TYPE_ALL_RIGHTS);
|
||||
lockmgr(&mach_right_list_lock, LK_RELEASE, NULL);
|
||||
|
||||
if (--med->med_bootstrap->mp_refcount == 0)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: mach_message.c,v 1.18 2002/12/31 15:47:37 manu Exp $ */
|
||||
/* $NetBSD: mach_message.c,v 1.19 2003/01/02 12:46:06 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_message.c,v 1.18 2002/12/31 15:47:37 manu Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_message.c,v 1.19 2003/01/02 12:46:06 manu Exp $");
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
#include "opt_compat_mach.h" /* For COMPAT_MACH in <sys/ktrace.h> */
|
||||
@ -70,9 +70,6 @@ __KERNEL_RCSID(0, "$NetBSD: mach_message.c,v 1.18 2002/12/31 15:47:37 manu Exp $
|
||||
/* Mach message pool */
|
||||
static struct pool mach_message_pool;
|
||||
|
||||
static int mach_move_right(int, mach_msg_header_t *, struct mach_right *,
|
||||
struct mach_right *, struct proc *);
|
||||
|
||||
int
|
||||
mach_sys_msg_overwrite_trap(p, v, retval)
|
||||
struct proc *p;
|
||||
@ -92,10 +89,11 @@ mach_sys_msg_overwrite_trap(p, v, retval)
|
||||
} */ *uap = v;
|
||||
struct mach_emuldata *med;
|
||||
struct mach_port *mp;
|
||||
struct mach_right *mr;
|
||||
size_t send_size, rcv_size;
|
||||
int error = 0;
|
||||
|
||||
*retval = 0;
|
||||
|
||||
send_size = SCARG(uap, send_size);
|
||||
rcv_size = SCARG(uap, rcv_size);
|
||||
|
||||
@ -150,9 +148,8 @@ mach_sys_msg_overwrite_trap(p, v, retval)
|
||||
ln = sm->msgh_local_port;
|
||||
rn = sm->msgh_remote_port;
|
||||
|
||||
lr = mach_right_check_all(ln, MACH_PORT_TYPE_ALL_RIGHTS);
|
||||
|
||||
rr = mach_right_check_all(rn, MACH_PORT_TYPE_ALL_RIGHTS);
|
||||
lr = mach_right_check(ln, p, MACH_PORT_TYPE_ALL_RIGHTS);
|
||||
rr = mach_right_check(rn, p, MACH_PORT_TYPE_ALL_RIGHTS);
|
||||
if (rr == NULL) {
|
||||
#ifdef DEBUG_MACH
|
||||
printf("msg id %d: invalid dest\n", sm->msgh_id);
|
||||
@ -161,13 +158,6 @@ mach_sys_msg_overwrite_trap(p, v, retval)
|
||||
goto out1;
|
||||
}
|
||||
|
||||
bits = MACH_MSGH_LOCAL_BITS(sm->msgh_bits);
|
||||
if ((*retval = mach_move_right(bits, sm, lr, rr, p)) != 0)
|
||||
goto out1;
|
||||
|
||||
bits = MACH_MSGH_REMOTE_BITS(sm->msgh_bits);
|
||||
if ((*retval = mach_move_right(bits, sm, rr, rr, p)) != 0)
|
||||
goto out1;
|
||||
|
||||
/*
|
||||
* Check that the process has send a send right on
|
||||
@ -191,6 +181,15 @@ mach_sys_msg_overwrite_trap(p, v, retval)
|
||||
struct mach_trap_args args;
|
||||
mach_msg_header_t *rm;
|
||||
|
||||
/*
|
||||
* Check that the local port is valid, else
|
||||
* we will not be able to send the reply
|
||||
*/
|
||||
if (lr == NULL) {
|
||||
*retval = MACH_SEND_INVALID_REPLY;
|
||||
goto out3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for the function that will handle it,
|
||||
* using the message id.
|
||||
@ -248,7 +247,7 @@ mach_sys_msg_overwrite_trap(p, v, retval)
|
||||
* Queue the reply
|
||||
*/
|
||||
mp = lr->mr_port;
|
||||
(void)mach_message_get(rm, rcv_size, mp);
|
||||
(void)mach_message_get(rm, rcv_size, mp, NULL);
|
||||
#ifdef DEBUG_MACH_MSG
|
||||
printf("pid %d: message queued on port %p (%d) [%p]\n",
|
||||
p->p_pid, mp, rm->msgh_id,
|
||||
@ -265,28 +264,69 @@ out3: free(sm, M_EMULDATA);
|
||||
} else {
|
||||
/*
|
||||
* The message is not to be handled by the kernel.
|
||||
* First, swap local and remote ports.
|
||||
*/
|
||||
|
||||
sm->msgh_local_port = rn;
|
||||
sm->msgh_remote_port = ln;
|
||||
|
||||
/*
|
||||
* Queue the message in the remote port, and wakeup
|
||||
* any process that would be sleeping for it.
|
||||
* Queue the message in the remote port.
|
||||
*/
|
||||
mp = rr->mr_port;
|
||||
(void)mach_message_get(sm, send_size, mp);
|
||||
(void)mach_message_get(sm, send_size, mp, p);
|
||||
#ifdef DEBUG_MACH_MSG
|
||||
printf("pid %d: message queued on port %p (%d) [%p]\n",
|
||||
p->p_pid, mp, sm->msgh_id,
|
||||
mp->mp_recv->mr_sethead);
|
||||
#endif
|
||||
/*
|
||||
* Drop any right carried by the message
|
||||
*/
|
||||
bits = MACH_MSGH_LOCAL_BITS(sm->msgh_bits);
|
||||
switch (bits) {
|
||||
case MACH_MSG_TYPE_MOVE_SEND:
|
||||
rights = MACH_PORT_TYPE_SEND;
|
||||
break;
|
||||
case MACH_MSG_TYPE_MOVE_SEND_ONCE:
|
||||
rights = MACH_PORT_TYPE_SEND_ONCE;
|
||||
break;
|
||||
case MACH_MSG_TYPE_MOVE_RECEIVE:
|
||||
rights = MACH_PORT_TYPE_RECEIVE;
|
||||
break;
|
||||
case MACH_MSG_TYPE_MAKE_SEND:
|
||||
case MACH_MSG_TYPE_COPY_SEND:
|
||||
case MACH_MSG_TYPE_MAKE_SEND_ONCE:
|
||||
default:
|
||||
rights = 0;
|
||||
break;
|
||||
}
|
||||
if ((lr != NULL) && (rights != 0))
|
||||
mach_right_put(lr, rights);
|
||||
|
||||
bits = MACH_MSGH_REMOTE_BITS(sm->msgh_bits);
|
||||
switch (bits) {
|
||||
case MACH_MSG_TYPE_MOVE_SEND:
|
||||
rights = MACH_PORT_TYPE_SEND;
|
||||
break;
|
||||
case MACH_MSG_TYPE_MOVE_SEND_ONCE:
|
||||
rights = MACH_PORT_TYPE_SEND_ONCE;
|
||||
break;
|
||||
case MACH_MSG_TYPE_MOVE_RECEIVE:
|
||||
rights = MACH_PORT_TYPE_RECEIVE;
|
||||
break;
|
||||
case MACH_MSG_TYPE_MAKE_SEND:
|
||||
case MACH_MSG_TYPE_COPY_SEND:
|
||||
case MACH_MSG_TYPE_MAKE_SEND_ONCE:
|
||||
default:
|
||||
rights = 0;
|
||||
break;
|
||||
}
|
||||
if ((rr != NULL) && (rights != 0))
|
||||
mach_right_put(rr, rights);
|
||||
|
||||
|
||||
/*
|
||||
* Wakeup any process awaiting for this message
|
||||
*/
|
||||
wakeup(mp->mp_recv->mr_sethead);
|
||||
}
|
||||
|
||||
out1:
|
||||
if (error != 0) {
|
||||
if (*retval != 0) {
|
||||
free(sm, M_EMULDATA);
|
||||
return 0;
|
||||
}
|
||||
@ -298,9 +338,13 @@ out1:
|
||||
if (SCARG(uap, option) & MACH_RCV_MSG) {
|
||||
struct mach_message *mm;
|
||||
mach_port_t mn;
|
||||
mach_port_t tmp;
|
||||
struct mach_right *cmr;
|
||||
struct mach_right *mr;
|
||||
struct mach_right *nmr;
|
||||
mach_msg_header_t *urm;
|
||||
int timeout;
|
||||
int bits, nr, or;
|
||||
|
||||
/*
|
||||
* Find a buffer for the reply
|
||||
@ -495,6 +539,124 @@ out1:
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get rights carried by the message if it is not a
|
||||
* reply from the kernel.
|
||||
*/
|
||||
if (mm->mm_p != NULL) {
|
||||
#ifdef DEBUG_MACH
|
||||
printf("mach_msg: non kernel-reply message\n");
|
||||
#endif
|
||||
bits = MACH_MSGH_LOCAL_BITS(mm->mm_msg->msgh_bits);
|
||||
switch (bits) {
|
||||
case MACH_MSG_TYPE_MAKE_SEND:
|
||||
or = MACH_PORT_TYPE_RECEIVE;
|
||||
nr = MACH_PORT_TYPE_SEND;
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_COPY_SEND:
|
||||
case MACH_MSG_TYPE_MOVE_SEND:
|
||||
or = MACH_PORT_TYPE_SEND;
|
||||
nr = MACH_PORT_TYPE_SEND;
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_MAKE_SEND_ONCE:
|
||||
or = MACH_PORT_TYPE_RECEIVE;
|
||||
nr = MACH_PORT_TYPE_SEND_ONCE;
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_MOVE_SEND_ONCE:
|
||||
or = MACH_PORT_TYPE_SEND_ONCE;
|
||||
nr = MACH_PORT_TYPE_SEND_ONCE;
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_MOVE_RECEIVE:
|
||||
or = MACH_PORT_TYPE_RECEIVE;
|
||||
nr = MACH_PORT_TYPE_RECEIVE;
|
||||
break;
|
||||
|
||||
default:
|
||||
or = 0;
|
||||
nr = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
mr = NULL;
|
||||
if (nr != 0) {
|
||||
mn = mm->mm_msg->msgh_local_port;
|
||||
mr = mach_right_check(mn, mm->mm_p, or);
|
||||
}
|
||||
|
||||
if (mr != NULL) {
|
||||
nmr = mach_right_get(mr->mr_port, p, nr, 0);
|
||||
mm->mm_msg->msgh_local_port = nmr->mr_name;
|
||||
} else {
|
||||
mm->mm_msg->msgh_local_port = 0;
|
||||
}
|
||||
|
||||
bits = MACH_MSGH_REMOTE_BITS(mm->mm_msg->msgh_bits);
|
||||
switch (bits) {
|
||||
case MACH_MSG_TYPE_MAKE_SEND:
|
||||
or = MACH_PORT_TYPE_RECEIVE;
|
||||
nr = MACH_PORT_TYPE_SEND;
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_COPY_SEND:
|
||||
case MACH_MSG_TYPE_MOVE_SEND:
|
||||
or = MACH_PORT_TYPE_SEND;
|
||||
nr = MACH_PORT_TYPE_SEND;
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_MAKE_SEND_ONCE:
|
||||
or = MACH_PORT_TYPE_RECEIVE;
|
||||
nr = MACH_PORT_TYPE_SEND_ONCE;
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_MOVE_SEND_ONCE:
|
||||
or = MACH_PORT_TYPE_SEND_ONCE;
|
||||
nr = MACH_PORT_TYPE_SEND_ONCE;
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_MOVE_RECEIVE:
|
||||
or = MACH_PORT_TYPE_RECEIVE;
|
||||
nr = MACH_PORT_TYPE_RECEIVE;
|
||||
break;
|
||||
|
||||
default:
|
||||
or = 0;
|
||||
nr = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
mr = NULL;
|
||||
if (nr != 0) {
|
||||
mn = mm->mm_msg->msgh_remote_port;
|
||||
mr = mach_right_check(mn, mm->mm_p, or);
|
||||
}
|
||||
|
||||
if (mr != NULL) {
|
||||
nmr = mach_right_get(mr->mr_port, p, nr, 0);
|
||||
mm->mm_msg->msgh_remote_port = nmr->mr_name;
|
||||
} else {
|
||||
mm->mm_msg->msgh_remote_port = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* swap local and remote ports, and
|
||||
* corresponding bits as well.
|
||||
*/
|
||||
bits = (bits & 0xffff0000) |
|
||||
((bits & 0xff00) >> 8) |
|
||||
((bits & 0x00ff) << 8);
|
||||
tmp = mm->mm_msg->msgh_remote_port;
|
||||
mm->mm_msg->msgh_remote_port =
|
||||
mm->mm_msg->msgh_local_port;
|
||||
mm->mm_msg->msgh_local_port = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the message to userland
|
||||
*/
|
||||
if ((error = copyout(mm->mm_msg, urm, mm->mm_size)) != 0) {
|
||||
*retval = MACH_RCV_INVALID_DATA;
|
||||
goto unlock;
|
||||
@ -553,10 +715,11 @@ mach_message_init(void)
|
||||
}
|
||||
|
||||
struct mach_message *
|
||||
mach_message_get(msgh, size, mp)
|
||||
mach_message_get(msgh, size, mp, p)
|
||||
mach_msg_header_t *msgh;
|
||||
size_t size;
|
||||
struct mach_port *mp;
|
||||
struct proc *p;
|
||||
{
|
||||
struct mach_message *mm;
|
||||
|
||||
@ -565,6 +728,7 @@ mach_message_get(msgh, size, mp)
|
||||
mm->mm_msg = msgh;
|
||||
mm->mm_size = size;
|
||||
mm->mm_port = mp;
|
||||
mm->mm_p = p;
|
||||
|
||||
lockmgr(&mp->mp_msglock, LK_EXCLUSIVE, NULL);
|
||||
TAILQ_INSERT_TAIL(&mp->mp_msglist, mm, mm_list);
|
||||
@ -620,137 +784,6 @@ mach_message_put_exclocked(mm)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move port according to what was specified in the message.
|
||||
*/
|
||||
static int
|
||||
mach_move_right(bits, msgh, mr, tr, p)
|
||||
int bits;
|
||||
mach_msg_header_t *msgh;
|
||||
struct mach_right *mr;
|
||||
struct mach_right *tr;
|
||||
struct proc *p;
|
||||
{
|
||||
struct mach_right *nmr;
|
||||
struct mach_port *mp;
|
||||
mach_port_t mn;
|
||||
struct proc *tp;
|
||||
int rights;
|
||||
|
||||
if (mr == NULL) {
|
||||
#ifdef DEBUG_MACH_RIGHT
|
||||
printf("mach_move_right: mr = NULL\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((tr->mr_port == NULL) ||
|
||||
(tr->mr_port->mp_recv == NULL) ||
|
||||
(tr->mr_port->mp_recv->mr_p == NULL)) {
|
||||
#ifdef DEBUG_MACH_RIGHT
|
||||
printf("mach_move_right: cannot find target proc, "
|
||||
"msg id %d, tr = %p, tr->mr_port = %p ",
|
||||
msgh->msgh_id, tr, tr->mr_port);
|
||||
|
||||
if (tr->mr_port == NULL)
|
||||
goto cr;
|
||||
printf("tr->mr_port->mp_recv = %p ",
|
||||
tr->mr_port->mp_recv);
|
||||
|
||||
if (tr->mr_port->mp_recv == NULL)
|
||||
goto cr;
|
||||
printf("tr->mr_port->mp_recv->mr_p = %p ",
|
||||
tr->mr_port->mp_recv->mr_p);
|
||||
cr:
|
||||
printf("\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
tp = tr->mr_port->mp_recv->mr_p;
|
||||
#ifdef DEBUG_MACH_RIGHT
|
||||
printf("mach_move_right: msg id %d, local pid = %d, target pid = %d\n",
|
||||
msgh->msgh_id, p->p_pid, tp->p_pid);
|
||||
#endif
|
||||
|
||||
switch (bits) {
|
||||
case MACH_MSG_TYPE_MAKE_SEND_ONCE:
|
||||
case MACH_MSG_TYPE_MAKE_SEND:
|
||||
case MACH_MSG_TYPE_MOVE_RECEIVE:
|
||||
rights = MACH_PORT_TYPE_RECEIVE;
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_COPY_SEND:
|
||||
rights = (MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_DEAD_NAME);
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_MOVE_SEND:
|
||||
rights = (MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_DEAD_NAME);
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_MOVE_SEND_ONCE:
|
||||
rights = (MACH_PORT_TYPE_SEND_ONCE | MACH_PORT_TYPE_DEAD_NAME);
|
||||
break;
|
||||
|
||||
default:
|
||||
return MACH_SEND_INVALID_HEADER;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mr->mr_type & rights) == 0) {
|
||||
#ifdef DEBUG_MACH_RIGHT
|
||||
printf("mach_move_right: right %x missing for %p in pid %d\n",
|
||||
rights, mr, p->p_pid);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
mp = mr->mr_port;
|
||||
mn = mr->mr_name;
|
||||
|
||||
switch (bits) {
|
||||
case MACH_MSG_TYPE_MAKE_SEND:
|
||||
case MACH_MSG_TYPE_COPY_SEND:
|
||||
nmr = mach_right_get(mp, tp, MACH_PORT_TYPE_SEND, mn);
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_MOVE_SEND:
|
||||
nmr = mach_right_get(mp, tp, MACH_PORT_TYPE_SEND, mn);
|
||||
/* mach_right_put(mr); */
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_MAKE_SEND_ONCE:
|
||||
nmr = mach_right_get(mp, tp, MACH_PORT_TYPE_SEND_ONCE, mn);
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_MOVE_SEND_ONCE:
|
||||
nmr = mach_right_get(mp, tp, MACH_PORT_TYPE_SEND_ONCE, mn);
|
||||
/* mach_right_put(mr); */
|
||||
break;
|
||||
|
||||
case MACH_MSG_TYPE_MOVE_RECEIVE:
|
||||
nmr = mach_right_get(mp, tp, MACH_PORT_TYPE_RECEIVE, mn);
|
||||
mach_right_put(mr);
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef DEBUG_MACH_RIGHT
|
||||
printf("mach_move_right, invalid bits = %d\n", bits);
|
||||
#endif
|
||||
return MACH_SEND_INVALID_HEADER;
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG_MACH_RIGHT
|
||||
printf("mach_move_right finished, nmr = %p(%x)", nmr, nmr->mr_type);
|
||||
if (nmr->mr_port != NULL)
|
||||
printf("=>%p", nmr->mr_port);
|
||||
if (nmr->mr_port->mp_recv != NULL)
|
||||
printf("[%p]", nmr->mr_port->mp_recv->mr_sethead);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MACH
|
||||
void
|
||||
mach_debug_message(void)
|
||||
|
@ -1,11 +1,11 @@
|
||||
/* $NetBSD: mach_message.h,v 1.12 2002/12/30 18:44:33 manu Exp $ */
|
||||
/* $NetBSD: mach_message.h,v 1.13 2003/01/02 12:46:07 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 2001-2003 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
* by Christos Zoulas and Emmanuel Dreyfus.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -223,11 +223,12 @@ struct mach_message {
|
||||
TAILQ_ENTRY(mach_message) mm_list;
|
||||
/* List of pending messages */
|
||||
struct mach_port *mm_port; /* The port on which msg is queued */
|
||||
struct proc *mm_p; /* The process that sent it */
|
||||
};
|
||||
|
||||
void mach_message_init(void);
|
||||
struct mach_message *mach_message_get(mach_msg_header_t *,
|
||||
size_t, struct mach_port *);
|
||||
size_t, struct mach_port *, struct proc *);
|
||||
void mach_message_put(struct mach_message *);
|
||||
void mach_message_put_shlocked(struct mach_message *);
|
||||
void mach_message_put_exclocked(struct mach_message *);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: mach_port.c,v 1.28 2002/12/31 15:47:38 manu Exp $ */
|
||||
/* $NetBSD: mach_port.c,v 1.29 2003/01/02 12:46:07 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -39,7 +39,7 @@
|
||||
#include "opt_compat_darwin.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_port.c,v 1.28 2002/12/31 15:47:38 manu Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_port.c,v 1.29 2003/01/02 12:46:07 manu Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
@ -155,7 +155,7 @@ mach_port_deallocate(args)
|
||||
if ((mr = mach_right_check(mn, p, MACH_PORT_TYPE_PORT_RIGHTS)) == NULL)
|
||||
return mach_msg_error(args, EINVAL);
|
||||
|
||||
mach_right_put(mr);
|
||||
mach_right_put(mr, MACH_PORT_TYPE_ALL_RIGHTS);
|
||||
|
||||
rep->rep_msgh.msgh_bits =
|
||||
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
|
||||
@ -280,7 +280,7 @@ mach_port_type(args)
|
||||
struct mach_right *mr;
|
||||
|
||||
mn = req->req_name;
|
||||
if ((mr = mach_right_check(mn, p, MACH_PORT_TYPE_PORT_RIGHTS)) == NULL)
|
||||
if ((mr = mach_right_check(mn, p, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
|
||||
return mach_msg_error(args, EPERM);
|
||||
|
||||
rep->rep_msgh.msgh_bits =
|
||||
@ -455,6 +455,10 @@ mach_right_get(mp, p, type, hint)
|
||||
struct mach_emuldata *med;
|
||||
int rights;
|
||||
|
||||
#ifdef DEBUG_MACH
|
||||
if (type == 0)
|
||||
uprintf("mach_right_get: right = 0\n");
|
||||
#endif
|
||||
med = (struct mach_emuldata *)p->p_emuldata;
|
||||
|
||||
/* Send and receive right must return an existing right */
|
||||
@ -487,10 +491,10 @@ mach_right_get(mp, p, type, hint)
|
||||
if (mp != NULL)
|
||||
mp->mp_refcount++;
|
||||
|
||||
/* Insert the right in one of the process right lists */
|
||||
/* Insert the right in the right lists */
|
||||
if (type & MACH_PORT_TYPE_ALL_RIGHTS) {
|
||||
mr->mr_name = mach_right_newname(p, hint);
|
||||
lockmgr(&mach_right_list_lock, LK_EXCLUSIVE, NULL);
|
||||
mr->mr_name = mach_right_newname(p, hint);
|
||||
LIST_INSERT_HEAD(&med->med_right, mr, mr_list);
|
||||
LIST_INSERT_HEAD(&mach_right_list, mr, mr_listall);
|
||||
lockmgr(&mach_right_list_lock, LK_RELEASE, NULL);
|
||||
@ -503,56 +507,72 @@ rcvck:
|
||||
* register the new right.
|
||||
*/
|
||||
if (mr->mr_port->mp_recv != NULL)
|
||||
mach_right_put(mr->mr_port->mp_recv);
|
||||
mach_right_put(mr->mr_port->mp_recv,
|
||||
MACH_PORT_TYPE_RECEIVE);
|
||||
mr->mr_port->mp_recv = mr;
|
||||
}
|
||||
return mr;
|
||||
}
|
||||
|
||||
void
|
||||
mach_right_put(mr)
|
||||
mach_right_put(mr, right)
|
||||
struct mach_right *mr;
|
||||
int right;
|
||||
{
|
||||
lockmgr(&mach_right_list_lock, LK_EXCLUSIVE, NULL);
|
||||
mach_right_put_exclocked(mr);
|
||||
mach_right_put_exclocked(mr, right);
|
||||
lockmgr(&mach_right_list_lock, LK_RELEASE, NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
mach_right_put_shlocked(mr)
|
||||
mach_right_put_shlocked(mr, right)
|
||||
struct mach_right *mr;
|
||||
int right;
|
||||
{
|
||||
lockmgr(&mach_right_list_lock, LK_UPGRADE, NULL);
|
||||
mach_right_put_exclocked(mr);
|
||||
mach_right_put_exclocked(mr, right);
|
||||
lockmgr(&mach_right_list_lock, LK_DOWNGRADE, NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
mach_right_put_exclocked(mr)
|
||||
mach_right_put_exclocked(mr, right)
|
||||
struct mach_right *mr;
|
||||
int right;
|
||||
{
|
||||
struct mach_right *cmr;
|
||||
|
||||
#ifdef DEBUG_MACH
|
||||
if ((mr->mr_type & right) == 0)
|
||||
printf("mach_right_put: droping nonexistant right %x on %x\n",
|
||||
right, mr->mr_name);
|
||||
#endif
|
||||
|
||||
mr->mr_type &= ~right;
|
||||
mr->mr_refcount--;
|
||||
if (mr->mr_refcount != 0)
|
||||
if (mr->mr_refcount != 0) {
|
||||
#ifdef DEBUG_MACH
|
||||
printf("tried to release right %x, but refcount = %d\n",
|
||||
mr->mr_name, mr->mr_refcount);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MACH_RIGHT
|
||||
printf("mach_right_put: put right %p, port %p\n", mr, mr->mr_port);
|
||||
#endif
|
||||
if (mr->mr_type & MACH_PORT_TYPE_PORT_SET) {
|
||||
while((cmr = LIST_FIRST(&mr->mr_set)) != NULL)
|
||||
mach_right_put_exclocked(cmr);
|
||||
while((cmr = LIST_FIRST(&mr->mr_set)) != NULL) {
|
||||
LIST_REMOVE(cmr, mr_setlist);
|
||||
cmr->mr_sethead = cmr;
|
||||
}
|
||||
}
|
||||
|
||||
if (mr->mr_type & MACH_PORT_TYPE_ALL_RIGHTS) {
|
||||
LIST_REMOVE(mr, mr_list);
|
||||
LIST_REMOVE(mr, mr_listall);
|
||||
}
|
||||
LIST_REMOVE(mr, mr_list);
|
||||
LIST_REMOVE(mr, mr_listall);
|
||||
|
||||
if (mr->mr_port != NULL) {
|
||||
mr->mr_port->mp_refcount--;
|
||||
@ -576,6 +596,9 @@ mach_right_check(mn, p, type)
|
||||
struct mach_right *cmr;
|
||||
struct mach_emuldata *med;
|
||||
|
||||
if ((mn == 0) || (mn == -1) || (p == NULL))
|
||||
return NULL;
|
||||
|
||||
med = (struct mach_emuldata *)p->p_emuldata;
|
||||
|
||||
lockmgr(&mach_right_list_lock, LK_SHARED, NULL);
|
||||
@ -600,30 +623,9 @@ mach_right_check(mn, p, type)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check for a right in any process
|
||||
*/
|
||||
struct mach_right *
|
||||
mach_right_check_all(mn, type)
|
||||
mach_port_t mn;
|
||||
int type;
|
||||
{
|
||||
struct mach_right *cmr;
|
||||
|
||||
lockmgr(&mach_right_list_lock, LK_SHARED, NULL);
|
||||
|
||||
LIST_FOREACH(cmr, &mach_right_list, mr_listall)
|
||||
if ((cmr->mr_name == mn) && (cmr->mr_type & type))
|
||||
break;
|
||||
|
||||
lockmgr(&mach_right_list_lock, LK_RELEASE, NULL);
|
||||
|
||||
return cmr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an usnused port name in a given process.
|
||||
* Right list should be locked.
|
||||
* Right lists should be locked.
|
||||
*/
|
||||
mach_port_t
|
||||
mach_right_newname(p, hint)
|
||||
@ -648,11 +650,7 @@ mach_right_newname(p, hint)
|
||||
hint++;
|
||||
}
|
||||
|
||||
if (newname != -1)
|
||||
med->med_nextright = hint;
|
||||
else
|
||||
uprintf("pid %d: cannot allocate new mach port names\n",
|
||||
p->p_pid);
|
||||
med->med_nextright = hint;
|
||||
|
||||
return newname;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $NetBSD: mach_port.h,v 1.14 2002/12/31 15:47:38 manu Exp $ */
|
||||
/* $NetBSD: mach_port.h,v 1.15 2003/01/02 12:46:07 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
@ -236,11 +236,10 @@ struct mach_right {
|
||||
mach_port_t mach_right_newname(struct proc *, mach_port_t);
|
||||
struct mach_right *mach_right_get(struct mach_port *,
|
||||
struct proc *, int, mach_port_t);
|
||||
void mach_right_put(struct mach_right *);
|
||||
void mach_right_put_shlocked(struct mach_right *);
|
||||
void mach_right_put_exclocked(struct mach_right *);
|
||||
void mach_right_put(struct mach_right *, int);
|
||||
void mach_right_put_shlocked(struct mach_right *, int);
|
||||
void mach_right_put_exclocked(struct mach_right *, int);
|
||||
struct mach_right *mach_right_check(mach_port_t, struct proc *, int);
|
||||
struct mach_right *mach_right_check_all(mach_port_t, int);
|
||||
|
||||
/* In-kernel Mach port description */
|
||||
struct mach_port {
|
||||
|
Loading…
Reference in New Issue
Block a user