GoogleCloudPlatform / gcsfuse

A user-space file system for interacting with Google Cloud Storage
https://cloud.google.com/storage/docs/gcs-fuse
Apache License 2.0
2.04k stars 421 forks source link

`panic: user: unknown userid` in a non-root container without user mapping #877

Open czka opened 1 year ago

czka commented 1 year ago

gcsfuse (at least the latest 0.41.10 that I tried) panics in a non-root container without a user mapping.

An example with Bitnami Wordpress image:

  1. docker pull bitnami/wordpress
  2. docker inspect bitnami/wordpress:latest | grep -i user:

    "User": "1001",
    "User": "1001",
  3. Adapt this Google's example to try Wordpress on Cloud Run with gcsfuse (not providing details here - irrelevant).
  4. Deploy to Cloud Run and observe the error for command gcsfuse --debug_gcs --debug_fuse --foreground $BUCKET /mnt/gcs:
    2023-01-02 14:07:26.969 CET Start gcsfuse/0.41.10 (Go version go1.18.4) for app "" using mount point: /mnt/gcs
    2023-01-02 14:07:26.969 CET Opening GCS connection...
    2023-01-02 14:07:26.973 CET Creating a mount at "/mnt/gcs"
    2023-01-02 14:07:26.978 CET Container called exit(2).
    2023-01-02 14:07:26.979 CET panic: user: unknown userid 1001 goroutine 1 [running]: github.com/googlecloudplatform/gcsfuse/internal/perms.MyUserAndGroup() /tmp/build_gcsfuse_gopath2289345396/src/github.com/googlecloudplatform/gcsfuse/internal/perms/perms.go:29 +0x1c5 main.mountWithConn({0x109de80, 0xc0001340c8}, {0x7ffefd44d5f0, 0x10}, {0x7ffefd44d601, 0x8}, 0xc000402420, 0x50?, {0x0, 0x0}, ...) /tmp/build_gcsfuse_gopath2289345396/src/github.com/googlecloudplatform/gcsfuse/mount.go:65 +0x131 main.mountWithArgs({0x7ffefd44d5f0, 0x10}, {0x7ffefd44d601, 0x8}, 0xc000402420, 0x6?) /tmp/build_gcsfuse_gopath2289345396/src/github.com/googlecloudplatform/gcsfuse/main.go:198 +0x2d2 main.runCLIApp(0xc0005bf8f8?) /tmp/build_gcsfuse_gopath2289345396/src/github.com/googlecloudplatform/gcsfuse/main.go:362 +0xef3 main.run.func1(0x1?) /tmp/build_gcsfuse_gopath2289345396/src/github.com/googlecloudplatform/gcsfuse/main.go:397 +0x25 github.com/googlecloudplatform/gcsfuse/vendor/github.com/urfave/cli.HandleAction({0xc94280?, 0xc0000443c0?}, 0xc0004c0e00?) /tmp/build_gcsfuse_gopath2289345396/src/github.com/googlecloudplatform/gcsfuse/vendor/github.com/urfave/cli/app.go:526 +0x50 github.com/googlecloudplatform/gcsfuse/vendor/github.com/urfave/cli.(*App).Run(0xc0004c0e00, {0xc00012c120, 0x6, 0x6}) /tmp/build_gcsfuse_gopath2289345396/src/github.com/googlecloudplatform/gcsfuse/vendor/github.com/urfave/cli/app.go:286 +0x7c5 main.run() /tmp/build_gcsfuse_gopath2289345396/src/github.com/googlecloudplatform/gcsfuse/main.go:401 +0xc5 main.main() /tmp/build_gcsfuse_gopath2289345396/src/github.com/googlecloudplatform/gcsfuse/main.go:419 +0x4a

Edit: FYI, the issue is gone after giving the user 1001 a name in my Dockerfile derived from the Bitnami Wordpress image, as follows:

FROM bitnami/wordpress:latest
(...)

USER 0
RUN useradd --uid 1001 --no-create-home anynameyoulike
USER 1001
(...)

That's only a workaround though.

raj-prince commented 1 year ago

Thanks @czka, We will discuss this issue with the team, and fix them accordingly. Closing this issue for now, since you have workaround for this.

czka commented 1 year ago

@raj-prince IMO the ticket should stay open until the underlying issue is fixed.

songjiaxun commented 1 year ago

I run into the same issue, as I am testing the GCS Fuse CSI Driver.

One customer is asking us to run the gcsfuse in a sidecar that uses a non-root uid/gid. I tested an arbitrary uid/gid 1000, but got the same error from gcsfuse user: unknown userid 1000.

I believe the error comes from the code user, err := user.Current().

According to the discussion https://github.com/golang/go/issues/38599, the golang os/user package cannot load an arbitrary uid/gid if the uid/gid does not exist in /etc/passwd. Unfortunately, the Kubernetes Pod Security Context only sets the uid/gid without setting the /etc/passwd file, meaning when you do id inside the container, you do see uid=1000 gid=1000, but the uid/gid does not exist in the /etc/passwd, which will cause this gcsfuse error. This also explains why after @czka gave the uid 1001 a name it worked -- because adding a name to the uid creates an entry in the /etc/passwd file.

My solution is to do cat /etc/passwd inside my sidecar container, then I got the following

root:x:0:0:root:/root:/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/sbin/nologin
nonroot:x:65532:65532:nonroot:/home/nonroot:/sbin/nologin

Then I chose 65532 nonroot uid/gid to run my sidecar container. In this case gcsfuse does not complain.

That being said, I still think it's worth it to fix the uid/gid check logic in gcsfuse because this issue prevents users from running gcsfuse binary in a container with an arbitrary uid/gid.

sethiay commented 1 year ago

As mentioned in https://github.com/GoogleCloudPlatform/gcsfuse/issues/877#issuecomment-1375258143 , we will evaluate this request and update here accordingly. Till then, we suggest to use the workaround mentioned in https://github.com/GoogleCloudPlatform/gcsfuse/issues/877#issue-1516412312.

papirosko commented 1 year ago
FROM docker.io/bitnami/postgresql-repmgr:15

USER root
RUN apt update
RUN install_packages curl

RUN useradd --uid 1001 --group root --no-create-home worker
USER 1001

this workaround helped me. without root group postgres failed to start