Кто-нибудь видит какие-либо проблемы в этой программе
После того, как я не получил ответ на этот вопрос о 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 ответ
- Почему вы назначаете значения по умолчанию для
path
,name
,exe
, если вы их все равно перезапишете? - Вы не должны возвращать отрицательные значения изнутри
main()
, Это делает фактическое возвращаемое значение неясным, поскольку POSIX использует только 8 младших значащих битов (т.е.-1
возвращается как255
, так далее.). - Вы не должны полагаться на
getuid()
;chroot()
должно сработатьCAP_SYS_CHROOT
способность тоже. Вместо этого вы можете попытатьсяchroot()
и проверьте, еслиerrno == EPERM
, chroot()
не меняет текущий рабочий каталог; Я думаю тебе следует позвонитьchdir()
тоже.- Что значит
environ = envp
назначение точно делать? Кажется, хак. - В любом случае вы можете добавить более качественные отчеты об ошибках.
И, наконец, chrootuid, вероятно, инструмент, который вы искали.