lavapipe: add version uuid to shader binary validation

this ensures compatible shader binaries across versions

cc: mesa-stable

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23636>
This commit is contained in:
Mike Blumenkrantz
2023-06-13 18:20:42 -04:00
committed by Marge Bot
parent b79f6ec397
commit 1563aea69f

View File

@@ -1239,21 +1239,25 @@ create_shader_object(struct lvp_device *device, const VkShaderCreateInfoEXT *pCr
goto fail; goto fail;
} else { } else {
assert(pCreateInfo->codeType == VK_SHADER_CODE_TYPE_BINARY_EXT); assert(pCreateInfo->codeType == VK_SHADER_CODE_TYPE_BINARY_EXT);
if (pCreateInfo->codeSize < SHA1_DIGEST_LENGTH + 1) if (pCreateInfo->codeSize < SHA1_DIGEST_LENGTH + VK_UUID_SIZE + 1)
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
struct blob_reader blob; struct blob_reader blob;
const uint8_t *data = pCreateInfo->pCode; const uint8_t *data = pCreateInfo->pCode;
size_t size = pCreateInfo->codeSize - SHA1_DIGEST_LENGTH; uint8_t uuid[VK_UUID_SIZE];
lvp_device_get_cache_uuid(uuid);
if (memcmp(uuid, data, VK_UUID_SIZE))
return VK_NULL_HANDLE;
size_t size = pCreateInfo->codeSize - SHA1_DIGEST_LENGTH - VK_UUID_SIZE;
unsigned char sha1[20]; unsigned char sha1[20];
struct mesa_sha1 sctx; struct mesa_sha1 sctx;
_mesa_sha1_init(&sctx); _mesa_sha1_init(&sctx);
_mesa_sha1_update(&sctx, data + SHA1_DIGEST_LENGTH, size); _mesa_sha1_update(&sctx, data + SHA1_DIGEST_LENGTH + VK_UUID_SIZE, size);
_mesa_sha1_final(&sctx, sha1); _mesa_sha1_final(&sctx, sha1);
if (memcmp(sha1, data, SHA1_DIGEST_LENGTH)) if (memcmp(sha1, data + VK_UUID_SIZE, SHA1_DIGEST_LENGTH))
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
blob_reader_init(&blob, data + SHA1_DIGEST_LENGTH, size); blob_reader_init(&blob, data + SHA1_DIGEST_LENGTH + VK_UUID_SIZE, size);
nir = nir_deserialize(NULL, device->pscreen->get_compiler_options(device->pscreen, PIPE_SHADER_IR_NIR, stage), &blob); nir = nir_deserialize(NULL, device->pscreen->get_compiler_options(device->pscreen, PIPE_SHADER_IR_NIR, stage), &blob);
if (!nir) if (!nir)
goto fail; goto fail;
@@ -1332,20 +1336,21 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_GetShaderBinaryDataEXT(
LVP_FROM_HANDLE(lvp_shader, shader, _shader); LVP_FROM_HANDLE(lvp_shader, shader, _shader);
VkResult ret = VK_SUCCESS; VkResult ret = VK_SUCCESS;
if (pData) { if (pData) {
if (*pDataSize < shader->blob.size + SHA1_DIGEST_LENGTH) { if (*pDataSize < shader->blob.size + SHA1_DIGEST_LENGTH + VK_UUID_SIZE) {
ret = VK_INCOMPLETE; ret = VK_INCOMPLETE;
*pDataSize = 0; *pDataSize = 0;
} else { } else {
*pDataSize = MIN2(*pDataSize, shader->blob.size + SHA1_DIGEST_LENGTH); *pDataSize = MIN2(*pDataSize, shader->blob.size + SHA1_DIGEST_LENGTH + VK_UUID_SIZE);
uint8_t *data = pData;
lvp_device_get_cache_uuid(data);
struct mesa_sha1 sctx; struct mesa_sha1 sctx;
_mesa_sha1_init(&sctx); _mesa_sha1_init(&sctx);
_mesa_sha1_update(&sctx, shader->blob.data, shader->blob.size); _mesa_sha1_update(&sctx, shader->blob.data, shader->blob.size);
_mesa_sha1_final(&sctx, pData); _mesa_sha1_final(&sctx, data + VK_UUID_SIZE);
uint8_t *data = pData; memcpy(data + SHA1_DIGEST_LENGTH + VK_UUID_SIZE, shader->blob.data, shader->blob.size);
memcpy(data + SHA1_DIGEST_LENGTH, shader->blob.data, shader->blob.size);
} }
} else { } else {
*pDataSize = shader->blob.size + SHA1_DIGEST_LENGTH; *pDataSize = shader->blob.size + SHA1_DIGEST_LENGTH + VK_UUID_SIZE;
} }
return ret; return ret;
} }