Skip to content

Commit

Permalink
Wordlist mode: Avoid PerRuleStats infinite loop with dupe suppressor
Browse files Browse the repository at this point in the history
Also ignore (force-disable) PerRuleStats with mask or when not logging

Fixes openwall#5148
  • Loading branch information
solardiz committed May 29, 2022
1 parent 78e8d46 commit 014ce22
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 6 deletions.
7 changes: 3 additions & 4 deletions src/cracker.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ int64_t crk_pot_pos;
void (*crk_fix_state)(void);
int (*crk_process_key)(char *key);

static int process_key(char *key);
static int process_key_stack_rules(char *key);

/* Expose max_keys_per_crypt to the world (needed in recovery.c) */
Expand Down Expand Up @@ -260,7 +259,7 @@ void crk_init(struct db_main *db, void (*fix_state)(void),
if (rules_stacked_after)
crk_process_key = process_key_stack_rules;
else
crk_process_key = process_key;
crk_process_key = crk_direct_process_key;

/*
* Resetting crk_process_key above disables the suppressor, but it can
Expand Down Expand Up @@ -1157,7 +1156,7 @@ int crk_process_buffer(void)
* All modes but Single call this function (as crk_process_key)
* for each candidate.
*/
static int process_key(char *key)
int crk_direct_process_key(char *key)
{
if (crk_key_index < crk_process_key_max_keys) {
crk_methods.set_key(key, crk_key_index++);
Expand Down Expand Up @@ -1236,7 +1235,7 @@ static int process_key_stack_rules(char *key)
char *word;

while ((word = rules_process_stack_all(key, &crk_rule_stack)))
if ((ret = process_key(word)))
if ((ret = crk_direct_process_key(word)))
break;

return ret;
Expand Down
6 changes: 6 additions & 0 deletions src/cracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ extern int crk_stacked_rule_count;
* The return value is non-zero if aborted or everything got cracked (the
* event_abort flag can be used to find out which of these has happened).
*/
extern int crk_direct_process_key(char *key);

/*
* Indirect way to call either crk_direct_process_key() or sometimes a wrapper
* around it implementing stacked rules or/and dupe suppression.
*/
extern int (*crk_process_key)(char *key);

/*
Expand Down
5 changes: 3 additions & 2 deletions src/wordlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,8 @@ void do_wordlist_crack(struct db_main *db, const char *name, int rules)

static unsigned int prev_g;
static unsigned long long prev_p;
if (rules && cfg_get_bool(SECTION_OPTIONS, NULL, "PerRuleStats", 0)) {
if (rules && cfg_get_bool(SECTION_OPTIONS, NULL, "PerRuleStats", 0) && !(options.flags & FLG_MASK_CHK) &&
(!(options.flags & FLG_NOLOG) || options.log_stderr)) {
rules = 2;
prev_g = status.guess_count;
prev_p = status.cands;
Expand Down Expand Up @@ -1399,7 +1400,7 @@ void do_wordlist_crack(struct db_main *db, const char *name, int rules)
if (rules > 1 && prerule) {
unsigned long long p = status.cands, fake_p = 0;
if (!(options.flags & FLG_STDOUT)) do {
crk_process_key("injected wrong password");
crk_direct_process_key("injected wrong password");
fake_p++;
} while (p == status.cands);
unsigned int g = status.guess_count - prev_g;
Expand Down

0 comments on commit 014ce22

Please sign in to comment.