Commit 47744b8e authored by rswindell's avatar rswindell
Browse files

Subtle bug-fix: when executing a native external program, the server process's

environment is no longer modified to set variables in the spawned process's
environment. This could result in a race condition where if multinodes executed
native externals simultaneously, one node's child process could get the wrong
node number (SBBSNNUM) or node directory (SBBSNODE) value (in theory).
We now use cool new string list functions to copy and append string blocks
to copy  the environment of the server before modifying and passing to the
child process. This bug-fix only applies to Win32 builds.
parent 1f6cfb00
......@@ -325,16 +325,6 @@ public:
uint cursubnum; /* For ARS */
uint curdirnum; /* For ARS */
ulong timeleft; /* Number of seconds user has left online */
char sbbsnnum[MAX_PATH+1]; /* Environment var to contain node num */
char sbbsnode[MAX_PATH+1]; /* Environment var to contain node dir path */
char sbbsctrl[MAX_PATH+1]; /* Environment var to contain ctrl dir path */
char sbbsdata[MAX_PATH+1]; /* Environment var to contain data dir path */
char sbbsexec[MAX_PATH+1]; /* Environment var to contain exec dir path */
char env_day[32]; /* Environment var for day of month */
char env_weekday[32]; /* Environment var for name of weekday */
char env_month[32]; /* Environment var for month number (1-based) */
char env_monthname[32]; /* Environment var for day of month abbreviation */
char env_year[32]; /* Environment var for the year */
char *comspec; /* Pointer to environment variable COMSPEC */
ushort altul; /* Upload to alternate path flag */
......
......@@ -8,7 +8,7 @@
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html *
* Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
......@@ -328,7 +328,10 @@ BYTE* cr_expand(BYTE* inbuf, ulong inlen, BYTE* outbuf, ulong& newlen)
/****************************************************************************/
int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
{
char str[MAX_PATH+1],*p;
char str[MAX_PATH+1];
char* p;
char* env_block=NULL;
char* env_strings;
const char* p_startup_dir;
char path[MAX_PATH+1];
char fname[MAX_PATH+1];
......@@ -346,6 +349,7 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
bool was_online=true;
bool rio_abortable_save=rio_abortable;
bool use_pipes=false; // NT-compatible console redirection
BOOL success;
BOOL processTerminated=false;
uint i;
time_t hungup=0;
......@@ -368,6 +372,7 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
DWORD last_error;
DWORD loop_since_io=0;
struct tm tm;
str_list_t env_list;
sbbsexec_start_t start;
OPENVXDHANDLE OpenVxDHandle;
......@@ -422,31 +427,37 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
if(native) { // Native (32-bit) external
if((env_list=strListInit())==NULL) {
XTRN_CLEANUP;
errormsg(WHERE, ERR_CREATE, "env_list", 0);
return(errno);
}
// Current environment passed to child process
sprintf(dszlog,"DSZLOG=%sPROTOCOL.LOG",cfg.node_dir);
sprintf(sbbsnode,"SBBSNODE=%s",cfg.node_dir);
sprintf(sbbsctrl,"SBBSCTRL=%s",cfg.ctrl_dir);
sprintf(sbbsdata,"SBBSDATA=%s",cfg.data_dir);
sprintf(sbbsexec,"SBBSEXEC=%s",cfg.exec_dir);
sprintf(sbbsnnum,"SBBSNNUM=%d",cfg.node_num);
putenv(dszlog); /* Makes the DSZ LOG active */
putenv(sbbsnode);
putenv(sbbsctrl);
putenv(sbbsdata);
putenv(sbbsexec);
putenv(sbbsnnum);
sprintf(str,"DSZLOG=%sPROTOCOL.LOG",cfg.node_dir); strListPush(&env_list,str);
sprintf(str,"SBBSNODE=%s",cfg.node_dir); strListPush(&env_list,str);
sprintf(str,"SBBSCTRL=%s",cfg.ctrl_dir); strListPush(&env_list,str);
sprintf(str,"SBBSDATA=%s",cfg.data_dir); strListPush(&env_list,str);
sprintf(str,"SBBSEXEC=%s",cfg.exec_dir); strListPush(&env_list,str);
sprintf(str,"SBBSNNUM=%d",cfg.node_num); strListPush(&env_list,str);
/* date/time env vars */
sprintf(env_day ,"DAY=%02u" ,tm.tm_mday);
sprintf(env_weekday ,"WEEKDAY=%s" ,wday[tm.tm_wday]);
sprintf(env_monthname ,"MONTHNAME=%s" ,mon[tm.tm_mon]);
sprintf(env_month ,"MONTH=%02u" ,tm.tm_mon+1);
sprintf(env_year ,"YEAR=%u" ,1900+tm.tm_year);
putenv(env_day);
putenv(env_weekday);
putenv(env_monthname);
putenv(env_month);
if(putenv(env_year))
errormsg(WHERE,ERR_WRITE,"environment",0);
sprintf(str,"DAY=%02u",tm.tm_mday); strListPush(&env_list,str);
sprintf(str,"WEEKDAY=%s",wday[tm.tm_wday]); strListPush(&env_list,str);
sprintf(str,"MONTHNAME=%s",mon[tm.tm_mon]); strListPush(&env_list,str);
sprintf(str,"MONTH=%02u",tm.tm_mon+1); strListPush(&env_list,str);
sprintf(str,"YEAR=%u",1900+tm.tm_year); strListPush(&env_list,str);
env_strings=GetEnvironmentStrings();
env_block=strListCopyBlock(env_strings);
if(env_strings!=NULL)
FreeEnvironmentStrings(env_strings);
env_block=strListAppendBlock(env_block,env_list);
strListFree(&env_list);
if(env_block==NULL) {
XTRN_CLEANUP;
errormsg(WHERE, ERR_CREATE, "env_block", 0);
return(errno);
}
} else { // DOS external
......@@ -638,18 +649,22 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
}
}
if(!CreateProcess(
success=CreateProcess(
NULL, // pointer to name of executable module
fullcmdline, // pointer to command line string
NULL, // process security attributes
NULL, // thread security attributes
native && !(mode&EX_OFFLINE), // handle inheritance flag
CREATE_NEW_CONSOLE/*|CREATE_SEPARATE_WOW_VDM*/, // creation flags
NULL, // pointer to new environment block
env_block, // pointer to new environment block
p_startup_dir, // pointer to current directory name
&startup_info, // pointer to STARTUPINFO
&process_info // pointer to PROCESS_INFORMATION
)) {
);
strListFreeBlock(env_block);
if(!success) {
XTRN_CLEANUP;
if(input_thread_mutex_locked && input_thread_running) {
pthread_mutex_unlock(&input_thread_mutex);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment