[Mimedefang] Ext3 error caused action_quarantine_entire_message to fail + Proposed fix

Kevin A. McGrail kmcgrail at pccc.com
Fri Oct 16 15:39:29 EDT 2009

Apparently, my quarantining had stopped working on one of my servers.  From 
researching, the issue is a problem with ext3 with "the max number of 
subdirectories in one directory is fixed to 32000".

Moreover, the error was caused by poor error checking in my filter routine 
coupled with what I see as a necessary feature extension needed in MD's 
get_quarantine_dir routine.

I've already fixed my filter routine but we are getting hammered with 
phishing emails that are being quarantined so the 32K limit is a huge issue.

For those that care, here is the fix I added to my filter to error check 
action_quarantine_entire_message.  Because of the dangerous attachments, I 
still chose to run action_drop_with_warning at the end.

        if (action_quarantine_entire_message()) {
          $quarantine_dir = get_quarantine_dir();
          $short_qdir = $quarantine_dir;
          $short_qdir =~ s/^.*\/qdir/qdir/;
          md_syslog( 'info', "$QueueID: MSG Quarantined: $quarantine_dir");
        } else {
          md_syslog( 'error', "$QueueID: MSG Quarantine failed!");
          $short_qdir = "[Error: The Message was Not Quarantined]\n";

David, what do you think of adding a subdirectory for day/hour to the 
quarantine dir?  Below is a quick throw together (not compiled or tested) on 
the issue.  The goal being to add more subdirectories and not bomb out on 
more than 32K quarantined messages.

First a new routine:

# %PROCEDURE: short_time_str
#  None
#  The current time in the form: "YYYY-MM-DD-HH"
#  Returns a string representing the current date and hour
sub short_time_str () {
    my($sec, $min, $hour, $mday, $mon, $year, $junk);
    ($sec, $min, $hour, $mday, $mon, $year, $junk) = localtime(time());
    return sprintf("%04d-%02d-%02d-%02d",
                   $year + 1900, $mon+1, $mday, $hour);

Then in get_quarantine_dir, adding these lines below the current my ($tm); 
(line 1299 in 2.67):

$short_tm = short_time_str();
$QuarantineSubdir = sprintf("%s/%s",

unless (-d $QuarantineSubdir) {
   if (mkdir($QuarantineSubdir, 0750)) {
      $success = 1;

if (!$success)
        $QuarantineSubdir = "";
        return "";

Finally, change:

$QuarantineSubdir = sprintf("%s/%s/qdir-%s-%03d",
$short_tm, $tm, $counter);

My belief is that these would seamlessly make the issue much less likely to 
occur.  Of course, that goes on the premise that subdirs of subdirs don't 
count towards the 32000 limit.


More information about the MIMEDefang mailing list