1
mirror of https://github.com/hashcat/hashcat synced 2024-11-24 14:27:14 +01:00

Merge pull request #3704 from matrix/fix_MTLCompilerService_InfiniteLoop_bug

Metal Backend: added workaround to prevent 'Infinite Loop' bug when build kernels
This commit is contained in:
Jens Steube 2023-05-05 13:20:12 +02:00 committed by GitHub
commit 56b322cf6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 104 additions and 38 deletions

View File

@ -83,6 +83,8 @@
- 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
- User Options: added --metal-compiler-runtime option
* changes v6.2.5 -> v6.2.6

View File

@ -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;

View File

@ -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);
// 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);
__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)
{

View File

@ -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 |",

View File

@ -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,15 @@ int user_options_sanity (hashcat_ctx_t *hashcat_ctx)
return -1;
}
// --metal-compiler-runtime is really used 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 +3218,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);