有谁发现这个程序有什么问题吗

发布于 2024-09-24 05:45:15 字数 1160 浏览 6 评论 0原文

在没有得到答案后,我喜欢 这个关于 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;
}

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

After not getting an answer I liked for this question about chroot, I went and rolled my own solution:

#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;
}

Does anyone see any bugs in that (or even better, know of a tool that makes it redundant)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

看轻我的陪伴 2024-10-01 05:45:15
  1. 如果您无论如何都覆盖它们,为什么还要为 pathnameexe 分配默认值?
  2. 您不应从 main() 中返回负值。它使得实际的返回值不清楚,因为 POSIX 仅使用它的 8 个最低有效位(即 -1 返回为 255 等)。
  3. 您不应该依赖 getuid()chroot() 也可以使用 CAP_SYS_CHROOT 功能。相反,您可以尝试chroot()并检查errno == EPERM
  4. chroot() 不会更改当前工作目录;我认为你也应该调用 chdir() 。
  5. environ = envp 赋值的具体作用是什么?看起来很老套。
  6. 无论如何,您都可以添加更好的错误报告。

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

  1. Why do you assign defaults to path, name, exe, if you overwrite them anyway?
  2. You should not return negative values from within main(). It makes the actual return value unclear, as POSIX uses only the 8 least significant bits of it (i.e. -1 is returned as 255, etc.).
  3. You shouldn't rely on getuid(); chroot() would work CAP_SYS_CHROOT capability too. Instead, you could try to chroot() and check if errno == EPERM.
  4. chroot() doesn't change the current working directory; I think you should call chdir() too.
  5. What does environ = envp assignment exactly do? It seems hacky.
  6. In any case, you could add better error reporting.

And finally, chrootuid is probably the tool you were looking for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文