4

在没有得到我喜欢这个关于 chroot的问题的答案后,我开始推出自己的解决方案:

#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>
extern char **environ;

int main(int argc, char** argv, char** envp) {
  char* path = "/";
  char* name = "nobody";
  char* exe = "/bin/false";
  struct passwd *pass;

  if(argc < 4) { printf("Need more args: username chroot exe args...\n"); return 1; }
  name = argv[1];
  path = argv[2];
  exe = argv[3];

  if(!(pass = getpwnam(name))) { printf("Unknown user %s", name); return 2; }

  if(chroot(path)) {
    if(errno == EPERM) { printf("chroot not allowed\n"); return 3; }
    printf("chroot failed\n");
    return 4;
  }
  chdir("/");

  if(setgid(pass->pw_gid)) { printf("setgid failed: %d\n", pass->pw_gid); return 5; }
  if(setuid(pass->pw_uid)) { printf("setuid failed: %d\n", pass->pw_uid); return 6; }

  environ = envp;
  execvp(exe, argv + 3);

  printf("exec of %s failed\n", exe);
  return 7;
}

有没有人看到其中的任何错误(或者更好的是,知道一个使它变得多余的工具)?

4

1 回答 1

4
  1. 如果仍然覆盖它们,为什么要将默认值分配给path, name, exe
  2. 您不应该从内部返回负值main()。它使实际返回值不清楚,因为 POSIX 仅使用它的 8 个最低有效位(即-1返回为255等)。
  3. 你不应该依赖getuid(); chroot()也会工作CAP_SYS_CHROOT能力。相反,您可以尝试chroot()检查是否errno == EPERM.
  4. chroot()不改变当前工作目录;我想你也应该打电话chdir()
  5. environ = envp赋值究竟是做什么的?看起来很hacky。
  6. 在任何情况下,您都可以添加更好的错误报告。

最后,chrootuid可能是您正在寻找的工具。

于 2010-09-23T18:00:11.810 回答