chrootコマンド
[root@localhost north]# cat chroot.c
[root@localhost north]# mkdir lib
[root@localhost north]# cp /lib/* lib/
[root@localhost north]# pwd
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
void main(int argc, char *argv[])
{
int pid, status, ret, fd;
char buf[64], exename[64];
if (argc == 1) {
printf("----------\n");
ret = syscall(SYS_getcwd, buf, 64);
printf("%s cwd is %s\n", argv[0], buf);
}
else {
ret = syscall(SYS_getcwd, buf, 64);
printf("%s cwd is %s\n", argv[0], buf);
pid = fork();
if (!pid) {
printf("%s/a.out try to exec by /a.out\n", argv[1]);
chroot(argv[1]);
execl("/a.out", "/a.out", NULL);
}
else {
waitpid(pid, &status, 0);
}
}
}
[root@localhost north]# mkdir lib
[root@localhost north]# cp /lib/* lib/
[root@localhost north]# pwd
/home/north[root@localhost north]# ./a.out /home/north
./a.out cwd is /home/north /home/north/a.out try to exec by /a.out ---------- /a.out cwd is /パス検索はcurrent->fs->rootから走査され、chrootはcurrent->fs->root = path(filename)となり、動的ライブラリの実行モジュール等プロセスのパス走査の掛かる実装に影響されます。
SYSCALL_DEFINE1(chroot, const char __user *, filename)
{
struct path path;
int error;
error = user_path_dir(filename, &path);
if (error)
goto out;
error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
if (error)
goto dput_and_out;
error = -EPERM;
if (!capable(CAP_SYS_CHROOT))
goto dput_and_out;
error = security_path_chroot(&path);
if (error)
goto dput_and_out;
set_fs_root(current->fs, &path);
error = 0;
dput_and_out:
path_put(&path);
out:
return error;
}
void set_fs_root(struct fs_struct *fs, struct path *path)
{
struct path old_root;
spin_lock(&fs->lock);
write_seqcount_begin(&fs->seq);
old_root = fs->root;
fs->root = *path;
path_get_longterm(path);
write_seqcount_end(&fs->seq);
spin_unlock(&fs->lock);
if (old_root.dentry)
path_put_longterm(&old_root);
}






