From 4e05d3ae2826e22811db810c359124edf1f42191 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 1 Oct 2010 12:05:14 -0400 Subject: [PATCH] Move set_project() into runas_setup(). Fixes a NULL deref when project support is enabled and sudo's -g flag is used without the -u flag. --HG-- branch : 1.7 --- set_perms.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ sudo.c | 74 ----------------------------------------------------- 2 files changed, 67 insertions(+), 74 deletions(-) diff --git a/set_perms.c b/set_perms.c index 81e2e7605..dab2fac02 100644 --- a/set_perms.c +++ b/set_perms.c @@ -47,6 +47,10 @@ #ifdef HAVE_LOGIN_CAP_H # include #endif +#ifdef HAVE_PROJECT_H +# include +# include +#endif #include "sudo.h" @@ -547,6 +551,66 @@ restore_groups() #endif /* HAVE_INITGROUPS */ +#ifdef HAVE_PROJECT_H +static void +set_project(pw) + struct passwd *pw; +{ + int errflags = NO_MAIL|MSG_ONLY|NO_EXIT; + int errval; + struct project proj; + struct project *resultp = '\0'; + char buf[1024]; + + /* + * Collect the default project for the user and settaskid + */ + setprojent(); + if (resultp = getdefaultproj(pw->pw_name, &proj, buf, sizeof(buf))) { + errval = setproject(resultp->pj_name, pw->pw_name, TASK_NORMAL); + if (errval != 0) { + switch(errval) { + case SETPROJ_ERR_TASK: + if (errno == EAGAIN) + log_error(errflags, "resource control limit has been reached"); + else if (errno == ESRCH) + log_error(errflags, "user \"%s\" is not a member of " + "project \"%s\"", pw->pw_name, resultp->pj_name); + else if (errno == EACCES) + log_error(errflags, "the invoking task is final"); + else + log_error(errflags, "could not join project \"%s\"", + resultp->pj_name); + break; + case SETPROJ_ERR_POOL: + if (errno == EACCES) + log_error(errflags, "no resource pool accepting " + "default bindings exists for project \"%s\"", + resultp->pj_name); + else if (errno == ESRCH) + log_error(errflags, "specified resource pool does " + "not exist for project \"%s\"", resultp->pj_name); + else + log_error(errflags, "could not bind to default " + "resource pool for project \"%s\"", resultp->pj_name); + break; + default: + if (errval <= 0) { + log_error(errflags, "setproject failed for project \"%s\"", + resultp->pj_name); + } else { + log_error(errflags, "warning, resource control assignment " + "failed for project \"%s\"", resultp->pj_name); + } + } + } + } else { + log_error(errflags, "getdefaultproj() error: %s", strerror(errno)); + } + endprojent(); +} +#endif /* HAVE_PROJECT_H */ + static void runas_setup() { @@ -558,6 +622,9 @@ runas_setup() if (runas_pw->pw_name != NULL) { gid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid; +#ifdef HAVE_PROJECT_H + set_project(runas_pw); +#endif #ifdef HAVE_GETUSERATTR aix_prep_user(runas_pw->pw_name, user_ttypath); #endif diff --git a/sudo.c b/sudo.c index b992eedac..9c3c944e9 100644 --- a/sudo.c +++ b/sudo.c @@ -88,10 +88,6 @@ # define LOGIN_DEFROOTCLASS "daemon" # endif #endif -#ifdef HAVE_PROJECT_H -# include -# include -#endif #ifdef HAVE_MBR_CHECK_MEMBERSHIP # include #endif @@ -118,7 +114,6 @@ static void init_vars __P((char **)); static int set_cmnd __P((int)); static void initial_setup __P((void)); static void set_loginclass __P((struct passwd *)); -static void set_project __P((struct passwd *)); static void set_runasgr __P((char *)); static void set_runaspw __P((char *)); static void show_version __P((void)); @@ -761,9 +756,6 @@ set_cmnd(sudo_mode) int rval; char *path = user_path; - /* Set project if applicable. */ - set_project(runas_pw); - /* Resolve the path and return. */ rval = FOUND; user_stat = emalloc(sizeof(struct stat)); @@ -1154,72 +1146,6 @@ set_loginclass(pw) } #endif /* HAVE_LOGIN_CAP_H */ -#ifdef HAVE_PROJECT_H -static void -set_project(pw) - struct passwd *pw; -{ - int errflags = NO_MAIL|MSG_ONLY|NO_EXIT; - int errval; - struct project proj; - struct project *resultp = '\0'; - char buf[1024]; - - /* - * Collect the default project for the user and settaskid - */ - setprojent(); - if (resultp = getdefaultproj(pw->pw_name, &proj, buf, sizeof(buf))) { - errval = setproject(resultp->pj_name, pw->pw_name, TASK_NORMAL); - if (errval != 0) { - switch(errval) { - case SETPROJ_ERR_TASK: - if (errno == EAGAIN) - log_error(errflags, "resource control limit has been reached"); - else if (errno == ESRCH) - log_error(errflags, "user \"%s\" is not a member of " - "project \"%s\"", pw->pw_name, resultp->pj_name); - else if (errno == EACCES) - log_error(errflags, "the invoking task is final"); - else - log_error(errflags, "could not join project \"%s\"", - resultp->pj_name); - break; - case SETPROJ_ERR_POOL: - if (errno == EACCES) - log_error(errflags, "no resource pool accepting " - "default bindings exists for project \"%s\"", - resultp->pj_name); - else if (errno == ESRCH) - log_error(errflags, "specified resource pool does " - "not exist for project \"%s\"", resultp->pj_name); - else - log_error(errflags, "could not bind to default " - "resource pool for project \"%s\"", resultp->pj_name); - break; - default: - if (errval <= 0) { - log_error(errflags, "setproject failed for project \"%s\"", - resultp->pj_name); - } else { - log_error(errflags, "warning, resource control assignment " - "failed for project \"%s\"", resultp->pj_name); - } - } - } - } else { - log_error(errflags, "getdefaultproj() error: %s", strerror(errno)); - } - endprojent(); -} -#else -static void -set_project(pw) - struct passwd *pw; -{ -} -#endif /* HAVE_PROJECT_H */ - /* * Look up the fully qualified domain name and set user_host and user_shost. */ -- 2.40.0