From 24edf92330b8d7e41a9951812c13ac09267ed76b Mon Sep 17 00:00:00 2001 From: FreeArtMan Date: Tue, 7 Sep 2021 08:33:45 +0100 Subject: Initial mount post --- md/writeup/writing_linux_mount_utility.md | 149 ++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 md/writeup/writing_linux_mount_utility.md (limited to 'md/writeup') diff --git a/md/writeup/writing_linux_mount_utility.md b/md/writeup/writing_linux_mount_utility.md new file mode 100644 index 0000000..9b71a84 --- /dev/null +++ b/md/writeup/writing_linux_mount_utility.md @@ -0,0 +1,149 @@ +title:Writing linux mount utility +keywords:c,linux,kernel,mount + +# Writing linux mount utility + +## Intro + +For long time wanted to understand how all stuff works on system level with linux. +From one side mounting looked like some sort of magic. Decided to write my +own mount utility. As its looks like only one syscall is needed to do that sys_mount. +Other part of it is to see how to get all different file systems and find +options that are possible to pass to mounted partition. All of this also preparations +to write my own linux userspace and to have non-Linux distro. Main inspiration +taken form arsv/minibase soure code. + +## Syscalls + +To implement mount there is enought just with one syscall mount. Its quite simple use case with just +passing param to syscall is enought. There is more time spent to figure out with params are supported +by each of filesystems. + +```c +int smount( + const char *source, + const char *target, + const char *filesystemtype, + unsigned long mountflags, + const void *data) +{ + int ret=-1; + ret = syscall(SYS_mount,source,target,filesystemtype,mountflags,data); + return ret; +} +``` + +Comparison to mount utility is straigforward. + +#### mount arguments +| Param | Descriptio | +|---|---| +| source | Source directory or file to mount | +| target | Target directory where to mount | +| filesystemtype | filesystem type | +| mountflags | mount params | +| data | specific to filesystem | + +### Supported filesystems + +Rund command to find filesystems supported by currently running kernel + +``` +cat /proc/filesystems +``` + +### Mount flags + +Mount flags that can be passed when mounting filesystems, those are taken from kernel definition + +```c +#define _MS_RDONLY (1<<0) +#define _MS_NOSUID (1<<1) +#define _MS_NODEV (1<<2) +#define _MS_NOEXEC (1<<3) +#define _MS_SYNCHRONOUS (1<<4) +#define _MS_REMOUNT (1<<5) +#define _MS_MANDLOCK (1<<6) +#define _MS_DIRSYNC (1<<7) +#define _MS_NOATIME (1<<10) +#define _MS_NODIRATIME (1<<11) +#define _MS_BIND (1<<12) +#define _MS_MOVE (1<<13) +#define _MS_REC (1<<14) +#define _MS_SILENT (1<<15) +#define _MS_POSIXACL (1<<16) +#define _MS_UNBINDABLE (1<<17) +#define _MS_PRIVATE (1<<18) +#define _MS_SLAVE (1<<19) +#define _MS_SHARED (1<<20) +#define _MS_RELATIME (1<<21) +#define _MS_KERNMOUNT (1<<22) +#define _MS_I_VERSION (1<<23) +#define _MS_STRICTATIME (1<<24) +#define _MS_LAZYTIME (1<<25) +``` + + + +## Kernel implementation + +Lates linux kernel source code where mount syscal is define is +https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/namespace.c + +There is 2 definitions one for syscall and one for mount code +```c +SYSCALL_DEFINE5(mount, char user *, dev_name, char user *, dir_name, + char user *, type, unsigned long, flags, void user *, data) + +long do_mount( + const char *dev_name, + const char __user *dir_name, + const char *type_page, + unsigned long flags, + void *data_page); +``` + +## Filesystems + +There is allways a mistery where all parameters that are suppported by particular filesystem comes from. +I spend some time to find all params that are supported for procfs,devtmps and tempfs. + +### Procfs + +| Param | Description | +|---|---| +| hidepid | __0__ - Everybody may access all proc, __1__ - User can access only their own proc, not other /proc/[pid], __2__ - As for mode 1, extra hides pid directories of others | +| gid | usergroup who sees /proc in mode 0 | + +### Devtmpfs + + + +### Tempfs + + +## Implementation + + +## Links + +http://git.main.lv/cgit.cgi/nmount.git/ +https://man7.org/linux/man-pages/man7/signal.7.html +https://man7.org/linux/man-pages/man2/mount.2.html +https://github.com/arsv/minibase/blob/master/src/rootfs/kmount.c +https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/namespace.c +[devtmpfs] +https://www.kernel.org/doc/Documentation/filesystems/sysfs.txt +https://elixir.bootlin.com/linux/v4.14.184/source/drivers/base/devtmpfs.c +https://man7.org/linux/man-pages/man7/file-hierarchy.7.html +[procsf] +https://www.man7.org/linux/man-pages/man5/proc.5.html +https://elixir.bootlin.com/linux/v4.14.184/source/fs/proc/root.c#L33 +[tmpfs] +https://www.kernel.org/doc/Documentation/filesystems/tmpfs.txt + + + + + + -- cgit v1.2.3