Thread: Need help finding clues to a fault involving a call to system()

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,018

    Need help finding clues to a fault involving a call to system()

    Here's the current order of actions
    1. I recompile and launch gasp
    2. gasp generates a shell string for use in system() so that it can launch itself under root user mode (sudo/pkexec)
    3. gasp prints the string then immediately calls system() with the string it printed, here's the generated string with paths a hacker could use edited to just ~
    Code:
    pkexec /~/gasp.elf --inrootmode  -D PWD="/~"  -D HOME="/~"  -D DISPLAY=":0"  -D XDG_CURRENT_DESKTOP="X-Cinnamon"  -D GDMSESSION="cinnamon"
    I tried clearing errno before the call then checking if it was set after to catch the error but no dice, I also try returning the value it returns to main() but also no dice, also before either of those codes get returned the 1st instance of gasp just seems to quit with this message:
    make: *** [makefile:127: run] Error 1
    Any ideas on how I could identify what actually happened so I can search for the source of the problem

  2. #2
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,018
    Well somehow got gede to boot up which allowed me to see where the error actually occured, turned out that somehow option->opt was no set at some point despite my handler expicitly declaring it after each realloc, I've now changed it so all parameters are set after a realloc no matter which one is being filled. I now however am coming across an semi-unrelated memory corrupt issue, unrelated because it's not the option's memory that's being changed but the array of option objects that's being changed, I'll start with the output (with paths edited to just project related):
    Code:
    gasp.c:466: Info: "Allocating default memory for strings"
    gasp.c:477: Info: "Checking given options"
    arguments.c:89: Info: "Iterating given arguments, 1"
    arguments.c:142: Info: "Done with given arguments"
    gasp.c:489: Info: "Adding environment variables as defines to options" " if they're not already defined"
    gasp.c:158: Info: "Checking for key 'PWD'"
    gasp.c:162: Info: "Value is '/~/gasp'"
    gasp.c:164: Info: "Checking if 'PWD' is already defined"
    gasp.c:183: Info: "Adding node for option -D PWD=\"/~/gasp\""
    arguments.c:42: Info: "Was 'opt'"
    arguments.c:51: Info: "Was 'key'"
    arguments.c:61: Info: "Was 'val'"
    gasp.c:200: Info: "Added -D PWD='/~/gasp'"
    gasp.c:158: Info: "Checking for key 'CWD'"
    gasp.c:158: Info: "Checking for key 'HOME'"
    gasp.c:162: Info: "Value is '/~'"
    gasp.c:164: Info: "Checking if 'HOME' is already defined"
    gasp.c:168: Info: "Comparing option '-D' to '-D'"
    gasp.c:172: Info: "Comparing key 'PWD' to 'HOME'"
    gasp.c:183: Info: "Adding node for option -D HOME=\"/~\""
    arguments.c:42: Info: "Was 'opt'"
    arguments.c:51: Info: "Was 'key'"
    arguments.c:61: Info: "Was 'val'"
    gasp.c:200: Info: "Added -D HOME='/~'"
    gasp.c:158: Info: "Checking for key 'GASP_PATH'"
    gasp.c:158: Info: "Checking for key 'DISPLAY'"
    gasp.c:162: Info: "Value is ':0'"
    gasp.c:164: Info: "Checking if 'DISPLAY' is already defined"
    gasp.c:168: Info: "Comparing option '-D' to '-D'"
    gasp.c:172: Info: "Comparing key 'PWD' to 'DISPLAY'"
    gasp.c:168: Info: "Comparing option '-D' to '-D'"
    gasp.c:172: Info: "Comparing key 'HOME' to 'DISPLAY'"
    gasp.c:183: Info: "Adding node for option -D DISPLAY=\":0\""
    arguments.c:42: Info: "Was 'opt'"
    arguments.c:51: Info: "Was 'key'"
    arguments.c:61: Info: "Was 'val'"
    gasp.c:200: Info: "Added -D DISPLAY=':0'"
    gasp.c:158: Info: "Checking for key 'XDG_CURRENT_DESKTOP'"
    gasp.c:162: Info: "Value is 'X-Cinnamon'"
    gasp.c:164: Info: "Checking if 'XDG_CURRENT_DESKTOP' is already defined"
    gasp.c:168: Info: "Comparing option '-D' to '-D'"
    gasp.c:172: Info: "Comparing key 'PWD' to 'XDG_CURRENT_DESKTOP'"
    gasp.c:168: Info: "Comparing option '-D' to '-D'"
    gasp.c:172: Info: "Comparing key 'HOME' to 'XDG_CURRENT_DESKTOP'"
    gasp.c:168: Info: "Comparing option '-D' to '-D'"
    gasp.c:172: Info: "Comparing key 'DISPLAY' to 'XDG_CURRENT_DESKTOP'"
    gasp.c:183: Info: "Adding node for option -D XDG_CURRENT_DESKTOP=\"X-Cinnamon\""
    arguments.c:42: Info: "Was 'opt'"
    arguments.c:51: Info: "Was 'key'"
    arguments.c:61: Info: "Was 'val'"
    gasp.c:200: Info: "Added -D XDG_CURRENT_DESKTOP='X-Cinnamon'"
    gasp.c:158: Info: "Checking for key 'GDMSESSION'"
    gasp.c:162: Info: "Value is 'cinnamon'"
    gasp.c:164: Info: "Checking if 'GDMSESSION' is already defined"
    gasp.c:168: Info: "Comparing option '-D' to '-D'"
    gasp.c:172: Info: "Comparing key 'PWD' to 'GDMSESSION'"
    gasp.c:168: Info: "Comparing option '-D' to '-D'"
    gasp.c:172: Info: "Comparing key 'HOME' to 'GDMSESSION'"
    gasp.c:168: Info: "Comparing option '-D' to '-D'"
    gasp.c:172: Info: "Comparing key 'DISPLAY' to 'GDMSESSION'"
    gasp.c:168: Info: "Comparing option '-D' to '-D'"
    gasp.c:172: Info: "Comparing key 'XDG_CURRENT_DESKTOP' to 'GDMSESSION'"
    gasp.c:183: Info: "Adding node for option -D GDMSESSION=\"cinnamon\""
    corrupted size vs. prev_size
    And now the function that lead to the corruption:
    Code:
    int gasp_make_defenv_opt( nodes_t *ARGS, ... ) {
    	int ret = 0;
    	option_t *options, *option;
    	char const *key, *val;
    	node_t i;
    	va_list v;
    	
    	va_start( v, ARGS );
    	options = ARGS->space.block;
    	while ( (key = va_arg( v, char const *)) )
    	{
    		REPORTF("Checking for key '%s'", key)
    		
    		if ( !(val = getenv(key)) )
    			continue;
    		REPORTF("Value is '%s'", val)
    		
    		REPORTF("Checking if '%s' is already defined", key)
    		for ( i = 0; i < ARGS->count; ++i )
    		{
    			option = options + i;
    			REPORTF("Comparing option '%s' to '-D'", option->opt)
    			if ( strcmp( option->opt, "-D" ) != 0 )
    				continue;
    				
    			REPORTF("Comparing key '%s' to '%s'", option->key,key)
    			if ( strcmp( option->key, key ) == 0 )
    				break;
    		}
    		
    		if ( i < ARGS->count )
    		{
    			REPORTF( "Already defined as '%s'", option->val );
    			continue;
    		}
    		
    		REPORTF("Adding node for option -D %s=\"%s\"", key, val) // Stopped at below call
    		if ( (ret = more_nodes(
    			option_t, ARGS, ARGS->count + 1 )) != 0
    		) break;
    		options = ARGS->space.block;
    		option = options + i;
    		
    		if ( (ret = append_to_option( option, "opt", "-D" )) != 0 )
    			return ret;
    		
    		if ( (ret = append_to_option( option, "key", key )) != 0 )
    			return ret;
    		
    		if ( (ret = append_to_option( option, "val", val )) != 0 )
    			return ret;
    		
    		ARGS->count++;
    		REPORTF( "Added %s %s='%s'",
    			option->opt, option->key, option->val )
    	}
    	va_end(v);
    	
    	return ret;
    }
    Which passed the allocation handling to this function:
    Code:
    int change_space( space_t *space, size_t want, int dir ) {
    	int ret = errno = 0;
    	uchar *block;
    	if ( !space ) {
    		if ( !want )
    			return ret;
    		ret = EDESTADDRREQ;
    		ERRMSG( ret, "Need somewhere to place allocated memory" );
    		return ret;
    	}
    	
    	if ( want % 16 )	
    		want += (16 - (want % 16));
    	
    	if ( want == space->given )
    		return 0;
    	
    	/* Shrink */
    	if ( dir < 0 && want > space->given ) {
    		ret = ERANGE;
    		ERRMSG( ret, "Tried to grow shrink-only memory" );
    		return ret;
    	}
    	
    	/* Expand */
    	if ( dir > 0 && want < space->given )
    		return 0;
    	
    	/* Release */
    	if ( !want ) {
    		if ( space->block ) free( space->block );
    		space->block = NULL;
    		space->given = 0;
    		return 0;
    	}
    	
    	if ( !(space->block) ) {
    		if ( !(space->block = malloc( want )) )
    		{
    			ret = errno;
    			space->given = 0;
    			return ret ? ret : ENOMEM;
    		}
    		(void)memset( space->block, 0, want );
    		space->given = want;
    		return 0;
    	}
    	
    	if ( !(block = realloc( space->block, want )) ) { // Here is last line executed before the crash
    		ret = errno;
    		return ret ? ret : ENOMEM;
    	}
    	
    	/* Do this 1st in case a thread tries to access it */
    	space->block = block;
    	space->given = want;
    	
    	if ( space->given < want )
    		(void)memset( block + space->given, 0, want - space->given );
    	
    	return 0;
    }
    Any ideas?

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,018
    Apparently it was caused by a poorly programmed realloc/malloc, they apparently do not pad the wanted size with enough room for the variables they want to attach, I've now added in a variable to add that padding in before allocation then remove it on successful allocation

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. I need help or clues on how to build an array in C++?
    By jason007thomas in forum C++ Programming
    Replies: 5
    Last Post: 11-24-2011, 05:47 AM
  2. Hendrix's last days reveal possible clues!
    By Sebastiani in forum General Discussions
    Replies: 7
    Last Post: 03-10-2010, 07:17 PM
  3. doing a system call
    By ozzy34 in forum C++ Programming
    Replies: 7
    Last Post: 10-02-2004, 08:20 AM
  4. C system call and library call
    By Coconut in forum C Programming
    Replies: 6
    Last Post: 08-22-2002, 11:20 AM
  5. system call
    By stautze in forum C Programming
    Replies: 2
    Last Post: 05-07-2002, 12:48 PM

Tags for this Thread