任务 8:使用 system() 和 execve() 调用外部程序
Section outline
-
虽然 system() 和 execve() 都可以用来运行新程序,但如果在特权程序(例如 Set-UID 程序)中使用 system(),则可能非常危险。我们已经看到 system() 如何受 PATH 环境变量的影响,因为该变量会影响 shell 的行为。而 execve() 没有这个问题,因为它不会调用 shell。调用 shell 还有另一个危险的后果,这次与环境变量无关。让我们看以下场景。
Bob 在一家审计机构工作,他需要调查一家公司是否存在欺诈行为。为了调查,Bob 需要能够读取公司 Unix 系统中的所有文件。但是为了保护系统的完整性,Bob 不应该能够修改任何文件。为此,系统的超级用户 Vince 编写了一个特殊的 set-root-uid 程序(见下文),并授予 Bob 可执行权限。该程序要求 Bob 在命令行输入一个文件名,然后它将运行 /bin/cat 来显示指定的文件。由于程序以 root 权限运行,它可以显示 Bob 指定的任何文件。然而,由于该程序没有写的操作,Vince 确信 Bob 无法使用这个特殊程序修改任何文件。
int main(int argc, char *argv[]) { char *v[3]; char *command; if(argc < 2) { printf("Please type a file name.\n"); return 1; } v[0] = "/bin/cat"; v[1] = argv[1]; v[2] = NULL; command = malloc(strlen(v[0]) + strlen(v[1]) + 2); sprintf(command, "%s %s", v[0], v[1]); // 仅使用以下两种方法之一。 system(command); // execve(v[0], v, NULL); return 0 ; }