chroot 可以用來切換當前程序的【根目錄】,它能夠將當前程序能夠訪問的目錄樹結構限制
在某個子目錄中,同時由於當前程序建立的子程序將會繼承父程序的根目錄結構,所以子進
程也隨之被限定。
通過 strace 來跟蹤一次 chroot 命令執行過程來研究其**執行過程。
這裡我刪除了與這個問題沒有太大關係的一些輸出,重要的系統呼叫資訊如下:
[root@localhost new_test]# strace chroot . sh
execve("/usr/sbin/chroot", ["chroot", ".", "sh"], 0x7fffbf1a9580 /* 28 vars */) = 0
..............................
chroot(".") = 0
chdir("/") = 0
execve("/usr/local/sbin/sh", ["sh"], 0x7fff5cd3d1a8 /* 28 vars */) = -1 enoent (沒有那個檔案或目錄)
execve("/usr/local/bin/sh", ["sh"], 0x7fff5cd3d1a8 /* 28 vars */) = -1 enoent (沒有那個檔案或目錄)
execve("/usr/sbin/sh", ["sh"], 0x7fff5cd3d1a8 /* 28 vars */) = -1 enoent (沒有那個檔案或目錄)
execve("/usr/bin/sh", ["sh"], 0x7fff5cd3d1a8 /* 28 vars */) = 0
.............................
上述過程可以總結為如下幾個步驟:
execve 執行 chroot 程式
chroot 系統呼叫切換當前命令的根目錄
chdir 系統呼叫切換當前命令的工作目錄到新的根目錄
根據路徑搜尋預設 shell 的位置,使用 execve 進行執行
這裡它搜尋預設 shell 的路徑時有幾個備選路徑,搜尋順序如下:
/usr/local/sbin/sh
/usr/local/bin/sh
/usr/sbin/sh
/usr/bin/sh
從上面的捕獲到的 chroot 命令的系統呼叫可以看到 chroot 命令的核心其實就是呼叫
chroot系統呼叫,這也就是其核心態的主要行為,這個行為並不是直接完成這項功能
的,它實際是通過一種間接的方式修改 task_struct 中的資料結構來達成的。
細心的讀者也許會注意到 chroot 在執行了 chroot 系統呼叫後,又呼叫了chdir切換
【當前目錄】到【新的根目錄】的行為,這個行為是必不可少的!
chdir 系統呼叫將會修改當前程序 task_sturct fs 中的 pwd 字段,這個字段儲存了當前工作
目錄的dentry結構體。
核心**如下:
set_fs_pwd
(current->fs,
&path)
;
如果 chroot 命令不 chdir 到 「/」 目錄,那麼我們仍舊可以在 chroot 後的程式中通過訪問到
外界的目錄
,這樣就會出現非常好玩的情景。為了驗證這點,我進行了如下幾個嘗試。
chroot 命令中有乙個–skip-chdir引數,在根目錄中執行如下命令來使用它:
[root@localhost /]
# /root/chroot --skip-chdir /root/chroot_environment/ sh
/root/chroot: option --skip-chdir only permitted if newroot is old '/'
這裡報錯資訊表明–skip-chdir 只在新的 root 目錄與老的根目錄相同時才被允許使用。
#if 0if(
! skip_chdir && chdir (
"/")
) die (exit_canceled, errno,_(
"cannot chdir to root directory"))
;#endif
重新編譯後執行,在終端中執行如下命令:
[root@localhost /]
# /chroot /root/chroot_environment sh
(unreachable)/ # ls
bin chroot etc lib media opt root sbin sys usr
boot dev home lib64 mnt proc run srv tmp var
(unreachable)/ # chroot .
[root@localhost /]
# ls
bin boot chroot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@localhost /]
# exit
exit
(unreachable)/ # cd ./root
sh: cd: can't cd to ./root: no such file or directory
(unreachable)/ # cd /root
~ # cd ..
/ # ls
bin dev etc lib64 proc root sys usr var
/ #
第一行命令切根後,由於沒有 chdir 到新的根目錄,cwd 中仍然儲存了舊的工作目錄的
dentry 資訊
,這樣我們仍舊能夠訪問到舊的根目錄下的所有檔案,第二行的 ls 命令的輸出資訊證實了這點。
第三行命令繼續執行了 chroot,注意這裡的引數為.,.表示當前目錄,這行命令執行後,又
切回了原來的根目錄。
第四行命令從第三行命令的 chroot 環境中退出,退出後嘗試 cd ./root,發現會報這個目錄
不存在的錯誤。
通過 strace 跟蹤這個 sh,發現它傳遞給 chdir 系統呼叫的命令並不是 ./root,而是 "
(unreachable)/root",這個目錄當然不存在嘍,就報了目錄不存在的錯誤。
chdir("(unreachable)/root") = -1 enoent (沒有那個檔案或目錄)
write(2, "sh: ", 4) = 4
write(2, "cd: ", 4) = 4
write(2, "can't cd to ./root: no such file"..., 45) = 45
單獨編寫了乙個呼叫 chdir(「root」) 的**編譯後執行測試,確認能夠 chdir,看來應該是 sh
進行了某種處理。
\w 當前工作目錄
我當前 shell 的 ps1 設定如下:
(unreachable)/ # echo $ps1
\w \$
看來 sh 執行的時候應該是通過當前目錄的變數將我輸入的 ./ 展開了,這樣就有上面的
問題了。
第五行命令中 cd /root 成功,這是肯定的,因為當前程序的根目錄已經切換了,所以我們能
夠進入到這個 /root 目錄,而且這個目錄也是新的目錄。
第六行命令中 cd … 返回根目錄,然後執行 ls 命令,可以看到此時根目錄下的檔案已經變
了,直至這裡才完成了 chroot 的所有過程。
Linux日誌分析命令之cut命令使用介紹
cut檔案內容檢視 顯示行中的指定部分,刪除檔案中指定字段 該命令有兩項功能,其一是用來顯示檔案的內容,它依次讀取由引數file所指明的檔案,將它們的內容輸出到標準輸出上 其二是連線兩個或多個檔案,如cut fl f2 f3將把檔案fl和幾的內容合併起來,然後通過輸出重定向符 的作用,將它們放入檔案...
Linux命令分析 touch
用途 更改檔案的時間戳,常用來建立新的空檔案 用法 touch 選項.檔案.touch命令可用來更改檔案的atime和mtime到當前時間,如果touch命令後接的檔案不存在,則會建立乙個該檔名的空檔案 除非有 c或 h引數 引數 a 只更改atime c no create 不建立任何檔案 d d...
Linux命令分析 whereis
用途 用於定位命令的二進位制檔案,原始碼檔案和man說明檔案的路徑 用法 whereis bmsu bms 目錄.f 檔案.whereis命令通過查詢mlocate資料庫來定位檔案,故執行速度較快,該資料庫在centos下的路徑是 var lib mlocate mlocate.db,該資料庫用來記...