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

Reply via email to