I chased the existing code a little further on this.
The behaviour is this.
If started as non-root, nothing is done.
If --user is not given, change user to "nobody"
If --group is not given, change group to "dip" if it exists, otherwise
change group to the main group associated with the user above.
If --group is given _with_a_value, change group the specified group.
If --group is given, but without a value, don't change group at all.
So that answer was there all along, just start dnsmasq with --group and
your container problem is solved.
The only patch required is to make this clear in the man page. I've done
that.
https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=8d8ad76d896f8eff3bd59dcdb207062c7466a49f
Cheers,
Simon.
On 06.08.2026 11:23, Leon Busch-George wrote:
Hello Simon :-)
Please excuse my clumsiness with the duplicate email - again.
On Tue, 28 Jul 2026 16:02:21 +0100
Simon Kelley <[email protected]> wrote:
Just to be clear, the current patch works because you're configuring
"group=root" and inhibiting setgid(0). I see how that works, since
then end-state is only achievable if the start state is gid==0, so
existing configurations are not affected. Have I got that right?
Right. I can't think of a case where setting 0 -> 0 is important.
Groups are a little special because groups can be used to restrict
permissions and setgid is disallowed by default (setgroups) in unshared
namespaces to prevent groups from being dropped (possibly expanding
privileges), iirc.
I think --nogroup or --group without an argument are cleaner too. If
for no other reason than it's much easier to describe what the
semantics are. (To inhibit setgid() set group to "root" and start as
group root, vs To inhibit setgiud use --nogroup or --group with no
argument.
My honest take is that "nogroup" is clearer. A patch should be on the
mailing list. I went for the "grp_id != 0" primarily to mimic the
existing check for the uid. I've added a "nouser" option for
consistency. If you're interested, maybe I can cook up a deprecation
warning for "ent_pw->pw_uid != 0".
I think I slightly prefer extending --group to adding --nogroup, but
if you write the patch, you can make the final choice.
I don't feel adequately equipped to decide this.
There are advantages to both alternatives. The core difference, in my
eyes, is "be clear and robust" on one hand and "keyhole surgery" on the
other. Both patches are on the list now and both are appropriate.
If you have trouble deciding, I think you should go with your instinct
and discard my new patch - no offence will be taken.
Cheers,
Simon.
kind regards,
Leon
On 28.07.2026 14:43, Leon Busch-George wrote:
Hi :-)
I agree about not breaking existing configurations. The only way I
can see the patch could break existing setups is when somebody is
switching from a non-root GID to root. In theory, a cleaner
solution would be to compare the existing GID and the target GID.
I chose to do the analogue of the check for switching the UID
("pw_uid != 0" on line 692), going off the assumption "We're still
running as root here" noted in a comment on line 686 (and the man
page).
My use case is running dnsmasq in a user namespace ("unshare -Ur")
like, for instance, with pasta (also creating a network namespace).
In a "bare" user namespace (unshare -U), no users/groups are
mapped. There just isn't anything to switch to - even if setgroups
was allowed.
In these environments, dnsmasq can't be used at all because of
setgid. The error is "failed to change group-id" (EVENT_GROUP_ERR).
There's no available GID to switch to and the default policy
disallows switching. For the UID, there is the 'user=root`
workaround (avoid the switch entirely).
A "nogroup" option would be clearer and safer for existing
configurations (if the "switching to root" scenario is of any
concern), albeit inconsistent with the handling of UIDs.
Make a wish! I should be able to create a patch for that "nogroup"
option.
kind regards,
Leon
On Mon, 27 Jul 2026 21:38:33 +0100
Simon Kelley <[email protected]> wrote:
Not sure this is the correct solution.
How are you configuring dnsmasq? If there's no --group option, then
it will try and set the group of the daemon process to "dip", which
is archaic, but quite likely still useful somewhere, so I don't
want to change it.
Are you overriding the change to "dip" by setting --group=root and
that what's causing the error? Again, there may be installations
where that's in use and required, which I don't want to break.
Could the solution to this be --group (with no arg) or a new
--nogroup option which explicitly disables the setgid() call?
Simon.
On 27.07.2026 13:51, Leon M. Busch-George wrote:
From: "Leon M. Busch-George" <[email protected]>
Without this patch, dnsmasq wont start in namespaces without group
ID mappings unless setgroups is explicitly allowed (e.g. write
"allow" to /proc/self/setgroups).
This happens even if the target gid matches the current one.
Work around this issue by not calling setgroups when the target
gid is 0, which matches the guard around calling setuid
(ent_pw->pw_uid != 0). ---
src/dnsmasq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 8fcbbda..2a3ff33 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -742,7 +742,7 @@ int main (int argc, char **argv)
gid_t dummy;
/* remove all supplementary groups */
- if (gp &&
+ if (gp && gp->gr_gid != 0 &&
(setgroups(0, &dummy) == -1 ||
setgid(gp->gr_gid) == -1))
{
_______________________________________________
Dnsmasq-discuss mailing list
[email protected]
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss
_______________________________________________
Dnsmasq-discuss mailing list
[email protected]
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss