replace_fd() returns the number of the new file descriptor through the return value of do_dup2(). However its callers never care about the specific returned number. In fact the caller in receive_fd_replace() treats any non-zero return value as an error and therefore never calls __receive_sock() for most file descriptors, which is a bug. To fix the bug in receive_fd_replace() and to avoid the same issue happening in future callers, signal success through a plain zero. Suggested-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Link: https://lore.kernel.org/lkml/20250801220215.GS222315@ZenIV/ Fixes: 173817151b15 ("fs: Expand __receive_fd() to accept existing fd") Fixes: 42eb0d54c08a ("fs: split receive_fd_replace from __receive_fd") Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Thomas Weißschuh <thomas.weissschuh@xxxxxxxxxxxxx> --- Changes in v3: - Make commit message slightly more precise - Avoid double-unlock of file_lock - Link to v2: https://lore.kernel.org/r/20250804-fix-receive_fd_replace-v2-1-ecb28c7b9129@xxxxxxxxxxxxx Changes in v2: - Move the fix to replace_fd() (Al) - Link to v1: https://lore.kernel.org/r/20250801-fix-receive_fd_replace-v1-1-d46d600c74d6@xxxxxxxxxxxxx --- Untested, it stuck out while reading the code. --- fs/file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/file.c b/fs/file.c index 6d2275c3be9c6967d16c75d1b6521f9b58980926..80957d0813db5946ba8a635520e8283c722982b9 100644 --- a/fs/file.c +++ b/fs/file.c @@ -1330,7 +1330,8 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags) err = expand_files(files, fd); if (unlikely(err < 0)) goto out_unlock; - return do_dup2(files, file, fd, flags); + err = do_dup2(files, file, fd, flags); + return err < 0 ? err : 0; out_unlock: spin_unlock(&files->file_lock); --- base-commit: d2eedaa3909be9102d648a4a0a50ccf64f96c54f change-id: 20250801-fix-receive_fd_replace-7fdd5ce6532d Best regards, -- Thomas Weißschuh <thomas.weissschuh@xxxxxxxxxxxxx>