From 3f341290510d222ffbfd9209694374b8b0060e37 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Thu, 16 Jan 2025 21:09:54 +0100 Subject: [PATCH] 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 --- src/login_nopam.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) 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 */