Potential bug: Assumption that POSIX time functions do not clobber errno

Florian Weimer fweimer at redhat.com
Tue Jul 13 21:38:44 EEST 2021


We accidentally ran the dovecot 2.3.14 testsuite on a host where
clock_gettime (and probably time and gettimeofday) succeed, but set
errno to ENOSYS.  This behavior is unusual, but permitted by POSIX:
successful function calls can overwrite errno, as long as they don't set
it to 0.

The relevant log excerpt looks like this:

make[3]: Entering directory '/builddir/build/BUILD/dovecot-2.3.14/src/master'  
for bin in test-auth-client test-auth-master test-master-login-auth; do \      
  if !  ./$bin; then exit 1; fi; \
done
test-common.c:200: Assert failed: suppress == TRUE                             
connection refused: run (ret == -1) .................................. : ok: Connection failed
CLIENT: Error: auth-client: conn unix:./auth-client-test: connect(./auth-client-test) failed: Function not implemented
connection refused ................................................... : FAILED
connection timed out: run (ret == -1) ................................ : ok: Connection failed
connection timed out: timeout ........................................ : ok
connection timed out ................................................. : ok
bad version: run (ret == -1) ......................................... : ok: Connection failed
bad version .......................................................... : ok
disconnect version: run (ret == -1) .................................. : ok: Internal failure
disconnect version ................................................... : ok
auth PLAIN disconnect: run (ret < 0) ................................. : ok
auth PLAIN disconnect ................................................ : ok
auth PLAIN reconnect: run (ret < 0) .................................. : ok
auth PLAIN reconnect ................................................. : ok
auth PLAIN failure: run (ret < 0) .................................... : ok
auth PLAIN failure ................................................... : ok
auth PLAIN success: run (ret == 0) ................................... : ok
auth PLAIN success ................................................... : ok
auth LOGIN failure 1: run (ret < 0) .................................. : ok
auth LOGIN failure 1 ................................................. : ok
auth LOGIN failure 2: run (ret < 0) .................................. : ok
auth LOGIN failure 2 ................................................. : ok
auth LOGIN success: run (ret == 0) ................................... : ok
auth LOGIN success ................................................... : ok
auth PLAIN parallel failure: run (ret < 0) ........................... : ok
auth PLAIN parallel failure .......................................... : ok
auth PLAIN parallel success: run (ret == 0) .......................... : ok
auth PLAIN parallel success .......................................... : ok
auth LOGIN parallel failure 1: run (ret < 0) ......................... : ok
auth LOGIN parallel failure 1 ........................................ : ok
auth LOGIN parallel failure 2: run (ret < 0) ......................... : ok
auth LOGIN parallel failure 2 ........................................ : ok
auth LOGIN parallel success: run (ret == 0) .......................... : ok
auth LOGIN parallel success .......................................... : ok
1 / 49 tests failed
make[3]: Leaving directory '/builddir/build/BUILD/dovecot-2.3.14/src/master'

“Function not implemented” suggests that dovecot somehow used the
clock_gettime (or gettimeofday) ENOSYS error instead of the expected
ECONNREFUSED error code.  Unfortunately, I have not figured out where
this exactly happens.

I don't expect that the problematic glibc build escapes to the wild
It was a glibc 2.34 development snapshot, and this particular source of
ENOSYS errors is gone again.  So fixing this is not urgent.

Thanks,
Florian



More information about the dovecot mailing list