DNSCrypt / dnscrypt-proxy

dnscrypt-proxy 2 - A flexible DNS proxy, with support for encrypted DNS protocols.
https://dnscrypt.info
ISC License
11.28k stars 1k forks source link

Dropping privileges [FATAL] Unable to drop additional groups: [function not implemented] #1646

Closed jumpsmm7 closed 3 years ago

jumpsmm7 commented 3 years ago

Who is the bug affecting?

Linux-arm branch

What is affected by this bug?

Dropping privileges

When does this occur?

on loading of dnscrypt-proxy 2 with user selected as nobody

Where does it happen?

on RMerlin Asuswrt arm7l

How do we replicate the issue?

Loading dnscrypt-proxy on arm7l with user selected as nobody.

Expected behavior (i.e. solution)

privileges to properly drop.

Other Comments

jedisct1 commented 3 years ago

Maybe this helps?

Was it just installed with dnscrypt-proxy -service install or do you have custom stuff in the systemd startup file to explicitly break that feature?

jumpsmm7 commented 3 years ago

Maybe this helps?

Was it just installed with dnscrypt-proxy -service install or do you have custom stuff in the systemd startup file to explicitly break that feature?

It is ran in JFFS on Asus-WRT Merlin Firmware Routers Flash Memory. It is without a service install. the service is invoked from a shell script with linux-arm build using nobody as the username within the .toml setup using your prebuilt linux-arm for the latest release. User nobody is chosen for its limited and more secure footprint on the Router. The Kernel having the issue is kernel 4.1. The Kernel is built with the correct CONFIG_MULTIUSER=y flag

jumpsmm7 commented 3 years ago

I have opened an issue with Asuswrt-Merlin Dev to try to figure out the issue, but we have looked at all possible angles from the firmware end. https://github.com/RMerl/asuswrt-merlin.ng/issues/728

jumpsmm7 commented 3 years ago

To be more specific, the kernel is 4.1.52 Linux/arm 4.1.52 Kernel Configuration An example of the build configuration is as follows. https://raw.githubusercontent.com/RMerl/asuswrt-merlin.ng/master/release/src-rt-5.02axhnd.675x/kernel/linux-4.1/config_base.6a.6750

jedisct1 commented 3 years ago

So, on your setup, this also happened when the ./dnscrypt-proxy -list command is run interactively, right?

Can you provide the exact system call returning this error as well the actual return code?

jumpsmm7 commented 3 years ago

[2021-03-25 14:05:47] [NOTICE] dnscrypt-proxy 2.0.45 [2021-03-25 14:05:47] [NOTICE] Dropping privileges [2021-03-25 14:05:47] [FATAL] Unable to drop additional groups: [function not implemented]

is the entire output from running

./dnscrypt-proxy -list

the username in the .toml file is nobody

According to RMerl the dev of AsusWrt-Merlin Firmware

I also confirmed that privileges dropping worked fine, with the following test program:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>

int main(){
  printf("start\n");
  printf("sleep\n"); usleep(5 * 1000 * 1000);

  uid_t uid = 65534; // user
  gid_t gid = 65534;  // group

        printf("setgroups()\n");
        printf("%d\n",setgroups(0, NULL));
        printf("setgid: %d\n", gid);
        printf("%d\n",setgid(gid));

        printf("setuid: %d\n", uid);
        printf("%d\n",setuid(uid));

  usleep(20*1000*1000);
  printf("exit\n");
}

If I examine the process during that 20 secs pause, it does show gid and uid of 65534 (both of which are nobody), and both calls return "0".

pannal commented 3 years ago

Can confirm, privilege dropping works on that kernel (see dnsmasq), just DNSCrypt-proxy doesn't seem to do it:

12475 nobody    4584 S    dnsmasq --log-async
12476 admin     4584 S    dnsmasq --log-async
17076 admin    10008 S    networkmap
21511 admin     783m S    /jffs/dnscrypt/dnscrypt-proxy -syslog -config /jffs/dnscrypt/dnscrypt-proxy.toml

Edit: It runs currently as admin, explicitly.

jedisct1 commented 3 years ago

Once again: can you provide the exact system call returning this error as well the actual return code?

pannal commented 3 years ago

Sure, if you tell me how, I'll gladly do that.

jedisct1 commented 3 years ago

Unfortunately I neither use Linux nor this router.

RMerl commented 3 years ago

According to the error message, the failure would be on setgroups(), which did work fine in my test program.

dnscrypt does its privilege drops here:

https://github.com/DNSCrypt/dnscrypt-proxy/blob/master/dnscrypt-proxy/privilege_linux.go#L58

Could be a GoLang issue or a compile issue rather than a dnscrypt code issue, assuming the three calls seen in that link above do map to the three calls I used in my test program.

jedisct1 commented 3 years ago

RawSyscall really doesn't do anything more than a syscall() call.

Since it doesn't use the C library, could the Go library use the wrong constant on that platform? That would be quite surprising, especially since this is the first time this issue is reported.

Having the actual syscall (with strace or watever is used on Linux these days) would be very useful.

RMerl commented 3 years ago

I can`t help you any further on this, I don't know anything about Go myself, sorry.

pannal commented 3 years ago

Is strace available on asuswrt-merlin? Then I'll try to get you that info.

RMerl commented 3 years ago

It can be installed through Entware, however once the second thread is spawned, it won't see the syscalls done to drop privileges.

pannal commented 3 years ago

Any hints on how I can assist with this then? (I'm the original reporter in the forum)

jumpsmm7 commented 3 years ago

I have feeling this is due to it being incompatible to linux kernel 4.1.

jedisct1 commented 3 years ago

https://github.com/golang/go/wiki/MinimumRequirements

For little-endian MIPS64, kernel version 4.1 is known to fail, and 4.8 works.

jedisct1 commented 3 years ago

And that was also mentioned in the dnscrypt-proxy documentation, right in the first paragraph https://github.com/DNSCrypt/dnscrypt-proxy/wiki/Installation-linux#installation-on-linux-overview

RMerl commented 3 years ago

The failing router is on ARM V7, not MIPS64.

pannal commented 3 years ago

Yep, please reopen.

jedisct1 commented 3 years ago

Can you check if this still happens with a more recent kernel? The minimum requirement page may not be up to date, with the same issue affecting ARMv7 platforms as well.

There's not much to be done in dnscrypt-proxy itself. Maybe hack a custom build with the correct system call for that kernel; doing this upstream is likely to break on all other kernels. If the issue is in the Go compiler, this is where it should be fixed, or at least documented.

If a more recent kernel fixes it, the documentation should definitely be updated here as well. Kernel 4.1 was released circa 2015, it's a little bit dated right now.

RMerl commented 3 years ago

The router kernel cannot be upgraded, it's tied to Broadcom's SDK.

I agree however that there isn't much that could be done from the dnscrypt devs at this point, and I also suspect it's a bug within Go itself. The code that I pointed earlier looks fine to me.

Just another reason while personally I much prefer C over higher level languages, which may introduce their own set of issues.

jumpsmm7 commented 3 years ago

@jedisct1 //// Dnscrypt-proxy2 works fine for all other model Asuswrt-Merlin Routers that use ARM7, the main differences though is that these newer ARM7 models(RTAX56U and RTAX58U) use a kernel that has been known to sometimes have operational issues with GO. From what I understand, the Devs of GO know about some of these unsupported Kernel Issues. Thank you for your continued efforts to keep Dnscrypt-proxy 2 a viable DNS privacy solution.