运行 猫 /proc/cpuinfo 能说会道

Running cat /proc/cpuinfo in glib

我一直在寻找关于如何使用的问题 g_spawn_sync() 他们说除了使用管道之外,当你想在终端中执行命令时使用它也很好。

我现在唯一想不通的是为什么命令cat /proc/cpuinfo不起作用。 error->message returns (No such file or directory) 但是如果我单独使用像 lscat 这样的命令,它就可以工作。我也试过 运行 cd /proc && cat cpuinfo 但它给了我同样的错误。

我不是 glib 专家,但我在手册中读到我可以使用 G_SPAWN_SEARCH_PATH 以便它会检查我的 PATH 是否可以使用不包含绝对路径的命令对于命令。

我有以下代码:

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);

}

我在这里回答我的问题。又看了一遍手册,决定使用另一个函数,g_spawn_command_line_sync,比g_spawn_sync更简单易用。

A simple version of g_spawn_sync() with little-used parameters removed, taking a command line instead of an argument vector. See g_spawn_sync() for full details. command_line will be parsed by g_shell_parse_argv(). Unlike g_spawn_sync(), the G_SPAWN_SEARCH_PATH flag is enabled. Note that G_SPAWN_SEARCH_PATH can have security implications, so consider using g_spawn_sync() directly if appropriate. Possible errors are those from g_spawn_sync() and those from g_shell_parse_argv().

这是我的新代码:

char *output = NULL; // will contain command output
GError *error = NULL;
gint exit_status = 0;
if (!g_spawn_command_line_sync("cat /proc/cpuinfo", &output, NULL, &exit_status, &error))
{
    printf("[getHardwareInfo] DEBUG: Error on g_spawn_command_line_sync %s.\n", error->message);

tl;dr:除非你真的知道自己在做什么,否则不要使用 g_spawn_command_line_sync()

首先,您遇到的实际问题:John Szakmeister 的评论是正确的:g_spawn_sync() 接受一个参数数组,第一个参数是要执行的程序的路径(或在$PATH,如果您指定了 G_SPAWN_SEARCH_PATH)。通过传递数组 { "cat /proc/cpuinfo", NULL },您是说您想要 运行 不带参数的程序 cat /proc/cpuinfo 而不是 程序 cat 与参数 /proc/cpuinfo.

然而,这里还有很多其他问题,我认为在人们开始对这段代码进行货物崇拜之前提及它们很重要,因为它们具有 安全隐患:

  • 正如 LegalProgrammer 所说,为什么在您可以调用 g_file_get_contents() 时生成 cat
  • 否则,请使用 GSubprocess 而不是 g_spawn_*()。它是一个更现代的 API,它允许您更轻松地监视派生进程的生命周期,以及让流 I/O 进出子进程。
  • 不要忽略手册中有关使用 g_spawn_command_line_sync() 的安全隐患的警告。有几个:
    • 它将 运行 在您的 $PATH 中找到的第一个匹配程序,因此如果攻击者控制了您的 $PATH,或对该 [=12] 中任何目录的写入权限=](比如~/.local/bin),你最终会运行一个攻击者控制的程序。
    • 这是一个同步函数,所以会在子进程完成时阻塞,这可能会花费无限时间。届时您的程序将没有响应。
    • 它 returns 输出在单个分配中,而不是作为流,所以如果子进程 returns 输出很多兆字节,你可能会遇到分配失败并中止。
    • 从“g_spawn_command_line_sync() 似乎做我想做的事”明显的下一步是“让我们使用 g_strdup_printf() 将命令放在一起 运行”,然后你有 shell injection vulnerabilities,控制 printf() 任何参数的攻击者可以扭曲整个 shell 命令来执行他们的任意代码。