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