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

Fix keeping certain groups with nogroups #4732

Merged
merged 3 commits into from
Dec 8, 2021

Conversation

kmk3
Copy link
Collaborator

@kmk3 kmk3 commented Dec 1, 2021

This amends commit b828a90 ("Keep audio and video groups regardless of
nogroups", 2021-11-28) from PR #4725.

The commit above did not change the behavior (the groups are still not
kept). With this commit, it appears to work properly:

$ groups | grep audio >/dev/null && echo kept
kept
# with check_can_drop_all_groups == 0
$ firejail --quiet --noprofile --nogroups groups |
  grep audio >/dev/null && echo kept
kept
# with check_can_drop_all_groups == 1
$ firejail --quiet --noprofile --nogroups groups |
  grep audio >/dev/null && echo kept
$

Add a new check_can_drop_all_groups function to check whether the
supplementary groups can be safely dropped without potentially causing
issues with audio, 3D hardware acceleration or input (and maybe more).
It returns false if nvidia (and no no3d) is used or if (e)logind is
not running, as in either case the supplementary groups might be needed.

Note: With this, the behavior from before #4725 is restored on (e)logind
systems (when not using nvidia), as it makes the supplementary groups
always be dropped.

Note2: Even with the static variable, these checks still happen at least
once per translation unit (so twice in total per my testing).

This also amends (/kind of reverts) commit 6ddedeb ("Make nogroups
work on nvidia again", 2021-11-29) from PR #4725, as it restores the
nvidia check from it into the new check_can_drop_all_groups function.

To not be confused with arg_nogroups, as in the vast majority of cases
drop_privs is called with either 0 or 1 rather than arg_nogroups.  The
rename makes it clearer that what the parameter does is to drop all
groups without exception, unlike arg_nogroups, which may have certain
groups be kept.
This amends commit 11418a4 ("dns fixes", 2019-10-31).

fwarning already prints "Warning: " at the beginning.

Kind of relates to commit 6ddedeb ("Make nogroups work on nvidia
again", 2021-11-29) / PR netblue30#4725, which removed code affected by this.

Command used to find the duplicates:

    git grep -i -F 'fwarning("Warning:' -- src
@kmk3
Copy link
Collaborator Author

kmk3 commented Dec 1, 2021

Force-pushed to fix this:

https://github.com/netblue30/firejail/runs/4386125509?check_suite_focus=true

clang-11 -g -O2 -ggdb -W -Wall -Werror -O2 -DVERSION='"0.9.67"'  -DPREFIX='"/usr/local"' -DSYSCONFDIR='"/usr/local/etc/firejail"' -DLIBDIR='"/usr/local/lib"' -DBINDIR='"/usr/local/bin"'   -DVARDIR='"/var/lib/firejail"'  -DHAVE_OUTPUT -DHAVE_X11 -DHAVE_PRIVATE_HOME   -DHAVE_USERTMPFS -DHAVE_DBUSPROXY -DHAVE_FIRETUNNEL -DHAVE_GLOBALCFG -DHAVE_CHROOT -DHAVE_NETWORK -DHAVE_USERNS -DHAVE_FILE_TRANSFER  -DHAVE_SUID  -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -Wformat -Wformat-security -mretpoline -fstack-clash-protection -fstack-protector-strong  -c util.c -o util.o
util.c:125:11: error: logical not is only applied to the left hand side of this comparison [-Werror,-Wlogical-not-parentheses]
        else if (!access("/run/systemd/seats/", F_OK) == 0) {
                 ^                                    ~~
util.c:125:11: note: add parentheses after the '!' to evaluate the comparison first
        else if (!access("/run/systemd/seats/", F_OK) == 0) {
                 ^
                  (                                       )
util.c:125:11: note: add parentheses around left hand side expression to silence this warning
        else if (!access("/run/systemd/seats/", F_OK) == 0) {
                 ^
                 (                                   )
1 error generated.
make[1]: *** [Makefile:7: util.o] Error 1

@kmk3
Copy link
Collaborator Author

kmk3 commented Dec 1, 2021

@kmk3 commented on Dec 1:

Note2: Even with the static variable, these checks still happen at least once
per translation unit (so twice in total per my testing).

By the way, I had also tried using a global variable (declared on main.c and
firejail.h, like e.g.: arg_nosound), but it did not work either. Maybe
drop_privs is called in multiple processes or something.

@kmk3
Copy link
Collaborator Author

kmk3 commented Dec 1, 2021

@crocket commented on Nov 30:

The concept behind this pull request should work, but it doesn't detect
presence of (e)logind.

It should be detected in this new PR. Could you test this on seatd?

Copy link
Collaborator

@topimiettinen topimiettinen left a comment

Choose a reason for hiding this comment

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

LGTM, one style nitpick

fwarning("NVIDIA card detected, nogroups command ignored\n");
can_drop_all_groups = 0;
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd move the else if ... here and put the comment below it. Now it looks like earlier if (access(... didn't have an else part but of course it does when you read further.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@topimiettinen on Dec 2:

I'd move the else if ... here and put the comment below it. Now it looks
like earlier if (access(... didn't have an else part but of course it does
when you read further.

I think I got this idea from something like this code on profile.c:

	// mkdir
	if (strncmp(ptr, "mkdir ", 6) == 0) {
		fs_mkdir(ptr + 6);
		return 1;	// process mkdir again while applying blacklists
	}
	// mkfile
	if (strncmp(ptr, "mkfile ", 7) == 0) {
		fs_mkfile(ptr + 7);
		return 1;	// process mkfile again while applying blacklists
	}
	// sandbox name
	else if (strncmp(ptr, "name ", 5) == 0) {
		cfg.name = ptr + 5;
		if (strlen(cfg.name) == 0) {
			fprintf(stderr, "Error: invalid sandbox name\n");
			exit(1);
		}
		return 0;
	}
	else if (strcmp(ptr, "ipc-namespace") == 0) {
		arg_ipc = 1;
		return 0;
	}

But yeah, it's not very obvious; I'll change it along with some other stuff and
force-push.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done. Just moving the comment made things look a bit crowded, so I added a few
more gotos instead.

@crocket
Copy link
Contributor

crocket commented Dec 3, 2021

I just tested your pull request. audio and input groups seem to be allowed. I haven't tested video group because I don't have a webcam.

@kmk3
Copy link
Collaborator Author

kmk3 commented Dec 4, 2021

@crocket commented on Dec 3:

I just tested your pull request. audio and input groups seem to be allowed. I
haven't tested video group because I don't have a webcam.

Thanks for testing! Could you also test if this fixes the audio/input issues
with RetroArch with the default profile (i.e.: without ignoring noroot /
nogroups)?

@crocket commented on Oct 10:

Either nogroup or noroot breaks ALSA(/dev/snd) and gamepad(/dev/input) on retroarch on Gentoo Linux.

$ ls -alh /dev/snd
total 0
drwxr-xr-x  3 root root      280 Oct 10 07:51 ./
drwxr-xr-x 18 root root     4.1K Oct 10 07:51 ../
drwxr-xr-x  2 root root       80 Oct 10 07:51 by-path/
crw-rw----  1 root audio 116, 10 Oct 10 07:51 controlC0
crw-rw----  1 root audio 116,  4 Oct 10 07:51 controlC1
crw-rw----  1 root audio 116,  9 Oct 10 07:51 hwC0D0
crw-rw----  1 root audio 116,  3 Oct 10 07:51 hwC1D0
crw-rw----  1 root audio 116,  6 Oct 10 07:51 pcmC0D0c
crw-rw----  1 root audio 116,  5 Oct 10 07:59 pcmC0D0p
crw-rw----  1 root audio 116,  7 Oct 10 07:51 pcmC0D1p
crw-rw----  1 root audio 116,  8 Oct 10 07:51 pcmC0D2c
crw-rw----  1 root audio 116,  2 Oct 10 07:51 pcmC1D3p
crw-rw----  1 root audio 116,  1 Oct 10 07:51 seq
crw-rw----  1 root audio 116, 33 Oct 10 07:51 timer
$ ls -alh /dev/input
total 0
drwxr-xr-x  4 root root     520 Oct 10 07:51 ./
drwxr-xr-x 18 root root    4.1K Oct 10 07:51 ../
drwxr-xr-x  2 root root     220 Oct 10 07:51 by-id/
drwxr-xr-x  2 root root     220 Oct 10 07:51 by-path/
crw-rw----  1 root input 13, 64 Oct 10 07:51 event0
crw-rw----  1 root input 13, 65 Oct 10 07:51 event1
crw-rw----  1 root input 13, 74 Oct 10 07:51 event10
crw-rw----  1 root input 13, 75 Oct 10 07:51 event11
crw-rw----  1 root input 13, 76 Oct 10 07:51 event12
crw-rw----  1 root input 13, 77 Oct 10 07:51 event13
crw-rw----  1 root input 13, 78 Oct 10 07:51 event14
crw-rw----  1 root input 13, 79 Oct 10 07:51 event15
crw-rw----  1 root input 13, 80 Oct 10 07:51 event16
crw-rw----  1 root input 13, 81 Oct 10 07:51 event17
crw-rw----  1 root input 13, 66 Oct 10 07:51 event2
crw-rw----  1 root input 13, 67 Oct 10 07:51 event3
crw-rw----  1 root input 13, 68 Oct 10 07:51 event4
crw-rw----  1 root input 13, 69 Oct 10 07:51 event5
crw-rw----  1 root input 13, 70 Oct 10 07:51 event6
crw-rw----  1 root input 13, 71 Oct 10 07:51 event7
crw-rw----  1 root input 13, 72 Oct 10 07:51 event8
crw-rw----  1 root input 13, 73 Oct 10 07:51 event9
crw-rw-r--  1 root input 13,  0 Oct 10 07:51 js0
crw-rw-r--  1 root input 13,  1 Oct 10 07:51 js1
crw-rw----  1 root input 13, 63 Oct 10 07:51 mice
crw-rw----  1 root input 13, 32 Oct 10 07:51 mouse0

@crocket
Copy link
Contributor

crocket commented Dec 4, 2021

Thanks for testing! Could you also test if this fixes the audio/input issues
with RetroArch with the default profile (i.e.: without ignoring noroot /
nogroups)?

I wrote that the pull request worked after testing retroarch with retroarch.profile. I didn't ignore noroot or nogroups.

@kmk3
Copy link
Collaborator Author

kmk3 commented Dec 4, 2021

@crocket commented on Dec 4:

Thanks for testing! Could you also test if this fixes the audio/input
issues with RetroArch with the default profile (i.e.: without ignoring
noroot / nogroups)?

I wrote that the pull request worked after testing retroarch with
retroarch.profile. I didn't ignore noroot or nogroups.

Nice, glad to have it confirmed that these issues are fixed with this.

(To clarify, I asked again because my original request was rather vague and it
wasn't clear to me if only the groups were tested (e.g.: with
firejail --noprofile --nogroups groups or if the audio/input functionalities
were tested)

This amends commit b828a90 ("Keep audio and video groups regardless of
nogroups", 2021-11-28) from PR netblue30#4725.

The commit above did not change the behavior (the groups are still not
kept).  With this commit, it appears to work properly:

    $ groups | grep audio >/dev/null && echo kept
    kept
    # with check_can_drop_all_groups == 0
    $ firejail --quiet --noprofile --nogroups groups |
      grep audio >/dev/null && echo kept
    kept
    # with check_can_drop_all_groups == 1
    $ firejail --quiet --noprofile --nogroups groups |
      grep audio >/dev/null && echo kept
    $

Add a new check_can_drop_all_groups function to check whether the
supplementary groups can be safely dropped without potentially causing
issues with audio, 3D hardware acceleration or input (and maybe more).
It returns false if nvidia (and no `no3d`) is used or if (e)logind is
not running, as in either case the supplementary groups might be needed.

Note: With this, the behavior from before netblue30#4725 is restored on (e)logind
systems (when not using nvidia), as it makes the supplementary groups
always be dropped on such systems.

Note2: Even with the static variable, these checks still happen at least
twice.  It seems that it happens once per translation unit (and I think
that it may happen more times if there are multiple processes involved).

This also amends (/kind of reverts) commit 6ddedeb ("Make nogroups
work on nvidia again", 2021-11-29) from PR netblue30#4725, as it restores the
nvidia check from it into the new check_can_drop_all_groups function.
@netblue30 netblue30 merged commit 1afa38f into netblue30:master Dec 8, 2021
@netblue30
Copy link
Owner

merged, thanks!

@kmk3 kmk3 deleted the fix-groups-misc3 branch December 8, 2021 17:32
@kmk3 kmk3 added this to In progress in Release 0.9.68 via automation Jan 27, 2022
@kmk3 kmk3 moved this from In progress to To Document (RELNOTES/man) in Release 0.9.68 Jan 27, 2022
@kmk3 kmk3 moved this from To Document (RELNOTES/man) to Done (on RELNOTES) in Release 0.9.68 Feb 5, 2022
kmk3 added a commit to kmk3/firejail that referenced this pull request Feb 11, 2022
Added on commit 7abce0b ("Fix keeping certain groups with nogroups",
2021-11-30) / PR netblue30#4732.

As reported by @rusty-snake on netblue30#4930, conflicting messages are printed
when using whitelist-run-common.inc with nogroups:

    $ cat test.profile
    include whitelist-run-common.inc
    nogroups
    $ firejail --profile=./test.profile groups
    Reading profile ./test.profile
    Reading profile /etc/firejail/whitelist-run-common.inc
    Parent pid 1234, child pid 1235
    Warning: logind not detected, nogroups command ignored     <--- is a lie
    Warning: cleaning all supplementary groups
    Child process initialized in 30.00 ms
    rusty-snake    <---- running `groups` outside of the sandbox shows more so groups are actually cleaned

    Parent is shutting down, bye...

This probably happens because wrc causes /run/systemd to be hidden in
the sandbox and because check_can_drop_all_groups is called multiple
times, seemingly both before and after the whitelisting goes into
effect.  So disable the message about nogroups being ignored, but keep
the message about cleaning all supplementary groups (which is unlikely
to be printed unless it really happens).

Fixes netblue30#4930.
kmk3 added a commit to kmk3/firejail that referenced this pull request Apr 22, 2022
When nogroups is used, the following warning may be issued (potentially
multiple times, as drop_privs may be called more than once):

    Warning: cleaning all supplementary groups

But the warning is being shown even when it seems that all supplementary
groups can be safely dropped (and are thus dropped), which is likely a
common scenario.  This commit prevents the warning from being printed in
that case, making it so that it is only shown in the non-happy paths (as
was the case on firejail 0.9.66).

Misc: The added code was copied from drop_privs.

This amends commit 7abce0b ("Fix keeping certain groups with
nogroups", 2021-11-30) / PR netblue30#4732.

Kind of relates to netblue30#4930.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Release 0.9.68
  
Done (on RELNOTES)
Development

Successfully merging this pull request may close these issues.

None yet

4 participants