SA Bugzilla – Bug 4103
Deep recursion error
Last modified: 2005-09-30 03:25:30 UTC
This bug might be considered a denial-of-service problem. A mail with many nested MIME messages will cause spamassassin and spamc/spamd to consume alot of memory and CPU. Example: 180 MB memory and 21 CPU seconds on an Intel Pentium 3, 1133MHz for a mail of about 200 kB with 122 nested MIME messages. The problem seems to only affect SA from version 3.0. It has been observed on 3.0.1, 3.0.2 and 3.1 trunk. The problem doesn't seem to exist in 2.64. The problem has been discussed on the users list: http://thread.gmane.org/gmane.mail.spam.spamassassin.general/62309 Several error messages will be logged about "Deep recursion": Jan 18 10:40:31 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::parse_body" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message.pm line 521, <GEN3284> line 6525. Jan 18 10:40:34 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::_do_parse" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message.pm line 242, <GEN3284> line 6525. Jan 18 10:40:34 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::_parse_normal" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message.pm line 446, <GEN3284> line 6525. Jan 18 10:40:34 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::_do_parse" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message.pm line 242, <GEN3284> line 6525. Jan 18 10:40:34 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::_parse_multipart" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message.pm line 437, <GEN3284> line 6525. Jan 18 10:40:34 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::_parse_normal" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message.pm line 446, <GEN3284> line 6525. Jan 18 10:40:34 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::_parse_normal" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message.pm line 446, <GEN3284> line 6525. Jan 18 10:40:34 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::new" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message.pm line 611, <GEN3284> line 6525. Jan 18 10:40:34 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::_parse_normal" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message.pm line 446, <GEN3284> line 6525. Jan 18 10:40:34 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::new" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message.pm line 611, <GEN3284> line 6525. Jan 18 10:40:37 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::Node::_find_parts" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message/Node.pm line 122, <GEN3284> line 6525. Jan 18 10:40:44 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::Node::_find_parts" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message/Node.pm line 122, <GEN3284> line 6525. Jan 18 10:40:46 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::Node::_find_parts" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message/Node.pm line 122. Jan 18 10:40:46 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::Node::content_summary" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message/Node.pm line 460. Jan 18 10:40:50 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::Node::finish" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message/Node.pm line 659. Jan 18 10:41:02 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::finish" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message/Node.pm line 659. Jan 18 10:41:02 imf spamd[6173]: Deep recursion on subroutine "Mail::SpamAssassin::Message::finish" at /usr/lib/perl5/site_perl/5.8.5/Mail/SpamAssassin/Message/Node.pm line 659.
Created attachment 2625 [details] message that triggers the problem Scanning this message with spamc/spamd or spamassassin will consume 180 MB memory on SA 3.
security issue
We need to add a recursion limit for any recursive message. I'm not sure how deep, we should make it work deep enough for any typical spam, ham, etc. that doesn't go overboard.
I'd say a quite-low limit would be perfectly sane -- like 5 levels deep. I don't think any MUAs will expand all message/rfc822 parts more than that, without user intervention; and if the MUAs won't display the message, then it's not a spammable vulnerability. In the meantime, what we have here is a DoS vulnerability. (at least to a degree.)
(In reply to comment #4) > I'd say a quite-low limit would be perfectly sane -- like 5 levels deep. How about 1? I can't think of any case where we'd want to go past the first level. I committed a fix as r168632. It defaults to a level of 1, but we can set it to any number we want. Martin, can you try out a 3.1 version r168632 or later and see if the issue is fixed? BTW: I couldn't reproduce the problem on my box with this message, but it could be a platform/perl version/etc thing.
Actually, hang on for a minute on this. The commit addresses one issue, but it doesn't deal with message/* parts in multipart/* parts. <sigh> (In reply to comment #5) > I committed a fix as r168632. It defaults to a level of 1, but we can set it to any number we want. Martin, > can you try out a 3.1 version r168632 or later and see if the issue is fixed?
Heh. Turns out the original commit did work, but did so by effectively disabling subparsing completely. Oops. Anyway, I fixed that issue and it should now work properly with multipart/* -> message/* parts as well. I had to modify t/mimeparse.t also as it was testing out >1 subparsing. r168638 (In reply to comment #6) > Actually, hang on for a minute on this. The commit addresses one issue, but it doesn't deal with > message/* parts in multipart/* parts. <sigh>
maybe we should come up with a test for this, and fix it based on what the test does ;)
(In reply to comment #5) > I committed a fix as r168632. It defaults to a level of 1, but we can set it to any number we want. Martin, > can you try out a 3.1 version r168632 or later and see if the issue is fixed? I tried r169362. spamd takes 20 seconds on an Intel Pentium3 800 MHz. Memory usage rises from 24M when spamd starts to 31M when spamd has processed the message. So your fix seems to be working.
marking FIXED. I've checked in a test, t/recursion.t, that exercises this pretty extensively on top of the t/mimeparse.t stuff, and I can't see a problem any more. cool ;) r169559.
*** Bug 4483 has been marked as a duplicate of this bug. ***
unchecking "security", as the fixes have in the field for nearly 5 months now...