Skip to content

Conversation

michalsieron
Copy link
Contributor

As long as container is not rootless, runc can run it on a kernel without enabled user namespaces, which makes sense to me. I think crun should be able to do the same, however I hit some issues with it.

First I got error opening file `/proc/self/uid_map`: No such file or directory
and that's because when kernel doesn't have user namespaces, the uid_map doesn't exist at all. Adding a check for file existence, before the read_all_file call, solves the issue.

With that change in place I got an error about next missing file. This time it was /proc/self/setgroups and it was coming from libcrun_container_setgroups call.
But if I understand it correctly, that call should only be made when user namespaces are enabled in the config.json, which is not the case when the container is non-rootless.

With both changes in place I am now able to run a non-rootless container on a kernel without user namespaces enabled.

Comment on lines 726 to 727
if (UNLIKELY (ret < 0))
return ret;
Copy link
Member

Choose a reason for hiding this comment

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

we need to treat ENOENT as run_in_userns = 0; so we don't need an additional syscall

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sorry, I am not sure if I fully understand your comment

The check needs to happen before read_all_file call, otherwise crun_make_error will be called on non-existing file.

Comment on lines 4700 to 4704
if (init_status->all_namespaces & CLONE_NEWUSER) {
ret = libcrun_container_setgroups (container, container->container_def->process, err);
if (UNLIKELY (ret < 0))
return ret;
}
Copy link
Member

Choose a reason for hiding this comment

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

this must be done also when user namespaces are not used/allowed. Can we drop this change? What error do you get otherwise?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

error opening file `/proc/self/setgroups`: No such file or directory

But now that, I think about it, a fix similar to check_running_in_user_namespace, but in can_setgroups should handle it.

Copy link
Member

@giuseppe giuseppe Oct 7, 2024

Choose a reason for hiding this comment

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

untested, but I think you need something like:

diff --git a/src/libcrun/linux.c b/src/libcrun/linux.c
index e2db6ebd..d3eb7730 100644
--- a/src/libcrun/linux.c
+++ b/src/libcrun/linux.c
@@ -2942,7 +2942,15 @@ can_setgroups (libcrun_container_t *container, libcrun_error_t *err)
 
   ret = read_all_file ("/proc/self/setgroups", &content, NULL, err);
   if (ret < 0)
-    return ret;
+    {
+      /* If the file does not exist, then the kernel does not support /proc/self/setgroups and setgroups can always be used.  */
+      if (crun_error_get_errno (err) == ENOENT)
+        {
+          crun_error_release (err);
+          return 1;
+        }
+      return ret;
+    }
 
   return strncmp (content, "deny", 4) == 0 ? 0 : 1;
 }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I should have read how errors are handled in crun more. For some reason, I assumed they cannot be cleared 😅

Copy link
Member

@giuseppe giuseppe left a comment

Choose a reason for hiding this comment

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

LGTM

As long as container is not rootless, runc can run it on a Kernel
without enabled user namespaces, which makes sense to me. I think crun
should be able to do the same, however I hit some issues with it.

First I got
    error opening file `/proc/self/uid_map`: No such file or directory
and that's because when kernel doesn't have user namespaces,
the uid_map doesn't exist at all. Adding a check for file existence,
after the read_all_file call, solves the issue.

With that change in place I got an error about next missing file.
This time it was /proc/self/setgroups and it was coming from
can_setgroups call. Adding similar fix to the one for uid_map, solves
the issue.

With both changes in place I am now able to run a non-rootless
container on a kernel without user namespaces enabled.

Signed-off-by: Michal Sieron <michalwsieron@gmail.com>
@michalsieron
Copy link
Contributor Author

This should fix formatting issues. I removed one space too much before.

Copy link
Collaborator

@flouthoc flouthoc left a comment

Choose a reason for hiding this comment

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

LGTM

@giuseppe giuseppe merged commit a3fcba9 into containers:main Oct 8, 2024
57 checks passed
@michalsieron michalsieron deleted the no-user-namespaces branch October 8, 2024 08:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants