From 4560d9a3fe16523ec1d716fd4e2f4f7df39a562a Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Tue, 25 Mar 2025 15:19:51 +0100 Subject: [PATCH] dix: add support for reserved extension slots In order to allow extensions being registered at fixed opcodes, there need to be a reserved slot range. Thus `NumExtensions` needs to start out with the upper ceiling of the reserved slot space. Thus it cannot tell whether the array already had been allocated, and some slots now may be NULL, so we need some extra checks. Signed-off-by: Enrico Weigelt, metux IT consult --- dix/extension.c | 50 ++++++++++++++++++++++++++++++++------------ dix/extension_priv.h | 12 +++++++++++ 2 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 dix/extension_priv.h diff --git a/dix/extension.c b/dix/extension.c index fa64429e3..d6d9cd39f 100644 --- a/dix/extension.c +++ b/dix/extension.c @@ -49,6 +49,7 @@ SOFTWARE. #include #include +#include "dix/extension_priv.h" #include "dix/registry_priv.h" #include "misc.h" @@ -66,7 +67,12 @@ static ExtensionEntry **extensions = (ExtensionEntry **) NULL; int lastEvent = EXTENSION_EVENT_BASE; static int lastError = FirstExtensionError; -static unsigned int NumExtensions = 0; +static unsigned int NumExtensions = RESERVED_EXTENSIONS; + +static int checkReserved(const char* name) +{ + return -1; +} ExtensionEntry * AddExtension(const char *name, int NumEvents, int NumErrors, @@ -75,7 +81,10 @@ AddExtension(const char *name, int NumEvents, int NumErrors, void (*CloseDownProc) (ExtensionEntry * e), unsigned short (*MinorOpcodeProc) (ClientPtr c3)) { - int i; + if (!extensions) + extensions = calloc(NumExtensions, sizeof(ExtensionEntry*)); + if (!extensions) + return NULL; if (!MainProc || !SwappedMainProc || !MinorOpcodeProc) return ((ExtensionEntry *) NULL); @@ -95,14 +104,19 @@ AddExtension(const char *name, int NumEvents, int NumErrors, if (!ext->name) goto badalloc; - i = NumExtensions; + int i = checkReserved(ext->name); + if (i == -1) { + i = NumExtensions; + ExtensionEntry **newexts = reallocarray(extensions, i + 1, sizeof(ExtensionEntry *)); + if (!newexts) + goto badalloc; - ExtensionEntry **newexts = reallocarray(extensions, i + 1, sizeof(ExtensionEntry *)); - if (!newexts) - goto badalloc; + NumExtensions++; + extensions = newexts; + } else { + i = i - EXTENSION_BASE; + } - NumExtensions++; - extensions = newexts; extensions[i] = ext; ext->index = i; ext->base = i + EXTENSION_BASE; @@ -150,11 +164,15 @@ badalloc: ExtensionEntry * CheckExtension(const char *extname) { + if (!extensions) + return NULL; + for (int i = 0; i < NumExtensions; i++) { if (extensions[i] && extensions[i]->name && - strcmp(extensions[i]->name, extname) == 0) + strcmp(extensions[i]->name, extname) == 0) { return extensions[i]; + } } return NULL; } @@ -165,7 +183,7 @@ CheckExtension(const char *extname) ExtensionEntry * GetExtensionEntry(int major) { - if (major < EXTENSION_BASE) + if ((major < EXTENSION_BASE) || !extensions) return NULL; major -= EXTENSION_BASE; if (major >= NumExtensions) @@ -182,9 +200,12 @@ StandardMinorOpcode(ClientPtr client) void CloseDownExtensions(void) { - int i; + if (!extensions) + return; - for (i = NumExtensions - 1; i >= 0; i--) { + for (int i = NumExtensions - 1; i >= 0; i--) { + if (!extensions[i]) + continue; if (extensions[i]->CloseDown) extensions[i]->CloseDown(extensions[i]); NumExtensions = i; @@ -195,6 +216,7 @@ CloseDownExtensions(void) } free(extensions); extensions = (ExtensionEntry **) NULL; + NumExtensions = RESERVED_EXTENSIONS; lastEvent = EXTENSION_EVENT_BASE; lastError = FirstExtensionError; } @@ -202,6 +224,8 @@ CloseDownExtensions(void) static Bool ExtensionAvailable(ClientPtr client, ExtensionEntry *ext) { + if (!ext) + return FALSE; if (XaceHookExtAccess(client, ext) != Success) return FALSE; if (!ext->base) @@ -262,7 +286,7 @@ ProcListExtensions(ClientPtr client) }; buffer = NULL; - if (NumExtensions) { + if (NumExtensions && extensions) { int i; for (i = 0; i < NumExtensions; i++) { diff --git a/dix/extension_priv.h b/dix/extension_priv.h new file mode 100644 index 000000000..b0c768485 --- /dev/null +++ b/dix/extension_priv.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: MIT OR X112 + * + * Copyright © 2024 Enrico Weigelt, metux IT consult + */ +#ifndef _XSERVER_EXTENSION_PRIV_H +#define _XSERVER_EXTENSION_PRIV_H + +#include "misc.h" + +#define RESERVED_EXTENSIONS 2 + +#endif /* _XSERVER_EXTENSION_PRIV_H */