[Mesa-dev] [PATCH v2 2/5] disk_cache: enable limited hash collision detection in release builds
Timothy Arceri
tarceri at itsqueeze.com
Wed Aug 23 06:32:58 UTC 2017
It really doesn't cost us much and will stop strange crashes should
the stars align.
---
src/util/disk_cache.c | 26 ++++++++++----------------
1 file changed, 10 insertions(+), 16 deletions(-)
diff --git a/src/util/disk_cache.c b/src/util/disk_cache.c
index 644a911e53..2df49cf626 100644
--- a/src/util/disk_cache.c
+++ b/src/util/disk_cache.c
@@ -981,63 +981,55 @@ inflate_cache_data(uint8_t *in_data, size_t in_data_size,
}
void *
disk_cache_get(struct disk_cache *cache, const cache_key key, size_t *size)
{
int fd = -1, ret;
struct stat sb;
char *filename = NULL;
uint8_t *data = NULL;
uint8_t *uncompressed_data = NULL;
+ uint8_t *file_header = NULL;
if (size)
*size = 0;
filename = get_cache_file(cache, key);
if (filename == NULL)
goto fail;
fd = open(filename, O_RDONLY | O_CLOEXEC);
if (fd == -1)
goto fail;
if (fstat(fd, &sb) == -1)
goto fail;
data = malloc(sb.st_size);
if (data == NULL)
goto fail;
size_t ck_size = cache->driver_keys_blob_size;
-#ifndef NDEBUG
- uint8_t *file_header = malloc(ck_size);
+ file_header = malloc(ck_size);
if (!file_header)
goto fail;
- assert(sb.st_size > ck_size);
- ret = read_all(fd, file_header, ck_size);
- if (ret == -1) {
- free(file_header);
+ if (sb.st_size < ck_size)
goto fail;
- }
-
- assert(memcmp(cache->driver_keys_blob, file_header, ck_size) == 0);
- free(file_header);
-#else
- /* The cache keys are currently just used for distributing precompiled
- * shaders, they are not used by Mesa so just skip them for now.
- */
- ret = lseek(fd, ck_size, SEEK_CUR);
+ ret = read_all(fd, file_header, ck_size);
if (ret == -1)
goto fail;
-#endif
+
+ /* Check for extremely unlikely hash collisions */
+ if (memcmp(cache->driver_keys_blob, file_header, ck_size) != 0)
+ goto fail;
/* Load the CRC that was created when the file was written. */
struct cache_entry_file_data cf_data;
size_t cf_data_size = sizeof(cf_data);
ret = read_all(fd, &cf_data, cf_data_size);
if (ret == -1)
goto fail;
/* Load the actual cache data. */
size_t cache_data_size = sb.st_size - cf_data_size - ck_size;
@@ -1065,20 +1057,22 @@ disk_cache_get(struct disk_cache *cache, const cache_key key, size_t *size)
return uncompressed_data;
fail:
if (data)
free(data);
if (uncompressed_data)
free(uncompressed_data);
if (filename)
free(filename);
+ if (file_header)
+ free(file_header);
if (fd != -1)
close(fd);
return NULL;
}
void
disk_cache_put_key(struct disk_cache *cache, const cache_key key)
{
const uint32_t *key_chunk = (const uint32_t *) key;
--
2.13.4
More information about the mesa-dev
mailing list