From 457aae13aad2f0393ba8db6bc8af9d3d698271ba Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Tue, 15 Mar 2011 11:04:13 +0100 Subject: [PATCH] Do full module probe on every LoaderOpen There is no guarantee that a loaded module stays the same in the filesystem since it was loaded for the first time. Opening the module again without checking module version leads to all the interesting issues the version check was supposed to avoid when the module changes in the filesystem (eg. due to package upgrade). --- hw/xfree86/loader/loadmod.c | 75 +++++++++++++++++++++++++++--------------- 1 files changed, 48 insertions(+), 27 deletions(-) diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c index 9f82099..5bffca7 100644 --- a/hw/xfree86/loader/loadmod.c +++ b/hw/xfree86/loader/loadmod.c @@ -84,6 +84,9 @@ static void RemoveChild(ModuleDescPtr); static ModuleDescPtr doLoadModule(const char *, const char *, const char **, const char **, pointer, const XF86ModReqInfo *, int *, int *); +static int /*bool*/ doLoaderOpen(ModuleDescPtr ret, const char * module, + const XF86ModReqInfo * modreq, pointer options, + int * errmaj, int * errmin); const ModuleVersions LoaderVersionInfo = { XORG_VERSION_CURRENT, @@ -787,6 +790,8 @@ DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent) ModuleDescPtr ret; int errmaj, errmin; + /* FIXME may need options and modreq to reopen module correctly */ + if (!mod) return NULL; @@ -794,20 +799,13 @@ DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent) if (ret == NULL) return NULL; - if (!(ret->handle = LoaderOpen(mod->path, &errmaj, &errmin))) { + if (!doLoaderOpen(ret, mod->path, NULL, NULL, &errmaj, &errmin)) { free(ret); return NULL; } - - ret->SetupProc = mod->SetupProc; - ret->TearDownProc = mod->TearDownProc; - ret->TearDownData = NULL; ret->child = DuplicateModule(mod->child, ret); ret->sib = DuplicateModule(mod->sib, parent); ret->parent = parent; - ret->VersionInfo = mod->VersionInfo; - ret->path = strdup(mod->path); - return ret; } @@ -824,7 +822,6 @@ doLoadModule(const char *module, const char *path, const char **subdirlist, const XF86ModReqInfo * modreq, int *errmaj, int *errmin) { - XF86ModuleData *initdata = NULL; char **pathlist = NULL; char *found = NULL; char *name = NULL; @@ -867,7 +864,13 @@ doLoadModule(const char *module, const char *path, const char **subdirlist, *errmin = 0; goto LoadModule_fail; } + + /* drop any explicit suffix from the module name */ + p = strchr(name, '.'); + if (p) + *p = '\0'; ret = NewModuleDesc(name); + if (!ret) { if (errmaj) *errmaj = LDR_NOMEM; @@ -915,23 +918,47 @@ doLoadModule(const char *module, const char *path, const char **subdirlist, *errmaj = LDR_NOENT; if (errmin) *errmin = 0; + free(ret); goto LoadModule_fail; } - ret->handle = LoaderOpen(found, errmaj, errmin); - if (ret->handle < 0) + if(! doLoaderOpen(ret, found, modreq, options, errmaj, errmin)) goto LoadModule_fail; - ret->path = strdup(found); + else + goto LoadModule_exit; - /* drop any explicit suffix from the module name */ - p = strchr(name, '.'); - if (p) - *p = '\0'; + + LoadModule_fail: + ret = NULL; + + LoadModule_exit: + FreePathList(pathlist); + FreePatterns(patterns); + free(found); + free(name); + + return ret; +} + +static int /*bool*/ doLoaderOpen(ModuleDescPtr ret, const char * module, + const XF86ModReqInfo * modreq, pointer options, + int * errmaj, int * errmin) +{ + XF86ModuleData *initdata = NULL; + char *p = NULL; + int retval = 1; + if (!ret || !ret->name) + goto LoadModule_fail; + + ret->handle = LoaderOpen(module, errmaj, errmin); + if (ret->handle < 0) + goto LoadModule_fail; + ret->path = strdup(module); /* * now check if the special data object ModuleData is * present. */ - if (asprintf(&p, "%sModuleData", name) == -1) { + if (asprintf(&p, "%sModuleData", ret->name) == -1) { p = NULL; if (errmaj) *errmaj = LDR_NOMEM; @@ -998,17 +1025,11 @@ doLoadModule(const char *module, const char *path, const char **subdirlist, goto LoadModule_exit; LoadModule_fail: - UnloadModule(ret); - ret = NULL; - + UnloadModule(ret); + retval = 0; LoadModule_exit: - FreePathList(pathlist); - FreePatterns(patterns); - free(found); - free(name); - free(p); - - return ret; + free(p); + return retval; } /* -- 1.7.5.4