有谁发现这个程序有什么问题吗
在没有得到答案后,我喜欢 这个关于 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
path
、name
、exe
分配默认值?main()
中返回负值。它使得实际的返回值不清楚,因为 POSIX 仅使用它的 8 个最低有效位(即-1
返回为255
等)。getuid()
;chroot()
也可以使用CAP_SYS_CHROOT
功能。相反,您可以尝试chroot()
并检查errno == EPERM
。chroot()
不会更改当前工作目录;我认为你也应该调用 chdir() 。environ = envp
赋值的具体作用是什么?看起来很老套。最后,chrootuid 可能就是您正在寻找的工具。
path
,name
,exe
, if you overwrite them anyway?main()
. It makes the actual return value unclear, as POSIX uses only the 8 least significant bits of it (i.e.-1
is returned as255
, etc.).getuid()
;chroot()
would workCAP_SYS_CHROOT
capability too. Instead, you could try tochroot()
and check iferrno == EPERM
.chroot()
doesn't change the current working directory; I think you should callchdir()
too.environ = envp
assignment exactly do? It seems hacky.And finally, chrootuid is probably the tool you were looking for.