From 665f8d2e3e52c3260bfc682044843a4183ecc210 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Wed, 3 Feb 2021 16:50:04 -0700 Subject: [PATCH] Only strip double quotes from an include path if len >= 2. Found locally using libfuzzer/oss-fuzz. --- plugins/sudoers/toke.c | 13 ++++++++----- plugins/sudoers/toke.l | 13 ++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/plugins/sudoers/toke.c b/plugins/sudoers/toke.c index 6717e4f..f8dd1e1 100644 --- a/plugins/sudoers/toke.c +++ b/plugins/sudoers/toke.c @@ -5201,26 +5201,29 @@ init_lexer(void) * Returns a reference-counted string. */ static char * -expand_include(const char *opath, size_t olen) +expand_include(const char *opath) { const char *cp, *ep; char *path, *pp; - int dirlen = 0, len; + size_t len, olen, dirlen = 0; size_t shost_len = 0; bool subst = false; debug_decl(expand_include, SUDOERS_DEBUG_PARSER); /* Strip double quotes if present. */ - if (*opath == '"') { + olen = strlen(opath); + if (olen > 1 && opath[0] == '"' && opath[olen - 1] == '"') { opath++; olen -= 2; } + if (olen == 0) + debug_return_ptr(NULL); /* Relative paths are located in the same dir as the sudoers file. */ if (*opath != '/') { char *dirend = strrchr(sudoers, '/'); if (dirend != NULL) - dirlen = (int)(dirend - sudoers) + 1; + dirlen = (size_t)(dirend - sudoers) + 1; } len = olen; @@ -5278,7 +5281,7 @@ push_include(const char *opath, bool isdir) FILE *fp; debug_decl(push_include, SUDOERS_DEBUG_PARSER); - if ((path = expand_include(opath, strlen(opath))) == NULL) + if ((path = expand_include(opath)) == NULL) debug_return_bool(false); /* push current state onto stack */ diff --git a/plugins/sudoers/toke.l b/plugins/sudoers/toke.l index 499f3b1..22430ac 100644 --- a/plugins/sudoers/toke.l +++ b/plugins/sudoers/toke.l @@ -1006,26 +1006,29 @@ init_lexer(void) * Returns a reference-counted string. */ static char * -expand_include(const char *opath, size_t olen) +expand_include(const char *opath) { const char *cp, *ep; char *path, *pp; - int dirlen = 0, len; + size_t len, olen, dirlen = 0; size_t shost_len = 0; bool subst = false; debug_decl(expand_include, SUDOERS_DEBUG_PARSER); /* Strip double quotes if present. */ - if (*opath == '"') { + olen = strlen(opath); + if (olen > 1 && opath[0] == '"' && opath[olen - 1] == '"') { opath++; olen -= 2; } + if (olen == 0) + debug_return_ptr(NULL); /* Relative paths are located in the same dir as the sudoers file. */ if (*opath != '/') { char *dirend = strrchr(sudoers, '/'); if (dirend != NULL) - dirlen = (int)(dirend - sudoers) + 1; + dirlen = (size_t)(dirend - sudoers) + 1; } len = olen; @@ -1083,7 +1086,7 @@ push_include(const char *opath, bool isdir) FILE *fp; debug_decl(push_include, SUDOERS_DEBUG_PARSER); - if ((path = expand_include(opath, strlen(opath))) == NULL) + if ((path = expand_include(opath)) == NULL) debug_return_bool(false); /* push current state onto stack */ -- 1.8.3.1