I've been trying to look for questions on how to use g_spawn_sync()
and they said that it is good to use when you want to execute a command in the terminal besides using pipes.
The only thing I can't figure out now is why the command cat /proc/cpuinfo
doesn't work. error->message
returns (No such file or directory)
but if I use commands like ls
or cat
alone, it works. I also tried running cd /proc && cat cpuinfo
but it gives me the same error.
I'm not an expert of glib but I read in the manual that I can use G_SPAWN_SEARCH_PATH
so that it will check my PATH
for the commands I can use without including the absolute path for the command.
I have the following code:
gchar *argv[] = { "cat /proc/cpuinfo", NULL };
char *output = NULL; // will contain command output
GError *error = NULL;
int exit_status = 0;
if (!g_spawn_sync(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
&output, NULL, &exit_status, &error))
{
printf("[getHardwareInfo] DEBUG: Error on g_spawn_sync %s.\n", error->message);
}
tl;dr: Do not use g_spawn_command_line_sync()
unless you really know what you are doing.
Firstly, the actual problem you are hitting: John Szakmeister’s comment was correct: g_spawn_sync()
takes an array of arguments, the first one of which is the path to the program to execute (or to look for in $PATH
, if you’ve specified G_SPAWN_SEARCH_PATH
). By passing the array { "cat /proc/cpuinfo", NULL }
, you are saying that you want to run the program cat /proc/cpuinfo
with no arguments, not the program cat
with the argument /proc/cpuinfo
.
However, there are many other problems here, and I think it’s important to mention them before people start cargo-culting this code, because they have security implications:
cat
when you could just call g_file_get_contents()
?GSubprocess
instead of g_spawn_*()
. It’s a more modern API, which allows you to monitor the lifecycle of the spawned process more easily, as well as getting streaming I/O in and out of the subprocess.g_spawn_command_line_sync()
. There are several:
$PATH
, so if an attacker has control of your $PATH
, or write access to any directory in that $PATH
(such as ~/.local/bin
), you will end up running an attacker-controlled program.g_spawn_command_line_sync()
seems to do what I want” is “let’s use g_strdup_printf()
to put together a command to run with it”, and then you have shell injection vulnerabilities, where an attacker who controls any of the parameters to that printf()
can twist the entire shell command to execute their arbitrary code.