chrootコマンド


[root@localhost north]# cat chroot.c
#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);
}

最終更新 2017/01/22 15:08:59 - north
(2014/07/31 18:07:49 作成)


検索

アクセス数
3585526
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。