Petri Hintukainen pushed to branch master at VideoLAN / libaacs


Commits:
5868f6d9 by npzacs at 2020-07-26T16:03:59+03:00
aacs_info: use stack-allocated buffer for temporary, known-size string

- - - - -
ab45c24c by npzacs at 2020-07-26T16:04:07+03:00
Fix storage size

- - - - -
7111734e by npzacs at 2020-07-26T16:04:19+03:00
Check for NULL

- - - - -
46bd3023 by npzacs at 2020-07-26T16:05:40+03:00
Add sanity checks

- - - - -
544f540a by npzacs at 2020-07-26T16:06:23+03:00
Hide path limit from path.c/h users

- - - - -
0fbb8c9a by npzacs at 2020-07-26T16:06:38+03:00
Silence coverity

- - - - -
0c09c3f5 by npzacs at 2020-07-26T16:07:08+03:00
Simplify alloc size calculation

- - - - -


11 changed files:

- src/devtools/mkb_dump.c
- src/examples/aacs_info.c
- src/file/keydb.h
- src/file/mmc_device_linux.c
- src/file/path.c
- src/file/path.h
- src/libaacs/aacs.c
- src/libaacs/cci.c
- src/libaacs/mmc.c
- src/libaacs/unit_key.c
- src/util/strutl.c


Changes:

