summaryrefslogtreecommitdiff
path: root/fs/file.c
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2020-01-01 20:05:03 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2020-01-02 16:15:33 -0800
commit74f1a299107b9e1a563831a4ba85f769ab577164 (patch)
tree847a00cb533bea4d8af5e451315ed60215548d19 /fs/file.c
parent738d2902773e30939a982c8df7a7f94293659810 (diff)
downloadlwn-74f1a299107b9e1a563831a4ba85f769ab577164.tar.gz
lwn-74f1a299107b9e1a563831a4ba85f769ab577164.zip
Revert "fs: remove ksys_dup()"
This reverts commit 8243186f0cc7 ("fs: remove ksys_dup()") and the subsequent fix for it in commit 2d3145f8d280 ("early init: fix error handling when opening /dev/console"). Trying to use filp_open() and f_dupfd() instead of pseudo-syscalls caused more trouble than what is worth it: it requires accessing vfs internals and it turns out there were other bugs in it too. In particular, the file reference counting was wrong - because unlike the original "open+2*dup" sequence it used "filp_open+3*f_dupfd" and thus had an extra leaked file reference. That in turn then caused odd problems with Androidx86 long after boot becaue of how the extra reference to the console kept the session active even after all file descriptors had been closed. Reported-by: youling 257 <youling257@gmail.com> Cc: Arvind Sankar <nivedita@alum.mit.edu> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/file.c')
-rw-r--r--fs/file.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/file.c b/fs/file.c
index 2f4fcf985079..3da91a112bab 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -960,7 +960,7 @@ SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd)
return ksys_dup3(oldfd, newfd, 0);
}
-SYSCALL_DEFINE1(dup, unsigned int, fildes)
+int ksys_dup(unsigned int fildes)
{
int ret = -EBADF;
struct file *file = fget_raw(fildes);
@@ -975,6 +975,11 @@ SYSCALL_DEFINE1(dup, unsigned int, fildes)
return ret;
}
+SYSCALL_DEFINE1(dup, unsigned int, fildes)
+{
+ return ksys_dup(fildes);
+}
+
int f_dupfd(unsigned int from, struct file *file, unsigned flags)
{
int err;