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

call syscall.Setgroups on groups from /etc/passwd and /etc/group #37

Merged
merged 3 commits into from
Aug 17, 2023

Conversation

caleblloyd
Copy link
Collaborator

Fixes #30

After UID/GID changes have been made, group membership that didn't match on container launch in /etc/passwd and /etc/groups may now match

This can be changed with syscall.Setgroups but will only remain effective if the next program is called via exec. In "command" mode the child process calling syscall.Setgroups won't affect the parent.

It also shouldn't need to be run on subsequent starts, because the container start process should resolve the proper groups from /etc/passwd and /etc/group after these files have already been changed

Signed-off-by: Caleb Lloyd <caleblloyd@gmail.com>
@aigarius
Copy link

In my experience the extra groups are not picked up also when the old and new uid/gid are matching. I believe that is because the fixuid process is not being run by the new uid user, it is actually run as root (because of the suid bit) and thus it never matches with the groups defined in the /etc/groups

fixuid.go Outdated Show resolved Hide resolved
@caleblloyd
Copy link
Collaborator Author

In my experience the extra groups are not picked up also when the old and new uid/gid are matching. I believe that is because the fixuid process is not being run by the new uid user, it is actually run as root (because of the suid bit) and thus it never matches with the groups defined in the /etc/groups

Can you provide an example of an /etc/passwd, /etc/group, and a UID/GID to launch the container with that generates the unexpected result?

@aigarius
Copy link

Sure.

$ cat Dockerfile
FROM ubuntu:jammy-20221003

ADD /~https://github.com/boxboat/fixuid/releases/download/v0.5.1/fixuid-0.5.1-linux-amd64.tar.gz /tmp/fixuid.tar.gz
RUN set -ex \
    && groupadd -g 1000 test \
    && useradd --create-home --no-log-init -u 1000 -g 1000 -G sudo,dialout,plugdev,audio,root,users,video -s /bin/bash test \
    && tar -C /usr/local/bin -xzf /tmp/fixuid.tar.gz \
    && rm -f /tmp/fixuid.tar.gz \
    && chown root:root /usr/local/bin/fixuid \
    && chmod 4755 /usr/local/bin/fixuid \
    && mkdir -p /etc/fixuid \
    && printf "user: test\ngroup: test\n" >/etc/fixuid/config.yml
ENV HOME="/home/test"

ENTRYPOINT [ "/usr/local/bin/fixuid" ]

$ docker build -t fixui_groups .
[...]
$ docker run --user=`id -u`:`id -g` fixui_groups bash -c "groups"
fixuid: fixuid should only ever be used on development systems. DO NOT USE IN PRODUCTION
fixuid: runtime UID '1000' already matches container user 'test' UID
fixuid: runtime GID '1000' already matches container group 'test' GID
test

Same result when the uid/gid inside does not match the outside (just extra logs about updating user/group and chowning home folder).

At the moment when fixuid binary gets started as root (as the consequence of having setuid root bit set) it looses all previously set user and group ids. As a standard security precaution. Or the groups inside the /etc/group in the container are just plainly ignored when the user/group is supplied from the command line.

@aigarius
Copy link

Running it this way:

docker run --user=`id -u` fixui_groups bash -c "groups"

does produce your expected behavior that it shows full groups if the called uid is matching and just the test group if it is not matching.

So it looks like the Docker run ignores /etc/group contents if there is any group specified on the command line and just resets the extra groups to an empty list.

@caleblloyd
Copy link
Collaborator Author

At the moment when fixuid binary gets started as root (as the consequence of having setuid root bit set) it looses all previously set user and group ids. As a standard security precaution. Or the groups inside the /etc/group in the container are just plainly ignored when the user/group is supplied from the command line.

I don't think it loses groups, the Effective UID just gets set to 0 (root). I'm not a POSIX expert by any means but I believe that getgroups stays the same inside the setuid script.

So it looks like the Docker run ignores /etc/group contents if there is any group specified on the command line and just resets the extra groups to an empty list.

Yes - this seems to be exactly what is happening. So we probably should run it every time then, since the instructions indicate that the user should set the group ID and most probably do

Copy link
Member

@matthewdevenny matthewdevenny left a comment

Choose a reason for hiding this comment

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

lgtm

Signed-off-by: Caleb Lloyd <caleblloyd@gmail.com>
@caleblloyd
Copy link
Collaborator Author

Updated to set supplemental groups every run

fixuid.go Outdated Show resolved Hide resolved
Signed-off-by: Caleb Lloyd <caleblloyd@gmail.com>
@caleblloyd caleblloyd merged commit 2952c72 into master Aug 17, 2023
@caleblloyd caleblloyd deleted the recompute-groups branch August 17, 2023 19:51
@caleblloyd caleblloyd changed the title recompute groups on first-run recompute groups Aug 17, 2023
@caleblloyd caleblloyd changed the title recompute groups call syscall.Setgroups on groups from /etc/passwd and /etc/group Aug 17, 2023
felipecrs added a commit to felipecrs/fixdockergid that referenced this pull request Aug 26, 2023
As the new fixuid version correctly retains the groups for the user.

Refs boxboat/fixuid#30
Refs boxboat/fixuid#37
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.

The fixed user seems to lose other groups
3 participants