OneFS:Linux 核心更新至 NFS 會導致「存取」呼叫失敗
摘要: Linux 核心中網路檔案系統 (NFS) 程式碼的更新已變更「存取」呼叫檢查特定 OneFS 權限集上「寫入」權限的行為。此變更使 Linux NFS 和伺服器訊息區塊 (SMB) 行為彼此一致,無論您使用何種通訊協定,此檢查都一致。
症状
Linux內核升級后,以前成功的訪問檢查現在在訪問使用者對其工作流涉及的目錄沒有“delete_child”許可權的目錄上失敗。您可以使用 Linux 進行驗證 test 命令含 -w 針對同一目錄進行標記;在舊內核版本上,該命令的返回代碼為 0 而在較新的內核中,它是 1。
這會影響 Red Hat 和 Centos 用戶端從版本 7 移至較新版本。
原因
此行為變更是在 Linux 主線核心 v4.13-rc2 重構 NFS 驅動程式代碼期間引入的。但是,很明顯,該檢查在主線內核 v3.7-rc1
中存在,並且未正確調用。
經過廣泛的審查,我們相信新的Linux內核行為和我們的行為都是正確的。Linux test 命令與 access 系統調用都基於 POSIX 標準,該標準僅概念化:
- 讀
- 寫
- 誅
鑒於根據 rfc1813#section-3.3.4 和 rfc7530#section-16.1
;NFS 允許更精細的許可權,因此概念化:
- 讀
- 修飾
- 䵙
- 刪除
- 誅
將 DELETE 權限定義為用戶端是否可以 Delete an existing directory entry。這直接映射到 delete_child 中,且在用戶端沒有該權限的情況下應予以拒絕。另請注意;POSIX 和 NFS 權限不完全相符。POSIX WRITE 包含 NFS 中的所有概念 修改、追加和刪除權限。因此,當POSIX工具嘗試檢查“寫入”許可權時,linux內核正在將“寫入”請求轉換為“修改並附加和刪除”
最後,較新的行為更符合也支援此許可權集的其他 Linux 檔案系統驅動程式。例如,針對具有相同許可權集的 SMB 檔案管理員進行測試,在檢查 POSIX WRITE 時,也會傳回失敗 test 命令使用 -w 旗。
# Old kernel ancons@ubuntu:~$ uname -r 4.13.0-041300rc1-generic ancons@ubuntu:~$ sudo mount -o vers=4,proto=tcp 10.20.0.181:/ifs /mnt/nfs ancons@ubuntu:~$ sudo mount -o user=admin,pass=a //10.20.0.181/ifs /mnt/smb ancons@ubuntu:~$ test -w /mnt/nfs/posix; echo "$?" 0 ancons@ubuntu:~$ test -w /mnt/smb/posix; echo "$?" 1 # New kernel ancons@ubuntu:~$ uname -r 4.14.0-041400rc4-generic ancons@ubuntu:~$ sudo mount -o vers=4,proto=tcp 10.20.0.181:/ifs /mnt/nfs ancons@ubuntu:~$ sudo mount -o user=admin,pass=a //10.20.0.181/ifs /mnt/smb ancons@ubuntu:~$ test -w /mnt/nfs/posix; echo "$?" 1 ancons@ubuntu:~$ test -w /mnt/smb/posix; echo "$?" 1
解决方案
在這種情況下,OneFS 和 Linux 行為皆正確,因為受此問題影響的工作流程必須提供 delete_child 受影響的使用者和組的許可權。例如,如果目錄提供對其擁有者使用者和組的完全訪問許可權,但移除 delete_child 從「每個人」許可權中,他們可以將該許可權添加到每個人,也可以為直接訪問控制清單 (ACL) 看到問題的使用者或組添加額外的訪問控制項 (ACE)。
# ACL that only allows root to delete child items p980-1-1# ls -led /ifs/posix-delete_child drwxrwxrwx + 2 root wheel 0 Jun 18 14:20 /ifs/posix-delete_child OWNER: user:root GROUP: group:wheel 0: user:root allow dir_gen_read,dir_gen_write,dir_gen_execute,std_write_dac,delete_child 1: group:wheel allow dir_gen_read,dir_gen_write,dir_gen_execute,delete_child 2: everyone allow dir_gen_read,dir_gen_write,dir_gen_execute # ACL that allows a specific additional group to delete child items p980-1-1# ls -led /ifs/posix-delete_child drwxrwxrwx + 2 root wheel 0 Jun 18 14:20 /ifs/posix-delete_child OWNER: user:root GROUP: group:wheel 0: group:admin allow dir_gen_read,dir_gen_write,dir_gen_execute,delete_child 1: user:root allow dir_gen_read,dir_gen_write,dir_gen_execute,std_write_dac,delete_child 2: group:wheel allow dir_gen_read,dir_gen_write,dir_gen_execute,delete_child 3: everyone allow dir_gen_read,dir_gen_write,dir_gen_execute # ACL that allows everyone to delete child items p980-1-1# ls -led /ifs/posix-delete_child drwxrwxrwx + 2 root wheel 0 Jun 18 14:20 /ifs/posix-delete_child OWNER: user:root GROUP: group:wheel 0: user:root allow dir_gen_read,dir_gen_write,dir_gen_execute,std_write_dac,delete_child 1: group:wheel allow dir_gen_read,dir_gen_write,dir_gen_execute,delete_child 2: everyone allow dir_gen_read,dir_gen_write,dir_gen_execute,delete_child
您也可以更新 Linux 核心以還原該行為。這需要在更新後從原始程式碼構建Linux內核 fs/nfs/dir.c 若要移除 NFS4_ACCESS_DELETE 要求來自 NFS_MAY_WRITE 巨集。
以前:
#define NFS_MAY_WRITE (NFS4_ACCESS_MODIFY | \ NFS4_ACCESS_EXTEND | \ NFS4_ACCESS_DELETE)
後:
#define NFS_MAY_WRITE (NFS4_ACCESS_MODIFY | \ NFS4_ACCESS_EXTEND)