From c73dec723c2dfcac050240820840ab07c83ed992 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Tue, 13 Sep 2016 09:06:25 -0600 Subject: [PATCH] Move valid domain name check into a new valid_domain() function. Fix memory leak if getdomainname(2) fails and avoid using heap garbage for the domain name matching in this case. --- plugins/sudoers/match.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c index 97f538b0c..3fb36f5e4 100644 --- a/plugins/sudoers/match.c +++ b/plugins/sudoers/match.c @@ -975,10 +975,30 @@ done: debug_return_bool(matched); } +#if defined(HAVE_GETDOMAINNAME) || defined(SI_SRPC_DOMAIN) +/* + * Check the domain for invalid characters. + * Linux getdomainname(2) returns (none) if no domain is set. + */ +static bool +valid_domain(const char *domain) +{ + const char *cp; + debug_decl(valid_domain, SUDOERS_DEBUG_MATCH) + + for (cp = domain; *cp != '\0'; cp++) { + /* Check for illegal characters, Linux may use "(none)". */ + if (*cp == '(' || *cp == ')' || *cp == ',' || *cp == ' ') + break; + } + if (cp == domain || *cp != '\0') + debug_return_bool(false); + debug_return_bool(true); +} + /* * Get NIS-style domain name and copy from static storage or NULL if none. */ -#if defined(HAVE_GETDOMAINNAME) || defined(SI_SRPC_DOMAIN) const char * sudo_getdomainname(void) { @@ -998,23 +1018,16 @@ sudo_getdomainname(void) domain = malloc(host_name_max + 1); if (domain != NULL) { -# ifdef SI_SRPC_DOMAIN domain[0] = '\0'; +# ifdef SI_SRPC_DOMAIN rc = sysinfo(SI_SRPC_DOMAIN, domain, host_name_max + 1); # else rc = getdomainname(domain, host_name_max + 1); # endif - if (rc != -1 && domain[0] != '\0') { - const char *cp; - - for (cp = domain; *cp != '\0'; cp++) { - /* Check for illegal characters, Linux may use "(none)". */ - if (*cp == '(' || *cp == ')' || *cp == ',' || *cp == ' ') { - free(domain); - domain = NULL; - break; - } - } + if (rc == -1 || !valid_domain(domain)) { + /* Error or invalid domain name. */ + free(domain); + domain = NULL; } } else { /* XXX - want to pass error back to caller */ -- 2.40.0