如果我尝试同时设置 S_ISUID 和所有者,为什么 nfsd 会清除 SETATTR 中的 S_ISUID 位?

Why nfsd clears S_ISUID bit in SETATTR if I try to set S_ISUID and owner at the same time?

nfsd 的 NFSv3 协议 specifies that SETATTR can set file/dir mode and owner at the same time (as well as few other things). And yet Linux implementation 表现得很奇怪:

/* Revoke setuid/setgid on chown */
if (!S_ISDIR(inode->i_mode) &&
    ((iap->ia_valid & ATTR_UID) || (iap->ia_valid & ATTR_GID))) {
    iap->ia_valid |= ATTR_KILL_PRIV;
    if (iap->ia_valid & ATTR_MODE) {
        /* we're setting mode too, just clear the s*id bits */
        iap->ia_mode &= ~S_ISUID;
        if (iap->ia_mode & S_IXGRP)
            iap->ia_mode &= ~S_ISGID;
    } else {
        /* set ATTR_KILL_* bits and let VFS handle it */
        iap->ia_valid |= (ATTR_KILL_SUID | ATTR_KILL_SGID);
    }
}

这是什么原因?我花了很多时间在一些旧应用程序中追踪它(由于某种原因无法在不丢失 suid 位的情况下通过 NFS 复制文件)。这是一个错误吗?即使新所有者是同一个人,也会发生这种情况。

禁用 SUID 是针对 不受信任的 NFS 服务器的某种保护:如果您本地计算机的管理员不信任 NFS 服务器,则它无法从服务器执行文件具有root权限。另请参阅文章 NFS, no_root_squash and SUID - Basic NFS Security

这是 Linux NFS 服务器实现中的错误。参见 NFS specs