libaacs | branch: master | npzacs <npz...@gmail.com> | Mon Jan 11 12:52:04 2016 +0200| [b05f96370b68b1d7cc934c0363ca0009bee04ced] | committer: npzacs
Check cache memory size before reading. TOCTOU between data size check and read: attacker could replace cache file with larger one and cause buffer overflow. > http://git.videolan.org/gitweb.cgi/libaacs.git/?a=commit;h=b05f96370b68b1d7cc934c0363ca0009bee04ced --- src/file/keydbcfg.c | 3 ++- src/file/keydbcfg.h | 3 ++- src/libaacs/aacs.c | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/file/keydbcfg.c b/src/file/keydbcfg.c index 76bb0e9..aae6e6c 100644 --- a/src/file/keydbcfg.c +++ b/src/file/keydbcfg.c @@ -473,7 +473,7 @@ int cache_save(const char *name, uint32_t version, const void *data, uint32_t le return result; } -int cache_get(const char *name, uint32_t *version, uint32_t *len, void *buf) +int cache_get(const char *name, uint32_t *version, uint32_t *len, void *buf, size_t buf_size) { int result = 0; char *file = _cache_file(name); @@ -491,6 +491,7 @@ int cache_get(const char *name, uint32_t *version, uint32_t *len, void *buf) if (fread(version, 1, 4, fp) == 4 && (!len || fread(len, 1, 4, fp) == 4) && + (!len || (size_t)*len <= buf_size) && (!buf || fread(buf, 1, *len, fp) == *len)) { BD_DEBUG(DBG_FILE, "Read %d bytes from %s, version %d\n", 4 + (len ? 4 : 0) + (buf ? *len : 0), file, *version); diff --git a/src/file/keydbcfg.h b/src/file/keydbcfg.h index 617960e..31ff198 100644 --- a/src/file/keydbcfg.h +++ b/src/file/keydbcfg.h @@ -23,6 +23,7 @@ #include "util/attributes.h" #include <stdint.h> +#include <stddef.h> /* size_t */ /* struct holding a digit and key pair for <ENTRY NUMBER> - <ENTRY> entries */ typedef struct digit_key_pair_t digit_key_pair; @@ -129,7 +130,7 @@ BD_PRIVATE int keycache_save(const char *type, const uint8_t *disc_id, BD_PRIVATE int keycache_find(const char *type, const uint8_t *disc_id, uint8_t *key, unsigned int len); -BD_PRIVATE int cache_get(const char *name, uint32_t *version, uint32_t *len, void *buf); /* use buf=NULL to get version and size */ +BD_PRIVATE int cache_get(const char *name, uint32_t *version, uint32_t *len, void *buf, size_t buf_size); /* use buf=NULL to get version and size */ BD_PRIVATE int cache_save(const char *name, uint32_t version, const void *data, uint32_t len); BD_PRIVATE int cache_remove(const char *name); diff --git a/src/libaacs/aacs.c b/src/libaacs/aacs.c index 1bd8ad5..47095eb 100644 --- a/src/libaacs/aacs.c +++ b/src/libaacs/aacs.c @@ -175,14 +175,14 @@ static void _update_rl(MKB *mkb) uint32_t cache_version; size_t rl_len; - if (!cache_get("drl", &cache_version, NULL, NULL) || cache_version < version) { + if (!cache_get("drl", &cache_version, NULL, NULL, 0) || cache_version < version) { const uint8_t *version_rec = mkb_type_and_version_record(mkb); const uint8_t *drl_rec = mkb_drive_revokation_entries(mkb, &rl_len); if (drl_rec && rl_len > 8) { _save_rl("drl", version, version_rec, drl_rec, rl_len); } } - if (!cache_get("hrl", &cache_version, NULL, NULL) || cache_version < version) { + if (!cache_get("hrl", &cache_version, NULL, NULL, 0) || cache_version < version) { const uint8_t *version_rec = mkb_type_and_version_record(mkb); const uint8_t *hrl_rec = mkb_host_revokation_entries(mkb, &rl_len); if (hrl_rec && rl_len > 8) { @@ -1294,11 +1294,11 @@ static AACS_RL_ENTRY *_get_rl(const char *type, int *num_records, int *mkbv) *num_records = *mkbv = 0; - cache_get(type, &version, &len, NULL); + cache_get(type, &version, &len, NULL, 0); if (version > 0 && len > 24) { data = malloc(len); - if (cache_get(type, &version, &len, data) && len > 24) { + if (cache_get(type, &version, &len, data, len) && len > 24) { if (_rl_verify_signature(data, len)) { *mkbv = version; _______________________________________________ libaacs-devel mailing list libaacs-devel@videolan.org https://mailman.videolan.org/listinfo/libaacs-devel