From 5f332995bca867235944f9d043eecdef140563ff Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Tue, 25 Apr 2023 17:17:46 +0200 Subject: [PATCH 1/4] Metal Backend: added workaround to prevent 'Infinite Loop' bug when build kernels --- docs/changes.txt | 1 + src/ext_metal.m | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 9534377b7..47c34f6ff 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -77,6 +77,7 @@ - Unicode: Update UTF-8 to UTF-16 conversion to match RFC 3629 - User Options: Added error message when mixing --username and --show to warn users of exponential delay - MetaMask: update extraction tool to support MetaMask Mobile wallets +- Metal Backend: added workaround to prevent 'Infinite Loop' bug when build kernels * changes v6.2.5 -> v6.2.6 diff --git a/src/ext_metal.m b/src/ext_metal.m index b8428369c..bbfb8dbb7 100644 --- a/src/ext_metal.m +++ b/src/ext_metal.m @@ -681,7 +681,8 @@ int hc_mtlCreateCommandQueue (void *hashcat_ctx, mtl_device_id metal_device, mtl int hc_mtlCreateKernel (void *hashcat_ctx, mtl_device_id metal_device, mtl_library metal_library, const char *func_name, mtl_function *metal_function, mtl_pipeline *metal_pipeline) { - backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + user_options_t *user_options = ((hashcat_ctx_t *) hashcat_ctx)->user_options; MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; @@ -708,7 +709,7 @@ int hc_mtlCreateKernel (void *hashcat_ctx, mtl_device_id metal_device, mtl_libra return -1; } - NSError *error = nil; + __block NSError *error = nil; NSString *f_name = [NSString stringWithCString: func_name encoding: NSUTF8StringEncoding]; @@ -721,6 +722,9 @@ int hc_mtlCreateKernel (void *hashcat_ctx, mtl_device_id metal_device, mtl_libra return -1; } + // workaround for MTLCompilerService 'Infinite Loop' bug + + /* mtl_pipeline mtl_pipe = [metal_device newComputePipelineStateWithFunction: mtl_func error: &error]; if (error != nil) @@ -729,6 +733,46 @@ int hc_mtlCreateKernel (void *hashcat_ctx, mtl_device_id metal_device, mtl_libra return -1; } + */ + + error = nil; + + __block mtl_pipeline mtl_pipe; + + dispatch_group_t group = dispatch_group_create (); + dispatch_queue_t queue = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + + // wait for 60 secs by default or using user-defined runtime if is set + long timeout = (user_options->runtime > 0) ? user_options->runtime : 60; + + dispatch_time_t when = dispatch_time (DISPATCH_TIME_NOW,NSEC_PER_SEC * timeout); + + __block int rc_async_err = 0; + + dispatch_group_async (group, queue, ^(void) + { + mtl_pipe = [metal_device newComputePipelineStateWithFunction: mtl_func error: &error]; + + if (error != nil) + { + event_log_error (hashcat_ctx, "%s(): failed to create '%s' pipeline, %s", __func__, func_name, [[error localizedDescription] UTF8String]); + + rc_async_err = -1; + } + }); + + long rc_queue = dispatch_group_wait (group, when); + + dispatch_release (group); + + if (rc_async_err != 0) return -1; + + if (rc_queue != 0) + { + event_log_error (hashcat_ctx, "%s(): failed to create '%s' pipeline, timeout reached (status %ld)", __func__, func_name, rc_queue); + + return -1; + } if (mtl_pipe == nil) { From 5ac38b381d2177f6efebc98ae1398d74f8f68933 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Wed, 26 Apr 2023 03:11:55 +0200 Subject: [PATCH 2/4] updated default build timeout on Apple Metal to 120 seconds --- src/ext_metal.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ext_metal.m b/src/ext_metal.m index bbfb8dbb7..d4a1b3102 100644 --- a/src/ext_metal.m +++ b/src/ext_metal.m @@ -742,8 +742,8 @@ int hc_mtlCreateKernel (void *hashcat_ctx, mtl_device_id metal_device, mtl_libra dispatch_group_t group = dispatch_group_create (); dispatch_queue_t queue = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - // wait for 60 secs by default or using user-defined runtime if is set - long timeout = (user_options->runtime > 0) ? user_options->runtime : 60; + // wait for 120 secs by default or using user-defined runtime if is set + long timeout = (user_options->runtime > 0) ? user_options->runtime : 120; dispatch_time_t when = dispatch_time (DISPATCH_TIME_NOW,NSEC_PER_SEC * timeout); From e6d1a4c8a252d377b8dc42a8f298861b7fa0ca68 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Mon, 1 May 2023 03:33:35 +0200 Subject: [PATCH 3/4] Added --metal-compiler-runtime option --- include/types.h | 76 ++++++++++++++++++++++++---------------------- src/ext_metal.m | 4 +-- src/usage.c | 1 + src/user_options.c | 16 ++++++++++ 4 files changed, 59 insertions(+), 38 deletions(-) diff --git a/include/types.h b/include/types.h index 9570189cb..c34ae9eb4 100644 --- a/include/types.h +++ b/include/types.h @@ -674,6 +674,7 @@ typedef enum user_options_defaults MARKOV_DISABLE = false, MARKOV_INVERSE = false, MARKOV_THRESHOLD = 0, + METAL_COMPILER_RUNTIME = 120, NONCE_ERROR_CORRECTIONS = 8, BACKEND_IGNORE_CUDA = false, BACKEND_IGNORE_HIP = false, @@ -793,56 +794,57 @@ typedef enum user_options_map IDX_MARKOV_HCSTAT2 = 0xff2d, IDX_MARKOV_INVERSE = 0xff2e, IDX_MARKOV_THRESHOLD = 't', - IDX_NONCE_ERROR_CORRECTIONS = 0xff2f, + IDX_METAL_COMPILER_RUNTIME = 0xff2f, + IDX_NONCE_ERROR_CORRECTIONS = 0xff30, IDX_OPENCL_DEVICE_TYPES = 'D', IDX_OPTIMIZED_KERNEL_ENABLE = 'O', IDX_MULTIPLY_ACCEL_DISABLE = 'M', - IDX_OUTFILE_AUTOHEX_DISABLE = 0xff30, - IDX_OUTFILE_CHECK_DIR = 0xff31, - IDX_OUTFILE_CHECK_TIMER = 0xff32, - IDX_OUTFILE_FORMAT = 0xff33, + IDX_OUTFILE_AUTOHEX_DISABLE = 0xff31, + IDX_OUTFILE_CHECK_DIR = 0xff32, + IDX_OUTFILE_CHECK_TIMER = 0xff33, + IDX_OUTFILE_FORMAT = 0xff34, IDX_OUTFILE = 'o', - IDX_POTFILE_DISABLE = 0xff34, - IDX_POTFILE_PATH = 0xff35, - IDX_PROGRESS_ONLY = 0xff36, - IDX_QUIET = 0xff37, - IDX_REMOVE = 0xff38, - IDX_REMOVE_TIMER = 0xff39, - IDX_RESTORE = 0xff3a, - IDX_RESTORE_DISABLE = 0xff3b, - IDX_RESTORE_FILE_PATH = 0xff3c, + IDX_POTFILE_DISABLE = 0xff35, + IDX_POTFILE_PATH = 0xff36, + IDX_PROGRESS_ONLY = 0xff37, + IDX_QUIET = 0xff38, + IDX_REMOVE = 0xff39, + IDX_REMOVE_TIMER = 0xff3a, + IDX_RESTORE = 0xff3b, + IDX_RESTORE_DISABLE = 0xff3c, + IDX_RESTORE_FILE_PATH = 0xff3d, IDX_RP_FILE = 'r', - IDX_RP_GEN_FUNC_MAX = 0xff3d, - IDX_RP_GEN_FUNC_MIN = 0xff3e, - IDX_RP_GEN_FUNC_SEL = 0xff3f, + IDX_RP_GEN_FUNC_MAX = 0xff3e, + IDX_RP_GEN_FUNC_MIN = 0xff3f, + IDX_RP_GEN_FUNC_SEL = 0xff40, IDX_RP_GEN = 'g', - IDX_RP_GEN_SEED = 0xff40, + IDX_RP_GEN_SEED = 0xff41, IDX_RULE_BUF_L = 'j', IDX_RULE_BUF_R = 'k', - IDX_RUNTIME = 0xff41, - IDX_SCRYPT_TMTO = 0xff42, + IDX_RUNTIME = 0xff42, + IDX_SCRYPT_TMTO = 0xff43, IDX_SEGMENT_SIZE = 'c', - IDX_SELF_TEST_DISABLE = 0xff43, + IDX_SELF_TEST_DISABLE = 0xff44, IDX_SEPARATOR = 'p', - IDX_SESSION = 0xff44, - IDX_SHOW = 0xff45, + IDX_SESSION = 0xff45, + IDX_SHOW = 0xff46, IDX_SKIP = 's', IDX_SLOW_CANDIDATES = 'S', - IDX_SPEED_ONLY = 0xff46, - IDX_SPIN_DAMP = 0xff47, - IDX_STATUS = 0xff48, - IDX_STATUS_JSON = 0xff49, - IDX_STATUS_TIMER = 0xff4a, - IDX_STDOUT_FLAG = 0xff4b, - IDX_STDIN_TIMEOUT_ABORT = 0xff4c, - IDX_TRUECRYPT_KEYFILES = 0xff4d, - IDX_USERNAME = 0xff4e, - IDX_VERACRYPT_KEYFILES = 0xff4f, - IDX_VERACRYPT_PIM_START = 0xff50, - IDX_VERACRYPT_PIM_STOP = 0xff51, + IDX_SPEED_ONLY = 0xff47, + IDX_SPIN_DAMP = 0xff48, + IDX_STATUS = 0xff49, + IDX_STATUS_JSON = 0xff4a, + IDX_STATUS_TIMER = 0xff4b, + IDX_STDOUT_FLAG = 0xff4c, + IDX_STDIN_TIMEOUT_ABORT = 0xff4d, + IDX_TRUECRYPT_KEYFILES = 0xff4e, + IDX_USERNAME = 0xff4f, + IDX_VERACRYPT_KEYFILES = 0xff50, + IDX_VERACRYPT_PIM_START = 0xff51, + IDX_VERACRYPT_PIM_STOP = 0xff52, IDX_VERSION_LOWER = 'v', IDX_VERSION = 'V', - IDX_WORDLIST_AUTOHEX_DISABLE = 0xff52, + IDX_WORDLIST_AUTOHEX_DISABLE = 0xff53, IDX_WORKLOAD_PROFILE = 'w', } user_options_map_t; @@ -2311,6 +2313,7 @@ typedef struct user_options bool remove_timer_chgd; bool rp_gen_seed_chgd; bool runtime_chgd; + bool metal_compiler_runtime_chgd; bool segment_size_chgd; bool workload_profile_chgd; bool skip_chgd; @@ -2435,6 +2438,7 @@ typedef struct user_options u32 rp_gen_func_min; u32 rp_gen_seed; u32 runtime; + u32 metal_compiler_runtime; u32 scrypt_tmto; u32 segment_size; u32 status_timer; diff --git a/src/ext_metal.m b/src/ext_metal.m index d4a1b3102..a9ab89229 100644 --- a/src/ext_metal.m +++ b/src/ext_metal.m @@ -742,8 +742,8 @@ int hc_mtlCreateKernel (void *hashcat_ctx, mtl_device_id metal_device, mtl_libra dispatch_group_t group = dispatch_group_create (); dispatch_queue_t queue = dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - // wait for 120 secs by default or using user-defined runtime if is set - long timeout = (user_options->runtime > 0) ? user_options->runtime : 120; + // if no user-defined runtime, set to METAL_COMPILER_RUNTIME + long timeout = (user_options->metal_compiler_runtime > 0) ? user_options->metal_compiler_runtime : METAL_COMPILER_RUNTIME; dispatch_time_t when = dispatch_time (DISPATCH_TIME_NOW,NSEC_PER_SEC * timeout); diff --git a/src/usage.c b/src/usage.c index 21f67934a..003a6eea6 100644 --- a/src/usage.c +++ b/src/usage.c @@ -49,6 +49,7 @@ static const char *const USAGE_BIG_PRE_HASHMODES[] = " --markov-classic | | Enables classic markov-chains, no per-position |", " --markov-inverse | | Enables inverse markov-chains, no per-position |", " -t, --markov-threshold | Num | Threshold X when to stop accepting new markov-chains | -t 50", + " --metal-compiler-runtime | Num | Abort Metal kernel build after X seconds of runtime | --metal-compiler-runtime=180", " --runtime | Num | Abort session after X seconds of runtime | --runtime=10", " --session | Str | Define specific session name | --session=mysession", " --restore | | Restore session from --session |", diff --git a/src/user_options.c b/src/user_options.c index 4198fa3bc..960031f2f 100644 --- a/src/user_options.c +++ b/src/user_options.c @@ -94,6 +94,7 @@ static const struct option long_options[] = {"markov-hcstat2", required_argument, NULL, IDX_MARKOV_HCSTAT2}, {"markov-inverse", no_argument, NULL, IDX_MARKOV_INVERSE}, {"markov-threshold", required_argument, NULL, IDX_MARKOV_THRESHOLD}, + {"metal-compiler-runtime", required_argument, NULL, IDX_METAL_COMPILER_RUNTIME}, {"nonce-error-corrections", required_argument, NULL, IDX_NONCE_ERROR_CORRECTIONS}, {"opencl-device-types", required_argument, NULL, IDX_OPENCL_DEVICE_TYPES}, {"optimized-kernel-enable", no_argument, NULL, IDX_OPTIMIZED_KERNEL_ENABLE}, @@ -236,6 +237,7 @@ int user_options_init (hashcat_ctx_t *hashcat_ctx) user_options->markov_hcstat2 = NULL; user_options->markov_inverse = MARKOV_INVERSE; user_options->markov_threshold = MARKOV_THRESHOLD; + user_options->metal_compiler_runtime = METAL_COMPILER_RUNTIME; user_options->nonce_error_corrections = NONCE_ERROR_CORRECTIONS; user_options->opencl_device_types = NULL; user_options->optimized_kernel_enable = OPTIMIZED_KERNEL_ENABLE; @@ -330,6 +332,7 @@ int user_options_getopt (hashcat_ctx_t *hashcat_ctx, int argc, char **argv) case IDX_STATUS_TIMER: case IDX_HASH_MODE: case IDX_RUNTIME: + case IDX_METAL_COMPILER_RUNTIME: case IDX_ATTACK_MODE: case IDX_RP_GEN: case IDX_RP_GEN_FUNC_MIN: @@ -436,6 +439,8 @@ int user_options_getopt (hashcat_ctx_t *hashcat_ctx, int argc, char **argv) user_options->hash_mode_chgd = true; break; case IDX_RUNTIME: user_options->runtime = hc_strtoul (optarg, NULL, 10); user_options->runtime_chgd = true; break; + case IDX_METAL_COMPILER_RUNTIME: user_options->metal_compiler_runtime = hc_strtoul (optarg, NULL, 10); + user_options->metal_compiler_runtime_chgd = true; break; case IDX_ATTACK_MODE: user_options->attack_mode = hc_strtoul (optarg, NULL, 10); user_options->attack_mode_chgd = true; break; case IDX_RP_FILE: user_options->rp_files[user_options->rp_files_cnt++] = optarg; break; @@ -732,6 +737,16 @@ int user_options_sanity (hashcat_ctx_t *hashcat_ctx) return -1; } + // --metal-compiler-runtime is really used only on Apple, + // but is useless to expose only on Apple + + if (user_options->metal_compiler_runtime_chgd == true && user_options->metal_compiler_runtime == 0) + { + event_log_error (hashcat_ctx, "Invalid --metal-compiler-runtime value specified (must be > 0)."); + + return -1; + } + if (user_options->limit_chgd == true && user_options->loopback == true) { event_log_error (hashcat_ctx, "Combining --limit with --loopback is not allowed."); @@ -3204,6 +3219,7 @@ void user_options_logger (hashcat_ctx_t *hashcat_ctx) logfile_top_uint (user_options->markov_disable); logfile_top_uint (user_options->markov_inverse); logfile_top_uint (user_options->markov_threshold); + logfile_top_uint (user_options->metal_compiler_runtime); logfile_top_uint (user_options->multiply_accel_disable); logfile_top_uint (user_options->backend_info); logfile_top_uint (user_options->backend_vector_width); From 2fe2d299bc3f40096c6739a578d5aa17e3a2fd78 Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Mon, 1 May 2023 03:44:39 +0200 Subject: [PATCH 4/4] update changes.txt + cleanup --- docs/changes.txt | 1 + src/user_options.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 502feeb5b..4d9bf3438 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -82,6 +82,7 @@ - User Options: Added error message when mixing --username and --show to warn users of exponential delay - MetaMask: update extraction tool to support MetaMask Mobile wallets - Metal Backend: added workaround to prevent 'Infinite Loop' bug when build kernels +- User Options: added --metal-compiler-runtime option * changes v6.2.5 -> v6.2.6 diff --git a/src/user_options.c b/src/user_options.c index 960031f2f..50da0dbd7 100644 --- a/src/user_options.c +++ b/src/user_options.c @@ -737,8 +737,7 @@ int user_options_sanity (hashcat_ctx_t *hashcat_ctx) return -1; } - // --metal-compiler-runtime is really used only on Apple, - // but is useless to expose only on Apple + // --metal-compiler-runtime is really used only on Apple if (user_options->metal_compiler_runtime_chgd == true && user_options->metal_compiler_runtime == 0) {