BIND 9.20.0: compat setresuid() is mis-implemented
Summary
When instructing named
to run as a non-privileged user, this is logged:
Aug 19 10:45:41 xxxxx named[25583]: unable to set effective uid to 14: Undefined error: 0
BIND version affected
$ /usr/local/sbin/named -V
BIND 9.20.0 (Stable Release) <id:14bbdfc>
running on NetBSD amd64 10.0 NetBSD 10.0 (GENERIC) #0: Thu Mar 28 08:33:33 UTC 2024 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC
built by make with '--with-libxml2=yes' '--with-tuning=large' '--enable-dnstap' '--sysconfdir=/etc' '--localstatedir=/var' '--with-openssl=/usr/lib'
compiled by GCC 10.5.0
compiled with OpenSSL version: OpenSSL 3.0.12 24 Oct 2023
linked to OpenSSL version: OpenSSL 3.0.12 24 Oct 2023
compiled with libuv version: 1.48.0
linked to libuv version: 1.48.0
compiled with liburcu version: 0.12.1
compiled with libnghttp2 version: 1.62.1
linked to libnghttp2 version: 1.62.1
compiled with libxml2 version: 2.12.8
linked to libxml2 version: 21208
compiled with zlib version: 1.2.13
linked to zlib version: 1.2.13
compiled with protobuf-c version: 1.5.0
linked to protobuf-c version: 1.5.0
threads support is enabled
DNSSEC algorithms: RSASHA1 NSEC3RSASHA1 RSASHA256 RSASHA512 ECDSAP256SHA256 ECDSAP384SHA384 ED25519 ED448
DS algorithms: SHA-1 SHA-256 SHA-384
HMAC algorithms: HMAC-MD5 HMAC-SHA1 HMAC-SHA224 HMAC-SHA256 HMAC-SHA384 HMAC-SHA512
TKEY mode 2 support (Diffie-Hellman): no
TKEY mode 3 support (GSS-API): yes
default paths:
named configuration: /etc/named.conf
rndc configuration: /etc/rndc.conf
nsupdate session key: /var/run/named/session.key
named PID file: /var/run/named/named.pid
$
Steps to reproduce
- Instruct named to start as user
named
via CLI switch:
$ ps axww | grep named
23212 ? Ssl 0:00.10 /usr/local/sbin/named -u named -t /var/chroot/named
3878 pts/3 S+ 0:00.00 grep named
$
- Try to do this on NetBSD 10.0
- Try to figure out why
rndc
no longer works, despite named running (that's a separate problem...) - Look at the syslog, and find the above error message
What is the current bug behavior?
named
does not manage to switch to the un-privileged userID.
Doing ktrace -i sh /etc/rc.d/named start
reveals:
25583 25583 named CALL getuid
25583 25583 named RET getuid 0
25583 25583 named CALL getgid
25583 25583 named RET getgid 0
25583 25583 named CALL getegid
25583 25583 named RET getegid 0
25583 25583 named CALL setregid(0xffffffff,0xe)
25583 25583 named RET setregid 0
25583 25583 named CALL getegid
25583 25583 named RET getegid 14/0xe
25583 25583 named CALL geteuid
25583 25583 named RET geteuid 0
25583 25583 named CALL setregid(0xffffffff,0xe)
25583 25583 named RET setregid 0
25583 25583 named CALL geteuid
25583 25583 named RET geteuid 0
25583 25583 named CALL issetugid
25583 25583 named RET issetugid 1
25583 25583 named CALL open(0x7f7fff80d410,0x400000,0xff80d42b)
25583 25583 named NAMI "/usr/share/nls/nls.alias.db"
25583 25583 named RET open -1 errno 2 No such file or directory
25583 25583 named CALL open(0x77d9cf59394b,0x400000,0)
25583 25583 named NAMI "/usr/share/nls/nls.alias"
25583 25583 named RET open -1 errno 2 No such file or directory
25583 25583 named CALL open(0x7f7fff80dce0,0x400000,0x3a)
25583 25583 named NAMI "/usr/share/nls/C/libc.cat"
25583 25583 named RET open -1 errno 2 No such file or directory
25583 25583 named CALL open(0x7f7fff80dce0,0x400000,0)
25583 25583 named NAMI "/usr/share/nls/libc/C"
25583 25583 named RET open -1 errno 2 No such file or directory
25583 25583 named CALL __gettimeofday50(0x7f7fff80c9b0,0)
25583 25583 named RET __gettimeofday50 0
25583 25583 named CALL getpid
25583 25583 named RET getpid 25583/0x63ef, 29687/0x73f7
25583 25583 named CALL fcntl(3,F_GETFL,0)
25583 25583 named RET fcntl 2
25583 25583 named CALL sendto(3,0x7f7fff80d410,0x8c,0,0,0)
25583 25583 named MISC msghdr: [name=0x0, namelen=0, iov=0xffffbb013bf83f50, iovlen=1, control=0x0, controllen=0, flags=0]
25583 25583 named GIO fd 3 wrote 140 bytes
"<28>1 2024-08-19T10:45:41.710927+00:00 xxxxxxx.xxxxx.no named \
25583 - - unable to set effective uid to 14: No such file or directory"
Note that named
here isn't actually trying to switch the user-ID(!), but rather the group-ID(!)
What is the expected correct behavior?
named
should switch to the userID represented by the -u
argument on the command line.
Relevant configuration files
Not really relevant here...
Relevant logs
See above.
I think this fixes the misplaced conditionals in the implementation of setresuid()
:
$ diff -U 10 bin/named/os.c.orig bin/named/os.c
--- bin/named/os.c.orig 2024-08-19 10:58:30.532424980 +0000
+++ bin/named/os.c 2024-08-19 10:58:54.025288332 +0000
@@ -288,25 +288,25 @@
return (0);
}
#endif /* !HAVE_GETRESUID */
#if !HAVE_SETRESUID
static int
setresuid(uid_t ruid, uid_t euid, uid_t suid) {
REQUIRE(ruid == (uid_t)-1);
REQUIRE(suid == (uid_t)-1);
-#if HAVE_SETREGID
- return (setregid(ruid, euid));
-#else /* HAVE_SETREGID */
- return (setegid(euid));
-#endif /* HAVE_SETREGID */
+#if HAVE_SETREUID
+ return (setreuid(ruid, euid));
+#else /* HAVE_SETREUID */
+ return (seteuid(euid));
+#endif /* HAVE_SETREUID */
}
#endif /* !HAVE_SETRESUID */
static int
set_effective_gid(gid_t gid) {
gid_t oldgid;
if (getresgid(&(gid_t){ 0 }, &oldgid, &(gid_t){ 0 }) == -1) {
return (-1);
}
$
Edited by Håvard Eidnes