Эх сурвалжийг харах

[PATCH] get rid of corner case in dup3() entirely

Since Ulrich is OK with getting rid of dup3(fd, fd, flags) completely,
to hell the damn thing goes.  Corner case for dup2() is handled in
sys_dup2() (complete with -EBADF if dup2(fd, fd) is called with fd
that is not open), the rest is done in dup3().

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Al Viro 17 жил өмнө
parent
commit
6c5d0512a0
1 өөрчлөгдсөн 11 нэмэгдсэн , 9 устгасан
  1. 11 9
      fs/fcntl.c

+ 11 - 9
fs/fcntl.c

@@ -135,18 +135,12 @@ asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
 	if ((flags & ~O_CLOEXEC) != 0)
 	if ((flags & ~O_CLOEXEC) != 0)
 		return -EINVAL;
 		return -EINVAL;
 
 
+	if (unlikely(oldfd == newfd))
+		return -EINVAL;
+
 	spin_lock(&files->file_lock);
 	spin_lock(&files->file_lock);
 	if (!(file = fcheck(oldfd)))
 	if (!(file = fcheck(oldfd)))
 		goto out_unlock;
 		goto out_unlock;
-	err = newfd;
-	if (unlikely(newfd == oldfd)) {
-		if (flags & O_CLOEXEC) {
-			fdt = files_fdtable(files);
-			FD_SET(newfd, fdt->close_on_exec);
-		}
-		goto out_unlock;
-	}
-	err = -EBADF;
 	if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
 	if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
 		goto out_unlock;
 		goto out_unlock;
 	get_file(file);			/* We are now finished with oldfd */
 	get_file(file);			/* We are now finished with oldfd */
@@ -194,6 +188,14 @@ out_fput:
 
 
 asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
 asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
 {
 {
+	if (unlikely(newfd == oldfd)) { /* corner case */
+		struct files_struct *files = current->files;
+		rcu_read_lock();
+		if (!fcheck_files(files, oldfd))
+			oldfd = -EBADF;
+		rcu_read_unlock();
+		return oldfd;
+	}
 	return sys_dup3(oldfd, newfd, 0);
 	return sys_dup3(oldfd, newfd, 0);
 }
 }