From: Tobias Stoeckmann Date: Thu, 16 Jan 2025 20:09:54 +0000 (+0100) Subject: src/login_nopam.c: list_match(): Use iteration instead of recursion X-Git-Tag: 4.17.3~65 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=3f341290510d222ffbfd9209694374b8b0060e37;p=thirdparty%2Fshadow.git src/login_nopam.c: list_match(): Use iteration instead of recursion The recursive nature of list_match() triggered regression during refactoring. In Linux-PAM, the same code exists which could lead to stack overflow because could be arbitrarily long. Use an iterative approach for easier refactoring, to support long lines in the future and to stay in sync with Linux-PAM. Signed-off-by: Tobias Stoeckmann Reviewed-by: Serge Hallyn Signed-off-by: Alejandro Colomar --- diff --git a/src/login_nopam.c b/src/login_nopam.c index ca04f68bb..896ab9410 100644 --- a/src/login_nopam.c +++ b/src/login_nopam.c @@ -147,29 +147,31 @@ static bool list_match(char *list, const char *item, bool (*match_fn)(char *, const char*)) { char *tok; + bool inclusion = true; + bool matched = false; + bool result = false; /* * Process tokens one at a time. We have exhausted all possible matches * when we reach an "EXCEPT" token or the end of the list. If we do find - * a match, look for an "EXCEPT" list and recurse to determine whether - * the match is affected by any exceptions. + * a match, look for an "EXCEPT" list and determine whether the match is + * affected by any exceptions. */ while (NULL != (tok = strsep(&list, ", \t"))) { - if (strcasecmp (tok, "EXCEPT") == 0) { /* EXCEPT: give up */ - break; + if (strcasecmp (tok, "EXCEPT") == 0) { /* EXCEPT: invert */ + if (!matched) { /* stop processing: not part of list */ + break; + } + inclusion = !inclusion; + matched = false; } else if ((*match_fn)(tok, item)) { - while ( (NULL != (tok = strsep(&list, ", \t"))) - && (strcasecmp (tok, "EXCEPT") != 0)) - /* VOID */ ; - if (tok == NULL || !list_match(list, item, match_fn)) { - return true; - } - break; + result = inclusion; + matched = true; } } - return false; + return result; } /* myhostname - figure out local machine name */