REDHAT-BUG-2521135: High severity rsyslog rainerscript vulnerability
doFuncReplace() in grammar/rainerscript.c implements replace(source, find, replaceWith) as two passes over the source string: pass 1 computes the output length, pass 2 allocates that many bytes with esnewStr() and fills them. On partial-match failure the two passes rewind by different amounts — pass 1 does i -= (j - 1), pass 2 does i -= j — so pass 1 resumes scanning at matchStart + 2 while pass 2 resumes at matchStart + 1. Every match that begins one byte after a failed partial match is therefore counted by pass 2 but not by pass 1. When replaceWith is longer than find, each such match makes the allocation short by lReplaceWith - lfind bytes, and pass 2 writes past the end of the buffer. Neither store site is bounds-checked. The source string is normally a message property ($msg, $rawmsg, …), so an unauthenticated remote syslog sender chooses the number of missed matches and thus the size of the overflow.
Affected Software
Event History
Frequently Asked Questions
Who is realistically exposed to this issue?
Rsyslog deployments that apply the Rainerscript replace(source, find, replaceWith) function to attacker-controlled message properties such as $msg or $rawmsg are exposed. An unauthenticated remote syslog sender can control the source string.
What input conditions are required to trigger the overflow?
The replacement string must be longer than the string being searched for. The source must contain failed partial matches followed immediately by matches that begin one byte after those failures, causing the allocation pass to underestimate the required buffer size.
How can an attacker influence the overflow size?
An attacker can choose the number of missed matches in the supplied syslog message. Each affected match can make the allocation too small by the difference between the replacement-string length and find-string length, while the second pass writes beyond that allocation.