1
0
mirror of https://github.com/wine-mirror/wine synced 2024-06-29 06:14:34 +00:00

winevulkan: Fix size mismatch when writing to return pointer.

Fixes vkMapMemory* writing past the returned pointer size in WOW64.
This commit is contained in:
Rémi Bernon 2024-06-07 14:11:31 +02:00 committed by Alexandre Julliard
parent 1a4cbba795
commit d138172b58
2 changed files with 102 additions and 23 deletions

View File

@ -830,11 +830,14 @@ class VkFunction(object):
for p in self.params:
if p.needs_variable(conv, self.unwrap):
if p.is_dynamic_array():
body += " {2}{0} *{1}_host;\n".format(
p.type, p.name, "const " if p.is_const() else "")
body += " {3}{0}{1} *{2}_host;\n".format(
p.type, p.pointer[:-1] if p.pointer else "",
p.name, "const " if p.is_const() else "")
elif p.optional:
body += " {0} *{1}_host = NULL;\n".format(p.type, p.name)
needs_alloc = True
elif p.pointer:
body += " {0} {1}{2}_host;\n".format(p.type, p.pointer[:-1], p.name)
else:
body += " {0} {1}_host;\n".format(p.type, p.name)
if p.needs_alloc(conv, self.unwrap):
@ -1286,12 +1289,15 @@ class VkVariable(object):
def is_pointer(self):
return self.pointer is not None
def is_pointer_pointer(self):
return self.pointer and self.pointer.count('*') > 1
def is_pointer_size(self):
if self.type in ["size_t", "HWND", "HINSTANCE"]:
return True
if self.is_handle() and self.handle.is_dispatchable():
return True
return False
return self.is_pointer_pointer()
def is_handle(self):
return self.handle is not None
@ -1726,6 +1732,7 @@ class VkParam(VkVariable):
const = param.text.strip() if param.text else None
type_elem = param.find("type")
pointer = type_elem.tail.strip() if type_elem.tail.strip() != "" else None
assert not pointer or pointer.count('*') <= 2 # only pointers and pointer of pointers are supported
attr = param.get("optional")
optional = attr and attr.startswith("true")
@ -1817,7 +1824,7 @@ class VkParam(VkVariable):
else:
if self.is_dynamic_array():
return " convert_{0}_array_{1}({2}_host, {3}, {4});\n".format(
self.type, suffix, self.name, self.value(prefix, conv),
self.type, suffix, self.name, self.value(prefix, conv).replace('const ', ''),
self.get_dyn_array_len(prefix, conv))
elif self.is_struct():
ref_part = "" if self.optional else "&"
@ -1885,6 +1892,10 @@ class VkParam(VkVariable):
def needs_conversion(self, conv, unwrap, direction, parent_const=False):
""" Check if param needs conversion. """
if self.is_pointer_pointer() and self.type != 'void':
if direction == Direction.INPUT or not self.is_const():
return conv
if self.is_struct():
return self.struct.needs_conversion(conv, unwrap, direction, self.is_const())
@ -2534,6 +2545,7 @@ class ArrayConversionFunction(object):
body += "#ifdef _WIN64\n"
needs_alloc = self.direction != Direction.OUTPUT and self.array.needs_alloc(self.conv, self.unwrap)
pointer_array = self.array.pointer_array or self.array.is_pointer_pointer()
win_type = self.type
if self.conv:
@ -2546,10 +2558,13 @@ class ArrayConversionFunction(object):
pointer_part = self.array.pointer if self.array.pointer else "*"
if self.direction == Direction.OUTPUT:
params = ["const {0} {1}in".format(self.type, pointer_part),
"{0} {1}out".format(win_type, pointer_part), "uint32_t count"]
if self.conv and pointer_array:
out = "PTR32 *out"
else:
out = "{0} {1}out".format(win_type, pointer_part)
params = ["const {0} {1}in".format(self.type, pointer_part), out, "uint32_t count"]
return_type = None
elif self.conv and self.array.pointer_array:
elif self.conv and pointer_array:
params = ["const PTR32 *in", "uint32_t count"]
return_type = self.type
else:
@ -2571,7 +2586,8 @@ class ArrayConversionFunction(object):
body += ")\n{\n"
if return_type:
body += " {0} {1}out;\n".format(return_type, "**" if self.array.pointer_array else "*")
pointer = self.array.pointer.replace('const*', '*').replace(' *', '*')
body += " {0} {1}out;\n".format(return_type, pointer)
if needs_copy:
body += " unsigned int i;\n\n"
@ -2595,7 +2611,7 @@ class ArrayConversionFunction(object):
if self.direction == Direction.INPUT and struct.needs_alloc(self.conv, self.unwrap):
ctx_part = "ctx, "
if not self.array.pointer_array:
if not pointer_array:
body += " convert_{0}_{1}({2}&in[i], &out[i]);\n".format(
struct.name, suffix, ctx_part)
else:
@ -2615,7 +2631,7 @@ class ArrayConversionFunction(object):
else:
body += " out[i] = UlongToPtr(in[i]);\n"
elif self.array.is_handle():
if self.array.pointer_array:
if pointer_array:
LOGGER.error("Unhandled handle pointer arrays")
handle = self.array.handle
if not self.conv or not handle.is_dispatchable():
@ -2631,15 +2647,18 @@ class ArrayConversionFunction(object):
body += " out[i] = {0};\n".format(handle.unwrap_handle(input, self.unwrap))
else:
LOGGER.warning("Unhandled handle output conversion")
elif self.array.pointer_array:
body += " out[i] = UlongToPtr(in[i]);\n"
elif pointer_array:
if self.direction == Direction.INPUT:
body += " out[i] = UlongToPtr(in[i]);\n"
else:
body += " out[i] = PtrToUlong(in[i]);\n"
else:
body += " out[i] = in[i];\n"
body += " }\n"
if return_type:
body += "\n return {0}out;\n".format("(void *)" if self.array.pointer_array else "")
body += "\n return {0}out;\n".format("(void *)" if pointer_array else "")
body += "}\n"
if not self.conv:

