一個故事看懂Linux文件權限管理

前情回顧

我通過open這個系統調用蟲洞來到了內核空間,又在老爺爺的指點下來到了sys_open的地盤,即將開始打開文件的工作。

詳情參見:內核地址空間大冒險:系統調用

 

open系統調用鏈

我是一個線程,出生在這個Linux帝國。
在老爺爺的指點下,通過系統調用表來到了這個叫sys_open的地方。這里很簡陋,簡單比劃了幾下就直接來到了do_sys_open的地盤。

一個負責接待的美女給我簡單辦理了手續,就讓我去里面一個do_filp_open的房間。進去之后,這個房間里的工作人員又讓我去后面的path_openat房間。
“打開個文件怎么這么麻煩,搞這么層級處理~”,我開始有點不爽了,便隨口抱怨了一句。

“這才哪到哪,后面要辦的手續還多著呢,年輕人一點耐心都沒有”,原來我的抱怨不小心被path_openat里的工作人員聽到了。
我有點不好意思,硬著頭皮走了過去。

“把你要打開的文件名和需要的權限準備好,先去左手邊的path_init窗口先做些準備工作”,工作人員低著頭說到。我

瞅了瞅旁邊的窗口,按他說的照辦。


“再去右手邊的link_path_walk窗口,找到你要訪問的文件”,工作人員再次說到。我繼續照辦。



“好了,我辦好了,這下該給我打開文件了吧?”,我累得上氣不接下氣。

“你穿過這個門,去do_last房間吧,里面有位大爺,他會接受你的請求的。

對了,把這個帶上,一會兒他們要用”,工作人員說完給了我一張紙條。

沒想到還沒辦完手續,不過這名字既然叫do_last,應該就是最后一道手續了吧。我揣起紙條,又繼續前行。


來到do_last房間,我傻眼了,這里看起來要做的事情很多啊,沒辦法,都走到這一步了咬著牙也得堅持下去。

一頓操作猛如虎,總算來到了一個叫finish_open函數的面前,看樣子馬上就要真正打開文件了。

 

權限檢查

“唉,等一下!”,突然一個聲音叫住了我,我不由得心頭一緊,難不成到嘴的肉要飛了?我轉過頭來,之前工作人員口中的大爺出現在我背后。

“大爺,您叫我干什么?”“小伙子,我是這里的保安,你現在還不能去那兒,先過來做個安檢”

真是怕啥來啥,打開個文件怎么就這么難!

“安檢?”

“對,這里有個may_open的大門,你先進去,檢查合格了我才能讓你打開文件。”,大爺一邊說一邊把我往may_open的大門里拽。

 

半推半就,我進入了他口中的may_open房間,環顧四周,這里也比較簡陋,沒兩步就到了一個叫inode_permission的房間。

這里面的氣氛一下子緊張了起來,幾個彪形大漢在此值守。

“把你要打開的文件的inode拿來,還有你要的訪問權限”,門口的一個大漢大聲說到。

“訪問權限我知道,我是要讀取權限READ,你說的文件inode是什么,我...我這里只有文件的名字”,我感覺到自己有點緊張。


“我要你名字干什么,我們需要inode信息,不然怎么檢查你有沒有權限,你一路走到這里怎么會沒有inode信息呢?”

他的這句話倒是提醒了我,想起剛剛在path_openat房間,那邊的工作人員給了我一個紙條。我掏了出來,上面果然記錄了inode信息,我趕緊交給了大漢。

“你跟我來,先去做常規DAC檢查”,其中一個稍微面善的老伯帶著我又來到隔壁一個叫generic_permission的房間。

這里面有一臺很大的機器在轟隆隆運轉著,旁邊還有三個大門,老伯走到機器前一頓操作。“我已經把你要訪問的文件inode信息輸入進去了,你從面前那個門走過去一下”

按照老伯的指示,我穿過了第一臺安檢門,機器自動發出了提示音:“ERROR,當前進程fsuid != 目標文件uid”聽到提示音的我嚇了一跳。

“看來這文件不是你所屬的用戶的啊,沒關系,再走過第二扇安檢門試試”

 

“老伯,這機器是怎么知道文件是不是我所屬的用戶的呢?”我有點好奇

“文件的歸屬用戶id是保存在文件索引inode里面的,而你所在的進程的用戶id也是保存在進程的task_struct里面的,這臺機器自動提取這兩個信息比較就知道了”,老伯微笑著說到。


“原來是這樣,我的task_struct里面確實有一個uid”

老伯搖了搖頭,“不對不對,不是那個,是fsuid。也不在那里,是在task_struct->cred里面的,這個cred就是你的憑證,來咱們內核空間辦事兒,到處都要檢查,你可要收好了,弄丟了就麻煩了”

“那現在怎么辦?這文件不是我所屬用戶的,我是不是沒有權限打開呢?”

“別著急,你再走過第二扇門試試”


聽從老伯的指示,我又穿過了第二道門,機器又一次發出了提示音:“ERROR,當前進程fsgid != 目標文件gid

又報錯了!我越發的擔心起來。


“看來你也不在這個文件的歸屬組里啊”,老伯嘆了口氣。我正想問,老伯又開口了,“不過別著急,還有一次機會,快走進第三扇門”

抱著一絲希望,走進了第三扇門,沒有意外的機器又報警了:“ERROR,目標文件權限640,其他用戶無訪問權限!

我的心情跌落到了谷底,沒想到忙活了這么久,居然沒有權限打開。

 

UGO & ACL

“先別氣餒,還有機會!”,老伯突然拍了下我的肩膀。

“不是三道門都報錯了嗎,怎么還有機會呢?”,我小聲的問道。

“UGO權限檢查沒通過,不過我注意到你要訪問的文件有ACL,興許還有機會也未可知。”

“UGO是什么?ACL又是什么”,面對這兩個新詞,我一下有點懵。

“UGO就是(User, Group, Other)的縮寫,Linux帝國為所有文件針對所屬用戶、同組用戶和其他用戶分別設置了訪問權限,Read、Write、Execute三種權限的組合,并把這些權限信息和文件的歸屬信息記錄在了索引信息inode里面,就是你之前拿到的那個紙條,帝國把這種權限管理方式叫UGO”

我聽得似懂非懂,“那ACL又是什么呢?”

“UGO的管理方式有些簡單粗暴,為了更精細化的管理,帝國高層經過商議后,頒布了新的政策就是ACL(Access Control List),訪問控制列表的意思,在UGO的基礎上,可以單獨記錄一些細粒度的權限信息,比如指定組外某一個特殊用戶允許對文件的訪問,這些信息就構成了一個訪問控制列表,把這個表的地址放到了inode里面,你看到那個紅色的+號沒,表示這個文件是有ACL的,所以你還有機會再試一試”

聽完老伯的講解,我又重新燃起了希望,辛苦大半天,我可不想空手而歸。

老伯再次對著機器一頓操作,出現了第四扇門,我給自己鼓了鼓勁,走了過去。

這一次機器沒有發出刺耳的聲音,而是一聲清脆的“SUCCESS”!

老伯走了過來,“恭喜,檢查通過了,咱們回去吧”

檢查通過的我仿佛經歷了一場大考,心里如釋重負,回去的步伐輕快了許多。

 

Cgroup & SELinux

回到inode_permission房間,老伯向另一個彪形大漢提交了檢查結果。

“阿虎,DAC檢查已經通過了,下面交給你了。”原來這一位叫阿虎,正想著,他走了過來。

“小子,跟我來吧,繼續做Cgroup檢查”

我的心咯噔一下,居然還有檢查。“Cgroup檢查又是干嘛的?”,我忍不住問到。

“我們是Linux帝國進程分組控制管理部下轄的devices部門,在此奉命檢查你是否有權限訪問對應的設備,請配合我們的工作”,阿虎嚴肅正經的回答。

“這應該是最后一次檢查了吧,完事兒總該放我走了吧?”

 

命運總是會跟我開玩笑,聽到我的問題,旁邊又一位大哥走了過來,“等會檢查通過的話,我們SELinux部門還有最后一道檢查,麻煩您再堅持一下~”

 

我一下沒了力氣,癱坐了一旁,“容我休息休息”。


未完待續·······

 

彩蛋

在我休息的間隙,隔壁generic_permission房間又傳來了幾下錯誤的提示音,不知道哪個倒霉蛋要空手而歸了。

一會兒老伯就出來了,“阿虎,DAC檢查已經通過了,下面交給你了。”

 

“老伯,我剛剛明明聽到了機器報警,檢查不通過才對啊”,我走上去問老伯。

“哦,你說他啊,他是一個特權進程的線程,有CAP_DAC_OVERRIDE能力標記,可以無視那臺機器,哈哈”

 

欲知后事如何,請關注后續精彩......

 

 

 

往期熱門文章

誰動了你的HTTPS流量?

堆棧里的秘密行動:劫持執行流

堆棧里的悄悄話——智能指針

路由器里的廣告秘密

內核地址空間大冒險2:中斷與異常

一個DNS數據包的驚險之旅

DDoS攻擊:無限戰爭一條

SQL注入引出的驚天大案

內核地址空間大冒險:系統調用

一個HTTP數據包的奇幻之旅

遠去的傳說:安全軟件群雄混戰史

默認瀏覽器爭霸傳奇

我是一個流氓軟件線程

我是一個殺毒軟件線程

posted @ 2020-02-25 14:10  軒轅之風  閱讀(...)  評論(...編輯  收藏
内部期期公开一波中特