=====================================
src/devtools/mkb_dump.c
=====================================
@@ -145,10 +145,10 @@ static void _dump_record(MKB *mkb, int record)
         len  = MKINT_BE24(data + pos + 1);
         if (type == record) {
             switch (record) {
-                case 0x02: _dump_signature(data + pos + 4, len - 4); break;
-                case 0x10: _dump_type_and_version(data + pos + 4, len - 4); 
break;
+                case 0x02: if (len > 4 && len <= 64) _dump_signature(data + 
pos + 4, len - 4); break;
+                case 0x10: if (len > 4)              
_dump_type_and_version(data + pos + 4, len - 4); break;
                 case 0x20:
-                case 0x21: _dump_aacs1_rl(data + pos + 4, len - 4); break;
+                case 0x21: if (len > 4)              _dump_aacs1_rl(data + pos 
+ 4, len - 4); break;
             }
             printf("  Raw data (%zu bytes):\n", len - 4);
             const uint8_t *p = data + pos + 4;
@@ -194,7 +194,7 @@ static void _list_records(MKB *mkb, uint8_t *seen_map)
         uint8_t type = data[pos];
         len  = MKINT_BE24(data + pos + 1);
         printf("    record 0x%02x: %10zu bytes  %s\n", type, len, 
rec_name(type));
-        seen_map[type] = 1;
+        seen_map[type & 0xff] = 1;
         if (len == 0) {
             printf("    UNKNOWN:     %10zu bytes\n", size - pos);
             break;


=====================================
src/examples/aacs_info.c
=====================================
@@ -24,14 +24,12 @@
 
 #include "util/macro.h"  /* MKINT_BE48 */
 
-static const char *_hex2str(const uint8_t *s, unsigned n)
+static const char *_hex2str(char *str, const uint8_t *s, unsigned n)
 {
     static const char hex[] = "0123456789ABCDEF";
-    static char *str = NULL;
 
     unsigned ii;
 
-    str = realloc(str, n*2 + 1);
     for (ii = 0; ii < n; ii++) {
         str[2*ii]     = hex[ s[ii] >> 4];
         str[2*ii + 1] = hex[ s[ii] & 0x0f];
@@ -98,18 +96,19 @@ int main (int argc, char **argv)
     const uint8_t *binding_id = aacs_get_device_binding_id(aacs);
     const uint8_t *bdj_hash   = aacs_get_bdj_root_cert_hash(aacs);
     const uint8_t *cc_id      = aacs_get_content_cert_id(aacs);
+    char           s[41];
 
-    printf("Disc ID: %s\n", id  ? _hex2str(id,  20) : "???");
-    printf("VID    : %s\n", vid ? _hex2str(vid, 16) : "???");
-    printf("MK     : %s\n", mk  ? _hex2str(mk, 16) : "???");
+    printf("Disc ID: %s\n", id  ? _hex2str(s, id,  20) : "???");
+    printf("VID    : %s\n", vid ? _hex2str(s, vid, 16) : "???");
+    printf("MK     : %s\n", mk  ? _hex2str(s, mk, 16) : "???");
     printf("MKBv   : %d\n", aacs_get_mkb_version(aacs));
-    printf("PMSN   : %s\n", pmsn ? _hex2str(pmsn, 16) : "???");
+    printf("PMSN   : %s\n", pmsn ? _hex2str(s, pmsn, 16) : "???");
     printf("Bus encryption:\n");
     printf("  Device support:   %s\n", (bec & AACS_BUS_ENCRYPTION_CAPABLE) ? 
"yes" : "no");
     printf("  Enabled in media: %s\n", (bec & AACS_BUS_ENCRYPTION_ENABLED) ? 
"yes" : "no");
-    printf("Content Certificate ID: %s\n", cc_id      ? _hex2str(cc_id,      
6)  : "???");
-    printf("BD-J Root Cert hash:    %s\n", bdj_hash   ? _hex2str(bdj_hash,   
20) : "???");
-    printf("Device binding ID:      %s\n", binding_id ? _hex2str(binding_id, 
16) : "???");
+    printf("Content Certificate ID: %s\n", cc_id      ? _hex2str(s, cc_id,     
 6)  : "???");
+    printf("BD-J Root Cert hash:    %s\n", bdj_hash   ? _hex2str(s, bdj_hash,  
 20) : "???");
+    printf("Device binding ID:      %s\n", binding_id ? _hex2str(s, 
binding_id, 16) : "???");
 
 
     aacs_close(aacs);


=====================================
src/file/keydb.h
=====================================
@@ -1,7 +1,7 @@
 
 /* encrypted keys */
 
-static const uint8_t internal_dk_list[][21] = {
+static const uint8_t internal_dk_list[][23] = {
   {
   },
 };


=====================================
src/file/mmc_device_linux.c
=====================================
@@ -89,11 +89,13 @@ int device_send_cmd(MMCDEV *dev, const uint8_t *cmd, 
uint8_t *buf, size_t tx, si
     result = ioctl(dev->fd, CDROM_SEND_PACKET, &cgc);
 
     BD_DEBUG(DBG_MMC, "Send LINUX MMC cmd %s:\n", str_print_hex(str, cmd, 16));
+    if (buf) {
     if (tx) {
         BD_DEBUG(DBG_MMC, "  Buffer: %s ->\n", str_print_hex(str, buf, 
tx>255?255:tx));
     } else {
         BD_DEBUG(DBG_MMC, "  Buffer: %s <-\n", str_print_hex(str, buf, 
rx>255?255:rx));
     }
+    }
 
     if (result >= 0) {
         BD_DEBUG(DBG_MMC, "  Send succeeded! [%d]\n", result);
@@ -132,12 +134,13 @@ static int _open_block_device(const char *path)
 
 MMCDEV *device_open(const char *path)
 {
-    char        resolved_path[AACS_PATH_MAX];
+    char       *resolved_path;
     size_t      path_len;
     int         fd;
 
     /* resolve path */
-    if (!aacs_resolve_path(path, resolved_path)) {
+    resolved_path = aacs_resolve_path(path);
+    if (!resolved_path) {
         BD_DEBUG(DBG_MMC | DBG_CRIT, "Failed resolving path %s\n", path);
         return NULL;
     }
@@ -182,10 +185,13 @@ MMCDEV *device_open(const char *path)
         }
 #else
         BD_DEBUG(DBG_MMC | DBG_CRIT, "Only block devices supported\n");
+        X_FREE(resolved_path);
         return NULL;
 #endif
     }
 
+    X_FREE(resolved_path);
+
     if (fd >= 0) {
         MMCDEV *dev = calloc(1, sizeof(MMCDEV));
         if (dev) {


=====================================
src/file/path.c
=====================================
@@ -27,10 +27,17 @@
 #include <string.h>
 #include <errno.h>
 
+#include "util/strutl.h"
+
 #define MAX_LINKS 32
 
-char *aacs_resolve_path(const char *path, char *resolved_path)
+#ifndef AACS_PATH_MAX
+#define AACS_PATH_MAX 1024
+#endif
+
+char *aacs_resolve_path(const char *path)
 {
+    char resolved_path[AACS_PATH_MAX];
     char tmp_path[AACS_PATH_MAX];
     char link[AACS_PATH_MAX];
     char *new_path = resolved_path;
@@ -133,14 +140,13 @@ char *aacs_resolve_path(const char *path, char 
*resolved_path)
     }
 
     *new_path = 0;
-    return resolved_path;
+    return str_dup(resolved_path);
 }
 
 #ifdef TEST_AACS_RESOLVE_PATH
 #include <stdio.h>
 void main(int argc, char *argv[]) {
-    char path[AACS_PATH_MAX];
-    printf("%s -> %s\n", argv[0], aacs_resolve_path(argv[0], path));
-    printf("%s -> %s\n", argv[1], aacs_resolve_path(argv[1], path));
+    printf("%s -> %s\n", argv[0], aacs_resolve_path(argv[0]));
+    printf("%s -> %s\n", argv[1], aacs_resolve_path(argv[1]));
 }
 #endif


=====================================
src/file/path.h
=====================================
@@ -22,10 +22,6 @@
 
 #include "util/attributes.h"
 
-#ifndef AACS_PATH_MAX
-#define AACS_PATH_MAX 1024
-#endif
-
-BD_PRIVATE char *aacs_resolve_path(const char *path, char *resolved_path);
+BD_PRIVATE char *aacs_resolve_path(const char *path);
 
 #endif /* AACS_PATH_H */


=====================================
src/libaacs/aacs.c
=====================================
@@ -506,7 +506,7 @@ static size_t _read_mkb_file(AACS *aacs, const char *file, 
void **pdata)
         size += read_size;
         chunk_size = MKINT_BE24(data + size - 4 + 1);
         if (data_size < size + chunk_size) {
-            for ( ; data_size < size + chunk_size; data_size *= 2) ;
+            data_size = 2*size + chunk_size;
             void *tmp = realloc(data, data_size);
             if (!tmp) {
                 X_FREE(data);


=====================================
src/libaacs/cci.c
=====================================
@@ -120,17 +120,25 @@ AACS_CCI *cci_parse(const void *data, size_t size)
     AACS_CCI *cci;
     const uint8_t *p = data;
     unsigned int ii;
+    unsigned num_entry;
 
     if (size < 16) {
         return NULL;
     }
 
+    num_entry = MKINT_BE16(p);
+    if (num_entry < 1 || num_entry > (2048-16)/6) {
+        BD_DEBUG(DBG_CCI | DBG_CRIT, "Invalid CCI header: %u entries\n", 
num_entry);
+        return NULL;
+    }
+
+
     cci = calloc(1, sizeof(*cci));
     if (!cci) {
         return NULL;
     }
 
-    cci->num_entry = MKINT_BE16(p);
+    cci->num_entry = num_entry;
     p += 16;
     size -= 16;
 


=====================================
src/libaacs/mmc.c
=====================================
@@ -259,6 +259,11 @@ static uint8_t *_mmc_read_mkb(MMC *mmc, uint8_t agid, int 
address, int *size)
 
         BD_DEBUG(DBG_MMC, "got mkb: pack 0/%d %d bytes\n", num_packs, len);
 
+        if (len <= 0 || len > 32768) {
+              BD_DEBUG(DBG_MMC | DBG_CRIT, "invalid pack\n");
+              return NULL;
+        }
+
         mkb = malloc(32768 * num_packs);
         if (!mkb) {
               BD_DEBUG(DBG_MMC | DBG_CRIT, "out of memory\n");
@@ -272,7 +277,10 @@ static uint8_t *_mmc_read_mkb(MMC *mmc, uint8_t agid, int 
address, int *size)
             if (_mmc_report_disc_structure(mmc, agid, 0x83, layer, pack, buf, 
sizeof(buf))) {
                 len = MKINT_BE16(buf) - 2;
                 BD_DEBUG(DBG_MMC, "got mkb: pack %d/%d %d bytes\n", pack, 
num_packs, len);
-
+                if (len <= 0 || len > 32768) {
+                    BD_DEBUG(DBG_MMC | DBG_CRIT, "invalid pack\n");
+                    break;
+                }
                 memcpy(mkb + *size, buf + 4, len);
                 *size += len;
             } else {


=====================================
src/libaacs/unit_key.c
=====================================
@@ -106,6 +106,11 @@ static int _assign_titles(AACS_UK *uk, const uint8_t *p, 
size_t size)
     top_menu   = MKINT_BE16(p + 22);
     num_titles = MKINT_BE16(p + 24);
 
+    if (num_titles > 0xffff - 2) {
+        BD_DEBUG(DBG_UK | DBG_CRIT, "Invalid title count %u\n", num_titles);
+        return -1;
+    }
+
     BD_DEBUG(DBG_UK, "Title FP : CPS unit %d\n", first_play);
     BD_DEBUG(DBG_UK, "Title TM : CPS unit %d\n", top_menu);
 
@@ -168,6 +173,9 @@ static int _parse_uks(AACS_UK *uk, const uint8_t *p, size_t 
size, int aacs2)
         BD_DEBUG(DBG_UK | DBG_CRIT, "No unit keys\n");
         return 0;
     }
+    if (uk->num_uk > 0xffff) {
+        return -1;
+    }
 
     if (size < uk_pos + 48 * uk->num_uk + 16) {
         BD_DEBUG(DBG_UK | DBG_CRIT, "Unexpected EOF (key data truncated)\n");


=====================================
src/util/strutl.c
=====================================
@@ -252,7 +252,7 @@ char *str_print_hex(char *out, const uint8_t *buf, int 
count)
     static const char nibble[16] = "0123456789abcdef";
     int zz;
     for (zz = 0; zz < count; zz++) {
-        out[zz*2    ] = nibble[buf[zz] >> 4];
+        out[zz*2    ] = nibble[(buf[zz] >> 4) & 0xf];
         out[zz*2 + 1] = nibble[buf[zz] & 0x0f];
     }
     out[zz*2] = 0;



View it on GitLab: 
https://code.videolan.org/videolan/libaacs/-/compare/9bceea3f0a022010aa15e898bbb1d47f2af45052...0c09c3f5476c3e19bfbf7b09fd6a0d1136874b31

-- 
View it on GitLab: 
https://code.videolan.org/videolan/libaacs/-/compare/9bceea3f0a022010aa15e898bbb1d47f2af45052...0c09c3f5476c3e19bfbf7b09fd6a0d1136874b31
You're receiving this email because of your account on code.videolan.org.


_______________________________________________
libaacs-devel mailing list
libaacs-devel@videolan.org
https://mailman.videolan.org/listinfo/libaacs-devel

Reply via email to