View File

@ -8101,6 +8101,22 @@ static inline const VkAccelerationStructureBuildGeometryInfoKHR *convert_VkAccel
return out;
}
static inline const VkAccelerationStructureBuildRangeInfoKHR * const*convert_VkAccelerationStructureBuildRangeInfoKHR_array_win32_to_host(struct conversion_context *ctx, const PTR32 *in, uint32_t count)
{
VkAccelerationStructureBuildRangeInfoKHR **out;
unsigned int i;
if (!in || !count) return NULL;
out = conversion_context_alloc(ctx, count * sizeof(*out));
for (i = 0; i < count; i++)
{
out[i] = UlongToPtr(in[i]);
}
return (void *)out;
}
static inline void convert_VkMicromapBuildInfoEXT_win32_to_host(struct conversion_context *ctx, const VkMicromapBuildInfoEXT32 *in, VkMicromapBuildInfoEXT *out)
{
if (!in) return;
@ -8833,6 +8849,34 @@ static inline void convert_VkAccelerationStructureInfoNV_win32_to_host(struct co
FIXME("Unexpected pNext\n");
}
static inline const uint32_t * const*convert_uint32_t_array_win32_to_host(struct conversion_context *ctx, const PTR32 *in, uint32_t count)
{
uint32_t **out;
unsigned int i;
if (!in || !count) return NULL;
out = conversion_context_alloc(ctx, count * sizeof(*out));
for (i = 0; i < count; i++)
{
out[i] = UlongToPtr(in[i]);
}
return (void *)out;
}
static inline void convert_uint32_t_array_host_to_win32(const uint32_t * const*in, PTR32 *out, uint32_t count)
{
unsigned int i;
if (!in) return;
for (i = 0; i < count; i++)
{
out[i] = PtrToUlong(in[i]);
}
}
static inline void convert_VkCopyAccelerationStructureInfoKHR_win32_to_host(const VkCopyAccelerationStructureInfoKHR32 *in, VkCopyAccelerationStructureInfoKHR *out)
{
if (!in) return;
@ -30974,6 +31018,7 @@ static NTSTATUS thunk32_vkBuildAccelerationStructuresKHR(void *args)
VkResult result;
} *params = args;
const VkAccelerationStructureBuildGeometryInfoKHR *pInfos_host;
const VkAccelerationStructureBuildRangeInfoKHR* const *ppBuildRangeInfos_host;
struct conversion_context local_ctx;
struct conversion_context *ctx = &local_ctx;
@ -30984,7 +31029,8 @@ static NTSTATUS thunk32_vkBuildAccelerationStructuresKHR(void *args)
else
ctx = &wine_deferred_operation_from_handle(params->deferredOperation)->ctx;
pInfos_host = convert_VkAccelerationStructureBuildGeometryInfoKHR_array_win32_to_host(ctx, (const VkAccelerationStructureBuildGeometryInfoKHR32 *)UlongToPtr(params->pInfos), params->infoCount);
params->result = wine_device_from_handle((VkDevice)UlongToPtr(params->device))->funcs.p_vkBuildAccelerationStructuresKHR(wine_device_from_handle((VkDevice)UlongToPtr(params->device))->host_device, params->deferredOperation ? wine_deferred_operation_from_handle(params->deferredOperation)->host_deferred_operation : 0, params->infoCount, pInfos_host, (const VkAccelerationStructureBuildRangeInfoKHR * const*)UlongToPtr(params->ppBuildRangeInfos));
ppBuildRangeInfos_host = convert_VkAccelerationStructureBuildRangeInfoKHR_array_win32_to_host(ctx, (const PTR32 *)UlongToPtr(params->ppBuildRangeInfos), params->infoCount);
params->result = wine_device_from_handle((VkDevice)UlongToPtr(params->device))->funcs.p_vkBuildAccelerationStructuresKHR(wine_device_from_handle((VkDevice)UlongToPtr(params->device))->host_device, params->deferredOperation ? wine_deferred_operation_from_handle(params->deferredOperation)->host_deferred_operation : 0, params->infoCount, pInfos_host, ppBuildRangeInfos_host);
if (params->deferredOperation == VK_NULL_HANDLE)
free_conversion_context(ctx);
return STATUS_SUCCESS;
@ -31786,12 +31832,15 @@ static void thunk32_vkCmdBuildAccelerationStructuresIndirectKHR(void *args)
PTR32 ppMaxPrimitiveCounts;
} *params = args;
const VkAccelerationStructureBuildGeometryInfoKHR *pInfos_host;
const uint32_t* const *ppMaxPrimitiveCounts_host;
struct conversion_context local_ctx;
struct conversion_context *ctx = &local_ctx;
init_conversion_context(ctx);
pInfos_host = convert_VkAccelerationStructureBuildGeometryInfoKHR_array_win32_to_host(ctx, (const VkAccelerationStructureBuildGeometryInfoKHR32 *)UlongToPtr(params->pInfos), params->infoCount);
wine_cmd_buffer_from_handle((VkCommandBuffer)UlongToPtr(params->commandBuffer))->device->funcs.p_vkCmdBuildAccelerationStructuresIndirectKHR(wine_cmd_buffer_from_handle((VkCommandBuffer)UlongToPtr(params->commandBuffer))->host_command_buffer, params->infoCount, pInfos_host, (const VkDeviceAddress *)UlongToPtr(params->pIndirectDeviceAddresses), (const uint32_t *)UlongToPtr(params->pIndirectStrides), (const uint32_t * const*)UlongToPtr(params->ppMaxPrimitiveCounts));
ppMaxPrimitiveCounts_host = convert_uint32_t_array_win32_to_host(ctx, (const PTR32 *)UlongToPtr(params->ppMaxPrimitiveCounts), params->infoCount);
wine_cmd_buffer_from_handle((VkCommandBuffer)UlongToPtr(params->commandBuffer))->device->funcs.p_vkCmdBuildAccelerationStructuresIndirectKHR(wine_cmd_buffer_from_handle((VkCommandBuffer)UlongToPtr(params->commandBuffer))->host_command_buffer, params->infoCount, pInfos_host, (const VkDeviceAddress *)UlongToPtr(params->pIndirectDeviceAddresses), (const uint32_t *)UlongToPtr(params->pIndirectStrides), ppMaxPrimitiveCounts_host);
convert_uint32_t_array_host_to_win32(ppMaxPrimitiveCounts_host, (PTR32 *)UlongToPtr(params->ppMaxPrimitiveCounts), params->infoCount);
free_conversion_context(ctx);
}
@ -31814,12 +31863,14 @@ static void thunk32_vkCmdBuildAccelerationStructuresKHR(void *args)
PTR32 ppBuildRangeInfos;
} *params = args;
const VkAccelerationStructureBuildGeometryInfoKHR *pInfos_host;
const VkAccelerationStructureBuildRangeInfoKHR* const *ppBuildRangeInfos_host;
struct conversion_context local_ctx;
struct conversion_context *ctx = &local_ctx;
init_conversion_context(ctx);
pInfos_host = convert_VkAccelerationStructureBuildGeometryInfoKHR_array_win32_to_host(ctx, (const VkAccelerationStructureBuildGeometryInfoKHR32 *)UlongToPtr(params->pInfos), params->infoCount);
wine_cmd_buffer_from_handle((VkCommandBuffer)UlongToPtr(params->commandBuffer))->device->funcs.p_vkCmdBuildAccelerationStructuresKHR(wine_cmd_buffer_from_handle((VkCommandBuffer)UlongToPtr(params->commandBuffer))->host_command_buffer, params->infoCount, pInfos_host, (const VkAccelerationStructureBuildRangeInfoKHR * const*)UlongToPtr(params->ppBuildRangeInfos));
ppBuildRangeInfos_host = convert_VkAccelerationStructureBuildRangeInfoKHR_array_win32_to_host(ctx, (const PTR32 *)UlongToPtr(params->ppBuildRangeInfos), params->infoCount);
wine_cmd_buffer_from_handle((VkCommandBuffer)UlongToPtr(params->commandBuffer))->device->funcs.p_vkCmdBuildAccelerationStructuresKHR(wine_cmd_buffer_from_handle((VkCommandBuffer)UlongToPtr(params->commandBuffer))->host_command_buffer, params->infoCount, pInfos_host, ppBuildRangeInfos_host);
free_conversion_context(ctx);
}
@ -37208,7 +37259,7 @@ static NTSTATUS thunk32_vkCreateComputePipelines(void *args)
init_conversion_context(ctx);
pCreateInfos_host = convert_VkComputePipelineCreateInfo_array_win32_to_host(ctx, (const VkComputePipelineCreateInfo32 *)UlongToPtr(params->pCreateInfos), params->createInfoCount);
params->result = wine_device_from_handle((VkDevice)UlongToPtr(params->device))->funcs.p_vkCreateComputePipelines(wine_device_from_handle((VkDevice)UlongToPtr(params->device))->host_device, params->pipelineCache, params->createInfoCount, pCreateInfos_host, NULL, (VkPipeline *)UlongToPtr(params->pPipelines));
convert_VkComputePipelineCreateInfo_array_host_to_win32(pCreateInfos_host, (const VkComputePipelineCreateInfo32 *)UlongToPtr(params->pCreateInfos), params->createInfoCount);
convert_VkComputePipelineCreateInfo_array_host_to_win32(pCreateInfos_host, (VkComputePipelineCreateInfo32 *)UlongToPtr(params->pCreateInfos), params->createInfoCount);
free_conversion_context(ctx);
return STATUS_SUCCESS;
}
@ -37752,7 +37803,7 @@ static NTSTATUS thunk32_vkCreateGraphicsPipelines(void *args)
init_conversion_context(ctx);
pCreateInfos_host = convert_VkGraphicsPipelineCreateInfo_array_win32_to_host(ctx, (const VkGraphicsPipelineCreateInfo32 *)UlongToPtr(params->pCreateInfos), params->createInfoCount);
params->result = wine_device_from_handle((VkDevice)UlongToPtr(params->device))->funcs.p_vkCreateGraphicsPipelines(wine_device_from_handle((VkDevice)UlongToPtr(params->device))->host_device, params->pipelineCache, params->createInfoCount, pCreateInfos_host, NULL, (VkPipeline *)UlongToPtr(params->pPipelines));
convert_VkGraphicsPipelineCreateInfo_array_host_to_win32(pCreateInfos_host, (const VkGraphicsPipelineCreateInfo32 *)UlongToPtr(params->pCreateInfos), params->createInfoCount);
convert_VkGraphicsPipelineCreateInfo_array_host_to_win32(pCreateInfos_host, (VkGraphicsPipelineCreateInfo32 *)UlongToPtr(params->pCreateInfos), params->createInfoCount);
free_conversion_context(ctx);
return STATUS_SUCCESS;
}
@ -38184,7 +38235,7 @@ static NTSTATUS thunk32_vkCreateRayTracingPipelinesKHR(void *args)
ctx = &wine_deferred_operation_from_handle(params->deferredOperation)->ctx;
pCreateInfos_host = convert_VkRayTracingPipelineCreateInfoKHR_array_win32_to_host(ctx, (const VkRayTracingPipelineCreateInfoKHR32 *)UlongToPtr(params->pCreateInfos), params->createInfoCount);
params->result = wine_device_from_handle((VkDevice)UlongToPtr(params->device))->funcs.p_vkCreateRayTracingPipelinesKHR(wine_device_from_handle((VkDevice)UlongToPtr(params->device))->host_device, params->deferredOperation ? wine_deferred_operation_from_handle(params->deferredOperation)->host_deferred_operation : 0, params->pipelineCache, params->createInfoCount, pCreateInfos_host, NULL, (VkPipeline *)UlongToPtr(params->pPipelines));
convert_VkRayTracingPipelineCreateInfoKHR_array_host_to_win32(pCreateInfos_host, (const VkRayTracingPipelineCreateInfoKHR32 *)UlongToPtr(params->pCreateInfos), params->createInfoCount);
convert_VkRayTracingPipelineCreateInfoKHR_array_host_to_win32(pCreateInfos_host, (VkRayTracingPipelineCreateInfoKHR32 *)UlongToPtr(params->pCreateInfos), params->createInfoCount);
if (params->deferredOperation == VK_NULL_HANDLE)
free_conversion_context(ctx);
return STATUS_SUCCESS;
@ -38229,7 +38280,7 @@ static NTSTATUS thunk32_vkCreateRayTracingPipelinesNV(void *args)
init_conversion_context(ctx);
pCreateInfos_host = convert_VkRayTracingPipelineCreateInfoNV_array_win32_to_host(ctx, (const VkRayTracingPipelineCreateInfoNV32 *)UlongToPtr(params->pCreateInfos), params->createInfoCount);
params->result = wine_device_from_handle((VkDevice)UlongToPtr(params->device))->funcs.p_vkCreateRayTracingPipelinesNV(wine_device_from_handle((VkDevice)UlongToPtr(params->device))->host_device, params->pipelineCache, params->createInfoCount, pCreateInfos_host, NULL, (VkPipeline *)UlongToPtr(params->pPipelines));
convert_VkRayTracingPipelineCreateInfoNV_array_host_to_win32(pCreateInfos_host, (const VkRayTracingPipelineCreateInfoNV32 *)UlongToPtr(params->pCreateInfos), params->createInfoCount);
convert_VkRayTracingPipelineCreateInfoNV_array_host_to_win32(pCreateInfos_host, (VkRayTracingPipelineCreateInfoNV32 *)UlongToPtr(params->pCreateInfos), params->createInfoCount);
free_conversion_context(ctx);
return STATUS_SUCCESS;
}
@ -40990,10 +41041,13 @@ static NTSTATUS thunk32_vkGetDescriptorSetHostMappingVALVE(void *args)
VkDescriptorSet DECLSPEC_ALIGN(8) descriptorSet;
PTR32 ppData;
} *params = args;
void *ppData_host;
TRACE("%#x, 0x%s, %#x\n", params->device, wine_dbgstr_longlong(params->descriptorSet), params->ppData);
wine_device_from_handle((VkDevice)UlongToPtr(params->device))->funcs.p_vkGetDescriptorSetHostMappingVALVE(wine_device_from_handle((VkDevice)UlongToPtr(params->device))->host_device, params->descriptorSet, (void **)UlongToPtr(params->ppData));
ppData_host = UlongToPtr(*(PTR32 *)UlongToPtr(params->ppData));
wine_device_from_handle((VkDevice)UlongToPtr(params->device))->funcs.p_vkGetDescriptorSetHostMappingVALVE(wine_device_from_handle((VkDevice)UlongToPtr(params->device))->host_device, params->descriptorSet, &ppData_host);
*(PTR32 *)UlongToPtr(params->ppData) = PtrToUlong(ppData_host);
return STATUS_SUCCESS;
}
@ -45055,10 +45109,13 @@ static NTSTATUS thunk32_vkMapMemory(void *args)
PTR32 ppData;
VkResult result;
} *params = args;
void *ppData_host;
TRACE("%#x, 0x%s, 0x%s, 0x%s, %#x, %#x\n", params->device, wine_dbgstr_longlong(params->memory), wine_dbgstr_longlong(params->offset), wine_dbgstr_longlong(params->size), params->flags, params->ppData);
params->result = wine_vkMapMemory((VkDevice)UlongToPtr(params->device), params->memory, params->offset, params->size, params->flags, (void **)UlongToPtr(params->ppData));
ppData_host = UlongToPtr(*(PTR32 *)UlongToPtr(params->ppData));
params->result = wine_vkMapMemory((VkDevice)UlongToPtr(params->device), params->memory, params->offset, params->size, params->flags, &ppData_host);
*(PTR32 *)UlongToPtr(params->ppData) = PtrToUlong(ppData_host);
return STATUS_SUCCESS;
}
@ -45084,6 +45141,7 @@ static NTSTATUS thunk32_vkMapMemory2KHR(void *args)
VkResult result;
} *params = args;
VkMemoryMapInfoKHR pMemoryMapInfo_host;
void *ppData_host;
struct conversion_context local_ctx;
struct conversion_context *ctx = &local_ctx;
@ -45091,7 +45149,9 @@ static NTSTATUS thunk32_vkMapMemory2KHR(void *args)
init_conversion_context(ctx);
convert_VkMemoryMapInfoKHR_win32_to_unwrapped_host(ctx, (const VkMemoryMapInfoKHR32 *)UlongToPtr(params->pMemoryMapInfo), &pMemoryMapInfo_host);
params->result = wine_vkMapMemory2KHR((VkDevice)UlongToPtr(params->device), &pMemoryMapInfo_host, (void **)UlongToPtr(params->ppData));
ppData_host = UlongToPtr(*(PTR32 *)UlongToPtr(params->ppData));
params->result = wine_vkMapMemory2KHR((VkDevice)UlongToPtr(params->device), &pMemoryMapInfo_host, &ppData_host);
*(PTR32 *)UlongToPtr(params->ppData) = PtrToUlong(ppData_host);
free_conversion_context(ctx);
return STATUS_SUCCESS;
}