diff --git a/MANIFEST b/MANIFEST index a053265cb..174cc88f4 100644 --- a/MANIFEST +++ b/MANIFEST @@ -245,6 +245,7 @@ lib/util/progname.c lib/util/pw_dup.c lib/util/pwrite.c lib/util/rcstr.c +lib/util/regex.c lib/util/reallocarray.c lib/util/regress/corpus/seed/sudo_conf/sudo.conf.1 lib/util/regress/corpus/seed/sudo_conf/sudo.conf.2 diff --git a/docs/sudo_logsrvd.conf.man.in b/docs/sudo_logsrvd.conf.man.in index 5c2598133..d66a18b3c 100644 --- a/docs/sudo_logsrvd.conf.man.in +++ b/docs/sudo_logsrvd.conf.man.in @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.TH "SUDO_LOGSRVD.CONF" "@mansectform@" "February 10, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.TH "SUDO_LOGSRVD.CONF" "@mansectform@" "February 11, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual" .nh .if n .ad l .SH "NAME" @@ -641,6 +641,9 @@ One or more POSIX extended regular expressions used to match password prompts in the terminal output when \fIlog_passwords\fR is disabled. +As an extension, if the regular expression begins with +\(lq(?i)\(rq, +it will be matched in a case-insensitive manner. Multiple \fIpassprompt_regex\fR settings may be specified. diff --git a/docs/sudo_logsrvd.conf.mdoc.in b/docs/sudo_logsrvd.conf.mdoc.in index 66d8723de..ee20ce28f 100644 --- a/docs/sudo_logsrvd.conf.mdoc.in +++ b/docs/sudo_logsrvd.conf.mdoc.in @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd February 10, 2022 +.Dd February 11, 2022 .Dt SUDO_LOGSRVD.CONF @mansectform@ .Os Sudo @PACKAGE_VERSION@ .Sh NAME @@ -571,6 +571,9 @@ One or more POSIX extended regular expressions used to match password prompts in the terminal output when .Em log_passwords is disabled. +As an extension, if the regular expression begins with +.Dq (?i) , +it will be matched in a case-insensitive manner. Multiple .Em passprompt_regex settings may be specified. diff --git a/docs/sudoers.man.in b/docs/sudoers.man.in index a63061d60..919647573 100644 --- a/docs/sudoers.man.in +++ b/docs/sudoers.man.in @@ -25,7 +25,7 @@ .nr BA @BAMAN@ .nr LC @LCMAN@ .nr PS @PSMAN@ -.TH "SUDOERS" "@mansectform@" "February 10, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.TH "SUDOERS" "@mansectform@" "February 11, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual" .nh .if n .ad l .SH "NAME" @@ -5424,6 +5424,9 @@ This setting is only supported by version 1.9.0 or higher. passprompt_regex A list of POSIX extended regular expressions used to match password prompts in the terminal output. +As an extension, if the regular expression begins with +\(lq(?i)\(rq, +it will be matched in a case-insensitive manner. This option is only used when \fIlog_passwords\fR has been disabled. diff --git a/docs/sudoers.mdoc.in b/docs/sudoers.mdoc.in index c0433eecd..90adf9763 100644 --- a/docs/sudoers.mdoc.in +++ b/docs/sudoers.mdoc.in @@ -24,7 +24,7 @@ .nr BA @BAMAN@ .nr LC @LCMAN@ .nr PS @PSMAN@ -.Dd February 10, 2022 +.Dd February 11, 2022 .Dt SUDOERS @mansectform@ .Os Sudo @PACKAGE_VERSION@ .Sh NAME @@ -5062,6 +5062,9 @@ This setting is only supported by version 1.9.0 or higher. .It passprompt_regex A list of POSIX extended regular expressions used to match password prompts in the terminal output. +As an extension, if the regular expression begins with +.Dq (?i) , +it will be matched in a case-insensitive manner. This option is only used when .Em log_passwords has been disabled. diff --git a/include/sudo_util.h b/include/sudo_util.h index 9f115746b..2fd543e17 100644 --- a/include/sudo_util.h +++ b/include/sudo_util.h @@ -256,6 +256,10 @@ sudo_dso_public char *sudo_rcstr_alloc(size_t len); sudo_dso_public char *sudo_rcstr_addref(const char *s); sudo_dso_public void sudo_rcstr_delref(const char *s); +/* regex.c */ +sudo_dso_public bool sudo_regex_compile_v1(void *v, const char *pattern, const char **errstr); +#define sudo_regex_compile(_a, _b, _c) sudo_regex_compile_v1((_a), (_b), (_c)) + /* roundup.c */ sudo_dso_public unsigned int sudo_pow2_roundup_v1(unsigned int len); #define sudo_pow2_roundup(_a) sudo_pow2_roundup_v1((_a)) diff --git a/lib/iolog/iolog_filter.c b/lib/iolog/iolog_filter.c index 040068e09..c27ee597f 100644 --- a/lib/iolog/iolog_filter.c +++ b/lib/iolog/iolog_filter.c @@ -41,6 +41,7 @@ #include "sudo_gettext.h" #include "sudo_iolog.h" #include "sudo_queue.h" +#include "sudo_util.h" struct pwfilt_regex { TAILQ_ENTRY(pwfilt_regex) entries; @@ -110,51 +111,6 @@ iolog_pwfilt_free(void *vhandle) debug_return; } -/* - * Like strdup but collapses repeated '?', '*' and '+' ops in a regex. - * Glibc regcomp() has a bug where it uses excessive memory for repeated - * '+' ops. Collapse them to avoid running the fuzzer out of memory. - */ -static char * -dup_pattern(const char *src) -{ - char *dst, *ret; - char ch, prev = '\0'; - size_t len; - debug_decl(dup_pattern, SUDO_DEBUG_UTIL); - - len = strlen(src); - ret = malloc(len + 1); - if (ret == NULL) - debug_return_ptr(NULL); - - dst = ret; - while ((ch = *src++) != '\0') { - switch (ch) { - case '\\': - if (*src != '\0') { - *dst++ = '\\'; - *dst++ = *src++; - prev = '\0'; - continue; - } - break; - case '?': - case '*': - case '+': - if (ch == prev) { - continue; - } - break; - } - *dst++ = ch; - prev = ch; - } - *dst = '\0'; - - debug_return_ptr(ret); -} - /* * Add a pattern to the password filter list. */ @@ -163,22 +119,19 @@ iolog_pwfilt_add(void *vhandle, const char *pattern) { struct pwfilt_handle *handle = vhandle; struct pwfilt_regex *filt; - char errbuf[1024]; - int errcode; + const char *errstr; debug_decl(iolog_pwfilt_add, SUDO_DEBUG_UTIL); filt = malloc(sizeof(*filt)); if (filt == NULL) goto oom; - filt->pattern = dup_pattern(pattern); + filt->pattern = strdup(pattern); if (filt->pattern == NULL) goto oom; - errcode = regcomp(&filt->regex, filt->pattern, REG_EXTENDED|REG_NOSUB); - if (errcode != 0) { - regerror(errcode, &filt->regex, errbuf, sizeof(errbuf)); + if (!sudo_regex_compile(&filt->regex, filt->pattern, &errstr)) { sudo_warnx(U_("invalid regular expression \"%s\": %s"), - pattern, errbuf); + pattern, U_(errstr)); goto bad; } diff --git a/lib/util/Makefile.in b/lib/util/Makefile.in index 048191cda..aa6bf6a0c 100644 --- a/lib/util/Makefile.in +++ b/lib/util/Makefile.in @@ -1,7 +1,7 @@ # # SPDX-License-Identifier: ISC # -# Copyright (c) 2011-2021 Todd C. Miller +# Copyright (c) 2011-2022 Todd C. Miller # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -140,9 +140,9 @@ SHELL = @SHELL@ LTOBJS = basename.lo @DIGEST@ event.lo fatal.lo key_val.lo gethostname.lo \ gettime.lo getgrouplist.lo gidlist.lo json.lo lbuf.lo locking.lo \ - logfac.lo logpri.lo mkdir_parents.lo parseln.lo progname.lo rcstr.lo \ - roundup.lo secure_path.lo setgroups.lo strsplit.lo strtobool.lo \ - strtoid.lo strtomode.lo strtonum.lo sudo_conf.lo \ + logfac.lo logpri.lo mkdir_parents.lo parseln.lo progname.lo rcstr.lo \ + regex.lo roundup.lo secure_path.lo setgroups.lo strsplit.lo \ + strtobool.lo strtoid.lo strtomode.lo strtonum.lo sudo_conf.lo \ sudo_debug.lo sudo_dso.lo term.lo ttyname_dev.lo \ ttysize.lo uuid.lo @COMMON_OBJS@ @LTLIBOBJS@ @@ -1212,6 +1212,16 @@ reallocarray.i: $(srcdir)/reallocarray.c $(incdir)/sudo_compat.h \ $(CC) -E -o $@ $(CPPFLAGS) $< reallocarray.plog: reallocarray.i rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/reallocarray.c --i-file $< --output-file $@ +regex.lo: $(srcdir)/regex.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ + $(incdir)/sudo_debug.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ + $(top_builddir)/config.h + $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regex.c +regex.i: $(srcdir)/regex.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ + $(incdir)/sudo_debug.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ + $(top_builddir)/config.h + $(CC) -E -o $@ $(CPPFLAGS) $< +regex.plog: regex.i + rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regex.c --i-file $< --output-file $@ roundup.lo: $(srcdir)/roundup.c $(incdir)/compat/stdbool.h \ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \ $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ diff --git a/lib/util/regex.c b/lib/util/regex.c new file mode 100644 index 000000000..64721c09f --- /dev/null +++ b/lib/util/regex.c @@ -0,0 +1,131 @@ +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 2022 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This is an open source non-commercial project. Dear PVS-Studio, please check it. + * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + */ + +#include + +#include +#include +#include +#include + +#include "sudo_compat.h" +#include "sudo_debug.h" +#include "sudo_util.h" +#include "sudo_gettext.h" + +static char errbuf[1024]; + +/* + * Like strdup but collapses repeated '?', '*' and '+' ops in a regex. + * Glibc regcomp() has a bug where it uses excessive memory for repeated + * '+' ops. Collapse them to avoid running the fuzzer out of memory. + */ +static char * +dup_pattern(const char *src) +{ + char *dst, *ret; + char ch, prev = '\0'; + size_t len; + debug_decl(dup_pattern, SUDO_DEBUG_UTIL); + + len = strlen(src); + ret = malloc(len + 1); + if (ret == NULL) + debug_return_ptr(NULL); + + dst = ret; + while ((ch = *src++) != '\0') { + switch (ch) { + case '\\': + if (*src != '\0') { + *dst++ = '\\'; + *dst++ = *src++; + prev = '\0'; + continue; + } + break; + case '?': + case '*': + case '+': + if (ch == prev) { + continue; + } + break; + } + *dst++ = ch; + prev = ch; + } + *dst = '\0'; + + debug_return_ptr(ret); +} + +/* + * Wrapper around regcomp() that handles a regex starting with (?i). + * Avoid using regex_t in the function args so we don't need to + * include regex.h everywhere. + */ +bool +sudo_regex_compile_v1(void *v, const char *pattern, const char **errstr) +{ + int errcode, cflags = REG_EXTENDED|REG_NOSUB; + regex_t *preg; + char *copy = NULL; + const char *cp; + regex_t rebuf; + debug_decl(regex_compile, SUDO_DEBUG_UTIL); + + /* Some callers just want to check the validity of the pattern. */ + preg = v ? v : &rebuf; + + /* Check for (?i) to enable case-insensitive matching. */ + cp = pattern[0] == '^' ? pattern + 1 : pattern; + if (strncmp(cp, "(?i)", 4) == 0) { + cflags |= REG_ICASE; + copy = dup_pattern(pattern + 4); + if (copy == NULL) { + *errstr = N_("unable to allocate memory"); + debug_return_bool(false); + } + if (pattern[0] == '^') + copy[0] = '^'; + } else { + copy = dup_pattern(pattern); + if (copy == NULL) { + *errstr = N_("unable to allocate memory"); + debug_return_bool(false); + } + } + + errcode = regcomp(preg, copy, cflags); + if (errcode == 0) { + if (preg == &rebuf) + regfree(&rebuf); + } else { + regerror(errcode, preg, errbuf, sizeof(errbuf)); + *errstr = errbuf; + } + free(copy); + + debug_return_bool(errcode == 0); +} diff --git a/lib/util/util.exp.in b/lib/util/util.exp.in index 5b760fa4f..48dcfb4af 100644 --- a/lib/util/util.exp.in +++ b/lib/util/util.exp.in @@ -119,6 +119,7 @@ sudo_rcstr_addref sudo_rcstr_alloc sudo_rcstr_delref sudo_rcstr_dup +sudo_regex_compile_v1 sudo_secure_dir_v1 sudo_secure_file_v1 sudo_setgroups_v1 diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c index ca4bdc2f9..3159a19fa 100644 --- a/plugins/sudoers/defaults.c +++ b/plugins/sudoers/defaults.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include "sudoers.h" @@ -1287,22 +1286,17 @@ bool cb_passprompt_regex(const union sudo_defs_val *sd_un, int op) { struct list_member *lm; - int errcode; - char errbuf[1024]; - regex_t re; + const char *errstr; debug_decl(cb_passprompt_regex, SUDOERS_DEBUG_DEFAULTS); - /* If adding one or more regexps, validate them with regcomp(). */ + /* If adding one or more regexps, make sure they are valid. */ if (op == '+' || op == true) { SLIST_FOREACH(lm, &sd_un->list, entries) { - errcode = regcomp(&re, lm->value, REG_EXTENDED|REG_NOSUB); - if (errcode != 0) { - regerror(errcode, &re, errbuf, sizeof(errbuf)); + if (!sudo_regex_compile(NULL, lm->value, &errstr)) { sudo_warnx(U_("invalid regular expression \"%s\": %s"), - lm->value, errbuf); + lm->value, U_(errstr)); debug_return_bool(false); } - regfree(&re); } } diff --git a/plugins/sudoers/match_command.c b/plugins/sudoers/match_command.c index e202c23ab..5e9ed9a0e 100644 --- a/plugins/sudoers/match_command.c +++ b/plugins/sudoers/match_command.c @@ -60,36 +60,20 @@ static bool regex_matches(const char *pattern, const char *str) { - int errcode, cflags = REG_EXTENDED|REG_NOSUB; - char *copy = NULL; + const char *errstr; + int errcode; regex_t re; debug_decl(regex_matches, SUDOERS_DEBUG_MATCH); - /* Check for (?i) to enable case-insensitive matching. */ - if (strncmp(pattern, "^(?i)", 5) == 0) { - cflags |= REG_ICASE; - copy = strdup(pattern + 4); - if (copy == NULL) { - sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - debug_return_bool(false); - } - copy[0] = '^'; - pattern = copy; - } - - errcode = regcomp(&re, pattern, cflags); - if (errcode == 0) { - errcode = regexec(&re, str, 0, NULL, 0); - regfree(&re); - } else { - char errbuf[1024]; - - regerror(errcode, &re, errbuf, sizeof(errbuf)); + if (!sudo_regex_compile(&re, pattern, &errstr)) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "unable to compile regular expression \"%s\": %s", - pattern, errbuf); + pattern, errstr); + debug_return_bool(false); } - free(copy); + + errcode = regexec(&re, str, 0, NULL, 0); + regfree(&re); debug_return_bool(errcode == 0); } diff --git a/plugins/sudoers/regress/sudoers/test28.in b/plugins/sudoers/regress/sudoers/test28.in index 645dccdfd..e546aedd5 100644 --- a/plugins/sudoers/regress/sudoers/test28.in +++ b/plugins/sudoers/regress/sudoers/test28.in @@ -1,3 +1,6 @@ +# Test passprompt_regex +Defaults passprompt_regex="(?i)password: *" + # Test simple command with regex args user ALL = /bin/ls ^/etc/(hosts|motd|issue)$ diff --git a/plugins/sudoers/regress/sudoers/test28.json.ok b/plugins/sudoers/regress/sudoers/test28.json.ok index 9706db4f4..4fa414583 100644 --- a/plugins/sudoers/regress/sudoers/test28.json.ok +++ b/plugins/sudoers/regress/sudoers/test28.json.ok @@ -1,4 +1,17 @@ { + "Defaults": [ + { + "Options": [ + { + "operation": "list_assign", + "passprompt_regex": [ + "(?i)password:", + "*" + ] + } + ] + } + ], "User_Specs": [ { "User_List": [ diff --git a/plugins/sudoers/regress/sudoers/test28.ldif.ok b/plugins/sudoers/regress/sudoers/test28.ldif.ok index d3318a4f3..1ecc5865b 100644 --- a/plugins/sudoers/regress/sudoers/test28.ldif.ok +++ b/plugins/sudoers/regress/sudoers/test28.ldif.ok @@ -1,3 +1,10 @@ +dn: cn=defaults,ou=SUDOers,dc=sudo,dc=ws +objectClass: top +objectClass: sudoRole +cn: defaults +description: Default sudoOption's go here +sudoOption: passprompt_regex=(?i)password: * + dn: cn=user,ou=SUDOers,dc=sudo,dc=ws objectClass: top objectClass: sudoRole diff --git a/plugins/sudoers/regress/sudoers/test28.ldif2sudo.ok b/plugins/sudoers/regress/sudoers/test28.ldif2sudo.ok index 3128a4e9d..0b642fe7f 100644 --- a/plugins/sudoers/regress/sudoers/test28.ldif2sudo.ok +++ b/plugins/sudoers/regress/sudoers/test28.ldif2sudo.ok @@ -1,3 +1,5 @@ +Defaults passprompt_regex="(?i)password: *" + # sudoRole user, user_1, user_2, user_3, user_4, user_5, user_6, user_7, # user_8, user_9, user_10, user_11 user ALL = /bin/ls ^/etc/(hosts|motd|issue)$, /usr/bin/c*\ diff --git a/plugins/sudoers/regress/sudoers/test28.out.ok b/plugins/sudoers/regress/sudoers/test28.out.ok index 399a67093..443573cb9 100644 --- a/plugins/sudoers/regress/sudoers/test28.out.ok +++ b/plugins/sudoers/regress/sudoers/test28.out.ok @@ -1,5 +1,7 @@ Parses OK +Defaults passprompt_regex="(?i)password: *" + user ALL = /bin/ls ^/etc/(hosts|motd|issue)$ user ALL = /usr/bin/c* ^/etc/(hosts|motd|issue)$ user ALL = ^/usr/bin/(who|w|id|whoami)$ diff --git a/plugins/sudoers/regress/sudoers/test28.toke.ok b/plugins/sudoers/regress/sudoers/test28.toke.ok index c51b24da4..03918b924 100644 --- a/plugins/sudoers/regress/sudoers/test28.toke.ok +++ b/plugins/sudoers/regress/sudoers/test28.toke.ok @@ -1,3 +1,6 @@ +# +DEFAULTS DEFVAR = BEGINSTR STRBODY ENDSTR WORD(4) + # WORD(6) ALL = COMMAND ARG REGEX diff --git a/plugins/sudoers/sudoreplay.c b/plugins/sudoers/sudoreplay.c index 786aae30d..5b8ebe501 100644 --- a/plugins/sudoers/sudoreplay.c +++ b/plugins/sudoers/sudoreplay.c @@ -1195,6 +1195,7 @@ parse_expr(struct search_node_list *head, char *argv[], bool sub_expr) bool or = false, not = false; struct search_node *sn; char type, **av; + const char *errstr; debug_decl(parse_expr, SUDO_DEBUG_UTIL); for (av = argv; *av != NULL; av++) { @@ -1288,8 +1289,10 @@ parse_expr(struct search_node_list *head, char *argv[], bool sub_expr) if (*(++av) == NULL) sudo_fatalx(U_("%s requires an argument"), av[-1]); if (type == ST_PATTERN) { - if (regcomp(&sn->u.cmdre, *av, REG_EXTENDED|REG_NOSUB) != 0) - sudo_fatalx(U_("invalid regular expression: %s"), *av); + if (!sudo_regex_compile(&sn->u.cmdre, *av, &errstr)) { + sudo_fatalx(U_("invalid regular expression \"%s\": %s"), + *av, U_(errstr)); + } } else if (type == ST_TODATE || type == ST_FROMDATE) { sn->u.tstamp.tv_sec = get_date(*av); sn->u.tstamp.tv_nsec = 0; @@ -1542,6 +1545,7 @@ list_sessions(int argc, char **argv, const char *pattern, const char *user, const char *tty) { regex_t rebuf, *re = NULL; + const char *errstr; debug_decl(list_sessions, SUDO_DEBUG_UTIL); /* Parse search expression if present */ @@ -1550,8 +1554,10 @@ list_sessions(int argc, char **argv, const char *pattern, const char *user, /* optional regex */ if (pattern) { re = &rebuf; - if (regcomp(re, pattern, REG_EXTENDED|REG_NOSUB) != 0) - sudo_fatalx(U_("invalid regular expression: %s"), pattern); + if (!sudo_regex_compile(re, pattern, &errstr)) { + sudo_fatalx(U_("invalid regular expression \"%s\": %s"), + pattern, U_(errstr)); + } } debug_return_int(find_sessions(session_dir, re, user, tty)); diff --git a/plugins/sudoers/toke.c b/plugins/sudoers/toke.c index 6f229c711..27c78b261 100644 --- a/plugins/sudoers/toke.c +++ b/plugins/sudoers/toke.c @@ -3083,7 +3083,7 @@ char *sudoerstext; int sudolineno; /* current sudoers line number. */ char *sudoers; /* sudoers file being parsed. */ -char *sudoers_errstr; /* description of last error from lexer. */ +const char *sudoers_errstr; /* description of last error from lexer. */ struct sudolinebuf sudolinebuf; /* sudoers line being parsed. */ /* Default sudoers path, mode and owner (may be set via sudo.conf) */ @@ -3648,7 +3648,7 @@ YY_RULE_SETUP BEGIN INITIAL; continued = false; if (sudoers_strict) { - if (!regex_valid(sudoerstext, &sudoers_errstr)) { + if (!sudo_regex_compile(NULL, sudoerstext, &sudoers_errstr)) { LEXTRACE("ERROR "); return ERROR; } @@ -4283,7 +4283,7 @@ YY_RULE_SETUP #line 774 "toke.l" { if (sudoers_strict) { - if (!regex_valid(sudoerstext, &sudoers_errstr)) { + if (!sudo_regex_compile(NULL, sudoerstext, &sudoers_errstr)) { LEXTRACE("ERROR "); return ERROR; } diff --git a/plugins/sudoers/toke.h b/plugins/sudoers/toke.h index 69496aa4e..d20cb458f 100644 --- a/plugins/sudoers/toke.h +++ b/plugins/sudoers/toke.h @@ -27,7 +27,7 @@ struct sudolinebuf { size_t toke_start; /* starting column of current token */ size_t toke_end; /* ending column of current token */ }; -extern char *sudoers_errstr; +extern const char *sudoers_errstr; extern struct sudolinebuf sudolinebuf; bool append(const char *, size_t); @@ -35,7 +35,6 @@ bool fill_args(const char *, size_t, int); bool fill_cmnd(const char *, size_t); bool fill(const char *, size_t); bool ipv6_valid(const char *s); -bool regex_valid(const char *pattern, char **errstr); int sudoers_trace_print(const char *); void sudoerserrorf(const char *, ...) __printf0like(1, 2); void sudoerserror(const char *); diff --git a/plugins/sudoers/toke.l b/plugins/sudoers/toke.l index 6972c5956..91280739b 100644 --- a/plugins/sudoers/toke.l +++ b/plugins/sudoers/toke.l @@ -55,7 +55,7 @@ int sudolineno; /* current sudoers line number. */ char *sudoers; /* sudoers file being parsed. */ -char *sudoers_errstr; /* description of last error from lexer. */ +const char *sudoers_errstr; /* description of last error from lexer. */ struct sudolinebuf sudolinebuf; /* sudoers line being parsed. */ /* Default sudoers path, mode and owner (may be set via sudo.conf) */ @@ -297,7 +297,7 @@ DEFVAR [a-z_]+ BEGIN INITIAL; continued = false; if (sudoers_strict) { - if (!regex_valid(sudoerstext, &sudoers_errstr)) { + if (!sudo_regex_compile(NULL, sudoerstext, &sudoers_errstr)) { LEXTRACE("ERROR "); return ERROR; } @@ -773,7 +773,7 @@ sudoedit { {REGEX} { if (sudoers_strict) { - if (!regex_valid(sudoerstext, &sudoers_errstr)) { + if (!sudo_regex_compile(NULL, sudoerstext, &sudoers_errstr)) { LEXTRACE("ERROR "); return ERROR; } diff --git a/plugins/sudoers/toke_util.c b/plugins/sudoers/toke_util.c index f03e0dae2..8860fa431 100644 --- a/plugins/sudoers/toke_util.c +++ b/plugins/sudoers/toke_util.c @@ -39,7 +39,6 @@ static unsigned int arg_len = 0; static unsigned int arg_size = 0; -static char errbuf[1024]; /* * Copy the string and collapse any escaped characters. @@ -247,36 +246,3 @@ ipv6_valid(const char *s) debug_return_bool(nmatch <= 1); } - -bool -regex_valid(const char *pattern, char **errstr) -{ - int errcode, cflags = REG_EXTENDED|REG_NOSUB; - char *copy = NULL; - regex_t re; - debug_decl(regex_valid, SUDOERS_DEBUG_PARSER); - - /* Check for (?i) to enable case-insensitive matching. */ - if (strncmp(pattern, "^(?i)", 5) == 0) { - cflags |= REG_ICASE; - copy = strdup(pattern + 4); - if (copy == NULL) { - sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - sudoerserror(NULL); - debug_return_bool(false); - } - copy[0] = '^'; - pattern = copy; - } - - errcode = regcomp(&re, pattern, cflags); - if (errcode == 0) { - regfree(&re); - } else { - regerror(errcode, &re, errbuf, sizeof(errbuf)); - *errstr = errbuf; - } - free(copy); - - debug_return_bool(errcode == 0); -}