Кто-нибудь видит какие-либо проблемы в этой программе

После того, как я не получил ответ на этот вопрос о 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;
}

Кто-нибудь видит какие-либо ошибки в этом (или даже лучше, знает инструмент, который делает его избыточным)?

1 ответ

  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 назначение точно делать? Кажется, хак.
  6. В любом случае вы можете добавить более качественные отчеты об ошибках.

И, наконец, chrootuid, вероятно, инструмент, который вы искали.

Другие вопросы по тегам