Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible server/utilities hang because of infinity loop in AbstractString::vprintf [CORE6012] #6262

Closed
firebird-automations opened this issue Feb 25, 2019 · 3 comments

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: @artyom-smirnov

The problem is because only result of vsnprintf checked, but not cause of this result (e.g. errno).

One of case with this issue I've got and reproduced is hanging gsec on CentOS 6 which have bug in glibc (https://sourceware.org/bugzilla/show_bug.cgi?id=6530)

For example simple reproduction for FB 3.x/4.x: shutdown server, create system audit file with service auditing and add it to firebird.conf:

services
{
enabled = true
log_filename = /tmp/log
log_services = true
log_service_query = false
}

Run gsec with locale which is not POSIX or C:

LANG=en_US.utf8 bin/gsec -user SYSDBA -password masterkey -add test -pw test

vprintf will get string like "-user SYSDBA -ADD \377TEST\377 -PW \377test\377" and will hang on it, because vsnprintf result always be -1 and errno always be 84.

All versions affected by infinity loop hang, because this part of code is same, but this particular case of course will hang only on 3.x/4.x.

What about:
1. Checking errno in vprintf and at least throw exception instead hang?
2. Cleanup service terminal symbols in TracePluginImpl::log_event_service_start before passing it to vprintf?

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

In manual page for vsnprintf I see:

RETURN VALUE
Upon successful return, these functions return the number of characters printed (excluding the null byte used to end output
to strings).

   The functions snprintf\(\) and vsnprintf\(\) do not write more than size bytes \(including the terminating null byte \('\\0'\)\)\.  If
   the output was truncated due to this limit, then the return value is the number of  characters  \(excluding  the  terminating
   null  byte\)  which  would have been written to the final string if enough space had been available\.  Thus, a return value of
   size or more means that the output was truncated\.  \(See also below under NOTES\.\)

   If an output error is encountered, a negative value is returned\.

Nothing is said about ability to check errno - the fact and the only reason to return negative value is _output error_.

Yes, that could be nice to make firebird never hang. No matter of bugs in libc. But in this particular case trying to analyze normally unused (and therefore having unknown value) errno may only cause suspicious behavior in a places that currently work OK.

@firebird-automations
Copy link
Collaborator Author

Modified by: @AlexPeshkoff

status: Open [ 1 ] => Resolved [ 5 ]

resolution: Won't Fix [ 2 ]

@firebird-automations
Copy link
Collaborator Author

Commented by: @romansimakov

Alex, we may not use errno, but we have to check negative value as said you doc which you've quoted. No?
Also you have no answered the second suggestion. Why to try print \377 symbol in trace?
Such "strange hangs" can happen at old glibc and I think we can and must to reduce a possibility of that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment