OneFS:Linux 内核更新到 NFS 会导致“访问”调用失败
Riepilogo: 对 Linux 内核中网络文件系统 (NFS) 代码的更新更改了检查特定 OneFS 权限集的“写入”权限的“访问”调用的行为。此更改使 Linux NFS 和服务器消息块 (SMB) 行为彼此一致,从而使此检查保持一致,而不管您使用什么协议。
Sintomi
在 Linux 内核升级后,对于访问用户对其工作流所涉及的目录没有“delete_child”权限的目录,以前成功的访问检查现在会失败。这可以使用 Linux 进行验证 test 命令替换为 -w 标记到同一目录;在旧内核版本上,该命令的返回代码为 0 而在较新的内核中,它是 1。
这会影响从版本 7 到更高版本的 Red Hat 和 Centos 客户端。
Causa
此行为更改是在重构 NFS 驱动程序代码期间在 Linux 主线内核 v4.13-rc2 中引入的。但是,显然从主线内核 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 在 OneFS 中,并且应在客户端没有该权限的情况下被拒绝。另请注意;POSIX 和 NFS 权限不完全匹配。POSIX WRITE 包括单独的 NFS MODIFY、APPEND 和 DELETE 权限中的所有概念。因此,当 POSIX 工具尝试检查“WRITE”权限时,linux 内核会将对“WRITE”的请求转换为“MODIFY and APPEND and DELETE”
最后,较新的行为更符合也支持此权限集的其他 Linux 文件系统驱动程序。例如,针对具有相同权限集的 SMB 文件管理器进行测试时,在使用 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
Risoluzione
在这种情况下,OneFS 和 Linux 的行为都是正确的,因为受此问题影响的此类工作流必须提供 delete_child 受影响的用户和组的权限。例如,如果目录为其所有者用户和组提供完全访问权限,但删除了 delete_child 在 Everyone 权限中,他们可以将该权限添加到 everyone,也可以为看到问题的用户或组添加额外的访问控制条目 (ACE) 直接添加到 的访问控制列表 (ACL)。
# 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)