sys_chroot

プロセス単位で有効

  • current->fs->root, current->fs->rootmntを指定したディレクトリのもので書き変えるだけ
    • chrootしたプロセスからは rootよりも上位のファイルは見えない( rootより上位のパスを指定してもカーネルはパスを解決しない? user_walk ?)
    • chrootしてもネットワークやデバイス等のリソース利用には影響しない
 572 
 573 asmlinkage long sys_chroot(const char __user * filename)
 574 {
 575         struct nameidata nd;
 576         int error;
 577         // chrootするディレクトリのnameidataを取得
 578         error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
 579         if (error)
 580                 goto out;
 581         // パーミッション
 582         error = permission(nd.dentry->d_inode,MAY_EXEC,&nd);
 583         if (error)
 584                 goto dput_and_out;
 585 	     // CAP_SYS_CHROOTケーパビリティが必要
 586         error = -EPERM;
 587         if (!capable(CAP_SYS_CHROOT))
 588                 goto dput_and_out;
 589 
 590         // 現在のプロセスのfs(fs_struct)に、chroot先として指定したディレクトリのvfsmount,dentryをセットする
 591         set_fs_root(current->fs, nd.mnt, nd.dentry);
 592 
 593         // altrootmnt//altrootをセットする??? => x86アーキテクチャでは常にNULLなので関係ない
 594         set_fs_altroot();
 595         error = 0;
 596 dput_and_out:
 597         path_release(&nd);
 598 out:
 599         return error;
 600 }


1215 /*
1216  * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
1217  * It can block. Requires the big lock held.
1218  */
1219 void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt,
1220                  struct dentry *dentry)
1221 {
1222         struct dentry *old_root;
1223         struct vfsmount *old_rootmnt;
1224 
1225         // fsは現在のプロセスのfs_struct
1226         write_lock(&fs->lock);
1227         old_root = fs->root;
1228         old_rootmnt = fs->rootmnt;
1229 
1230         // 指定したパスのvfsmountを新しいvfsmountにする
1231         // mntgetはmnt_countをインクリする
1232         fs->rootmnt = mntget(mnt);
1233 
1234         // 指定したパスのdentryをrootとして設定する
1235         // dgetは d_countをインクリする
1236         fs->root = dget(dentry);
1237         write_unlock(&fs->lock);
1238         if (old_root) {
1239                 dput(old_root);
1240                 mntput(old_rootmnt);
1241         }
1242 }