Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runsc: boot: use a more reliable method to check /proc #10254

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

terenceli
Copy link

Currently we check whether /proc is umounted by 'unix.Access'. If we run runsc as setuid binary using unprivileged user(in our use cases) we may get EPERM even the /proc is umounted as Linux uses uid to perform the check. In this case we get the error '/proc is still accessible'.

Notice this error can only occur combined with following two conditions:

  1. we uses --network host. This is because in non-host mode, the runsc will create a new userns and do uid identity mapping, the child process will be run as 0:0(uid:gid) so the check will be ok
  2. the umask setting should be set to mask the all perm of others such as 0027. This is because if we don't mask the others's read perm, the check will also be ok as the unprivileged uid can also read /proc/ file.

This patch uses a more reliable method to do check /proc check.

@terenceli
Copy link
Author

@ayushr2 Could you please review this? I see you add this code.
Thanks

runsc/cmd/boot.go Outdated Show resolved Hide resolved
@ayushr2
Copy link
Collaborator

ayushr2 commented Apr 10, 2024

I am a bit confused, if access(2) fails with EPERM due to lack of read permission for /proc directory, then won't ioutil.ReadDir() (which should use getdents(2) on an open FD) also fail with EPERM when opening a O_RDONLY FD to /proc?

@terenceli
Copy link
Author

I am a bit confused, if access(2) fails with EPERM due to lack of read permission for /proc directory, then won't ioutil.ReadDir() (which should use getdents(2) on an open FD) also fail with EPERM when opening a O_RDONLY FD to /proc?

No in the setuid root binary case, the access uses the real uid(which is not 0) to do check, and the open syscall uses the euid(which is 0) to do the check.

@ayushr2
Copy link
Collaborator

ayushr2 commented Apr 10, 2024

No in the setuid root binary case, the access uses the real uid(which is not 0) to do check, and the open syscall uses the euid(which is 0) to do the check.

I see, could you update the description to reflect this. I know you already mention "Linux uses uid to perform the check", but explicitly calling out that open(2) uses euid so this is more friendly for setuid use cases will make it more clear.

@terenceli
Copy link
Author

No in the setuid root binary case, the access uses the real uid(which is not 0) to do check, and the open syscall uses the euid(which is 0) to do the check.

I see, could you update the description to reflect this. I know you already mention "Linux uses uid to perform the check", but explicitly calling out that open(2) uses euid so this is more friendly for setuid use cases will make it more clear.

Ok, will make a revision for the commit msg and code.

@EtiennePerot
Copy link
Contributor

EtiennePerot commented Apr 11, 2024

we run runsc as setuid binary using unprivileged user

FWIW, this doesn't seem very safe. This means an unprivileged user on the system can run runsc as root. In turn, that means such a user can also access anything on the host filesystem (since runsc allows you to create sandboxes that can mount and modify any host file). In turn, that means the user effectively has root on the host. This is functionally the same as if one were to configure sudo to be available to all unprivileged users with no authentication to access the root user. I suggest reconsidering the approach.

@terenceli
Copy link
Author

we run runsc as setuid binary using unprivileged user

FWIW, this doesn't seem very safe. This means an unprivileged user on the system can run runsc as root. In turn, that means such a user can also access anything on the host filesystem (since runsc allows you to create sandboxes that can mount and modify any host file). In turn, that means the user effectively has root on the host. This is functionally the same as if one were to configure sudo to be available to all unprivileged users with no authentication to access the root user. I suggest reconsidering the approach.

@EtiennePerot Yes you're right, we have also consider this risk. We uses it in very restricted scenario and we also investigated some other methods.

Once the this issue #9918 is resovled totaly we will uses this rootless mode.

Thanks

runsc/cmd/boot.go Outdated Show resolved Hide resolved
Currently we check whether /proc is umounted by 'unix.Access'.
If we run runsc as setuid binary using unprivileged user(this is
unsafe, not recommended) we may get EPERM even the /proc is umounted.
This is because access(2) uses the real uid to perform the
permission check but open(2) uses the euid to perform the check.
In setuid cases the uid is not the same as the euid.

In this case we get the error '/proc is stil accessible'.

Notice this error can only occur combined with following two conditions:
1. we uses --network host. This is because in non-host mode, the runsc
will create a new userns and do uid identity mapping, the child process
will be run as 0:0(uid:gid) so the check will be ok
2. the umask setting should be set to mask the all perm of others such as
0027. This is because if we don't mask the others's read perm, the check
will also be ok as the unprivileged uid can also read /proc/ file.

This patch uses a more reliable method to do /proc check.
if err := unix.Access("/proc/self", unix.F_OK); err != unix.ENOENT {
util.Fatalf("/proc is still accessible")

entries, err := os.ReadDir("/proc");
Copy link
Collaborator

@avagin avagin May 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls add a comment here to explain why we use ReadDir.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants