linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] remove ksys_dup()
@ 2019-12-12 14:07 Dominik Brodowski
  2019-12-12 14:07 ` [PATCH 1/2] init: unify opening /dev/console as stdin/stdout/stderr Dominik Brodowski
  2019-12-12 14:07 ` [PATCH 2/2] fs: remove ksys_dup() Dominik Brodowski
  0 siblings, 2 replies; 6+ messages in thread
From: Dominik Brodowski @ 2019-12-12 14:07 UTC (permalink / raw)
  To: Alexander Viro, Linus Torvalds; +Cc: Ingo Molnar, Andrew Morton, linux-kernel

Instead of pretending to be userspace, the opening of
/dev/console as stdin/stdout/stderr can be implemented
using in-kernel functions.

---

@viro: is this something for you to take and push upstream
for the next cycle?

The same changes (on top of commit ae4b064e2a616b545acf02b8f50cc513b32c7522:

  Merge tag 'afs-fixes-20191211' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs (2019-12-11 18:10:40 -0800)

are also available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/brodo/linux.git remove-ksys-dup

including all changes up to d7aacb7ad766adea665b440b56e9c9152b1065f7:

  fs: remove ksys_dup() (2019-12-12 14:59:48 +0100)

----------------------------------------------------------------
Dominik Brodowski (2):
      init: unify opening /dev/console as stdin/stdout/stderr
      fs: remove ksys_dup()

 fs/file.c                |  7 +------
 include/linux/initrd.h   |  2 ++
 include/linux/syscalls.h |  1 -
 init/do_mounts_initrd.c  |  5 +----
 init/main.c              | 31 ++++++++++++++++++++++++++-----
 5 files changed, 30 insertions(+), 16 deletions(-)

Thanks,
	Dominik

-- 
2.24.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/2] init: unify opening /dev/console as stdin/stdout/stderr
  2019-12-12 14:07 [PATCH 0/2] remove ksys_dup() Dominik Brodowski
@ 2019-12-12 14:07 ` Dominik Brodowski
  2019-12-12 14:07 ` [PATCH 2/2] fs: remove ksys_dup() Dominik Brodowski
  1 sibling, 0 replies; 6+ messages in thread
From: Dominik Brodowski @ 2019-12-12 14:07 UTC (permalink / raw)
  To: Alexander Viro, Linus Torvalds; +Cc: Ingo Molnar, Andrew Morton, linux-kernel

Merge the two instances where /dev/console is opened as
stdin/stdout/stderr.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
 include/linux/initrd.h  |  2 ++
 init/do_mounts_initrd.c |  5 +----
 init/main.c             | 17 ++++++++++++-----
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/include/linux/initrd.h b/include/linux/initrd.h
index d77fe34fb00a..aa5914355728 100644
--- a/include/linux/initrd.h
+++ b/include/linux/initrd.h
@@ -28,3 +28,5 @@ extern unsigned int real_root_dev;
 
 extern char __initramfs_start[];
 extern unsigned long __initramfs_size;
+
+void console_on_rootfs(void);
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index a9c6cc56f505..a1bc10045fd2 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -48,10 +48,7 @@ early_param("initrd", early_initrd);
 static int init_linuxrc(struct subprocess_info *info, struct cred *new)
 {
 	ksys_unshare(CLONE_FS | CLONE_FILES);
-	/* stdin/stdout/stderr for /linuxrc */
-	ksys_open("/dev/console", O_RDWR, 0);
-	ksys_dup(0);
-	ksys_dup(0);
+	console_on_rootfs();
 	/* move initrd over / and chdir/chroot in initrd root */
 	ksys_chdir("/root");
 	ksys_mount(".", "/", NULL, MS_MOVE, NULL);
diff --git a/init/main.c b/init/main.c
index 91f6ebb30ef0..2cd736059416 100644
--- a/init/main.c
+++ b/init/main.c
@@ -1155,6 +1155,17 @@ static int __ref kernel_init(void *unused)
 	      "See Linux Documentation/admin-guide/init.rst for guidance.");
 }
 
