linux 命令分析之 chroot 的原理

2021-10-25 04:27:45 字數 4248 閱讀 8272

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,該資料庫用來記...