souk4711 / hakoniwa

Process isolation for Linux using namespaces, resource limits and seccomp.
Apache License 2.0
19 stars 3 forks source link

uid not mapped for /proc/ #5

Closed fishrockz closed 4 months ago

fishrockz commented 5 months ago

I think the uid/gid mapping for proc might be broken or i might be using it wrong.

I looked at the example

✦ ❯ cargo run -- run --ro-bind /etc/passwd --uid 0 -- whoami
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.03s
     Running `target/debug/hakoniwa run --ro-bind /etc/passwd --uid 0 -- whoami`
root

And expanded it to how the file system is mapped through.

✦ ❯ cargo run -- run --ro-bind /etc/passwd --uid 0 -- ls -ln
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.03s
     Running `target/debug/hakoniwa run --ro-bind /etc/passwd --uid 0 -- ls -ln`
total 340
dr-xr-xr-x.   3 65534 65534  69632 May  1 21:53 bin
drwxr-xr-x.   2     0  1000    120 Jun 15 12:49 dev
drwxr-xr-x.   2     0  1000     60 Jun 15 12:49 etc
dr-xr-xr-x.  84 65534 65534  36864 Apr 27 17:49 lib
dr-xr-xr-x. 202 65534 65534 225280 May  1 21:53 lib64
dr-xr-xr-x. 622 65534 65534      0 Jun 15 12:49 proc
drwxr-xr-x.  15 65534 65534   4096 Apr 27 17:45 usr

I would have expected /proc/ to also be mapped in the same way as /dev/

For my use case i use a existing mount point but with the users permissions, ie files/directories at mountpoint are owned by the user running this code.

    let mut executor = sandbox.command(prog, &argv);
    for env in environment_variables {
        executor.setenv(&env.name, &env.value);
    }
    executor.rw_bind("/dev/null", "/dev/null").unwrap();
    executor.rw_bind("/dev/random", "/dev/random").unwrap();
    executor.rw_bind("/dev/urandom", "/dev/urandom").unwrap();
    executor.rw_bind("/dev/zero", "/dev/zero").unwrap();
    //executor.rw_bind("tmpfs", "/tmp/").unwrap();
    executor
        ._bind("", "/tmp/", Some("tmpfs"), Some(true))
        .unwrap();
    executor.uid(0);
    executor.gid(0);

    if interactive {
        executor.stdout(Stdio::inherit());
        executor.stderr(Stdio::inherit());
        executor.stdin(Stdio::inherit());
    }

    if network {
        executor.share_net_ns(true);
    }

    executor.container_root_dir(mountpoint).unwrap();

    let result = executor.run();

then i get

sh-5.2# ls -ln
total 3
lrw-r--r--.   1     0     0  3 Jan  1  1970 bin -> usr/bin
drwxr-xr-x.   2     0     0  0 Jan  1  1970 boot
drwxr-xr-x.   2     0     0  0 Jan  1  1970 dev
drwxr-xr-x.  55     0     0  0 Jan  1  1970 etc
drwxr-xr-x.   2     0     0  0 Jan  1  1970 home
lrw-r--r--.   1     0     0  3 Jan  1  1970 lib -> usr/lib
lrw-r--r--.   1     0     0  5 Jan  1  1970 lib32 -> usr/lib32
lrw-r--r--.   1     0     0  5 Jan  1  1970 lib64 -> usr/lib64
lrw-r--r--.   1     0     0  6 Jan  1  1970 libx32 -> usr/libx32
drwxr-xr-x.   2     0     0  0 Jan  1  1970 media
drwxr-xr-x.   2     0     0  0 Jan  1  1970 mnt
drwxr-xr-x.   2     0     0  0 Jan  1  1970 opt
dr-xr-xr-x. 611 65534 65534  0 Jun 15 12:36 proc
drwxr-xr-x.   2     0     0  0 Jan  1  1970 root
drwxr-xr-x.   5     0     0  0 Jan  1  1970 run
lrw-r--r--.   1     0     0  4 Jan  1  1970 sbin -> usr/sbin
drwxr-xr-x.   2     0     0  0 Jan  1  1970 srv
drwxr-xr-x.   2     0     0  0 Jan  1  1970 sys
drwxrwxrwt.   2     0     0 40 Jun 15 12:36 tmp
drwxr-xr-x.  14     0     0  0 Jan  1  1970 usr
drwxr-xr-x.  11     0     0  0 Jan  1  1970 var
sh-5.2# ls -l 
total 3
lrw-r--r--.   1 root   root     3 Jan  1  1970 bin -> usr/bin
drwxr-xr-x.   2 root   root     0 Jan  1  1970 boot
drwxr-xr-x.   2 root   root     0 Jan  1  1970 dev
drwxr-xr-x.  55 root   root     0 Jan  1  1970 etc
drwxr-xr-x.   2 root   root     0 Jan  1  1970 home
lrw-r--r--.   1 root   root     3 Jan  1  1970 lib -> usr/lib
lrw-r--r--.   1 root   root     5 Jan  1  1970 lib32 -> usr/lib32
lrw-r--r--.   1 root   root     5 Jan  1  1970 lib64 -> usr/lib64
lrw-r--r--.   1 root   root     6 Jan  1  1970 libx32 -> usr/libx32
drwxr-xr-x.   2 root   root     0 Jan  1  1970 media
drwxr-xr-x.   2 root   root     0 Jan  1  1970 mnt
drwxr-xr-x.   2 root   root     0 Jan  1  1970 opt
dr-xr-xr-x. 611 nobody nogroup  0 Jun 15 12:36 proc
drwxr-xr-x.   2 root   root     0 Jan  1  1970 root
drwxr-xr-x.   5 root   root     0 Jan  1  1970 run
lrw-r--r--.   1 root   root     4 Jan  1  1970 sbin -> usr/sbin
drwxr-xr-x.   2 root   root     0 Jan  1  1970 srv
drwxr-xr-x.   2 root   root     0 Jan  1  1970 sys
drwxrwxrwt.   2 root   root    40 Jun 15 12:36 tmp
drwxr-xr-x.  14 root   root     0 Jan  1  1970 usr
drwxr-xr-x.  11 root   root     0 Jan  1  1970 var
sh-5.2#

Note: I deliberately set the ctime/mtime/atime to the UNIX epoc to try to make thing running in the sandbox to be as consistent as possible. (this is a fuse file system so is easy to do this)

fishrockz commented 4 months ago

I found that the proc UID/GID mapping seems to be broken even if you don't map your UID to another.

✦ ❯ cargo run -- run --ro-bind /etc/passwd -- ls -lnh
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.03s
     Running `target/debug/hakoniwa run --ro-bind /etc/passwd -- ls -lnh`
total 340K
dr-xr-xr-x.   3 65534 65534  68K May  1 21:53 bin
drwxr-xr-x.   2  1000  1000  120 Jun 15 22:11 dev
drwxr-xr-x.   2  1000  1000   60 Jun 15 22:11 etc
dr-xr-xr-x.  84 65534 65534  36K Apr 27 17:49 lib
dr-xr-xr-x. 202 65534 65534 220K May  1 21:53 lib64
dr-xr-xr-x. 716 65534 65534    0 Jun 15 22:11 proc
drwxr-xr-x.  15 65534 65534 4.0K Apr 27 17:45 usr
souk4711 commented 4 months ago

I found that the proc UID/GID mapping seems to be broken even if you don't map your UID to another.

✦ ❯ cargo run -- run --ro-bind /etc/passwd -- ls -lnh
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.03s
     Running `target/debug/hakoniwa run --ro-bind /etc/passwd -- ls -lnh`
total 340K
dr-xr-xr-x.   3 65534 65534  68K May  1 21:53 bin
drwxr-xr-x.   2  1000  1000  120 Jun 15 22:11 dev
drwxr-xr-x.   2  1000  1000   60 Jun 15 22:11 etc
dr-xr-xr-x.  84 65534 65534  36K Apr 27 17:49 lib
dr-xr-xr-x. 202 65534 65534 220K May  1 21:53 lib64
dr-xr-xr-x. 716 65534 65534    0 Jun 15 22:11 proc
drwxr-xr-x.  15 65534 65534 4.0K Apr 27 17:45 usr

current user (e.g. uid 1000, gid 1000) is mapped into container by default.

souk4711 commented 4 months ago

i do not think we can map /proc in the same way as /dev without root, plz see https://github.com/containers/podman/discussions/16558

fishrockz commented 4 months ago

Yes having spoke to some others about this, i now realise that this is how it should work.