diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2024-07-14 18:14:35 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2024-07-14 18:14:35 +0200 |
commit | 98e07c497c9d866c0342696918a020b3f0303405 (patch) | |
tree | 7ed2f4972848a6b973e01e9566a518bd0e298069 | |
parent | cf4a7d9f3882c28292b5e00a314d4cbd36a90002 (diff) | |
download | mig-98e07c497c9d866c0342696918a020b3f0303405.tar.gz mig-98e07c497c9d866c0342696918a020b3f0303405.tar.bz2 mig-98e07c497c9d866c0342696918a020b3f0303405.zip |
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.
-rw-r--r-- | server.c | 23 |
1 files changed, 23 insertions, 0 deletions
@@ -789,6 +789,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) { const ipc_type_t *it = arg->argType; @@ -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, "", ""); /* |