summaryrefslogblamecommitdiffstats
path: root/md/writeup/writing_linux_mount_utility.md
blob: 0959f93cbc5cee4e95b506e8ba337926ec4cb0d6 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












                                                                                     
                                      


           

                                                                                                     















                                                                          
                                               











                                                      
                                                                     







































                                                                                                
                                                                  

                                                                                        
                                                              













                                                                           
                                                                                                      
                                                                                                              







                                                                                                                                                                                      
           
 
              
 




                                                
 


                                                
 



                                               
 








                                              















                                                                                        






                                                                
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 source code. 

## Syscalls

To implement mount there is enough just with one syscall mount. Its quite simple use case with just 
passing param to syscall is enough. 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 straightforward.

#### 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

Run 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

Latest linux kernel source code where mount syscall is define is  
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/namespace.c  

There are 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 always a mystery where all parameters that are supported by particular filesystem comes from.
I spent some time to find places where all params that are supported for procfs, devtmps and tempfs come from.

### 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 |

## Examples

### Mount proc

```bash
nmount_static -t proc -d ma_proc -f hidepid=0 -v
```

### Mount mqueue

```bash
nmount_static -t mqueue -d ma_quque -f noexec -v
```

### Mount devtmpfs
```bash
mount_static -t devtmpfs -d mq_dev -f noexec -v
```

### Mount tmpfs
```bash
nmount_static -t mqueue -d ma_ram -f noexec -v
```

### Mount sysfs
```bash 
nmount_static -t sysfs -d ma_sys -f silent -v
```


## 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  
https://www.kernel.org/doc/Documentation/filesystems/tmpfs.txt