chrootコマンド


Rev.3を表示中。最新版はこちら

chrootコマンドでrootを変更する場合、前もってbashおよび掛かるdllを、rootとなるホルダ配下に配置させる必要がありますが、これはchrootそのものの制約ではありません。
[root@localhost kitamura]# pwd
/home/kitamura
[root@localhost kitamura]# chroot /home/
chroot: failed to run command `/bin/bash': No such file or directory

[root@localhost kitamura]# ldd /bin/bash
       linux-gate.so.1 =>  (0xb77ca000)
       libtinfo.so.5 => /lib/libtinfo.so.5 (0x48787000)
       libdl.so.2 => /lib/libdl.so.2 (0x47596000)
       libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x475f3000)
       libc.so.6 => /lib/libc.so.6 (0x473e3000)
       /lib/ld-linux.so.2 (0x473be000)
chrootコマンドの処理は、chroot("/home")とし、chdir("/")でcwdを/にで、execve("/bin/bash")としています。従ってルートとなる、/home以下にbashかかるdllが無ければなりません。なければrootが変更されたchrootコマンドプロセスは終了し、元のbashに戻るだけです。

chrootシステムコールは、呼び出しプロセスのrootを更新します。ターミナルからchrootコマンドを起動すると、bashの子プロセスとしてchrootコマンドのプロセスが起動され、そこでchrootすれば、親のbashプロセスのrootでなく、chrootコマンドプロセスのrootを変更します。そのプロセスとbashをexecv()で差し替えることで、rootを/homeとする、子プロセスとしての別bashが起動さ、exitで親のrootが変更されていない親のbashに戻るわけです。

chrootシステムコールは、current->fs->root = path(filename)とするだけで、以降このプロセスの絶対パスでのファイル検索は、current->fs->rootから走査されるということです。
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);
}

備考

2.6.0では異なるアーキテクチャをサポートするカーネル(64ビットカーネルで32ビット/64ビットを動作させる等)で、current->fsにaltrootを有しており、アーキテクチャ毎に通常のrootと別のrootを切り分けることで実装されていましたが、3.3.8ではサポートされなくなったようです。


最終更新 2014/07/31 18:29:26 - north
(2014/07/31 18:07:49 作成)


検索

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