Merge branch 'remove-ksys-mount-dup' of git://git.kernel.org/pub/scm/linux/kernel/git/brodo/linux
Pull ksys_mount() and ksys_dup() removal from Dominik Brodowski: "This small series replaces all in-kernel calls to the userspace-focused ksys_mount() and ksys_dup() with calls to kernel-centric functions: For each replacement of ksys_mount() with do_mount(), one needs to verify that the first and third parameter (char *dev_name, char *type) are strings allocated in kernelspace and that the fifth parameter (void *data) is either NULL or refers to a full page (only occurence in init/do_mounts.c::do_mount_root()). The second and fourth parameters (char *dir_name, unsigned long flags) are passed by ksys_mount() to do_mount() unchanged, and therefore do not require particular care. Moreover, instead of pretending to be userspace, the opening of /dev/console as stdin/stdout/stderr can be implemented using in-kernel functions as well. Thereby, ksys_dup() can be removed for good" [ This doesn't get rid of the special "kernel init runs with KERNEL_DS" case, but it at least removes _some_ of the users of "treat kernel pointers as user pointers for our magical init sequence". One day we'll hopefully be rid of it all, and can initialize our init_thread addr_limit to USER_DS. - Linus ] * 'remove-ksys-mount-dup' of git://git.kernel.org/pub/scm/linux/kernel/git/brodo/linux: fs: remove ksys_dup() init: unify opening /dev/console as stdin/stdout/stderr init: use do_mount() instead of ksys_mount() initrd: use do_mount() instead of ksys_mount() devtmpfs: use do_mount() instead of ksys_mount()
This commit is contained in:
commit
2e6d304515
|
@ -359,7 +359,7 @@ static int handle_remove(const char *nodename, struct device *dev)
|
|||
* If configured, or requested by the commandline, devtmpfs will be
|
||||
* auto-mounted after the kernel mounted the root filesystem.
|
||||
*/
|
||||
int devtmpfs_mount(const char *mntdir)
|
||||
int devtmpfs_mount(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -369,7 +369,7 @@ int devtmpfs_mount(const char *mntdir)
|
|||
if (!thread)
|
||||
return 0;
|
||||
|
||||
err = ksys_mount("devtmpfs", mntdir, "devtmpfs", MS_SILENT, NULL);
|
||||
err = do_mount("devtmpfs", "dev", "devtmpfs", MS_SILENT, NULL);
|
||||
if (err)
|
||||
printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
|
||||
else
|
||||
|
@ -394,7 +394,7 @@ static int devtmpfsd(void *p)
|
|||
*err = ksys_unshare(CLONE_NEWNS);
|
||||
if (*err)
|
||||
goto out;
|
||||
*err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
|
||||
*err = do_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
|
||||
if (*err)
|
||||
goto out;
|
||||
ksys_chdir("/.."); /* will traverse into overmounted root */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -3325,8 +3325,8 @@ struct dentry *mount_subtree(struct vfsmount *m, const char *name)
|
|||
}
|
||||
EXPORT_SYMBOL(mount_subtree);
|
||||
|
||||
int ksys_mount(const char __user *dev_name, const char __user *dir_name,
|
||||
const char __user *type, unsigned long flags, void __user *data)
|
||||
SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
|
||||
char __user *, type, unsigned long, flags, void __user *, data)
|
||||
{
|
||||
int ret;
|
||||
char *kernel_type;
|
||||
|
@ -3359,12 +3359,6 @@ int ksys_mount(const char __user *dev_name, const char __user *dir_name,
|
|||
return ret;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
|
||||
char __user *, type, unsigned long, flags, void __user *, data)
|
||||
{
|
||||
return ksys_mount(dev_name, dir_name, type, flags, data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a kernel mount representation for a new, prepared superblock
|
||||
* (specified by fs_fd) and attach to an open_tree-like file descriptor.
|
||||
|
|
|
@ -1666,11 +1666,11 @@ extern bool kill_device(struct device *dev);
|
|||
#ifdef CONFIG_DEVTMPFS
|
||||
extern int devtmpfs_create_node(struct device *dev);
|
||||
extern int devtmpfs_delete_node(struct device *dev);
|
||||
extern int devtmpfs_mount(const char *mntdir);
|
||||
extern int devtmpfs_mount(void);
|
||||
#else
|
||||
static inline int devtmpfs_create_node(struct device *dev) { return 0; }
|
||||
static inline int devtmpfs_delete_node(struct device *dev) { return 0; }
|
||||
static inline int devtmpfs_mount(const char *mountpoint) { return 0; }
|
||||
static inline int devtmpfs_mount(void) { return 0; }
|
||||
#endif
|
||||
|
||||
/* drivers/base/power/shutdown.c */
|
||||
|
|
|
@ -28,3 +28,5 @@ extern unsigned int real_root_dev;
|
|||
|
||||
extern char __initramfs_start[];
|
||||
extern unsigned long __initramfs_size;
|
||||
|
||||
void console_on_rootfs(void);
|
||||
|
|
|
@ -1231,10 +1231,7 @@ asmlinkage long sys_ni_syscall(void);
|
|||
* the ksys_xyzyyz() functions prototyped below.
|
||||
*/
|
||||
|
||||
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);
|
||||
|
|
|
@ -387,12 +387,25 @@ static void __init get_fs_names(char *page)
|
|||
*s = '\0';
|
||||
}
|
||||
|
||||
static int __init do_mount_root(char *name, char *fs, int flags, void *data)
|
||||
static int __init do_mount_root(const char *name, const char *fs,
|
||||
const int flags, const void *data)
|
||||
{
|
||||
struct super_block *s;
|
||||
int err = ksys_mount(name, "/root", fs, flags, data);
|
||||
if (err)
|
||||
return err;
|
||||
char *data_page;
|
||||
struct page *p;
|
||||
int ret;
|
||||
|
||||
/* do_mount() requires a full page as fifth argument */
|
||||
p = alloc_page(GFP_KERNEL);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
data_page = page_address(p);
|
||||
strncpy(data_page, data, PAGE_SIZE - 1);
|
||||
|
||||
ret = do_mount(name, "/root", fs, flags, data_page);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ksys_chdir("/root");
|
||||
s = current->fs->pwd.dentry->d_sb;
|
||||
|
@ -402,7 +415,10 @@ static int __init do_mount_root(char *name, char *fs, int flags, void *data)
|
|||
s->s_type->name,
|
||||
sb_rdonly(s) ? " readonly" : "",
|
||||
MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
|
||||
return 0;
|
||||
|
||||
out:
|
||||
put_page(p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __init mount_block_root(char *name, int flags)
|
||||
|
@ -670,8 +686,8 @@ void __init prepare_namespace(void)
|
|||
|
||||
mount_root();
|
||||
out:
|
||||
devtmpfs_mount("dev");
|
||||
ksys_mount(".", "/", NULL, MS_MOVE, NULL);
|
||||
devtmpfs_mount();
|
||||
do_mount(".", "/", NULL, MS_MOVE, NULL);
|
||||
ksys_chroot(".");
|
||||
}
|
||||
|
||||
|
|
|
@ -48,13 +48,10 @@ 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);
|
||||
do_mount(".", "/", NULL, MS_MOVE, NULL);
|
||||
ksys_chroot(".");
|
||||
ksys_setsid();
|
||||
return 0;
|
||||
|
@ -89,7 +86,7 @@ static void __init handle_initrd(void)
|
|||
current->flags &= ~PF_FREEZER_SKIP;
|
||||
|
||||
/* move initrd to rootfs' /old */
|
||||
ksys_mount("..", ".", NULL, MS_MOVE, NULL);
|
||||
do_mount("..", ".", NULL, MS_MOVE, NULL);
|
||||
/* switch root and cwd back to / of rootfs */
|
||||
ksys_chroot("..");
|
||||
|
||||
|
@ -103,7 +100,7 @@ static void __init handle_initrd(void)
|
|||
mount_root();
|
||||
|
||||
printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
|
||||
error = ksys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
|
||||
error = do_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
|
||||
if (!error)
|
||||
printk("okay\n");
|
||||
else {
|
||||
|
|
31
init/main.c
31
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>
|
||||
|
@ -1155,6 +1156,30 @@ static int __ref kernel_init(void *unused)
|
|||
"See Linux Documentation/admin-guide/init.rst for guidance.");
|
||||
}
|
||||
|
||||
void console_on_rootfs(void)
|
||||
{
|
||||
struct file *file;
|
||||
unsigned int i;
|
||||
|
||||
/* Open /dev/console in kernelspace, this should never fail */
|
||||
file = filp_open("/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;
|
||||
|
||||
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)
|
||||
{
|
||||
/*
|
||||
|
@ -1190,12 +1215,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
|
||||
|
|
Loading…
Reference in New Issue