From 9eb2c87ee60cc21b0120f54bf0e5233c7eadc7a0 Mon Sep 17 00:00:00 2001 From: speidy Date: Tue, 4 Oct 2016 01:53:24 -0400 Subject: [PATCH] sesman: env_set_user, fix potential bof issues --- common/os_calls.c | 18 +++++++++++------- common/os_calls.h | 6 +++--- sesman/env.c | 39 ++++++++++++++++++++++++++++++--------- sesman/env.h | 2 +- sesman/session.c | 9 ++++++--- 5 files changed, 51 insertions(+), 23 deletions(-) diff --git a/common/os_calls.c b/common/os_calls.c index 7075ee34..a79a0f9a 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -224,14 +224,17 @@ g_sprintf(char* dest, const char* format, ...) } /*****************************************************************************/ -void DEFAULT_CC +int DEFAULT_CC g_snprintf(char* dest, int len, const char* format, ...) { + int err; va_list ap; va_start(ap, format); - vsnprintf(dest, len, format, ap); + err = vsnprintf(dest, len, format, ap); va_end(ap); + + return err; } /*****************************************************************************/ @@ -2180,10 +2183,11 @@ g_sigterm(int pid) /*****************************************************************************/ /* returns 0 if ok */ +/* the caller is responsible to free the buffs */ /* does not work in win32 */ int APP_CC -g_getuser_info(const char* username, int* gid, int* uid, char* shell, - char* dir, char* gecos) +g_getuser_info(const char *username, int *gid, int *uid, char **shell, + char **dir, char **gecos) { #if defined(_WIN32) return 1; @@ -2203,15 +2207,15 @@ g_getuser_info(const char* username, int* gid, int* uid, char* shell, } if (dir != 0) { - g_strcpy(dir, pwd_1->pw_dir); + *dir = g_strdup(pwd_1->pw_dir); } if (shell != 0) { - g_strcpy(shell, pwd_1->pw_shell); + *shell = g_strdup(pwd_1->pw_shell); } if (gecos != 0) { - g_strcpy(gecos, pwd_1->pw_gecos); + *gecos = g_strdup(pwd_1->pw_gecos); } return 0; } diff --git a/common/os_calls.h b/common/os_calls.h index 5c7d848e..d4e5fc1d 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -47,7 +47,7 @@ void DEFAULT_CC g_printf(const char *format, ...); void DEFAULT_CC g_sprintf(char* dest, const char* format, ...); -void DEFAULT_CC +int DEFAULT_CC g_snprintf(char* dest, int len, const char* format, ...); void DEFAULT_CC g_writeln(const char* format, ...); @@ -251,8 +251,8 @@ g_getpid(void); int APP_CC g_sigterm(int pid); int APP_CC -g_getuser_info(const char* username, int* gid, int* uid, char* shell, - char* dir, char* gecos); +g_getuser_info(const char* username, int* gid, int* uid, char** shell, + char** dir, char** gecos); int APP_CC g_getgroup_info(const char* groupname, int* gid); int APP_CC diff --git a/sesman/env.c b/sesman/env.c index 4bcb22e8..1bd1d55b 100644 --- a/sesman/env.c +++ b/sesman/env.c @@ -59,19 +59,21 @@ env_check_password_file(char* filename, char* password) /******************************************************************************/ int DEFAULT_CC -env_set_user(char* username, char* passwd_file, int display) +env_set_user(char* username, char** passwd_file, int display) { int error; int pw_uid; int pw_gid; int uid; - char pw_shell[256]; - char pw_dir[256]; - char pw_gecos[256]; + int len; + char *pw_shell; + char *pw_dir; char text[256]; - error = g_getuser_info(username, &pw_gid, &pw_uid, pw_shell, pw_dir, - pw_gecos); + pw_shell = 0; + pw_dir = 0; + error = g_getuser_info(username, &pw_gid, &pw_uid, &pw_shell, &pw_dir, 0); + if (error == 0) { g_rm_temp_dir(); @@ -105,16 +107,35 @@ env_set_user(char* username, char* passwd_file, int display) /* if no auth_file_path is set, then we go for $HOME/.vnc/sesman_username_passwd */ g_mkdir(".vnc"); - g_sprintf(passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username); + + len = g_snprintf(NULL, 0, "%s/.vnc/sesman_%s_passwd", pw_dir, username); + + *passwd_file = (char *) g_malloc(len + 1, 1); + if (*passwd_file != NULL) + { + g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username); + } } else { /* we use auth_file_path as requested */ - g_sprintf(passwd_file, g_cfg->auth_file_path, username); + len = g_snprintf(NULL, 0, g_cfg->auth_file_path, username); + + *passwd_file = (char *) g_malloc(len + 1, 1); + if (*passwd_file != NULL) + { + g_sprintf(*passwd_file, g_cfg->auth_file_path, username); + } + } + + if (*passwd_file != NULL) + { + LOG_DBG(&(g_cfg->log), "pass file: %s", *passwd_file); } - LOG_DBG(&(g_cfg->log), "pass file: %s", passwd_file); } } + g_free(pw_dir); + g_free(pw_shell); } else { diff --git a/sesman/env.h b/sesman/env.h index b14344af..ec447601 100644 --- a/sesman/env.h +++ b/sesman/env.h @@ -49,7 +49,7 @@ env_check_password_file(char* filename, char* password); * */ int DEFAULT_CC -env_set_user(char* username, char* passwd_file, int display); +env_set_user(char* username, char** passwd_file, int display); #endif diff --git a/sesman/session.c b/sesman/session.c index 2960a7f7..a725c1cf 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -329,7 +329,7 @@ session_start_fork(int width, int height, int bpp, char* username, char depth[32]; char screen[32]; char text[256]; - char passwd_file[256]; + char *passwd_file; char ** pp1 = (char **)NULL; struct session_chain * temp = (struct session_chain *)NULL; struct list * xserver_params = (struct list *)NULL; @@ -343,7 +343,8 @@ session_start_fork(int width, int height, int bpp, char* username, g_memset(depth,0,sizeof(char) * 32); g_memset(screen,0,sizeof(char) * 32); g_memset(text,0,sizeof(char) * 256); - g_memset(passwd_file,0,sizeof(char) * 256); + + passwd_file = 0; /* check to limit concurrent sessions */ if (g_session_count >= g_cfg->sess.max_sessions) @@ -475,7 +476,7 @@ session_start_fork(int width, int height, int bpp, char* username, } else if (xpid == 0) /* child */ { - env_set_user(username, passwd_file, display); + env_set_user(username, &passwd_file, display); env_check_password_file(passwd_file, password); if (type == SESMAN_SESSION_TYPE_XVNC) { @@ -490,6 +491,7 @@ session_start_fork(int width, int height, int bpp, char* username, list_add_item(xserver_params, (long)g_strdup(depth)); list_add_item(xserver_params, (long)g_strdup("-rfbauth")); list_add_item(xserver_params, (long)g_strdup(passwd_file)); + g_free(passwd_file); /* additional parameters from sesman.ini file */ //config_read_xserver_params(SESMAN_SESSION_TYPE_XVNC, @@ -512,6 +514,7 @@ session_start_fork(int width, int height, int bpp, char* username, list_add_item(xserver_params, (long)g_strdup(geometry)); list_add_item(xserver_params, (long)g_strdup("-depth")); list_add_item(xserver_params, (long)g_strdup(depth)); + g_free(passwd_file); /* additional parameters from sesman.ini file */ //config_read_xserver_params(SESMAN_SESSION_TYPE_XRDP,