Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/compat/mach Better error reporting in mach_msg_trap: thi...
details: https://anonhg.NetBSD.org/src/rev/e473d8e7a908
branches: trunk
changeset: 540799:e473d8e7a908
user: manu <manu%NetBSD.org@localhost>
date: Tue Dec 24 15:54:26 2002 +0000
description:
Better error reporting in mach_msg_trap: this system call does not use the
standard error codes.
diffstat:
sys/compat/mach/mach_errno.c | 6 +-
sys/compat/mach/mach_message.c | 135 +++++++++++++++++++++++++++++-----------
sys/compat/mach/mach_message.h | 48 ++++++++++++++-
3 files changed, 146 insertions(+), 43 deletions(-)
diffs (truncated from 371 to 300 lines):
diff -r 42387bfd5ced -r e473d8e7a908 sys/compat/mach/mach_errno.c
--- a/sys/compat/mach/mach_errno.c Tue Dec 24 15:53:46 2002 +0000
+++ b/sys/compat/mach/mach_errno.c Tue Dec 24 15:54:26 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mach_errno.c,v 1.9 2002/12/17 18:42:56 manu Exp $ */
+/* $NetBSD: mach_errno.c,v 1.10 2002/12/24 15:54:26 manu Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mach_errno.c,v 1.9 2002/12/17 18:42:56 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mach_errno.c,v 1.10 2002/12/24 15:54:26 manu Exp $");
#include <sys/types.h>
#include <sys/systm.h>
@@ -157,5 +157,5 @@
*msglen = sizeof(*rep);
- return error;
+ return 0;
}
diff -r 42387bfd5ced -r e473d8e7a908 sys/compat/mach/mach_message.c
--- a/sys/compat/mach/mach_message.c Tue Dec 24 15:53:46 2002 +0000
+++ b/sys/compat/mach/mach_message.c Tue Dec 24 15:54:26 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mach_message.c,v 1.7 2002/12/22 21:51:56 manu Exp $ */
+/* $NetBSD: mach_message.c,v 1.8 2002/12/24 15:54:26 manu Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mach_message.c,v 1.7 2002/12/22 21:51:56 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mach_message.c,v 1.8 2002/12/24 15:54:26 manu Exp $");
#include "opt_ktrace.h"
#include "opt_compat_mach.h" /* For COMPAT_MACH in <sys/ktrace.h> */
@@ -97,11 +97,10 @@
int timeout;
/*
- * Catch unhandled options
+ * If neither send nor recieve, do nothing.
*/
- if (SCARG(uap, option) & ~(MACH_SEND_MSG | MACH_RCV_MSG))
- uprintf("mach_msg: unhandled option 0x%x\n",
- SCARG(uap, option));
+ if (SCARG(uap, option) & ~(MACH_SEND_MSG | MACH_RCV_MSG))
+ return 0;
/*
* XXX Sanity check on the message size. This is not an accurate
@@ -111,24 +110,31 @@
*/
send_size = SCARG(uap, send_size);
rcv_size = SCARG(uap, rcv_size);
- if ((send_size > MACH_MAX_MSG_LEN) || (rcv_size > MACH_MAX_MSG_LEN))
- return E2BIG;
+ if ((send_size > MACH_MAX_MSG_LEN) || (rcv_size > MACH_MAX_MSG_LEN)) {
+ *retval = MACH_SEND_TOO_LARGE;
+ return 0;
+ }
/*
* Two options: receive or send. If both are
- * set, we must send, and then receive.
+ * set, we must send, and then receive. If
+ * send fail, then we skip recieve.
*/
if (SCARG(uap, option) & MACH_SEND_MSG) {
- if (SCARG(uap, msg) == NULL)
- return EINVAL;
+ if (SCARG(uap, msg) == NULL) {
+ *retval = MACH_SEND_INVALID_DATA;
+ return 0;
+ }
/*
* Allocate memory for the message and its reply,
* and copy the whole message in the kernel.
*/
sm = malloc(send_size, M_EMULDATA, M_WAITOK);
- if ((error = copyin(SCARG(uap, msg), sm, send_size)) != 0)
+ if ((error = copyin(SCARG(uap, msg), sm, send_size)) != 0) {
+ *retval = MACH_SEND_INVALID_DATA;
goto out1;
+ }
#ifdef KTRACE
/* Dump the Mach message */
@@ -142,7 +148,7 @@
*/
if (mach_right_check((struct mach_right *)sm->msgh_remote_port,
p, MACH_PORT_TYPE_SEND | MACH_PORT_TYPE_SEND_ONCE) == 0) {
- error = EPERM;
+ *retval = MACH_SEND_INVALID_RIGHT;
goto out1;
}
@@ -169,7 +175,7 @@
if (map->map_handler == NULL) {
uprintf("No mach trap handler for id = %d\n",
sm->msgh_id);
- error = EINVAL;
+ *retval = MACH_SEND_INVALID_DEST;
goto out3;
}
#ifdef KTRACE
@@ -193,14 +199,15 @@
args.smsg = sm;
args.rmsg = rm;
args.rsize = &rcv_size;
- if ((error = (*map->map_handler)(&args)) != 0)
+ if ((*retval = (*map->map_handler)(&args)) != 0)
goto out2;
/*
* Catch potential bug in the handler
*/
if (rcv_size > SCARG(uap, rcv_size)) {
- uprintf("mach_msg: reply too big\n");
+ uprintf("mach_msg: reply too big in %s\n",
+ map->map_name);
rcv_size = SCARG(uap, rcv_size);
}
@@ -213,8 +220,10 @@
urm = SCARG(uap, rcv_msg);
else
urm = SCARG(uap, msg);
- if ((error = copyout(rm, urm, rcv_size)) != 0)
+ if ((error = copyout(rm, urm, rcv_size)) != 0) {
+ *retval = MACH_RCV_INVALID_DATA;
goto out2;
+ }
#ifdef KTRACE
/* Dump the Mach message */
if (KTRPOINT(p, KTR_MMSG))
@@ -224,7 +233,7 @@
out2: free(rm, M_EMULDATA);
out3: free(sm, M_EMULDATA);
- return error;
+ return 0;
} else {
@@ -252,7 +261,7 @@
out1:
if (error != 0) {
free(sm, M_EMULDATA);
- return error;
+ return 0;
}
}
@@ -267,8 +276,10 @@
urm = SCARG(uap, rcv_msg);
else if (SCARG(uap, msg) != NULL)
urm = SCARG(uap, msg);
- else
- return EINVAL;
+ else {
+ *retval = MACH_RCV_INVALID_DATA;
+ return 0;
+ }
if (SCARG(uap, option) & MACH_RCV_TIMEOUT)
timeout = SCARG(uap, timeout) * hz / 1000;
@@ -285,8 +296,10 @@
* Is it a port set?
*/
if ((mach_right_check(mr, p,
- MACH_PORT_TYPE_PORT_SET)) == 0)
- return EPERM;
+ MACH_PORT_TYPE_PORT_SET)) == 0) {
+ *retval = MACH_RCV_INVALID_NAME;
+ return 0;
+ }
/*
* This is a port set. For each port in the
@@ -295,8 +308,10 @@
*/
LIST_FOREACH(cmr, &mr->mr_set, mr_setlist) {
if ((mach_right_check(cmr, p,
- MACH_PORT_TYPE_RECEIVE)) == 0)
- return EPERM;
+ MACH_PORT_TYPE_RECEIVE)) == 0) {
+ *retval = MACH_RCV_INVALID_NAME;
+ return 0;
+ }
mp = cmr->mr_port;
#ifdef DEBUG_MACH
@@ -315,17 +330,35 @@
*/
if (cmr == NULL) {
error = tsleep(mr, PZERO, "mach_msg", timeout);
- if ((error == ERESTART) || (error == EINTR))
- return EINTR;
+ if ((error == ERESTART) || (error == EINTR)) {
+ *retval = MACH_RCV_INTERRUPTED;
+ return 0;
+ }
+ /*
+ * Check we did not loose the receive right
+ * while we were sleeping.
+ */
+ if ((mach_right_check(mr, p,
+ MACH_PORT_TYPE_PORT_SET)) == 0) {
+ *retval = MACH_RCV_PORT_DIED;
+ return 0;
+ }
+
+ /*
+ * Is there any pending message for
+ * a port in the port set?
+ */
LIST_FOREACH(cmr, &mr->mr_set, mr_setlist) {
mp = cmr->mr_port;
if (mp->mp_count != 0)
break;
}
- if (cmr == NULL)
- return ETIMEDOUT;
+ if (cmr == NULL) {
+ *retval = MACH_RCV_TIMED_OUT;
+ return 0;
+ }
}
/*
@@ -347,12 +380,26 @@
"port/right\n");
#endif
if (mp->mp_count == 0) {
- error = tsleep(mp->mp_recv, PZERO,
- "mach_msg", timeout);
- if ((error == ERESTART) || (error == EINTR))
- return EINTR;
- if (mp->mp_count == 0)
- return ETIMEDOUT;
+ error = tsleep(mr, PZERO, "mach_msg", timeout);
+ if ((error == ERESTART) || (error == EINTR)) {
+ *retval = MACH_RCV_INTERRUPTED;
+ return 0;
+ }
+
+ /*
+ * Check we did not loose the receive right
+ * while we were sleeping.
+ */
+ if ((mach_right_check(mr, p,
+ MACH_PORT_TYPE_RECEIVE)) == 0) {
+ *retval = MACH_RCV_PORT_DIED;
+ return 0;
+ }
+
+ if (mp->mp_count == 0) {
+ *retval = MACH_RCV_TIMED_OUT;
+ return 0;
+ }
}
}
@@ -366,13 +413,22 @@
mm = TAILQ_FIRST(&mp->mp_msglist);
if (mm->mm_size > rcv_size) {
- lockmgr(&mp->mp_msglock, LK_RELEASE, NULL);
- return ENOBUFS;
+ /*
+ * If MACH_RCV_LARGE was not set, destroy the
+ * message. If it was set, just notice that
+ * the message is too big.
+ */
+ if ((SCARG(uap, option) & MACH_RCV_LARGE) == 0) {
+ free(mm->mm_msg, M_EMULDATA);
+ mach_message_put_shlocked(mm);
+ }
+ *retval = MACH_RCV_TOO_LARGE;
+ goto unlock;
}
if ((error = copyout(mm->mm_msg, urm, mm->mm_size)) != 0) {
- lockmgr(&mp->mp_msglock, LK_RELEASE, NULL);
- return error;
+ *retval = MACH_RCV_INVALID_DATA;
+ goto unlock;
}
#ifdef KTRACE
Home |
Main Index |
Thread Index |
Old Index