1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
commit 98e07c497c9d866c0342696918a020b3f0303405
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Sun Jul 14 18:14:35 2024 +0200
server: Fix bogus port deallocation on server error
For inlined port arrays, WriteExtractArg compacts them from a
mach_port_name_inlined_t array to a mach_port_t array, reusing the
memory area. But when the server returns an error, the caller will
destroy the message, and thus expects the original inlined port arrays
available.
diff --git a/server.c b/server.c
index 81147b5..e02e1e7 100644
--- a/server.c
+++ b/server.c
@@ -788,6 +788,27 @@ WriteExtractArg(FILE *file, const argument_t *arg)
}
}
+static void
+WriteRestoreArg(FILE *file, const argument_t *arg)
+{
+ if (akCheckAll(arg->argKind, akbSendRcv|akbPointer)) {
+ if (akCheck(arg->argKind, akbIndefinite)) {
+ fprintf(file, "\tif (OutP->%s != KERN_SUCCESS && In%dP->%s%s.msgt_inline) {\n",
+ arg->argRoutine->rtRetCode->argMsgField,
+ arg->argRequestPos, arg->argTTName, arg->argLongForm ? ".msgtl_header" : "");
+ fprintf(file, "\t\tmach_msg_type_number_t i;\n");
+ fprintf(file, "\t\t/* Restore the mach_port_name_inlined_t input array for message destruction. */\n");
+ fprintf(file, "\t\tfor (i = In%dP->%s.msgt%s_number; i > 1; i--) {\n",
+ arg->argRequestPos, arg->argTTName, arg->argLongForm ? "l" : "");
+ fprintf(file, "\t\t\t%s[i-1].name = %sP[i-1];\n", InArgMsgField(arg), arg->argVarName);
+ fprintf(file, "\t\t}\n");
+ fprintf(file, "\t}\n");
+ }
+ else
+ assert(false);
+ }
+}
+
static void
WriteServerCallArg(FILE *file, const argument_t *arg)
{
@@ -1435,6 +1456,8 @@ WriteRoutine(FILE *file, const routine_t *rt)
WriteServerCall(file, rt);
WriteGetReturnValue(file, rt);
+ WriteReverseList(file, rt->rtArgs, WriteRestoreArg, akbNone, "", "");
+
WriteReverseList(file, rt->rtArgs, WriteDestroyArg, akbDestroy, "", "");
/*
|