In cfg_parse_users(), we scan all config keywords and only want to
evaluate those whose section is CFG_USERLIST. However, the section
is checked as a bit field instead of an equality, and CFG_USERLIST
is 3, which is CFG_GLOBAL|CFG_LISTEN, meaning that we can call a
wrong parser for keywords "user" or "group" when they are registered
in one of these sections. This is what randomly happens when the
global "group" keyword is refactored to have its own parser, depending
on build options the linker, it may randomly be found before or after
the userlist's and cause startup failures if the global section's
keyword parser is called from the userlist parser, such as in this
regtest that only fails with ASAN on the CI when the config only has
"group" set in a userlist section:
config : parsing [cfg:18] : cannot find group id for 'admins' (0:Success)
This was introduced in 3.4 with commit
c17ed69bf3 ("MINOR: cfgparse:
Refactor "userlist" parser to print it in -dKall operation") so it must
be backported there.
If a config works it's OK, but this was still marked major because
there's simply no workaround for a failing binary where it only
depends on build options. It could happen for example if other
keywords are added via Lua or patches.
#endif
}
-int
-cfg_parse_users(const char *file, int linenum, char **args, int kwm)
+/* parser for a "userlist" section */
+int cfg_parse_users(const char *file, int linenum, char **args, int kwm)
{
int err_code = 0;
list_for_each_entry(kwl, &cfg_keywords.list, list) {
for (index = 0; kwl->kw[index].kw; index++) {
- if ((kwl->kw[index].section & CFG_USERLIST) &&
+ if ((kwl->kw[index].section == CFG_USERLIST) &&
(strcmp(kwl->kw[index].kw, args[0]) == 0)) {
err_code |= kwl->kw[index].parse(args, CFG_USERLIST, NULL, NULL, file, linenum, &errmsg);
if (errmsg) {