patch-2.3.12 linux/include/linux/file.h

Next file: linux/include/linux/fs.h
Previous file: linux/include/linux/binfmts.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.11/linux/include/linux/file.h linux/include/linux/file.h
@@ -56,18 +56,6 @@
 }
 
 /*
- * Install a file pointer in the fd array.
- */
-extern inline void fd_install(unsigned int fd, struct file * file)
-{
-	struct files_struct *files = current->files;
-
-	write_lock(&files->file_lock);
-	files->fd[fd] = file;
-	write_unlock(&files->file_lock);
-}
-
-/*
  * 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>: 
  * 
  * Since those functions where calling other functions, it was compleatly 
@@ -89,5 +77,27 @@
 		_fput(file);
 }
 extern void put_filp(struct file *);
+
+/*
+ * Install a file pointer in the fd array.  
+ *
+ * The VFS is full of places where we drop the files lock between
+ * setting the open_fds bitmap and installing the file in the file
+ * array.  At any such point, we are vulnerable to a dup2() race
+ * installing a file in the array before us.  We need to detect this and
+ * fput() the struct file we are about to overwrite in this case.
+ */
+
+extern inline void fd_install(unsigned int fd, struct file * file)
+{
+	struct files_struct *files = current->files;
+	struct file * result;
+	
+	write_lock(&files->file_lock);
+	result = xchg(&files->fd[fd], file);
+	write_unlock(&files->file_lock);
+	if (result)
+		fput(result);
+}
 
 #endif /* __LINUX_FILE_H */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)