Allow callers of do_dup2 to free the old file descriptor in case they need to make additional operations on it. Signed-off-by: aloktiagi <aloktiagi@xxxxxxxxx> --- fs/file.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/file.c b/fs/file.c index 4b2346b8a5ee..04c8775d337a 100644 --- a/fs/file.c +++ b/fs/file.c @@ -1086,7 +1086,7 @@ bool get_close_on_exec(unsigned int fd) } static int do_dup2(struct files_struct *files, - struct file *file, unsigned fd, unsigned flags) + struct file *file, unsigned fd, struct file **fdfile, unsigned flags) __releases(&files->file_lock) { struct file *tofree; @@ -1120,7 +1120,7 @@ __releases(&files->file_lock) spin_unlock(&files->file_lock); if (tofree) - filp_close(tofree, files); + *fdfile = tofree; return fd; @@ -1132,6 +1132,7 @@ __releases(&files->file_lock) int replace_fd(unsigned fd, struct file *file, unsigned flags) { int err; + struct file *fdfile = NULL; struct files_struct *files = current->files; if (!file) @@ -1144,7 +1145,10 @@ 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, &fdfile, flags); + if (fdfile) + filp_close(fdfile, files); + return err; out_unlock: spin_unlock(&files->file_lock); @@ -1216,6 +1220,7 @@ static int ksys_dup3(unsigned int oldfd, unsigned int newfd, int flags) { int err = -EBADF; struct file *file; + struct file *fdfile = NULL; struct files_struct *files = current->files; if ((flags & ~O_CLOEXEC) != 0) @@ -1237,7 +1242,10 @@ static int ksys_dup3(unsigned int oldfd, unsigned int newfd, int flags) goto Ebadf; goto out_unlock; } - return do_dup2(files, file, newfd, flags); + err = do_dup2(files, file, newfd, &fdfile, flags); + if (fdfile) + filp_close(fdfile, files); + return err; Ebadf: err = -EBADF; -- 2.34.1