#1000793 bind9-dnsutils: dig command fails with "`fd > STDERR_FILENO' failed" when run from a XFCE4 desktop applet

Package:
bind9-dnsutils
Source:
bind9
Description:
Clients provided with BIND 9
Submitter:
Enrique Garcia
Date:
2023-04-24 09:57:05 UTC
Severity:
normal
Tags:
#1000793#5
Date:
2021-11-28 23:48:33 UTC
From:
To:
I am experiencing a weird bug in which the dig command fails when run as part
of a shell script executed inside the XFCE4 "Generic monitor" plugin. The error
message is:

dig: ./src/unix/core.c:570: uv__close: Assertion `fd > STDERR_FILENO' failed.
Aborted

It looks like something doesn't like that the stdout or stderr is not managed
by the terminal.
The command I am running is:

dig @resolver4.opendns.com myip.opendns.com +short -4

As a way to reproduce it: add the "Generic monitor" plugin to a xfce4 panel and
in the properties set the command to the one above.

Is I run the command in the terminal then everything is fine.

#1000793#10
Date:
2021-11-29 09:32:24 UTC
From:
To:
That’s a constraint from libuv.

Why would the monitoring software **close** the stderr anyway?  It’s not
about the redirection, that would be fine.  The problem is that the “Generic monitoring”
plugin closes the stderr descriptor which seems to me as wrong thing
to do.

Ondrej
--
Ondřej Surý (He/Him)
ondrej@sury.org

#1000793#15
Date:
2021-11-29 23:53:20 UTC
From:
To:
Hi,

thanks for looking into this!

It might be that the source of the problem is in xfce-plugin-genmon, but
I traced down when this started to fail: it was after an upgrade from
bind9-libs 1:9.16.15-1 to 1:9.16.22-1~deb11u1. So something in that
upgrade changed the behavior in dig.

#1000793#20
Date:
2021-11-30 12:39:50 UTC
From:
To:
I have tracked it a bit more using the git code of bind9 under
https://gitlab.isc.org/isc-projects/bind9. It seems that in the v9_16_22
branch the problem started to happen with this commit:

* commit ef1d909fa96479e6c4832e2e76f3ce3912cab930
| Author: Evan Hunt <each@isc.org>
| Date:   Wed May 12 17:17:05 2021 -0700
|
|     backport of netmgr/taskmgr to 9.16
|
|     this rolls up numerous changes that have been applied to the
|     main branch, including moving isc_task operations into the
|     netmgr event loops, and other general stabilization.

Just in case this is useful...

#1000793#25
Date:
2021-11-30 12:41:02 UTC
From:
To:
Hi,

so, it’s actually not a stderr that gets closed, but stdout or stdin here (or all of them).

The thing that has changed between the versions is the number of file
descriptors open during the `dig` operation (there’s less descriptors
open by default and then the opened socket gets fd == 1.

epoll_create1(EPOLL_CLOEXEC)            = 1
pipe2([3, 4], O_CLOEXEC)                = 0

And then libuv complains about operating on fd < 2.

Writing a lightweight wrapper around dig:

#!/bin/sh
/usr/bin/dig $@ >/dev/null </dev/null

would fix the xfce-plugin-genmon that closes the stdout (or stdin).

Also dig can be called with +noall option to silence all output, so closing stdin
is also wrong here.

Given this test program:

#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>

int
main(void) {
	int fd = open("/tmp/test.txt", O_WRONLY | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH);

	assert(fd >= 0);

	write(STDOUT_FILENO, "stdout\n", 7);
	write(STDERR_FILENO, "stderr\n", 7);

	write(fd, "test\n", 5);

	close(fd);
}

You will get stuff written to wrong file if you close the STDOUT_FILENO and STDERR_FILENO:

$ rm *txt && ./a.out >stdout.txt 2>stderr.txt ; echo '== stdout ==' ; cat stdout.txt ; echo '== stderr ==' ; cat stderr.txt ; echo '== test.txt ==' && cat test.txt
== stdout ==
stdout
== stderr ==
stderr
== test.txt ==
test

$ rm *txt && ./a.out >&- 2>stderr.txt ; echo '== stdout ==' ; cat stdout.txt ; echo '== stderr ==' ; cat stderr.txt ; echo '== test.txt ==' && cat test.txt
== stdout ==
cat: stdout.txt: No such file or directory
== stderr ==
stderr
== test.txt ==
stdout
test

$ rm *txt && ./a.out >stdout.txt 2>&- ; echo '== stdout ==' ; cat stdout.txt ; echo '== stderr ==' ; cat stderr.txt ; echo '== test.txt ==' && cat test.txt
== stdout ==
stdout
== stderr ==
cat: stderr.txt: No such file or directory
== test.txt ==
stderr
test

Also see https://pubs.opengroup.org/onlinepubs/9699919799/functions/stdin.html

I am inclined to reassign this to xfce-plugin-genmon as it breaks POSIX.

Ondrej
--
Ondřej Surý (He/Him)
ondrej@sury.org

#1000793#30
Date:
2021-11-30 12:46:19 UTC
From:
To:
Yes, that’s the commit, but it’s not that something in BIND 9 changed. It just opens less file descriptors at start now.

I don’t think this is BIND 9 bug.

Ondrej
--
Ondřej Surý (He/Him)
ondrej@sury.org

#1000793#35
Date:
2021-11-30 13:52:07 UTC
From:
To:
Nope, I am not using Linux on Desktop.

Ondrej
--
Ondřej Surý (He/Him)
ondrej@sury.org

#1000793#40
Date:
2023-04-23 22:04:11 UTC
From:
To:
This turned out to be a bug in xfce4-genmon-plugin. For the record, this
is the bug report:

https://gitlab.xfce.org/panel-plugins/xfce4-genmon-plugin/-/issues/19

And this is the patch:

https://gitlab.xfce.org/cquike/xfce4-genmon-plugin/-/merge_requests/1

This is included in xfce4-genmon-plugin 4.2.0 released recently
(https://docs.xfce.org/panel-plugins/xfce4-genmon-plugin/start#latest_release).

#1000793#45
Date:
2023-04-24 09:52:59 UTC
From:
To:
Hi Cesar,

Thanks for following up on this. I'll reassign the bug accordingly.

Bernhard