If a malformed, severely too long TAG is used in legacy (RFC3164) syslog messages, rsyslog can abort based on the conditions described in this security advisory.
Affected Stable Versions:
v4.6.0 to 4.6.7 (inclusive)
v5.2.0 to 5.8.4 (inclusive)
Devel and Beta versions are probably also affected, but are not suitable for production and thus not analyzed in detail. Version 3 is not affeceted. Versions prior to 3 have not been analyzed.
Update to 4.6.8 or 5.8.5. The fix is also included in the following non-beta versions: 4.7.5, 5.9.3, 6.1.12, 6.3.5.
For non current affected versions, the following patches can most probably be applied: v4, v5. Note that due to the myriad of different versions we can not provide individual patches for all outdated versions (and in general it is less secure to run outdated versions).
An excessively long TAG inside a legacy syslog message can lead to a two-byte stack buffer overflow. If rsyslog has been compiled with stack guard, this can lead to an abort. This has been seen on 32bit platforms, but not on 64 bit ones (though not outruled there). If not compiled with stack guard, no fatal problem occurs and the tag character is usually just truncated. Exact behaviour depends on the platform and may be slightly different on compilers different from gcc and/or non-Intel architecture machines.
Denial of Service if triggering conditions are met. Remote code injection is not possible due to the limited size of the buffer overflow.
Yes, if rsyslog is configured to listen to remote hosts. This is not the case by default.
Adiscon’s severity Rating:
This is based on the fact that environment-specific non-default compile options must be selected to trigger this bug. However, stack guard is an option often activated by packages because it provides a very useful protection against attacks. So it is not unexpected that some packages contain this switch. Based on our check of some important distributions, a very small set of platforms actually was vulnerable.
If proper firewalling is applied, DoS may be triggered only from permitted hosts, e.g. as a second stage after an attack into these hosts.
An attacker may use this vulnerability to hide details of the attack (or even the fact that an attack is ongoing).
Some general advise:
It is highly suggested to apply proper firewalling to the syslog machine. Also, it is suggested to protect remote access to the syslog server via TLS and mutual authentication via RFC5424/5425, especially if syslog messages need to be accepted from public or semi-public networks.
We want to thank the Red Hat secrurity team for identifying this issue and working with us in resolving it.
The problem is rooted inside the legacy syslog parser. If the TAG is larger than the defined absolute max tag size, one or two bytes above the actual tag buffer, which is kept on the stack, is overwritten with a “\0” or “:\0” respectively. By default, this parser is called for all messages that do not have RFC5424 format. This includes local messages as well as remotely received ones. The problem is hard to reproduce on different platforms because it depends on many factors that need to go together. However, if it is reproducible, it is so always on the platform in question (so for an affected platform, the problem is always reproducible).
The problem is triggered by these variable definitions:
1193 int i; /* general index for parsing */
1194 uchar bufParseTAG[CONF_TAG_MAXSIZE];
1195 uchar bufParseHOSTNAME[CONF_HOSTNAME_MAXSIZE];
The buffer potentially overrun is bufParseTAG. Let’s assume the compiler does not reorder variables. Then the following happens:
(a) on many platforms, variable i is partially overwritten. This index is used shortly thereafter. Truncation of TAG can happen, but no abort:
(aa) on big endian machines, not follow-up error occurs, as the overwritten location continued 0 and the same value is written
(ab) on little endian machines, the lowest byte is overwritten with zero,leading to a truncation of the tag value.
(b) on some platforms, bufParseHOSTNAME is overrun. This is no problem, because it is no longer used when this happens. Also bufParseTAG is strcpy()’ed right away, so this causes no issue at all.
Not all possible permutations if the compiler reorders have been analyzed (a pointless excersice). But obviously, some of the them can cause problems. The most important cases are overwriting the parse pointer or, as seen here, the return address (if bufParseTAG is located right after it).
This rearrangement happens with stack guard. Without knowing the implementation details, it looks like stack guard seems to reorder EITHER bufParseTAG or bufParseHOSTNAME directly after the guard variable. If it is bufParseTAG, the overrun will be detected and an abort happens. However, if it is bufParseHOSTNAME, the problem will neither be detected nor cause any damage (as described above). Thus the problem is not always reproducible on all platforms even if stack guard is consistenly active.
We don’t see any theoretical evidence why 32 vs 64 bitness should make a difference, but problem reports seem to indicate that an abort only happens on 32 bit platforms.