Issue Details (XML | Word | Printable)

Key: CORE-6012
Type: Bug Bug
Status: Resolved Resolved
Resolution: Won't Fix
Priority: Major Major
Assignee: Unassigned
Reporter: Artyom Smirnov
Votes: 0
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
Firebird Core

Possible server/utilities hang because of infinity loop in AbstractString::vprintf

Created: 25/Feb/19 01:06 PM   Updated: 25/Feb/19 01:41 PM
Component/s: Engine
Affects Version/s: 4.0 Initial, 3.0.0, 3.0.1, 3.0.2, 4.0 Alpha 1, 3.0.3, 3.0.4, 4.0 Beta 1, 3.0.5, 4.0 Beta 2, 3.0.6
Fix Version/s: None

QA Status: No test


 Description  « Hide
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?


 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Alexander Peshkov added a comment - 25/Feb/19 01:23 PM
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.

Roman Simakov added a comment - 25/Feb/19 01:41 PM
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.