File 284.patch of Package dislocker
From 95e2483dfedfdc4dbd74652702504626a0e4eec7 Mon Sep 17 00:00:00 2001
From: Gabriel Kihlman <gk@sysctl.se>
Date: Tue, 21 Jun 2022 19:55:05 +0200
Subject: [PATCH 1/2] Avoid indexing out of bounds of value_type_str and
value_types_prop
They have 20 entries, not 22.
Found when trying to mount an image and getting a segfault:
$ sudo losetup -P /dev/loop100 /user/src_image.img.ntfs_aes_xts.bitlocker
$ sudo ./src/dislocker-fuse -v -V /dev/loop100p1 -upassword -- /mnt
/user/kode/dislocker/src/metadata/datums.c:288:5: runtime error: index 21 out of bounds for type 'const char *[20]'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /user/kode/dislocker/src/metadata/datums.c:288:5 in
=================================================================
==147051==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7fa609c9d4e8 at pc 0x7fa609c5c1fd bp 0x7ffc711f22e0 sp 0x7ffc711f22d8
READ of size 8 at 0x7fa609c9d4e8 thread T0
#0 0x7fa609c5c1fc in print_header /user/kode/dislocker/src/metadata/datums.c:288:5
#1 0x7fa609c5b92e in print_one_datum /user/kode/dislocker/src/metadata/datums.c:260:2
#2 0x7fa609c5d4c1 in print_datum_vmk /user/kode/dislocker/src/metadata/datums.c:447:3
#3 0x7fa609c5b993 in print_one_datum /user/kode/dislocker/src/metadata/datums.c:265:3
#4 0x7fa609c6e20c in print_data /user/kode/dislocker/src/metadata/print_metadata.c:247:3
#5 0x7fa609c60eaf in dis_metadata_initialize /user/kode/dislocker/src/metadata/metadata.c:265:2
#6 0x7fa609c4fa30 in dis_initialize /user/kode/dislocker/src/dislocker.c:188:8
#7 0x55e435d92d6e in main /user/kode/dislocker/src/dislocker-fuse.c:222:5
#8 0x7fa60986d54f in __libc_start_call_main (/lib64/libc.so.6+0x2954f) (BuildId: ad65a880a208f9831f1031675a3ef1792e67c2fc)
#9 0x7fa60986d608 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x29608) (BuildId: ad65a880a208f9831f1031675a3ef1792e67c2fc)
#10 0x55e435c9d424 in _start (/user/kode/dislocker/src/dislocker-fuse+0x1f424) (BuildId: 46d2c626e01bf3feeb7f40039b1af5bf2ed51062)
0x7fa609c9d4e8 is located 8 bytes to the right of global variable 'value_type_str' defined in '/user/kode/dislocker/src/metadata/datums.c:34:20' (0x7fa609c9d440) of size 160
SUMMARY: AddressSanitizer: global-buffer-overflow /user/kode/dislocker/src/metadata/datums.c:288:5 in print_header
Shadow bytes around the buggy address:
0x0ff54138ba40: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x0ff54138ba50: f9 f9 f9 f9 f9 f9 00 00 00 00 f9 f9 f9 f9 f9 f9
0x0ff54138ba60: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0x0ff54138ba70: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00
0x0ff54138ba80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0ff54138ba90: 00 00 00 00 00 00 00 00 00 00 00 00 f9[f9]f9 f9
0x0ff54138baa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ff54138bab0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ff54138bac0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ff54138bad0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ff54138bae0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==147051==ABORTING
---
include/dislocker/metadata/datums.h | 4 +---
src/metadata/datums.c | 4 ++--
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/include/dislocker/metadata/datums.h b/include/dislocker/metadata/datums.h
index d092030d..6985a6f0 100644
--- a/include/dislocker/metadata/datums.h
+++ b/include/dislocker/metadata/datums.h
@@ -42,7 +42,7 @@
/**
* Here stand datums' value types stuff
*/
-#define NB_DATUMS_VALUE_TYPES 22
+#define NB_DATUMS_VALUE_TYPES 20
enum value_types
{
@@ -353,8 +353,6 @@ static const print_datum_f print_datum_tab[NB_DATUMS_VALUE_TYPES] =
print_datum_generic,
print_datum_generic,
print_datum_generic,
- print_datum_generic,
- print_datum_generic,
};
diff --git a/src/metadata/datums.c b/src/metadata/datums.c
index 14277b63..d4d2b5cb 100644
--- a/src/metadata/datums.c
+++ b/src/metadata/datums.c
@@ -229,7 +229,7 @@ int get_payload_safe(void* data, void** payload, size_t* size_payload)
if(!get_header_safe(data, &header))
return FALSE;
- if(header.value_type > NB_DATUMS_VALUE_TYPES)
+ if(header.value_type >= NB_DATUMS_VALUE_TYPES)
return FALSE;
size_header = datum_value_types_prop[header.value_type].size_header;
@@ -662,7 +662,7 @@ int get_nested_datum(void* datum, void** datum_nested)
if(!get_header_safe(datum, &header))
return FALSE;
- if(header.value_type > NB_DATUMS_VALUE_TYPES)
+ if(header.value_type >= NB_DATUMS_VALUE_TYPES)
return FALSE;
if(!datum_value_types_prop[header.value_type].has_nested_datum)
From e3b370c81a1de48af2a09a48b7192e9ef818fb79 Mon Sep 17 00:00:00 2001
From: Gabriel Kihlman <gk@sysctl.se>
Date: Tue, 21 Jun 2022 22:00:17 +0200
Subject: [PATCH 2/2] Check return value from argument parsing and exit if -1
Fixes an use heap after free crash when the user, for example, forgets a 'u' in front of the password :)
$ sudo ./src/dislocker-fuse -vvvvv -V /dev/loop100 -'tefe' -- /mnt
dislocker by Romain Coltel, v0.7.2 (compiled for Linux/x86_64)
Compiled version: master:44ea0da
Usage: dislocker [-hqrsv] [-l LOG_FILE] [-O OFFSET] [-V VOLUME DECRYPTMETHOD -F[N]] [-- ARGS...]
with DECRYPTMETHOD = -p[RECOVERY_PASSWORD]|-f BEK_FILE|-u[USER_PASSWORD]|-k FVEK_FILE|-K VMK_FILE|-c
Options:
-c, --clearkey decrypt volume using a clear key (default)
-f, --bekfile BEKFILE
decrypt volume using the bek file (on USB key)
-F, --force-block=[N] force use of metadata block number N (1, 2 or 3)
-h, --help print this help and exit
-k, --fvek FVEK_FILE decrypt volume using the FVEK directly
-K, --vmk VMK_FILE decrypt volume using the VMK directly
-l, --logfile LOG_FILE
put messages into this file (stdout by default)
-O, --offset OFFSET BitLocker partition offset, in bytes (default is 0)
-p, --recovery-password=[RECOVERY_PASSWORD]
decrypt volume using the recovery password method
-q, --quiet do NOT display anything
-r, --readonly do not allow to write on the BitLocker volume
-s, --stateok do not check the volume's state, assume it's ok to mount it
-u, --user-password=[USER_PASSWORD]
decrypt volume using the user password method
-v, --verbosity increase verbosity (CRITICAL errors are displayed by default)
-V, --volume VOLUME volume to get metadata and keys from
-- end of program options, beginning of FUSE's ones
ARGS are any arguments you want to pass to FUSE. You need to pass at least
the mount-point.
Tue Jun 21 21:53:08 2022 [DEBUG] Verbosity level to DEBUG (4) into 'stdout'
Tue Jun 21 21:53:08 2022 [INFO] dislocker by Romain Coltel, v0.7.2 (compiled for Linux/x86_64)
Tue Jun 21 21:53:08 2022 [INFO] Compiled version: master:44ea0da
Tue Jun 21 21:53:08 2022 [DEBUG] --- Config...
Tue Jun 21 21:53:08 2022 [DEBUG] Verbosity: 5
Tue Jun 21 21:53:08 2022 [DEBUG] Trying to decrypt '#'
Tue Jun 21 21:53:08 2022 [DEBUG] not using any decryption mean
Tue Jun 21 21:53:08 2022 [DEBUG] Using the first valid metadata block
Tue Jun 21 21:53:08 2022 [DEBUG] ... End config ---
Tue Jun 21 21:53:08 2022 [DEBUG] Trying to open '#'...
Tue Jun 21 21:53:08 2022 [DEBUG] Trying to open '#'...
=================================================================
==148764==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000000010 at pc 0x55683b69784b bp 0x7ffe50b3e1b0 sp 0x7ffe50b3d970
READ of size 2 at 0x602000000010 thread T0
#0 0x55683b69784a in printf_common(void*, char const*, __va_list_tag*) asan_interceptors.cpp.o
#1 0x55683b69af55 in __interceptor_vsnprintf (/user/kode/dislocker/src/dislocker-fuse+0xb0f55) (BuildId: 46d2c626e01bf3feeb7f40039b1af5bf2ed51062)
#2 0x55683b69b396 in __snprintf_chk (/user/kode/dislocker/src/dislocker-fuse+0xb1396) (BuildId: 46d2c626e01bf3feeb7f40039b1af5bf2ed51062)
#3 0x7f1b75c7921b in dis_open /user/kode/dislocker/src/common.c:62:3
#4 0x7f1b75c753d3 in dis_initialize /user/kode/dislocker/src/dislocker.c:131:20
#5 0x55683b6fed6e in main /user/kode/dislocker/src/dislocker-fuse.c:222:5
#6 0x7f1b7589454f in __libc_start_call_main (/lib64/libc.so.6+0x2954f) (BuildId: ad65a880a208f9831f1031675a3ef1792e67c2fc)
#7 0x7f1b75894608 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x29608) (BuildId: ad65a880a208f9831f1031675a3ef1792e67c2fc)
#8 0x55683b609424 in _start (/user/kode/dislocker/src/dislocker-fuse+0x1f424) (BuildId: 46d2c626e01bf3feeb7f40039b1af5bf2ed51062)
0x602000000010 is located 0 bytes inside of 13-byte region [0x602000000010,0x60200000001d)
freed by thread T0 here:
#0 0x55683b6ba9e8 in __interceptor_free.part.0 asan_malloc_linux.cpp.o
#1 0x7f1b75c80ca1 in dis_free /user/kode/dislocker/src/xstd/xstdlib.c:66:2
#2 0x55683b6fec70 in main /user/kode/dislocker/src/dislocker-fuse.c:201:14
#3 0x7f1b7589454f in __libc_start_call_main (/lib64/libc.so.6+0x2954f) (BuildId: ad65a880a208f9831f1031675a3ef1792e67c2fc)
previously allocated by thread T0 here:
#0 0x55683b683398 in strdup (/user/kode/dislocker/src/dislocker-fuse+0x99398) (BuildId: 46d2c626e01bf3feeb7f40039b1af5bf2ed51062)
#1 0x7f1b75c7bc34 in dis_setopt /user/kode/dislocker/src/config.c:552:24
SUMMARY: AddressSanitizer: heap-use-after-free asan_interceptors.cpp.o in printf_common(void*, char const*, __va_list_tag*)
Shadow bytes around the buggy address:
0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa[fd]fd fa fa fd fd fa fa fd fd fa fa fd fd
0x0c047fff8010: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fd
0x0c047fff8020: fa fa fd fd fa fa fd fd fa fa fd fd fa fa 00 07
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==148764==ABORTING enter the commit message for your changes. Lines starting
---
src/dislocker-fuse.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/dislocker-fuse.c b/src/dislocker-fuse.c
index a103e601..f01b9e46 100644
--- a/src/dislocker-fuse.c
+++ b/src/dislocker-fuse.c
@@ -199,6 +199,8 @@ int main(int argc, char** argv)
/* Get command line options */
dis_ctx = dis_new();
param_idx = dis_getopts(dis_ctx, argc, argv);
+ if (param_idx == -1)
+ exit(EXIT_FAILURE);
/*
* Check we have a volume path given and if not, take the first non-argument