Package: release.debian.org Severity: normal User: [email protected] Usertags: unblock
Hi Please unblock package radare2 The upload to unstable fixes CVE-2017-7946, #860962. The changelog reads as: >radare2 (1.1.0+dfsg-5) unstable; urgency=high > > * Add upstream patch to fix security bug > - CVE-2017-7946 (Closes: #860962) > The get_relocs_64 function in libr/bin/format/mach0/mach0.c in > radare2 1.3.0 allows remote attackers to cause a denial of service > (use-after-free and application crash) via a crafted Mach0 file. > > -- Sebastian Reichel <[email protected]> Sun, 23 Apr 2017 23:20:16 +0200 and I'm attaching the full debdiff against the version in testing. unblock radare2/1.1.0+dfsg-5 Regards, Salvatore
diff -Nru radare2-1.1.0+dfsg/debian/changelog radare2-1.1.0+dfsg/debian/changelog --- radare2-1.1.0+dfsg/debian/changelog 2017-04-11 15:34:39.000000000 +0200 +++ radare2-1.1.0+dfsg/debian/changelog 2017-04-23 23:20:16.000000000 +0200 @@ -1,3 +1,13 @@ +radare2 (1.1.0+dfsg-5) unstable; urgency=high + + * Add upstream patch to fix security bug + - CVE-2017-7946 (Closes: #860962) + The get_relocs_64 function in libr/bin/format/mach0/mach0.c in + radare2 1.3.0 allows remote attackers to cause a denial of service + (use-after-free and application crash) via a crafted Mach0 file. + + -- Sebastian Reichel <[email protected]> Sun, 23 Apr 2017 23:20:16 +0200 + radare2 (1.1.0+dfsg-4) unstable; urgency=high * Add upstream patches to fix security bugs diff -Nru radare2-1.1.0+dfsg/debian/patches/0008-fix-CVE-2017-7946.patch radare2-1.1.0+dfsg/debian/patches/0008-fix-CVE-2017-7946.patch --- radare2-1.1.0+dfsg/debian/patches/0008-fix-CVE-2017-7946.patch 1970-01-01 01:00:00.000000000 +0100 +++ radare2-1.1.0+dfsg/debian/patches/0008-fix-CVE-2017-7946.patch 2017-04-23 23:20:16.000000000 +0200 @@ -0,0 +1,175 @@ +From d1e8ac62c6d978d4662f69116e30230d43033c92 Mon Sep 17 00:00:00 2001 +From: pancake <[email protected]> +Date: Tue, 18 Apr 2017 13:37:33 +0200 +Subject: [PATCH] Fix null deref and uaf in mach0 parser + +--- + libr/bin/format/mach0/mach0.c | 92 ++++++++++++++++++++++++------------------- + 1 file changed, 51 insertions(+), 41 deletions(-) + +diff --git a/libr/bin/format/mach0/mach0.c b/libr/bin/format/mach0/mach0.c +index 206ab11..398a44b 100644 +--- a/libr/bin/format/mach0/mach0.c ++++ b/libr/bin/format/mach0/mach0.c +@@ -1119,7 +1119,7 @@ static int init_items(struct MACH0_(obj_t)* bin) { + case LC_LOAD_WEAK_DYLIB: + sdb_set (bin->kv, sdb_fmt (0, "mach0_cmd_%d.cmd", i), "load_dylib", 0); + bin->nlibs++; +- if (!parse_dylib(bin, off)){ ++ if (!parse_dylib (bin, off)){ + eprintf ("Cannot parse dylib\n"); + bin->nlibs--; + return false; +@@ -1130,30 +1130,31 @@ static int init_items(struct MACH0_(obj_t)* bin) { + { + ut8 dyldi[sizeof (struct dyld_info_command)] = {0}; + sdb_set (bin->kv, sdb_fmt (0, "mach0_cmd_%d.cmd", i), "dyld_info", 0); +- bin->dyld_info = malloc (sizeof(struct dyld_info_command)); +- +- if (off + sizeof (struct dyld_info_command) > bin->size){ +- eprintf ("Cannot parse dyldinfo\n"); +- free (bin->dyld_info); +- return false; +- } +- if (r_buf_read_at (bin->b, off, dyldi, sizeof (struct dyld_info_command)) == -1) { +- free (bin->dyld_info); +- bin->dyld_info = NULL; +- eprintf ("Error: read (LC_DYLD_INFO) at 0x%08"PFMT64x"\n", off); +- } else { +- bin->dyld_info->cmd = r_read_ble32 (&dyldi[0], bin->big_endian); +- bin->dyld_info->cmdsize = r_read_ble32 (&dyldi[4], bin->big_endian); +- bin->dyld_info->rebase_off = r_read_ble32 (&dyldi[8], bin->big_endian); +- bin->dyld_info->rebase_size = r_read_ble32 (&dyldi[12], bin->big_endian); +- bin->dyld_info->bind_off = r_read_ble32 (&dyldi[16], bin->big_endian); +- bin->dyld_info->bind_size = r_read_ble32 (&dyldi[20], bin->big_endian); +- bin->dyld_info->weak_bind_off = r_read_ble32 (&dyldi[24], bin->big_endian); +- bin->dyld_info->weak_bind_size = r_read_ble32 (&dyldi[28], bin->big_endian); +- bin->dyld_info->lazy_bind_off = r_read_ble32 (&dyldi[32], bin->big_endian); +- bin->dyld_info->lazy_bind_size = r_read_ble32 (&dyldi[36], bin->big_endian); +- bin->dyld_info->export_off = r_read_ble32 (&dyldi[40], bin->big_endian); +- bin->dyld_info->export_size = r_read_ble32 (&dyldi[44], bin->big_endian); ++ bin->dyld_info = calloc (1, sizeof (struct dyld_info_command)); ++ if (bin->dyld_info) { ++ if (off + sizeof (struct dyld_info_command) > bin->size){ ++ eprintf ("Cannot parse dyldinfo\n"); ++ R_FREE (bin->dyld_info); ++ return false; ++ } ++ if (r_buf_read_at (bin->b, off, dyldi, sizeof (struct dyld_info_command)) == -1) { ++ free (bin->dyld_info); ++ bin->dyld_info = NULL; ++ eprintf ("Error: read (LC_DYLD_INFO) at 0x%08"PFMT64x"\n", off); ++ } else { ++ bin->dyld_info->cmd = r_read_ble32 (&dyldi[0], bin->big_endian); ++ bin->dyld_info->cmdsize = r_read_ble32 (&dyldi[4], bin->big_endian); ++ bin->dyld_info->rebase_off = r_read_ble32 (&dyldi[8], bin->big_endian); ++ bin->dyld_info->rebase_size = r_read_ble32 (&dyldi[12], bin->big_endian); ++ bin->dyld_info->bind_off = r_read_ble32 (&dyldi[16], bin->big_endian); ++ bin->dyld_info->bind_size = r_read_ble32 (&dyldi[20], bin->big_endian); ++ bin->dyld_info->weak_bind_off = r_read_ble32 (&dyldi[24], bin->big_endian); ++ bin->dyld_info->weak_bind_size = r_read_ble32 (&dyldi[28], bin->big_endian); ++ bin->dyld_info->lazy_bind_off = r_read_ble32 (&dyldi[32], bin->big_endian); ++ bin->dyld_info->lazy_bind_size = r_read_ble32 (&dyldi[36], bin->big_endian); ++ bin->dyld_info->export_off = r_read_ble32 (&dyldi[40], bin->big_endian); ++ bin->dyld_info->export_size = r_read_ble32 (&dyldi[44], bin->big_endian); ++ } + } + } + break; +@@ -1747,17 +1748,20 @@ struct reloc_t* MACH0_(get_relocs)(struct MACH0_(obj_t)* bin) { + if ((bind_size + lazy_size)<1) { + return NULL; + } +- if (bin->dyld_info->bind_off > bin->size || bin->dyld_info->bind_off + bind_size > bin->size) ++ if (bin->dyld_info->bind_off > bin->size || bin->dyld_info->bind_off + bind_size > bin->size) { + return NULL; ++ } + if (bin->dyld_info->lazy_bind_off > bin->size || \ +- bin->dyld_info->lazy_bind_off + lazy_size > bin->size) ++ bin->dyld_info->lazy_bind_off + lazy_size > bin->size) { + return NULL; +- if (bin->dyld_info->bind_off+bind_size+lazy_size > bin->size) ++ } ++ if (bin->dyld_info->bind_off+bind_size+lazy_size > bin->size) { + return NULL; ++ } + // NOTE(eddyb) it's a waste of memory, but we don't know the actual number of relocs. +- if (!(relocs = calloc (1, (1 + bind_size + lazy_size) * sizeof (struct reloc_t)))) ++ if (!(relocs = calloc (1, (1 + bind_size + lazy_size) * sizeof (struct reloc_t)))) { + return NULL; +- ++ } + opcodes = calloc (1, bind_size + lazy_size + 1); + if (!opcodes) { + free (relocs); +@@ -1905,12 +1909,14 @@ relocs[i++].last = 0;\ + free (opcodes); + } else { + int j; +- if (!bin->symtab || !bin->symstr || !bin->sects || !bin->indirectsyms) ++ if (!bin->symtab || !bin->symstr || !bin->sects || !bin->indirectsyms) { + return NULL; +- if (!(relocs = malloc ((bin->dysymtab.nundefsym + 1) * sizeof(struct reloc_t)))) ++ } ++ if (!(relocs = malloc ((bin->dysymtab.nundefsym + 1) * sizeof(struct reloc_t)))) { + return NULL; ++ } + for (j = 0; j < bin->dysymtab.nundefsym; j++) { +- if (parse_import_ptr(bin, &relocs[i], bin->dysymtab.iundefsym + j)) { ++ if (parse_import_ptr (bin, &relocs[i], bin->dysymtab.iundefsym + j)) { + relocs[i].ord = j; + relocs[i++].last = 0; + } +@@ -1954,7 +1960,6 @@ struct addr_t* MACH0_(get_entrypoint)(struct MACH0_(obj_t)* bin) { + } + bin->entry = entry->addr; + } +- + return entry; + } + +@@ -1962,10 +1967,12 @@ struct lib_t* MACH0_(get_libs)(struct MACH0_(obj_t)* bin) { + struct lib_t *libs; + int i; + +- if (!bin->nlibs) ++ if (!bin->nlibs) { + return NULL; +- if (!(libs = calloc ((bin->nlibs + 1), sizeof(struct lib_t)))) ++ } ++ if (!(libs = calloc ((bin->nlibs + 1), sizeof(struct lib_t)))) { + return NULL; ++ } + for (i = 0; i < bin->nlibs; i++) { + strncpy (libs[i].name, bin->libs[i], R_BIN_MACH0_STRING_LENGTH); + libs[i].name[R_BIN_MACH0_STRING_LENGTH-1] = '\0'; +@@ -1978,12 +1985,14 @@ struct lib_t* MACH0_(get_libs)(struct MACH0_(obj_t)* bin) { + ut64 MACH0_(get_baddr)(struct MACH0_(obj_t)* bin) { + int i; + +- if (bin->hdr.filetype != MH_EXECUTE && bin->hdr.filetype != MH_DYLINKER) ++ if (bin->hdr.filetype != MH_EXECUTE && bin->hdr.filetype != MH_DYLINKER) { + return 0; +- +- for (i = 0; i < bin->nsegs; ++i) +- if (bin->segs[i].fileoff == 0 && bin->segs[i].filesize != 0) ++ } ++ for (i = 0; i < bin->nsegs; ++i) { ++ if (bin->segs[i].fileoff == 0 && bin->segs[i].filesize != 0) { + return bin->segs[i].vmaddr; ++ } ++ } + return 0; + } + +@@ -2309,8 +2318,9 @@ ut64 MACH0_(get_main)(struct MACH0_(obj_t)* bin) { + ut8 b[128]; + ut64 entry = addr_to_offset(bin, bin->entry); + // XXX: X86 only and hacky! +- if (entry > bin->size || entry + sizeof (b) > bin->size) ++ if (entry > bin->size || entry + sizeof (b) > bin->size) { + return 0; ++ } + i = r_buf_read_at (bin->b, entry, b, sizeof (b)); + if (i < 1) { + return 0; diff -Nru radare2-1.1.0+dfsg/debian/patches/series radare2-1.1.0+dfsg/debian/patches/series --- radare2-1.1.0+dfsg/debian/patches/series 2017-04-11 15:34:39.000000000 +0200 +++ radare2-1.1.0+dfsg/debian/patches/series 2017-04-23 23:20:13.000000000 +0200 @@ -5,3 +5,4 @@ 0005-fix-FTBFS-for-as-needed.patch 0006-fix-CVE-2017-6194.patch 0007-fix-CVE-2017-6448.patch +0008-fix-CVE-2017-7946.patch

