mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
pipe-loader: fix driconf memory management
this had a number of issues: * pipe_loader_get_driinfo_xml() frees driver_driconf immediately, except the driOptionCache struct string pointers are all just copied in merge_driconf instead of having the strings copied, which means any subsequent access of driver_driconf strings is invalid access * pipe_loader_drm_get_driconf_by_name() is a disaster that only happened to work because the dlopen here is the same lib that gets opened elsewhere by mesa and not closed. if the lib here is actually closed, then all the statically allocated strings become invalid, which means they need to be manually copied cc: mesa-stable Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30494>
This commit is contained in:
parent
390151bef2
commit
0c220741e6
2 changed files with 35 additions and 1 deletions
|
|
@ -159,10 +159,10 @@ pipe_loader_get_driinfo_xml(const char *driver_name)
|
|||
unsigned merged_count;
|
||||
const driOptionDescription *merged_driconf =
|
||||
merge_driconf(driver_driconf, driver_count, &merged_count);
|
||||
free((void *)driver_driconf);
|
||||
|
||||
char *xml = driGetOptionsXml(merged_driconf, merged_count);
|
||||
|
||||
free((void *)driver_driconf);
|
||||
free((void *)merged_driconf);
|
||||
|
||||
return xml;
|
||||
|
|
|
|||
|
|
@ -384,8 +384,42 @@ pipe_loader_drm_get_driconf_by_name(const char *driver_name, unsigned *count)
|
|||
} else {
|
||||
*count = dd->driconf_count;
|
||||
size_t size = sizeof(*driconf) * *count;
|
||||
size_t base_size = size;
|
||||
/* factor in all the statically allocated string lengths */
|
||||
for (unsigned i = 0; i < dd->driconf_count; i++) {
|
||||
if (dd->driconf[i].desc)
|
||||
size += strlen(dd->driconf[i].desc) + 1;
|
||||
if (dd->driconf[i].info.name)
|
||||
size += strlen(dd->driconf[i].info.name) + 1;
|
||||
if (dd->driconf[i].info.type == DRI_STRING)
|
||||
size += strlen(dd->driconf[i].value._string) + 1;
|
||||
}
|
||||
driconf = malloc(size);
|
||||
memcpy(driconf, dd->driconf, size);
|
||||
|
||||
uint8_t *ptr = (void*)driconf;
|
||||
ptr += base_size;
|
||||
/* manually set up pointers and copy in all the statically allocated strings */
|
||||
for (unsigned i = 0; i < dd->driconf_count; i++) {
|
||||
if (dd->driconf[i].desc) {
|
||||
driconf[i].desc = (void*)ptr;
|
||||
size_t str_size = strlen(dd->driconf[i].desc) + 1;
|
||||
memcpy((void*)driconf[i].desc, dd->driconf[i].desc, str_size);
|
||||
ptr += str_size;
|
||||
}
|
||||
if (dd->driconf[i].info.name) {
|
||||
driconf[i].info.name = (void*)ptr;
|
||||
size_t str_size = strlen(dd->driconf[i].info.name) + 1;
|
||||
memcpy((void*)driconf[i].info.name, dd->driconf[i].info.name, str_size);
|
||||
ptr += str_size;
|
||||
}
|
||||
if (dd->driconf[i].info.type == DRI_STRING) {
|
||||
driconf[i].value._string = (void*)ptr;
|
||||
size_t str_size = strlen(dd->driconf[i].value._string) + 1;
|
||||
memcpy((void*)driconf[i].value._string, dd->driconf[i].value._string, str_size);
|
||||
ptr += str_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lib)
|
||||
util_dl_close(lib);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue