前情回顧:
我通過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能力標記,可以無視那台機器,哈哈”
欲知后事如何,請關注后續精彩......
往期熱門文章: