Hello to everyone.

I have discovered a couple of bugs related to the sieve
implementation in mailutils 1.0. For the first, I include a patch that
solves it, while 
for the second I have written the necessary code to expose it and I
cannot (in short time) provide a fix myself.

The first bug has to do with the vacation action implementation. In
libsieve/extensions/vacation.c file, vacation_subject() function, at
(or near) line 411 there is a check

else if (mu_message_get_header (msg, &hdr) == 0
     && mu_header_aget_value_unfold (hdr, MU_HEADER_SUBJECT, &value)
     == 0)

The problem is when this check fails, when for example the message has
no subject or its subject is empty. In this case, the control goes to 

  if (mu_rfc2047_encode (MU_SIEVE_CHARSET, "quoted-printable",
                         subject, &value))

with a random subject pointer. Also the variable subject_allocated is
uninitialized. We have noticed excaustive cpu usage in our delivery
agent in our production systems because of this

(example stack trace:

#0  0xb7ea80d3 in mallopt () from /lib/tls/libc.so.6
#1  0xb7ea7f6e in mallopt () from /lib/tls/libc.so.6
#2  0xb7ea6dcb in free () from /lib/tls/libc.so.6
#3  0xb7fa7dbe in mu_header_set_value () 
#4  0xb7a4d740 in vacation_reply () 
#5  0xb7a4da38 in sieve_action_vacation () 
#6  0xb7f811fe in instr_run () 
#7  0xb7f81293 in instr_action () 
#8  0xb7f818c5 in sieve_run () 
#9  0xb7f81b88 in mu_sieve_message () 
...)

The attached patch solves the issue.

The second bug is in the sieve parser. To demonstrate the bug, I have
implemented a new sieve action called notify (attached also). This
notify action accepts a tag and has no arguments

notify  [:method <url: string>]
 
When you have a sieve file like

#searchpath "/path/to/mailutils"
require["notify"];

if header :contains ["from"] ["kzorba"] { notify :method "sms:+3069XXXXXX"; }

everything is fine, but if you make a syntactic error and you have

#searchpath "/path/to/mailutils"
require["notify"];

if header :contains ["from"] ["kzorba"] { notify :method ; }
(the tag's argument is missing) then the sieve engine consumes all cpu
resources with the following stack trace:

(gdb) bt
#0  0xb7dd4e13 in pthread_rwlock_wrlock () from /lib/tls/libpthread.so.0
#1  0xb7fa0fc7 in monitor_pthread_wrlock (lock=0x80548d8) at monitor.c:280
#2  0xb7fa0e67 in mu_monitor_wrlock (monitor=0x8050f48) at monitor.c:179
#3  0xb7f94d41 in mu_list_append (list=0x80548b0, item=0x98d2c728) at list.c:92
#4  0xb7f6fc63 in mu_sieve_palloc (pool=0x80547a8, size=8) at util.c:52
#5  0xb7f6fdeb in mu_sieve_malloc (mach=0x80547a0, size=8) at util.c:108
#6  0xb7f69234 in sieve_code_command (reg=0x80596e8, arglist=0x805a428) at 
prog.c:202
#7  0xb7f697c7 in sieve_code_action (reg=0x80596e8, arglist=0x805a428) at 
prog.c:355
#8  0xb7f6bb8d in mu_sieve_yyparse () at sieve.y:266
#9  0xb7f6c9ba in mu_sieve_compile (mach=0x80547a0, name=0xbfffc660 
"XXX.sieve") at sieve.y:603

Any input is highly welcome.

Regards,
Kostas


-- 
  Kostas Zorbadelos
  [EMAIL PROTECTED] contact: kzorba (at) otenet.gr
  
  Out there in the darkness, out there in the night
  out there in the starlight, one soul burns brighter
  than a thousand suns.

--- vacation.c.orig     2006-09-12 11:24:50.000000000 +0300
+++ vacation.c.patched  2006-10-03 17:18:47.233459022 +0300
@@ -399,8 +399,8 @@
 {
   mu_sieve_value_t *arg;
   char *value;
-  char *subject;
-  int subject_allocated;
+  char *subject = NULL;
+  int subject_allocated = 0;
   mu_header_t hdr;
   
   if (mu_sieve_tag_lookup (tags, "subject", &arg))
@@ -449,6 +449,9 @@
       free (value);
     }
 
+  if (subject == NULL) /* The original message had no subject or its subject 
was empty */
+    subject = "Re: Your mail";
+
   if (mu_rfc2047_encode (MU_SIEVE_CHARSET, "quoted-printable",
                         subject, &value))
     mu_header_set_value (newhdr, MU_HEADER_SUBJECT, subject, 0);
/* A sceleton notify action. This is to demonstrate the bug in the 
   sieve engine's parsing.

   Author: Kostas Zorbadelos 
   Last modification: 3/10/2006 
   Syntax: notify  [:method <url: string>]
*/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <mailutils/libsieve.h>

/* Produce diagnostic output. */
static int
diag (mu_sieve_machine_t mach)
{
  if (mu_sieve_get_debug_level (mach) & MU_SIEVE_DEBUG_TRACE)
    {
      mu_sieve_locus_t locus;
      mu_sieve_get_locus (mach, &locus);
      mu_sieve_debug (mach, "%s:%lu: NOTIFY\n",
		      locus.source_file,
		      (unsigned long) locus.source_line);
    }

  mu_sieve_log_action (mach, "NOTIFY", NULL);
  return mu_sieve_is_dry_run (mach);
}


/* ------------------------------------------------------------------------- */
/* The notify action function */
/* ------------------------------------------------------------------------- */
int
sieve_action_notify (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
{
  mu_sieve_value_t *val;
  int status;
  mu_sieve_locus_t locus;
  char *url;

  if (diag (mach))
    return 0;

  status = mu_sieve_get_locus (mach, &locus);
  if (status) /* Cannot get locus ?! */
    {
      mu_sieve_error (mach, "NOTIFY: Cannot get locus for sieve engine");
      return -1;
    }
  if (mu_sieve_tag_lookup (tags, "method", &val))
    {
      url = val->v.string;
    }
  else
    {      
      mu_sieve_error (mach,"%s:%lu: NOTIFY: cannot get :method tag",
		      locus.source_file,
		      (unsigned long) locus.source_line);
      return -1;
    }

  return 0;

}


/* Tagged arguments: */
static mu_sieve_tag_def_t notify_tags[] = {
  {"method", SVT_STRING},
  {NULL}
};

static mu_sieve_tag_group_t notify_tag_groups[] = {
  {notify_tags, NULL},
  {NULL}
};

/* Required arguments: */
/* There are no required arguments */
static mu_sieve_data_type notify_args[] = {
  SVT_VOID
};

int SIEVE_EXPORT (notify, init) (mu_sieve_machine_t mach)
{
  return mu_sieve_register_action (mach, "notify", sieve_action_notify,
				   notify_args, notify_tag_groups, 1);
}
_______________________________________________
Bug-mailutils mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-mailutils

Reply via email to