+void console_on_rootfs(void)
+{
+	/* Open the /dev/console as stdin, this should never fail */
+	if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
+		pr_err("Warning: unable to open an initial console.\n");
+
+	/* create stdout/stderr */
+	(void) ksys_dup(0);
+	(void) ksys_dup(0);
+}
+
 static noinline void __init kernel_init_freeable(void)
 {
 	/*
@@ -1190,12 +1201,8 @@ static noinline void __init kernel_init_freeable(void)
 
 	do_basic_setup();
 
-	/* Open the /dev/console on the rootfs, this should never fail */
-	if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
-		pr_err("Warning: unable to open an initial console.\n");
+	console_on_rootfs();
 
-	(void) ksys_dup(0);
-	(void) ksys_dup(0);
 	/*
 	 * check if there is an early userspace init.  If yes, let it do all
 	 * the work
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] fs: remove ksys_dup()
  2019-12-12 14:07 [PATCH 0/2] remove ksys_dup() Dominik Brodowski
  2019-12-12 14:07 ` [PATCH 1/2] init: unify opening /dev/console as stdin/stdout/stderr Dominik Brodowski
@ 2019-12-12 14:07 ` Dominik Brodowski
  2019-12-12 17:09   ` Linus Torvalds
  2019-12-12 18:38   ` Al Viro
  1 sibling, 2 replies; 6+ messages in thread
From: Dominik Brodowski @ 2019-12-12 14:07 UTC (permalink / raw)
  To: Alexander Viro, Linus Torvalds; +Cc: Ingo Molnar, Andrew Morton, linux-kernel

ksys_dup() is used only at one place in the kernel, namely to duplicate
fd 0 of /dev/console to stdout and stderr. The same functionality can be
achieved by using functions already available within the kernel namespace.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
 fs/file.c                |  7 +------
 include/linux/syscalls.h |  1 -
 init/main.c              | 26 ++++++++++++++++++++------
 3 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/fs/file.c b/fs/file.c
index 3da91a112bab..2f4fcf985079 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);
 }
 
-int ksys_dup(unsigned int fildes)
+SYSCALL_DEFINE1(dup, unsigned int, fildes)
 {
 	int ret = -EBADF;
 	struct file *file = fget_raw(fildes);
@@ -975,11 +975,6 @@ int ksys_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;
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index d0391cc2dae9..517dd0bd3939 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -1234,7 +1234,6 @@ asmlinkage long sys_ni_syscall(void);
 int ksys_mount(const char __user *dev_name, const char __user *dir_name,
 	       const char __user *type, unsigned long flags, void __user *data);
 int ksys_umount(char __user *name, int flags);
-int ksys_dup(unsigned int fildes);
 int ksys_chroot(const char __user *filename);
 ssize_t ksys_write(unsigned int fd, const char __user *buf, size_t count);
 int ksys_chdir(const char __user *filename);
diff --git a/init/main.c b/init/main.c
index 2cd736059416..b397ab7aad2c 100644
--- a/init/main.c
+++ b/init/main.c
@@ -93,6 +93,7 @@
 #include <linux/rodata_test.h>
 #include <linux/jump_label.h>
 #include <linux/mem_encrypt.h>
+#include <linux/file.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -1157,13 +1158,26 @@ static int __ref kernel_init(void *unused)
 
 void console_on_rootfs(void)
 {
-	/* Open the /dev/console as stdin, this should never fail */
-	if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
-		pr_err("Warning: unable to open an initial console.\n");
+	struct file *file;
+	unsigned int i;
+
+	/* Open /dev/console in kernelspace, this should never fail */
+	file = filp_open((const char *) "/dev/console", O_RDWR, 0);
+	if (!file)
+		goto err_out;
+
+	/* create stdin/stdout/stderr, this should never fail */
+	for (i = 0; i < 3; i++) {
+		if (f_dupfd(i, file, 0) != i)
+			goto err_out;
+	}
+
+	return;
 
-	/* create stdout/stderr */
-	(void) ksys_dup(0);
-	(void) ksys_dup(0);
+err_out:
+	/* no panic -- this might not be fatal */
+	pr_err("Warning: unable to open an initial console.\n");
+	return;
 }
 
 static noinline void __init kernel_init_freeable(void)
-- 
2.24.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] fs: remove ksys_dup()
  2019-12-12 14:07 ` [PATCH 2/2] fs: remove ksys_dup() Dominik Brodowski
@ 2019-12-12 17:09   ` Linus Torvalds
  2019-12-12 18:38   ` Al Viro
  1 sibling, 0 replies; 6+ messages in thread
From: Linus Torvalds @ 2019-12-12 17:09 UTC (permalink / raw)
  To: Dominik Brodowski
  Cc: Alexander Viro, Ingo Molnar, Andrew Morton, Linux Kernel Mailing List

On Thu, Dec 12, 2019 at 6:08 AM Dominik Brodowski
<linux@dominikbrodowski.net> wrote:
>
> -       if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
> +       file = filp_open((const char *) "/dev/console", O_RDWR, 0);

You need to remove the now pointless cast too.

                        Linus

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] fs: remove ksys_dup()
  2019-12-12 14:07 ` [PATCH 2/2] fs: remove ksys_dup() Dominik Brodowski
  2019-12-12 17:09   ` Linus Torvalds
@ 2019-12-12 18:38   ` Al Viro
  2019-12-12 18:48     ` Linus Torvalds
  1 sibling, 1 reply; 6+ messages in thread
From: Al Viro @ 2019-12-12 18:38 UTC (permalink / raw)
  To: Dominik Brodowski
  Cc: Linus Torvalds, Ingo Molnar, Andrew Morton, linux-kernel

On Thu, Dec 12, 2019 at 03:07:52PM +0100, Dominik Brodowski wrote:
> ksys_dup() is used only at one place in the kernel, namely to duplicate
> fd 0 of /dev/console to stdout and stderr. The same functionality can be
> achieved by using functions already available within the kernel namespace.

Let's not expose the kernel guts to init/*.c more than absolutely unavoidable.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/2] fs: remove ksys_dup()
  2019-12-12 18:38   ` Al Viro
@ 2019-12-12 18:48     ` Linus Torvalds
  0 siblings, 0 replies; 6+ messages in thread
From: Linus Torvalds @ 2019-12-12 18:48 UTC (permalink / raw)
  To: Al Viro
  Cc: Dominik Brodowski, Ingo Molnar, Andrew Morton, Linux Kernel Mailing List

On Thu, Dec 12, 2019 at 10:38 AM Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> Let's not expose the kernel guts to init/*.c more than absolutely unavoidable.

Well, in this case I think it's more than justified: it removes one of
the nasty "pass user pointers from kernel space" cases.

I'd like to get to the point where "init" doesn't need set_fs() at
all. We're not there now - do_execve() is going to be painful. So
maybe we'll never be. But this gets us one step closer, at least.

               Linus

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-12-12 18:48 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-12 14:07 [PATCH 0/2] remove ksys_dup() Dominik Brodowski
2019-12-12 14:07 ` [PATCH 1/2] init: unify opening /dev/console as stdin/stdout/stderr Dominik Brodowski
2019-12-12 14:07 ` [PATCH 2/2] fs: remove ksys_dup() Dominik Brodowski
2019-12-12 17:09   ` Linus Torvalds
2019-12-12 18:38   ` Al Viro
2019-12-12 18:48     ` Linus Torvalds

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).