buildah
buildah copied to clipboard
buildah commands that don't involve building containers at all run through unshare
Description
This is yet another in the series of 'issues to do with running buildah in a locked-down container' - see https://github.com/containers/buildah/issues/4563 , https://github.com/containers/buildah/issues/1901 - but with a twist: we want to use buildah to do things that don't involve building containers at all, but those commands still run through unshare. @terinjokes also noted this in https://github.com/containers/buildah/issues/1901#issuecomment-1674648806 .
@jeremycline and I are working on improving Fedora's container registry publication. All this needs to do is take some already-built container images from a Fedora compose, create a multiarch manifest, and push the images and the manifest to some registries. The only tools we've found for doing this are buildah and podman. We have the code for this all written. But when we try to deploy it in an openshift container (which is where we want to deploy it), it blows up because unshare doesn't work. Well, sure, it doesn't, and we don't really want to mess around with the container security stuff to allow it, because we shouldn't need it to do this. Commands which just create manifests and push images to registries should not need to run through isolation; they're just writing trivial JSON and making web API calls. (podman appears to have basically the same problem as buildah).
We would happily use a different tool for this if we could find one that just does this and avoids the mess, but we can't (suggestions welcome). We really don't want to have to write one.
Steps to reproduce the issue:
- Create a bog-standard Fedora container in Fedora openshift, with buildah in it
- Try and run
buildah loginorbuildah manifest createorbuildah manifest push
Describe the results you received:
sh-5.2$ HOME=/tmp/whatever buildah login
WARN[0000] Reading allowed ID mappings: reading subuid mappings for user "1001340000" and subgid mappings for group "1001340000": no subuid ranges found for user "1001340000" in /etc/subuid
WARN[0000] Found no UID ranges set aside for user "1001340000" in /etc/subuid.
WARN[0000] Found no GID ranges set aside for user "1001340000" in /etc/subgid.
Error during unshare(CLONE_NEWUSER): Function not implemented
ERRO[0000] parsing PID "": strconv.Atoi: parsing "": invalid syntax
ERRO[0000] (Unable to determine exit status)
sh-5.2$
Describe the results you expected: successful login
The HOME=/tmp/whatever is needed because without that buildah has a fit about ~/.config not being owned by the current user, btw.
Ugh. I guess https://github.com/containers/buildah/issues/3259 is a complicating factor here?
Here's a kinda silly 'fix' for this, I guess...
diff --git a/cmd/buildah/main.go b/cmd/buildah/main.go
index 524d87b32..df42a82f5 100644
--- a/cmd/buildah/main.go
+++ b/cmd/buildah/main.go
@@ -40,6 +40,7 @@ type globalFlags struct {
MemoryProfile string
UserShortNameAliasConfPath string
CgroupManager string
+ NoUnshare bool
}
var rootCmd = &cobra.Command{
@@ -105,6 +106,7 @@ func init() {
rootCmd.PersistentFlags().StringVar(&globalFlagResults.LogLevel, logLevel, "warn", `the log level to be used, one of "trace", "debug", "info", "warn", "error", "fatal", or "panic"`)
rootCmd.PersistentFlags().StringVar(&globalFlagResults.CPUProfile, "cpu-profile", "", "`file` to write CPU profile")
rootCmd.PersistentFlags().StringVar(&globalFlagResults.MemoryProfile, "memory-profile", "", "`file` to write memory profile")
+ rootCmd.PersistentFlags().BoolVar(&globalFlagResults.NoUnshare, "no-unshare", false, "disable user namespace re-exec when unprivileged (for running non-build commands like pull, push and manifest in locked-down containers)")
if err := rootCmd.PersistentFlags().MarkHidden("cpu-profile"); err != nil {
logrus.Fatalf("unable to mark cpu-profile flag as hidden: %v", err)
@@ -145,6 +147,13 @@ func before(cmd *cobra.Command) error {
case "", "help", "version", "mount":
return nil
}
+ if globalFlagResults.NoUnshare {
+ switch cmd.Use {
+ case "add", "build", "commit", "copy", "from", "mkcw", "run", "umount", "unshare":
+ return fmt.Errorf("command %s cannot be used with --no-unshare", cmd.Use)
+ }
+ return nil
+ }
debugCapabilities()
unshare.MaybeReexecUsingUserNamespace(false)
if globalFlagResults.CPUProfile != "" {
Let's just add the ones that make no sense to unshare to the line above:
switch cmd.Use {
case "", "help", "version", "mount":
return nil
}
A friendly reminder that this issue had no activity for 30 days.
I suppose this is the same thing that stops me from using:
$ buildah login $CI_REGISTRY -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
Error during unshare(CLONE_NEWUSER): Operation not permitted
time="2025-04-22T09:19:06Z" level=error msg="parsing PID \"\": strconv.Atoi: parsing \"\": invalid syntax"
time="2025-04-22T09:19:06Z" level=error msg="(Unable to determine exit status)"
when running in an unprivileged container? EDIT: The issue was me, customizing (installing packages with microdnf) the container and not using a "mint" quay.io/buildah/stable:v1.39 image. EDIT2: Scratch that, i was given a privileged runner, thats why it worked with the "mint" quay.io/buildah/stable:v1.39 image. I removed the priv. and now its showing the same error.